Skip to content

_vultr

sc_crawler.vendors._vultr #

Functions:

Name Description
inventory_regions

List all regions from Vultr API.

inventory_zones

List all regions as availability zones.

inventory_servers

List all servers from Vultr API.

inventory_traffic_prices

Public network traffic rates (flat worldwide).

inventory_ipv4_prices

Reserved / additional public IPv4 (flat worldwide).

inventory_databases

List Vultr managed PostgreSQL plans.

inventory_database_storages

Vultr managed PostgreSQL storage is bundled into DB plans.

inventory_database_storage_prices

No standalone Vultr managed DB storage price meters are exposed.

inventory_regions #

inventory_regions(vendor)

List all regions from Vultr API.

Source code in sc_crawler/vendors/_vultr.py
def inventory_regions(vendor):
    """List all regions from Vultr API."""
    items = []
    regions = _get_regions()
    for region in regions:
        with sentry_capture_or_raise(vendor=vendor):
            location = _REGION_LOCATIONS.get(region["id"], {})
            items.append(
                {
                    "vendor_id": vendor.vendor_id,
                    "region_id": region["id"],
                    "name": region["city"],
                    "api_reference": region["id"],
                    "display_name": f"{region['city']} ({region['country']})",
                    "aliases": [],
                    "country_id": region["country"],
                    "state": location.get("state"),
                    "city": region["city"],
                    "address_line": None,
                    "zip_code": None,
                    "lon": location.get("lon"),
                    "lat": location.get("lat"),
                    "founding_year": location.get("founding_year"),
                    "green_energy": location.get("green_energy"),
                }
            )
    return items

inventory_zones #

inventory_zones(vendor)

List all regions as availability zones.

There is no concept of having multiple availability zones within a region (virtual datacenter) at Vultr, so creating 1-1 dummy Zones reusing the Region id and name.

Source code in sc_crawler/vendors/_vultr.py
def inventory_zones(vendor):
    """List all regions as availability zones.

    There is no concept of having multiple availability zones within
    a region (virtual datacenter) at Vultr, so creating 1-1
    dummy Zones reusing the Region id and name.

    """
    items = []
    for region in vendor.regions:
        items.append(
            {
                "vendor_id": vendor.vendor_id,
                "region_id": region.region_id,
                "zone_id": region.region_id,
                "name": region.name,
                "api_reference": region.name,
                "display_name": region.name,
            }
        )
    return items

inventory_servers #

inventory_servers(vendor)

List all servers from Vultr API.

Lifecycle: free plan or empty locations -> INACTIVE, otherwise ACTIVE.

Source code in sc_crawler/vendors/_vultr.py
def inventory_servers(vendor):
    """List all servers from Vultr API.

    Lifecycle: free plan or empty `locations` -> INACTIVE, otherwise ACTIVE.
    """
    plans = _get_plans()
    plans_metal = _get_plans_metal()

    items = []
    for server in plans + plans_metal:
        # CPU
        cpu_model_raw = server.get("cpu_model", "")
        cpu_manufacturer = server.get("cpu_vendor") or server.get("cpu_manufacturer")
        cpu_family = _extract_cpu_family(cpu_model_raw)
        cpu_model = _standardize_cpu_model(cpu_model_raw)
        vcpus = server.get("vcpu_count") or server.get("cpu_threads")
        cpu_cores = server.get("cpu_count")
        # Plan type → CPU allocation (API has no dedicated/shared flag).
        # Shared: vc2, vhp, vhf — https://www.vultr.com/pricing/ ("Cloud Compute" /
        #   "These virtual machines run atop shared vCPUs")
        # Dedicated: voc — same page ("Optimized Cloud Compute" / "fully dedicated")
        # Dedicated: vx1 — https://docs.vultr.com/vultr-vx1-cloud-compute
        # Dedicated: vcg, vdm, and bare metal (type SSD/NVMe from /v2/plans/metal)
        cpu_allocation = (
            CpuAllocation.SHARED
            if server.get("type") in ("vc2", "vhp", "vhf")
            else CpuAllocation.DEDICATED
        )
        cpu_architecture = (
            CpuArchitecture.ARM64 if cpu_family == "Grace" else CpuArchitecture.X86_64
        )
        cpu_speed_mhz = server.get("cpu_mhz")
        cpu_speed_ghz = cpu_speed_mhz / 1000 if cpu_speed_mhz else None

        # Memory
        memory_amount = server["ram"]

        # GPU
        gpu_brand = server.get("gpu_brand", "")
        gpu_type = server.get("gpu_type")
        gpu_vram_total_gb = server.get("gpu_vram_gb") or 0
        gpu_count_from_api = server.get("gpu_count")
        gpu_fallback = _DEDICATED_METAL_GPU_PLANS.get(server["id"])
        if gpu_fallback:
            gpu_type = gpu_type or gpu_fallback.get("gpu_type")
            gpu_vram_total_gb = gpu_vram_total_gb or gpu_fallback.get(
                "gpu_vram_total_gb", 0
            )
            gpu_count_from_api = gpu_count_from_api or gpu_fallback.get("gpu_count")
            if not gpu_brand and gpu_type:
                gpu_brand = gpu_type.split("_")[0]
        gpu_manufacturer_from_type = gpu_type.split("_")[0] if gpu_type else ""
        gpu_manufacturer = _extract_manufacturer(gpu_brand) or _extract_manufacturer(
            gpu_manufacturer_from_type
        )
        gpu_profile = _GPU_TYPES.get(gpu_type, {})
        gpu_vram_gb = gpu_profile.get("vram_gb")
        gpu_family = gpu_profile.get("family")
        gpu_memory_min = (
            int(min(gpu_vram_gb, gpu_vram_total_gb) * _MIB_PER_GIB)
            if gpu_vram_gb and gpu_vram_total_gb
            else 0
        )
        gpu_count = None
        if gpu_count_from_api:
            if isinstance(gpu_count_from_api, str) and "/" in gpu_count_from_api:
                num, den = gpu_count_from_api.split("/", 1)
                gpu_count = round(int(num) / int(den), 4)
            else:
                gpu_count = gpu_count_from_api
        if gpu_count is None:
            gpu_count = (
                round(gpu_vram_total_gb / gpu_vram_gb, 4)
                if gpu_vram_gb and gpu_vram_total_gb
                else 0
            )
        if gpu_type:
            gpu_model_parts = gpu_type.split("_")
            if len(gpu_model_parts) > 1:
                gpu_model = gpu_model_parts[1]
            else:
                gpu_model = gpu_type
        else:
            gpu_model = None

        # Storage
        storage_size_per_disk = server.get("disk")
        storage_type = _storage_type_from_plan(server)
        storage_size = storage_size_per_disk * server.get("disk_count", 1)
        family = _PLAN_TYPES.get(server["type"])

        description = _server_description(
            family,
            vcpus,
            memory_amount,
            storage_size,
            storage_type,
            gpu_count,
            gpu_model,
            gpu_vram_gb,
        )

        item = {
            "vendor_id": vendor.vendor_id,
            "server_id": server["id"],
            "name": server["id"],
            "api_reference": server["id"],
            "display_name": server["id"],
            "description": description,
            "family": family,
            "vcpus": vcpus,
            "hypervisor": None,
            "cpu_allocation": cpu_allocation,
            "cpu_cores": cpu_cores,
            "cpu_speed": cpu_speed_ghz,
            "cpu_architecture": cpu_architecture,
            "cpu_manufacturer": cpu_manufacturer,
            "cpu_family": cpu_family,
            "cpu_model": cpu_model,
            "cpu_l1d_cache": None,
            "cpu_l1d_cache_total": None,
            "cpu_l1i_cache": None,
            "cpu_l1i_cache_total": None,
            "cpu_l2_cache": None,
            "cpu_l2_cache_total": None,
            "cpu_l3_cache": None,
            "cpu_l3_cache_total": None,
            "cpu_flags": [],
            "cpus": [],
            "memory_amount": memory_amount,
            "memory_generation": None,
            "memory_speed": None,
            "memory_ecc": None,
            "gpu_count": gpu_count,
            "gpu_memory_min": gpu_memory_min,
            "gpu_memory_total": (
                int(gpu_vram_total_gb * _MIB_PER_GIB) if gpu_vram_total_gb else 0
            ),
            "gpu_manufacturer": gpu_manufacturer,
            "gpu_family": gpu_family,
            "gpu_model": gpu_model,
            "gpus": [],
            "storage_size": storage_size,
            "storage_type": storage_type,
            "storages": [],
            "network_speed_baseline": None,
            # link_speed is Gbps when present ("up to" / provisioned; no documented baseline)
            # link_type (shared|dedicated) is network uplink, not mapped to a column
            "network_speed_max": server.get("link_speed"),
            "network_storage_speed_baseline": None,
            "network_storage_speed_max": None,
            "inbound_traffic": 0,
            "outbound_traffic": server.get("bandwidth", 0),
            # the smallest plan is IPv6-only
            "ipv4": 0 if server["id"] == "vc2-1c-0.5gb-v6" else 1,
        }

        # exclude limited plans not generally available without scale
        if item["server_id"] == "vc2-1c-0.5gb-free" or not server.get("locations"):
            item["status"] = Status.INACTIVE
        else:
            item["status"] = Status.ACTIVE

        items.append(item)
    return items

inventory_traffic_prices #

inventory_traffic_prices(vendor)

Public network traffic rates (flat worldwide).

Ingress is free. Outbound overage beyond pooled plan + account quota is billed per GB; included allowances are on each server plan bandwidth field.

Source: https://docs.vultr.com/support/platform/billing/what-is-the-bandwidth-overage-rate

Source code in sc_crawler/vendors/_vultr.py
def inventory_traffic_prices(vendor):
    """Public network traffic rates (flat worldwide).

    Ingress is free. Outbound overage beyond pooled plan + account quota is
    billed per GB; included allowances are on each server plan ``bandwidth`` field.

    Source: <https://docs.vultr.com/support/platform/billing/what-is-the-bandwidth-overage-rate>
    """
    items = []
    regions = _get_regions()
    for region in regions:
        items.append(
            {
                "vendor_id": vendor.vendor_id,
                "region_id": region["id"],
                "price": 0,
                "price_tiered": [],
                "currency": "USD",
                "unit": PriceUnit.GB_MONTH,
                "direction": TrafficDirection.IN,
            }
        )
        items.append(
            {
                "vendor_id": vendor.vendor_id,
                "region_id": region["id"],
                "price": 0.01,
                "price_tiered": [],
                "currency": "USD",
                "unit": PriceUnit.GB_MONTH,
                "direction": TrafficDirection.OUT,
            }
        )
    return items

inventory_ipv4_prices #

inventory_ipv4_prices(vendor)

Reserved / additional public IPv4 (flat worldwide).

Primary instance IPv4 is included in compute pricing; this is the published rate for reserved IPs (also used for extra addresses).

Source: https://docs.vultr.com/support/products/network/are-reserved-ips-free

Source code in sc_crawler/vendors/_vultr.py
def inventory_ipv4_prices(vendor):
    """Reserved / additional public IPv4 (flat worldwide).

    Primary instance IPv4 is included in compute pricing; this is the published
    rate for reserved IPs (also used for extra addresses).

    Source: <https://docs.vultr.com/support/products/network/are-reserved-ips-free>
    """
    items = []
    regions = _get_regions()
    for region in regions:
        items.append(
            {
                "vendor_id": vendor.vendor_id,
                "region_id": region["id"],
                "price": 3.0,
                "currency": "USD",
                "unit": PriceUnit.MONTH,
            }
        )
    return items

inventory_databases #

inventory_databases(vendor)

List Vultr managed PostgreSQL plans.

  • Provisioning uses POST /v2/databases with plan and database_engine.
  • Plan ids come from GET /v2/databases/plans.
  • Vultr Managed Databases are managed clusters, not plain VM images. https://docs.vultr.com/products/storage/databases/postgresql/provisioning https://docs.vultr.com/products/storage/databases
Source code in sc_crawler/vendors/_vultr.py
def inventory_databases(vendor):
    """List Vultr managed PostgreSQL plans.

    - Provisioning uses POST /v2/databases with `plan` and `database_engine`.
    - Plan ids come from GET /v2/databases/plans.
    - Vultr Managed Databases are managed clusters, not plain VM images.
    https://docs.vultr.com/products/storage/databases/postgresql/provisioning
    https://docs.vultr.com/products/storage/databases
    """
    plans = _get_database_plans()
    services = _get_database_available_services()
    # Source: GET /v2/databases/available-services (`available_services.pg`).
    # https://www.vultr.com/api/
    versions = services.get("available_services", {}).get("pg", [])
    items = []
    for plan in plans:
        database_id = plan.get("id")
        vcpus = plan.get("vcpu_count")
        memory = plan.get("ram")
        storage_size = plan.get("disk")
        node_count = plan.get("number_of_nodes")
        # Replica nodes are read-only failover replicas. We model this as
        # readable-cluster HA when a plan includes more than one node.
        # https://docs.vultr.com/support/products/managed-databases/what-are-replica-nodes
        # https://docs.vultr.com/support/products/managed-databases/what-type-of-replica-nodes-are-attached-to-a-vultr-managed-database
        # https://docs.vultr.com/support/products/managed-databases/how-does-vultr-managed-databases-handle-automated-failover-in-multi-node-clusters
        if node_count > 1:
            ha = [DatabaseHaLevel.SINGLE_ZONE]
            ha_strategy = [DatabaseHaStrategy.READABLE_CLUSTER]
        else:
            ha = [DatabaseHaLevel.NONE]
            ha_strategy = [DatabaseHaStrategy.NONE]
        # Plans with zero locations are not currently orderable in any region.
        status = Status.ACTIVE if plan.get("locations") else Status.INACTIVE
        family = _database_family_name(plan)
        items.append(
            {
                "vendor_id": vendor.vendor_id,
                "database_id": database_id,
                "name": database_id,
                "display_name": plan.get("name", database_id),
                "description": _database_description(
                    f"Vultr PostgreSQL {family}", vcpus, memory, storage_size
                ),
                "api_reference": database_id,
                # API/IaC provisioning references this plan id and engine.
                # https://docs.vultr.com/products/storage/databases/postgresql/provisioning
                "api_reference_object": {
                    "plan": database_id,
                    "database_engine": "pg",
                },
                # Managed Databases are provisioned as managed clusters, not as
                # plain VM images with a stable 1:1 server SKU mapping.
                # https://docs.vultr.com/products/storage/databases
                "server_id": None,
                "engine": DatabaseEngine.POSTGRESQL,
                "wire_protocol": DatabaseWireProtocol.POSTGRESQL,
                "engine_versions": versions,
                "family": family,
                "vcpus": vcpus,
                "memory_amount": memory,
                "storage_size": storage_size,
                # Vultr does not expose explicit storage extra min/max/autosize - only bundled storage size is present
                "storage_extra_min": 0,
                "storage_extra_max": 0,
                "storage_extra_autosize": False,
                "ha": ha,
                "ha_strategy": ha_strategy,
                "max_read_replicas": max(node_count - 1, 0),
                # PostgreSQL settings are configurable via Advanced Configuration.
                # https://docs.vultr.com/products/storage/databases/postgresql/management/settings/configuration-options
                "custom_config": True,
                # Vultr supports enabling PostgreSQL extensions.
                # https://docs.vultr.com/support/products/managed-databases/how-do-i-enable-extensions-in-a-vultr-managed-postgresql-database
                "custom_extensions": True,
                # Vultr documents encryption at rest for Managed Databases.
                # https://docs.vultr.com/support/products/managed-databases/how-does-vultr-protect-my-database-data-at-rest
                "disk_encryption": True,
                # Vultr supports scheduling upgrade windows for managed
                # PostgreSQL version upgrades.
                # https://docs.vultr.com/products/storage/databases/postgresql/management/upgrade-databases
                "auto_upgrade_versions": True,
                # PostgreSQL plans are automatically backed up.
                # https://docs.vultr.com/support/products/managed-databases/is-my-vultr-managed-mysql-or-postgresql-database-backed-up
                "scheduled_backups": True,
                # PostgreSQL FAQ documents PITR retention by node-plan tier:
                # Premium=30 days, Business=14 days, Startup=2 days, Hobbyist=None.
                # https://docs.vultr.com/products/managed-database/postgresql/faq
                "continuous_backups": _database_pitr_days(database_id),
                # Vultr Managed PostgreSQL includes PgBouncer and supports
                # managing connection pools.
                # https://docs.vultr.com/products/storage/databases/postgresql/management/pgbouncer
                # https://docs.vultr.com/products/storage/databases/postgresql/management/connection/connection-pools
                "connection_pool": True,
                # Usage graphs and API/CLI usage endpoints cover CPU, memory,
                # disk and network monitoring for managed databases.
                # https://docs.vultr.com/products/storage/databases/mysql/management/monitor-databases
                "system_monitoring": True,
                "database_monitoring": True,
                # Vultr exposes manual advanced-option tuning, but no documented
                # built-in auto-tuning advisor or auto-apply feature.
                # https://docs.vultr.com/reference/vultr-cli/database/advanced-option/update
                # https://docs.vultr.com/products/storage/databases/postgresql/management/settings/configuration-options
                "autotuning_advice": None,
                "autotuning_apply": None,
                # Managed Databases are advertised with a 99.99% SLA.
                # https://www.vultr.com/products/managed-databases/
                "sla": 99.99,
                "status": status,
                # Provisioning supports `trusted_ips` and `vpc_id`.
                # https://docs.vultr.com/products/storage/databases/postgresql/provisioning
                # Vultr documents TLS in transit for Managed Databases.
                # https://docs.vultr.com/support/products/managed-databases/is-a-vultr-managed-database-secure
                "security_features": [
                    DatabaseSecurityFeature.IP_FILTERING,
                    DatabaseSecurityFeature.PRIVATE_NETWORK,
                    DatabaseSecurityFeature.ENFORCED_TLS,
                ],
            }
        )
    return items

inventory_database_storages #

inventory_database_storages(vendor)

Vultr managed PostgreSQL storage is bundled into DB plans.

Resizing storage is done by changing the database node plan; there is no separate DB storage catalog product exposed by the public API. https://docs.vultr.com/products/storage/databases/postgresql/management/resize-databases

Source code in sc_crawler/vendors/_vultr.py
def inventory_database_storages(vendor):
    """Vultr managed PostgreSQL storage is bundled into DB plans.

    Resizing storage is done by changing the database node plan; there is no
    separate DB storage catalog product exposed by the public API.
    https://docs.vultr.com/products/storage/databases/postgresql/management/resize-databases
    """
    return []

inventory_database_storage_prices #

inventory_database_storage_prices(vendor)

No standalone Vultr managed DB storage price meters are exposed.

Source code in sc_crawler/vendors/_vultr.py
def inventory_database_storage_prices(vendor):
    """No standalone Vultr managed DB storage price meters are exposed."""
    return []