Merge branch 'feature/improve_vultr' of https://github.com/sergerdn/libcloud into sergerdn-feature/improve_vultr
diff --git a/contrib/update_vultr_fixtures.sh b/contrib/update_vultr_fixtures.sh
new file mode 100644
index 0000000..12ed572
--- /dev/null
+++ b/contrib/update_vultr_fixtures.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+set -e
+# set -x
+# make sure:
+# - you installed curl
+# - you installed jq
+
+API_POINT="api.vultr.com"
+FIXTURES_PATH="./libcloud/test/compute/fixtures/vultr"
+[ ! -d "$FIXTURES_PATH" ] && echo "Please run command from root dir of project" && exit
+
+if ! [ -x "$(command -v curl)" ]; then
+ echo 'Error: curl is not installed.' >&2
+ exit 1
+fi
+if ! [ -x "$(command -v jq)" ]; then
+ echo 'Error: jq is not installed.' >&2
+ exit 1
+fi
+#unauthenticated_endpoints = { # {action: methods}
+# '/v1/app/list': ['GET'],
+# '/v1/os/list': ['GET'],
+# '/v1/plans/list': ['GET'],
+# '/v1/plans/list_vc2': ['GET'],
+# '/v1/plans/list_vdc2': ['GET'],
+# '/v1/regions/availability': ['GET'],
+# '/v1/regions/list': ['GET']
+# }
+
+curl "https://$API_POINT/v1/os/list" | jq >"$FIXTURES_PATH/list_images.json"
+curl "https://$API_POINT/v1/plans/list" | jq >"$FIXTURES_PATH/list_sizes.json"
+curl "https://$API_POINT/v1/regions/list" | jq >"$FIXTURES_PATH/list_locations.json"
diff --git a/libcloud/compute/drivers/vultr.py b/libcloud/compute/drivers/vultr.py
index 4f54ad8..44d65ca 100644
--- a/libcloud/compute/drivers/vultr.py
+++ b/libcloud/compute/drivers/vultr.py
@@ -15,20 +15,574 @@
"""
Vultr Driver
"""
-
import time
from functools import update_wrapper
-from libcloud.utils.py3 import httplib
-from libcloud.utils.py3 import urlencode
-
from libcloud.common.base import ConnectionKey, JsonResponse
-from libcloud.compute.types import Provider, NodeState
from libcloud.common.types import InvalidCredsError
from libcloud.common.types import LibcloudError
from libcloud.common.types import ServiceUnavailableError
-from libcloud.compute.base import NodeDriver
from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
+from libcloud.compute.base import NodeDriver
+from libcloud.compute.types import Provider, NodeState
+from libcloud.utils.iso8601 import parse_date
+from libcloud.utils.py3 import httplib
+from libcloud.utils.py3 import urlencode
+
+# For matching region by id
+VULTR_COMPUTE_INSTANCE_LOCATIONS = {
+ "1": {
+ "DCID": "1",
+ "name": "New Jersey",
+ "country": "US",
+ "continent": "North America",
+ "state": "NJ",
+ "regioncode": "EWR"
+ },
+ "2": {
+ "DCID": "2",
+ "name": "Chicago",
+ "country": "US",
+ "continent": "North America",
+ "state": "IL",
+ "regioncode": "ORD"
+ },
+ "3": {
+ "DCID": "3",
+ "name": "Dallas",
+ "country": "US",
+ "continent": "North America",
+ "state": "TX",
+ "regioncode": "DFW"
+ },
+ "4": {
+ "DCID": "4",
+ "name": "Seattle",
+ "country": "US",
+ "continent": "North America",
+ "state": "WA",
+ "regioncode": "SEA"
+ },
+ "5": {
+ "DCID": "5",
+ "name": "Los Angeles",
+ "country": "US",
+ "continent": "North America",
+ "state": "CA",
+ "regioncode": "LAX"
+ },
+ "6": {
+ "DCID": "6",
+ "name": "Atlanta",
+ "country": "US",
+ "continent": "North America",
+ "state": "GA",
+ "regioncode": "ATL"
+ },
+ "7": {
+ "DCID": "7",
+ "name": "Amsterdam",
+ "country": "NL",
+ "continent": "Europe",
+ "state": "",
+ "regioncode": "AMS"
+ },
+ "8": {
+ "DCID": "8",
+ "name": "London",
+ "country": "GB",
+ "continent": "Europe",
+ "state": "",
+ "regioncode": "LHR"
+ },
+ "9": {
+ "DCID": "9",
+ "name": "Frankfurt",
+ "country": "DE",
+ "continent": "Europe",
+ "state": "",
+ "regioncode": "FRA"
+ },
+ "12": {
+ "DCID": "12",
+ "name": "Silicon Valley",
+ "country": "US",
+ "continent": "North America",
+ "state": "CA",
+ "regioncode": "SJC"
+ },
+ "19": {
+ "DCID": "19",
+ "name": "Sydney",
+ "country": "AU",
+ "continent": "Australia",
+ "state": "",
+ "regioncode": "SYD"
+ },
+ "22": {
+ "DCID": "22",
+ "name": "Toronto",
+ "country": "CA",
+ "continent": "North America",
+ "state": "",
+ "regioncode": "YTO"
+ },
+ "24": {
+ "DCID": "24",
+ "name": "Paris",
+ "country": "FR",
+ "continent": "Europe",
+ "state": "",
+ "regioncode": "CDG"
+ },
+ "25": {
+ "DCID": "25",
+ "name": "Tokyo",
+ "country": "JP",
+ "continent": "Asia",
+ "state": "",
+ "regioncode": "NRT"
+ },
+ "34": {
+ "DCID": "34",
+ "name": "Seoul",
+ "country": "KR",
+ "continent": "Asia",
+ "state": "",
+ "regioncode": "ICN"
+ },
+ "39": {
+ "DCID": "39",
+ "name": "Miami",
+ "country": "US",
+ "continent": "North America",
+ "state": "FL",
+ "regioncode": "MIA"
+ },
+ "40": {
+ "DCID": "40",
+ "name": "Singapore",
+ "country": "SG",
+ "continent": "Asia",
+ "state": "",
+ "regioncode": "SGP"
+ }
+}
+# For matching image by id
+VULTR_COMPUTE_INSTANCE_IMAGES = {
+ "127": {
+ "OSID": 127,
+ "name": "CentOS 6 x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": False
+ },
+ "147": {
+ "OSID": 147,
+ "name": "CentOS 6 i386",
+ "arch": "i386",
+ "family": "centos",
+ "windows": False
+ },
+ "167": {
+ "OSID": 167,
+ "name": "CentOS 7 x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": False
+ },
+ "381": {
+ "OSID": 381,
+ "name": "CentOS 7 SELinux x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": False
+ },
+ "362": {
+ "OSID": 362,
+ "name": "CentOS 8 x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": False
+ },
+ "401": {
+ "OSID": 401,
+ "name": "CentOS 8 Stream x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": False
+ },
+ "215": {
+ "OSID": 215,
+ "name": "Ubuntu 16.04 x64",
+ "arch": "x64",
+ "family": "ubuntu",
+ "windows": False
+ },
+ "216": {
+ "OSID": 216,
+ "name": "Ubuntu 16.04 i386",
+ "arch": "i386",
+ "family": "ubuntu",
+ "windows": False
+ },
+ "270": {
+ "OSID": 270,
+ "name": "Ubuntu 18.04 x64",
+ "arch": "x64",
+ "family": "ubuntu",
+ "windows": False
+ },
+ "387": {
+ "OSID": 387,
+ "name": "Ubuntu 20.04 x64",
+ "arch": "x64",
+ "family": "ubuntu",
+ "windows": False
+ },
+ "194": {
+ "OSID": 194,
+ "name": "Debian 8 i386 (jessie)",
+ "arch": "i386",
+ "family": "debian",
+ "windows": False
+ },
+ "244": {
+ "OSID": 244,
+ "name": "Debian 9 x64 (stretch)",
+ "arch": "x64",
+ "family": "debian",
+ "windows": False
+ },
+ "352": {
+ "OSID": 352,
+ "name": "Debian 10 x64 (buster)",
+ "arch": "x64",
+ "family": "debian",
+ "windows": False
+ },
+ "230": {
+ "OSID": 230,
+ "name": "FreeBSD 11 x64",
+ "arch": "x64",
+ "family": "freebsd",
+ "windows": False
+ },
+ "327": {
+ "OSID": 327,
+ "name": "FreeBSD 12 x64",
+ "arch": "x64",
+ "family": "freebsd",
+ "windows": False
+ },
+ "366": {
+ "OSID": 366,
+ "name": "OpenBSD 6.6 x64",
+ "arch": "x64",
+ "family": "openbsd",
+ "windows": False
+ },
+ "394": {
+ "OSID": 394,
+ "name": "OpenBSD 6.7 x64",
+ "arch": "x64",
+ "family": "openbsd",
+ "windows": False
+ },
+ "391": {
+ "OSID": 391,
+ "name": "Fedora CoreOS",
+ "arch": "x64",
+ "family": "fedora-coreos",
+ "windows": False
+ },
+ "367": {
+ "OSID": 367,
+ "name": "Fedora 31 x64",
+ "arch": "x64",
+ "family": "fedora",
+ "windows": False
+ },
+ "389": {
+ "OSID": 389,
+ "name": "Fedora 32 x64",
+ "arch": "x64",
+ "family": "fedora",
+ "windows": False
+ },
+ "124": {
+ "OSID": 124,
+ "name": "Windows 2012 R2 x64",
+ "arch": "x64",
+ "family": "windows",
+ "windows": False
+ },
+ "240": {
+ "OSID": 240,
+ "name": "Windows 2016 x64",
+ "arch": "x64",
+ "family": "windows",
+ "windows": False
+ },
+ "159": {
+ "OSID": 159,
+ "name": "Custom",
+ "arch": "x64",
+ "family": "iso",
+ "windows": False
+ },
+ "164": {
+ "OSID": 164,
+ "name": "Snapshot",
+ "arch": "x64",
+ "family": "snapshot",
+ "windows": False
+ },
+ "180": {
+ "OSID": 180,
+ "name": "Backup",
+ "arch": "x64",
+ "family": "backup",
+ "windows": False
+ },
+ "186": {
+ "OSID": 186,
+ "name": "Application",
+ "arch": "x64",
+ "family": "application",
+ "windows": False
+ }
+}
+VULTR_COMPUTE_INSTANCE_SIZES = {
+ "201": {
+ "VPSPLANID": "201",
+ "name": "1024 MB RAM,25 GB SSD,1.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "1024",
+ "disk": "25",
+ "bandwidth": "1.00",
+ "bandwidth_gb": "1024",
+ "price_per_month": "5.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "202": {
+ "VPSPLANID": "202",
+ "name": "2048 MB RAM,55 GB SSD,2.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "2048",
+ "disk": "55",
+ "bandwidth": "2.00",
+ "bandwidth_gb": "2048",
+ "price_per_month": "10.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "203": {
+ "VPSPLANID": "203",
+ "name": "4096 MB RAM,80 GB SSD,3.00 TB BW",
+ "vcpu_count": "2",
+ "ram": "4096",
+ "disk": "80",
+ "bandwidth": "3.00",
+ "bandwidth_gb": "3072",
+ "price_per_month": "20.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "204": {
+ "VPSPLANID": "204",
+ "name": "8192 MB RAM,160 GB SSD,4.00 TB BW",
+ "vcpu_count": "4",
+ "ram": "8192",
+ "disk": "160",
+ "bandwidth": "4.00",
+ "bandwidth_gb": "4096",
+ "price_per_month": "40.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "205": {
+ "VPSPLANID": "205",
+ "name": "16384 MB RAM,320 GB SSD,5.00 TB BW",
+ "vcpu_count": "6",
+ "ram": "16384",
+ "disk": "320",
+ "bandwidth": "5.00",
+ "bandwidth_gb": "5120",
+ "price_per_month": "80.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "206": {
+ "VPSPLANID": "206",
+ "name": "32768 MB RAM,640 GB SSD,6.00 TB BW",
+ "vcpu_count": "8",
+ "ram": "32768",
+ "disk": "640",
+ "bandwidth": "6.00",
+ "bandwidth_gb": "6144",
+ "price_per_month": "160.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "207": {
+ "VPSPLANID": "207",
+ "name": "65536 MB RAM,1280 GB SSD,10.00 TB BW",
+ "vcpu_count": "16",
+ "ram": "65536",
+ "disk": "1280",
+ "bandwidth": "10.00",
+ "bandwidth_gb": "10240",
+ "price_per_month": "320.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "208": {
+ "VPSPLANID": "208",
+ "name": "98304 MB RAM,1600 GB SSD,15.00 TB BW",
+ "vcpu_count": "24",
+ "ram": "98304",
+ "disk": "1600",
+ "bandwidth": "15.00",
+ "bandwidth_gb": "15360",
+ "price_per_month": "640.00",
+ "plan_type": "SSD",
+ "windows": False,
+ },
+ "115": {
+ "VPSPLANID": "115",
+ "name": "8192 MB RAM,110 GB SSD,10.00 TB BW",
+ "vcpu_count": "2",
+ "ram": "8192",
+ "disk": "110",
+ "bandwidth": "10.00",
+ "bandwidth_gb": "10240",
+ "price_per_month": "60.00",
+ "plan_type": "DEDICATED",
+ "windows": False,
+ },
+ "116": {
+ "VPSPLANID": "116",
+ "name": "16384 MB RAM,2x110 GB SSD,20.00 TB BW",
+ "vcpu_count": "4",
+ "ram": "16384",
+ "disk": "110",
+ "bandwidth": "20.00",
+ "bandwidth_gb": "20480",
+ "price_per_month": "120.00",
+ "plan_type": "DEDICATED",
+ "windows": False,
+ },
+ "117": {
+ "VPSPLANID": "117",
+ "name": "24576 MB RAM,3x110 GB SSD,30.00 TB BW",
+ "vcpu_count": "6",
+ "ram": "24576",
+ "disk": "110",
+ "bandwidth": "30.00",
+ "bandwidth_gb": "30720",
+ "price_per_month": "180.00",
+ "plan_type": "DEDICATED",
+ "windows": False,
+ },
+ "118": {
+ "VPSPLANID": "118",
+ "name": "32768 MB RAM,4x110 GB SSD,40.00 TB BW",
+ "vcpu_count": "8",
+ "ram": "32768",
+ "disk": "110",
+ "bandwidth": "40.00",
+ "bandwidth_gb": "40960",
+ "price_per_month": "240.00",
+ "plan_type": "DEDICATED",
+ "windows": False,
+ },
+ "400": {
+ "VPSPLANID": "400",
+ "name": "1024 MB RAM,32 GB SSD,1.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "1024",
+ "disk": "32",
+ "bandwidth": "1.00",
+ "bandwidth_gb": "1024",
+ "price_per_month": "6.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ },
+ "401": {
+ "VPSPLANID": "401",
+ "name": "2048 MB RAM,64 GB SSD,2.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "2048",
+ "disk": "64",
+ "bandwidth": "2.00",
+ "bandwidth_gb": "2048",
+ "price_per_month": "12.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ },
+ "402": {
+ "VPSPLANID": "402",
+ "name": "4096 MB RAM,128 GB SSD,3.00 TB BW",
+ "vcpu_count": "2",
+ "ram": "4096",
+ "disk": "128",
+ "bandwidth": "3.00",
+ "bandwidth_gb": "3072",
+ "price_per_month": "24.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ },
+ "403": {
+ "VPSPLANID": "403",
+ "name": "8192 MB RAM,256 GB SSD,4.00 TB BW",
+ "vcpu_count": "3",
+ "ram": "8192",
+ "disk": "256",
+ "bandwidth": "4.00",
+ "bandwidth_gb": "4096",
+ "price_per_month": "48.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ },
+ "404": {
+ "VPSPLANID": "404",
+ "name": "16384 MB RAM,384 GB SSD,5.00 TB BW",
+ "vcpu_count": "4",
+ "ram": "16384",
+ "disk": "384",
+ "bandwidth": "5.00",
+ "bandwidth_gb": "5120",
+ "price_per_month": "96.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ },
+ "405": {
+ "VPSPLANID": "405",
+ "name": "32768 MB RAM,512 GB SSD,6.00 TB BW",
+ "vcpu_count": "8",
+ "ram": "32768",
+ "disk": "512",
+ "bandwidth": "6.00",
+ "bandwidth_gb": "6144",
+ "price_per_month": "192.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ },
+ "406": {
+ "VPSPLANID": "406",
+ "name": "49152 MB RAM,768 GB SSD,8.00 TB BW",
+ "vcpu_count": "12",
+ "ram": "49152",
+ "disk": "768",
+ "bandwidth": "8.00",
+ "bandwidth_gb": "8192",
+ "price_per_month": "256.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": False,
+ }
+}
class rate_limited:
@@ -56,7 +610,7 @@
def wrapper(*args, **kwargs):
last_exception = None
- for i in range(self.retries + 1):
+ for _ in range(self.retries + 1):
try:
return call(*args, **kwargs)
except ServiceUnavailableError as e:
@@ -150,6 +704,19 @@
return True
+class VultrNodeDriverHelper(object):
+ """
+ VultrNode helper class.
+ """
+
+ def handle_extra(self, extra_keys, data):
+ extra = {}
+ for key in extra_keys:
+ if key in data:
+ extra[key] = data[key]
+ return extra
+
+
class VultrNodeDriver(NodeDriver):
"""
VultrNode node driver.
@@ -184,6 +751,10 @@
EX_CREATE_ATTRIBUTES.extend(EX_CREATE_YES_NO_ATTRIBUTES)
EX_CREATE_ATTRIBUTES.extend(EX_CREATE_ID_ATTRIBUTES.keys())
+ def __init__(self, *args, **kwargs):
+ super(VultrNodeDriver, self).__init__(*args, **kwargs)
+ self._helper = VultrNodeDriverHelper()
+
def list_nodes(self):
return self._list_resources('/v1/server/list', self._to_node)
@@ -233,6 +804,7 @@
def list_images(self):
return self._list_resources('/v1/os/list', self._to_image)
+ # pylint: disable=too-many-locals
def create_node(self, name, size, image, location, ex_ssh_key_ids=None,
ex_create_attr=None):
"""
@@ -311,7 +883,7 @@
retry_count = 3
created_node = None
- for i in range(retry_count):
+ for _ in range(retry_count):
try:
nodes = self.list_nodes()
created_node = [n for n in nodes if n.id == subid][0]
@@ -343,7 +915,7 @@
if 'status' in data:
state = self.NODE_STATE_MAP.get(data['status'], NodeState.UNKNOWN)
if state == NodeState.RUNNING and \
- data['power_status'] != 'running':
+ data['power_status'] != 'running':
state = NodeState.STOPPED
else:
state = NodeState.UNKNOWN
@@ -352,41 +924,90 @@
public_ips = [data['main_ip']]
else:
public_ips = []
+ # simple check that we have ip address in value
+ if len(data['internal_ip']) > 0:
+ private_ips = [data['internal_ip']]
+ else:
+ private_ips = []
+ created_at = parse_date(data['date_created'])
- extra_keys = []
- extra = {}
- for key in extra_keys:
- if key in data:
- extra[key] = data[key]
+ # response ordering
+ extra_keys = [
+ "location", # Location name
+ "default_password", "pending_charges", "cost_per_month",
+ "current_bandwidth_gb", "allowed_bandwidth_gb", "netmask_v4",
+ "gateway_v4", "power_status", "server_state",
+ "v6_networks",
+ # TODO: Does we really need kvm_url?
+ "kvm_url",
+ "auto_backups", "tag",
+ # "OSID", # Operating system to use. See v1/os/list.
+ "APPID", "FIREWALLGROUPID"
+ ]
+ extra = self._helper.handle_extra(extra_keys, data)
- node = Node(id=data['SUBID'], name=data['label'], state=state,
- public_ips=public_ips, private_ips=None, extra=extra,
- driver=self)
+ resolve_data = VULTR_COMPUTE_INSTANCE_IMAGES.get(data["OSID"])
+ if resolve_data:
+ image = self._to_image(resolve_data)
+ else:
+ image = None
+
+ resolve_data = VULTR_COMPUTE_INSTANCE_SIZES.get(data["VPSPLANID"])
+ if resolve_data:
+ size = self._to_size(resolve_data)
+ else:
+ size = None
+
+ # resolve_data = VULTR_COMPUTE_INSTANCE_LOCATIONS.get(data['DCID'])
+ # if resolve_data:
+ # location = self._to_location(resolve_data)
+ # extra['location'] = location
+
+ node = Node(
+ id=data['SUBID'],
+ name=data['label'],
+ state=state,
+ public_ips=public_ips,
+ private_ips=private_ips,
+ image=image,
+ size=size,
+ extra=extra,
+ created_at=created_at,
+ driver=self)
return node
def _to_location(self, data):
+ extra_keys = ['continent', 'state', 'ddos_protection',
+ 'block_storage', 'regioncode']
+ extra = self._helper.handle_extra(extra_keys, data)
+
return NodeLocation(id=data['DCID'], name=data['name'],
- country=data['country'], driver=self)
+ country=data['country'], extra=extra, driver=self)
def _to_size(self, data):
- extra = {
- 'vcpu_count': int(data['vcpu_count']),
- 'plan_type': data['plan_type'],
- 'available_locations': data['available_locations']
- }
+ extra_keys = [
+ 'vcpu_count', 'plan_type', 'available_locations',
+ ]
+ extra = self._helper.handle_extra(extra_keys, data)
+
+ # backward compatibility
+ if extra.get('vcpu_count').isdigit():
+ extra['vcpu_count'] = int(extra['vcpu_count'])
+
ram = int(data['ram'])
disk = int(data['disk'])
- bandwidth = float(data['bandwidth'])
+ # NodeSize accepted int instead float
+ bandwidth = int(float(data['bandwidth']))
price = float(data['price_per_month'])
-
return NodeSize(id=data['VPSPLANID'], name=data['name'],
ram=ram, disk=disk,
bandwidth=bandwidth, price=price,
extra=extra, driver=self)
def _to_image(self, data):
- extra = {'arch': data['arch'], 'family': data['family']}
+ extra_keys = ['arch', 'family']
+ extra = self._helper.handle_extra(extra_keys, data)
return NodeImage(id=data['OSID'], name=data['name'], extra=extra,
driver=self)
diff --git a/libcloud/test/compute/fixtures/vultr/create_node.json b/libcloud/test/compute/fixtures/vultr/create_node.json
index 57aa548..2a58f23 100644
--- a/libcloud/test/compute/fixtures/vultr/create_node.json
+++ b/libcloud/test/compute/fixtures/vultr/create_node.json
@@ -1,3 +1,3 @@
{
- "SUBID": "1"
+ "SUBID": "41326859"
}
diff --git a/libcloud/test/compute/fixtures/vultr/list_images.json b/libcloud/test/compute/fixtures/vultr/list_images.json
index 139f2af..45a3596 100644
--- a/libcloud/test/compute/fixtures/vultr/list_images.json
+++ b/libcloud/test/compute/fixtures/vultr/list_images.json
@@ -1 +1,184 @@
-{"127":{"OSID":127,"name":"CentOS 6 x64","arch":"x64","family":"centos","windows":false},"147":{"OSID":147,"name":"CentOS 6 i386","arch":"i386","family":"centos","windows":false},"162":{"OSID":162,"name":"CentOS 5 x64","arch":"x64","family":"centos","windows":false},"163":{"OSID":163,"name":"CentOS 5 i386","arch":"i386","family":"centos","windows":false},"167":{"OSID":167,"name":"CentOS 7 x64","arch":"x64","family":"centos","windows":false},"160":{"OSID":160,"name":"Ubuntu 14.04 x64","arch":"x64","family":"ubuntu","windows":false},"161":{"OSID":161,"name":"Ubuntu 14.04 i386","arch":"i386","family":"ubuntu","windows":false},"128":{"OSID":128,"name":"Ubuntu 12.04 x64","arch":"x64","family":"ubuntu","windows":false},"148":{"OSID":148,"name":"Ubuntu 12.04 i386","arch":"i386","family":"ubuntu","windows":false},"181":{"OSID":181,"name":"Ubuntu 14.10 x64","arch":"x64","family":"ubuntu","windows":false},"182":{"OSID":182,"name":"Ubuntu 14.10 i386","arch":"i386","family":"ubuntu","windows":false},"139":{"OSID":139,"name":"Debian 7 x64 (wheezy)","arch":"x64","family":"debian","windows":false},"152":{"OSID":152,"name":"Debian 7 i386 (wheezy)","arch":"i386","family":"debian","windows":false},"140":{"OSID":140,"name":"FreeBSD 10 x64","arch":"x64","family":"freebsd","windows":false},"124":{"OSID":124,"name":"Windows 2012 R2 x64","arch":"x64","family":"windows","windows":true},"159":{"OSID":159,"name":"Custom","arch":"x64","family":"iso","windows":false},"164":{"OSID":164,"name":"Snapshot","arch":"x64","family":"snapshot","windows":false},"180":{"OSID":180,"name":"Backup","arch":"x64","family":"backup","windows":false}}
\ No newline at end of file
+{
+ "127": {
+ "OSID": 127,
+ "name": "CentOS 6 x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": false
+ },
+ "147": {
+ "OSID": 147,
+ "name": "CentOS 6 i386",
+ "arch": "i386",
+ "family": "centos",
+ "windows": false
+ },
+ "167": {
+ "OSID": 167,
+ "name": "CentOS 7 x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": false
+ },
+ "381": {
+ "OSID": 381,
+ "name": "CentOS 7 SELinux x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": false
+ },
+ "362": {
+ "OSID": 362,
+ "name": "CentOS 8 x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": false
+ },
+ "401": {
+ "OSID": 401,
+ "name": "CentOS 8 Stream x64",
+ "arch": "x64",
+ "family": "centos",
+ "windows": false
+ },
+ "215": {
+ "OSID": 215,
+ "name": "Ubuntu 16.04 x64",
+ "arch": "x64",
+ "family": "ubuntu",
+ "windows": false
+ },
+ "216": {
+ "OSID": 216,
+ "name": "Ubuntu 16.04 i386",
+ "arch": "i386",
+ "family": "ubuntu",
+ "windows": false
+ },
+ "270": {
+ "OSID": 270,
+ "name": "Ubuntu 18.04 x64",
+ "arch": "x64",
+ "family": "ubuntu",
+ "windows": false
+ },
+ "387": {
+ "OSID": 387,
+ "name": "Ubuntu 20.04 x64",
+ "arch": "x64",
+ "family": "ubuntu",
+ "windows": false
+ },
+ "194": {
+ "OSID": 194,
+ "name": "Debian 8 i386 (jessie)",
+ "arch": "i386",
+ "family": "debian",
+ "windows": false
+ },
+ "244": {
+ "OSID": 244,
+ "name": "Debian 9 x64 (stretch)",
+ "arch": "x64",
+ "family": "debian",
+ "windows": false
+ },
+ "352": {
+ "OSID": 352,
+ "name": "Debian 10 x64 (buster)",
+ "arch": "x64",
+ "family": "debian",
+ "windows": false
+ },
+ "230": {
+ "OSID": 230,
+ "name": "FreeBSD 11 x64",
+ "arch": "x64",
+ "family": "freebsd",
+ "windows": false
+ },
+ "327": {
+ "OSID": 327,
+ "name": "FreeBSD 12 x64",
+ "arch": "x64",
+ "family": "freebsd",
+ "windows": false
+ },
+ "366": {
+ "OSID": 366,
+ "name": "OpenBSD 6.6 x64",
+ "arch": "x64",
+ "family": "openbsd",
+ "windows": false
+ },
+ "394": {
+ "OSID": 394,
+ "name": "OpenBSD 6.7 x64",
+ "arch": "x64",
+ "family": "openbsd",
+ "windows": false
+ },
+ "391": {
+ "OSID": 391,
+ "name": "Fedora CoreOS",
+ "arch": "x64",
+ "family": "fedora-coreos",
+ "windows": false
+ },
+ "367": {
+ "OSID": 367,
+ "name": "Fedora 31 x64",
+ "arch": "x64",
+ "family": "fedora",
+ "windows": false
+ },
+ "389": {
+ "OSID": 389,
+ "name": "Fedora 32 x64",
+ "arch": "x64",
+ "family": "fedora",
+ "windows": false
+ },
+ "124": {
+ "OSID": 124,
+ "name": "Windows 2012 R2 x64",
+ "arch": "x64",
+ "family": "windows",
+ "windows": true
+ },
+ "240": {
+ "OSID": 240,
+ "name": "Windows 2016 x64",
+ "arch": "x64",
+ "family": "windows",
+ "windows": true
+ },
+ "159": {
+ "OSID": 159,
+ "name": "Custom",
+ "arch": "x64",
+ "family": "iso",
+ "windows": false
+ },
+ "164": {
+ "OSID": 164,
+ "name": "Snapshot",
+ "arch": "x64",
+ "family": "snapshot",
+ "windows": false
+ },
+ "180": {
+ "OSID": 180,
+ "name": "Backup",
+ "arch": "x64",
+ "family": "backup",
+ "windows": false
+ },
+ "186": {
+ "OSID": 186,
+ "name": "Application",
+ "arch": "x64",
+ "family": "application",
+ "windows": false
+ }
+}
diff --git a/libcloud/test/compute/fixtures/vultr/list_locations.json b/libcloud/test/compute/fixtures/vultr/list_locations.json
index 6cf6d0b..63a6194 100644
--- a/libcloud/test/compute/fixtures/vultr/list_locations.json
+++ b/libcloud/test/compute/fixtures/vultr/list_locations.json
@@ -1 +1,172 @@
-{"6":{"DCID":"6","name":"Atlanta","country":"US","continent":"North America","state":"GA"},"2":{"DCID":"2","name":"Chicago","country":"US","continent":"North America","state":"IL"},"3":{"DCID":"3","name":"Dallas","country":"US","continent":"North America","state":"TX"},"5":{"DCID":"5","name":"Los Angeles","country":"US","continent":"North America","state":"CA"},"39":{"DCID":"39","name":"Miami","country":"US","continent":"","state":"FL"},"1":{"DCID":"1","name":"New Jersey","country":"US","continent":"North America","state":"NJ"},"4":{"DCID":"4","name":"Seattle","country":"US","continent":"North America","state":"WA"},"12":{"DCID":"12","name":"Silicon Valley","country":"US","continent":"North America","state":"CA"},"7":{"DCID":"7","name":"Amsterdam","country":"NL","continent":"Europe","state":""},"25":{"DCID":"25","name":"Tokyo","country":"JP","continent":"Asia","state":""},"8":{"DCID":"8","name":"London","country":"GB","continent":"Europe","state":""},"24":{"DCID":"24","name":"France","country":"FR","continent":"Europe","state":""},"9":{"DCID":"9","name":"Frankfurt","country":"DE","continent":"Europe","state":""},"19":{"DCID":"19","name":"Australia","country":"AU","continent":"Australia","state":""}}
+{
+ "6": {
+ "DCID": "6",
+ "name": "Atlanta",
+ "country": "US",
+ "continent": "North America",
+ "state": "GA",
+ "ddos_protection": false,
+ "block_storage": false,
+ "regioncode": "ATL"
+ },
+ "2": {
+ "DCID": "2",
+ "name": "Chicago",
+ "country": "US",
+ "continent": "North America",
+ "state": "IL",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "ORD"
+ },
+ "3": {
+ "DCID": "3",
+ "name": "Dallas",
+ "country": "US",
+ "continent": "North America",
+ "state": "TX",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "DFW"
+ },
+ "5": {
+ "DCID": "5",
+ "name": "Los Angeles",
+ "country": "US",
+ "continent": "North America",
+ "state": "CA",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "LAX"
+ },
+ "39": {
+ "DCID": "39",
+ "name": "Miami",
+ "country": "US",
+ "continent": "North America",
+ "state": "FL",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "MIA"
+ },
+ "1": {
+ "DCID": "1",
+ "name": "New Jersey",
+ "country": "US",
+ "continent": "North America",
+ "state": "NJ",
+ "ddos_protection": true,
+ "block_storage": true,
+ "regioncode": "EWR"
+ },
+ "4": {
+ "DCID": "4",
+ "name": "Seattle",
+ "country": "US",
+ "continent": "North America",
+ "state": "WA",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "SEA"
+ },
+ "12": {
+ "DCID": "12",
+ "name": "Silicon Valley",
+ "country": "US",
+ "continent": "North America",
+ "state": "CA",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "SJC"
+ },
+ "40": {
+ "DCID": "40",
+ "name": "Singapore",
+ "country": "SG",
+ "continent": "Asia",
+ "state": "",
+ "ddos_protection": false,
+ "block_storage": false,
+ "regioncode": "SGP"
+ },
+ "7": {
+ "DCID": "7",
+ "name": "Amsterdam",
+ "country": "NL",
+ "continent": "Europe",
+ "state": "",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "AMS"
+ },
+ "34": {
+ "DCID": "34",
+ "name": "Seoul",
+ "country": "KR",
+ "continent": "Asia",
+ "state": "",
+ "ddos_protection": false,
+ "block_storage": false,
+ "regioncode": "ICN"
+ },
+ "25": {
+ "DCID": "25",
+ "name": "Tokyo",
+ "country": "JP",
+ "continent": "Asia",
+ "state": "",
+ "ddos_protection": false,
+ "block_storage": false,
+ "regioncode": "NRT"
+ },
+ "8": {
+ "DCID": "8",
+ "name": "London",
+ "country": "GB",
+ "continent": "Europe",
+ "state": "",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "LHR"
+ },
+ "24": {
+ "DCID": "24",
+ "name": "Paris",
+ "country": "FR",
+ "continent": "Europe",
+ "state": "",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "CDG"
+ },
+ "9": {
+ "DCID": "9",
+ "name": "Frankfurt",
+ "country": "DE",
+ "continent": "Europe",
+ "state": "",
+ "ddos_protection": true,
+ "block_storage": false,
+ "regioncode": "FRA"
+ },
+ "22": {
+ "DCID": "22",
+ "name": "Toronto",
+ "country": "CA",
+ "continent": "North America",
+ "state": "",
+ "ddos_protection": false,
+ "block_storage": false,
+ "regioncode": "YTO"
+ },
+ "19": {
+ "DCID": "19",
+ "name": "Sydney",
+ "country": "AU",
+ "continent": "Australia",
+ "state": "",
+ "ddos_protection": false,
+ "block_storage": false,
+ "regioncode": "SYD"
+ }
+}
diff --git a/libcloud/test/compute/fixtures/vultr/list_nodes.json b/libcloud/test/compute/fixtures/vultr/list_nodes.json
index e12ba4a..2648f5e 100644
--- a/libcloud/test/compute/fixtures/vultr/list_nodes.json
+++ b/libcloud/test/compute/fixtures/vultr/list_nodes.json
@@ -1 +1,116 @@
-{"1":{"SUBID":"1","os":"Ubuntu 12.04 x64","ram":"1024 MB","disk":"Virtual 20 GB","main_ip":"108.61.206.153","vcpu_count":"1","location":"Los Angeles","DCID":"5","default_password":"twizewnatpom!7","date_created":"2014-03-21 12:46:35","pending_charges":"1.92","status":"active","cost_per_month":"7.00","current_bandwidth_gb":0.929,"allowed_bandwidth_gb":"2000","netmask_v4":"255.255.254.0","gateway_v4":"108.61.206.1","power_status":"running","VPSPLANID":"30","v6_network":"::","v6_main_ip":"","v6_network_size":"0","label":"","internal_ip":"","kvm_url":"https:\/\/my.vultr.com\/subs\/vps\/novnc\/api.php?data=IF3C6VCEN5NFOZ3VMM3FOV3JJVXUQV3OHBWDG6TUKI3VST3JMFDXOOCMIE3HCTBWKVJXOZZYF5BVMZ3IM5XXGWRZIVZW4S2WKAVTSMTQHFCG4QTCNFUEKOCXKY3CW3LGNF4HIVTVJ5GXM4CJORTU6SKYOBDE6WJVMZ3E4ZSVOB2FQ4KYF5DXC5CTJI4FETDIGBITQQZPGFLXKTSRKRJS6ODOMFKDSNLLNVETONSNKA2XQ6CWLJMW6L2EGI2U6SDNN5FGUTJYNB3UC5DXN46Q","auto_backups":"no"},"2":{"SUBID":"2","os":"Ubuntu 14.04 x64","ram":"768 MB","disk":"Virtual 15 GB","main_ip":"104.207.153.143","vcpu_count":"1","location":"Los Angeles","DCID":"5","default_password":"cewxoaezap!0","date_created":"2014-11-08 14:12:13","pending_charges":"0.01","status":"active","cost_per_month":"5.00","current_bandwidth_gb":0,"allowed_bandwidth_gb":"1000","netmask_v4":"255.255.254.0","gateway_v4":"104.207.152.1","power_status":"running","VPSPLANID":"29","v6_network":"::","v6_main_ip":"","v6_network_size":"0","label":"vultr-test1","internal_ip":"","kvm_url":"https:\/\/my.vultr.com\/subs\/vps\/novnc\/api.php?data=NBUUYMTDI4VXGVZXOFBE6UBWKFLWE43MI5EFOR3MJNZW4NRXLFBHA33BHF3C63LSOJRXAU2PO5GHM5LPOFAW2MSDMFZWUMCNNJRG6TRWJREWYNBLG5VTG2DEGIYWITKIGV2FA3JTNJVEETLOGBHFG42XLEZHG22VFNWHE5RUKFIWU3DSOJCS6WDQGJRDIZRPIU2HILZTKB4E4MZSNZIFEQ3SOFSDANCBHBBEWRLVGZEUEVDSJVQVKOKZNQ4GKSRSIJEG62TWMREG6USNIE6Q","auto_backups":"no"}}
+{
+ "41326859": {
+ "SUBID": "41326859",
+ "os": "CentOS SELinux 8 x64",
+ "ram": "1024 MB",
+ "disk": "Virtual 25 GB",
+ "main_ip": "217.69.11.158",
+ "vcpu_count": "1",
+ "location": "Paris",
+ "DCID": "24",
+ "default_password": "*7j6j6[#q",
+ "date_created": "2020-10-15 03:17:22",
+ "pending_charges": "0.04",
+ "status": "active",
+ "cost_per_month": "5.00",
+ "current_bandwidth_gb": 0,
+ "allowed_bandwidth_gb": "1000",
+ "netmask_v4": "255.255.254.0",
+ "gateway_v4": "217.69.10.1",
+ "power_status": "running",
+ "server_state": "locked",
+ "VPSPLANID": "201",
+ "v6_main_ip": "2001:19f0:6801:1cc8:5400:03ff:fe03:5478",
+ "v6_network_size": "64",
+ "v6_network": "2001:19f0:6801:1cc8::",
+ "v6_networks": [
+ {
+ "v6_main_ip": "2001:19f0:6801:1cc8:5400:03ff:fe03:5478",
+ "v6_network_size": "64",
+ "v6_network": "2001:19f0:6801:1cc8::"
+ }
+ ],
+ "label": "labelname",
+ "internal_ip": "10.24.96.3",
+ "kvm_url": "https://my.vultr.com/subs/novnc/api.php?data=eawxFVZw2mXnhGUV",
+ "auto_backups": "yes",
+ "tag": "",
+ "OSID": "362",
+ "APPID": "0",
+ "FIREWALLGROUPID": "0"
+ },
+ "41306569": {
+ "SUBID": "41306569",
+ "os": "Ubuntu 20.04 x64",
+ "ram": "1024 MB",
+ "disk": "Virtual 25 GB",
+ "main_ip": "45.76.43.87",
+ "vcpu_count": "1",
+ "location": "Amsterdam",
+ "DCID": "7",
+ "default_password": "h6*hrte6tg",
+ "date_created": "2020-10-14 09:37:50",
+ "pending_charges": "0.18",
+ "status": "active",
+ "cost_per_month": "5.00",
+ "current_bandwidth_gb": 0.026,
+ "allowed_bandwidth_gb": "1000",
+ "netmask_v4": "255.255.254.0",
+ "gateway_v4": "45.76.42.1",
+ "power_status": "running",
+ "server_state": "installingbooting",
+ "VPSPLANID": "201",
+ "v6_main_ip": "2001:19f0:5001:2b9c:5400:03ff:fe03:9568",
+ "v6_network_size": "64",
+ "v6_network": "2001:19f0:5001:2b9c::",
+ "v6_networks": [
+ {
+ "v6_main_ip": "2001:19f0:5001:2b9c:5400:03ff:fe03:9568",
+ "v6_network_size": "64",
+ "v6_network": "2001:19f0:5001:2b9c::"
+ }
+ ],
+ "label": "libcloud-label",
+ "internal_ip": "10.7.96.85",
+ "kvm_url": "https://my.vultr.com/subs/novnc/api.php?data=erewawxFVZw2mXnhGUV",
+ "auto_backups": "yes",
+ "tag": "Web",
+ "OSID": "387",
+ "APPID": "0",
+ "FIREWALLGROUPID": "0"
+ },
+ "41326895": {
+ "SUBID": "41326895",
+ "os": "Ubuntu 18.04 x64",
+ "ram": "2048 MB",
+ "disk": "Virtual 55 GB",
+ "main_ip": "136.244.113.89",
+ "vcpu_count": "1",
+ "location": "Paris",
+ "DCID": "24",
+ "default_password": "Dy4@K_Z1gvb!!8zw",
+ "date_created": "2020-10-15 03:17:54",
+ "pending_charges": "0.00",
+ "status": "pending",
+ "cost_per_month": "10.00",
+ "current_bandwidth_gb": 0,
+ "allowed_bandwidth_gb": "2000",
+ "netmask_v4": "255.255.254.0",
+ "gateway_v4": "136.244.112.1",
+ "power_status": "running",
+ "server_state": "none",
+ "VPSPLANID": "202",
+ "v6_main_ip": false,
+ "v6_network_size": "",
+ "v6_network": "",
+ "v6_networks": [],
+ "label": "servlabel",
+ "internal_ip": "",
+ "kvm_url": "",
+ "auto_backups": "no",
+ "tag": "",
+ "OSID": "270",
+ "APPID": "0",
+ "FIREWALLGROUPID": "4e83489b"
+ }
+}
\ No newline at end of file
diff --git a/libcloud/test/compute/fixtures/vultr/list_sizes.json b/libcloud/test/compute/fixtures/vultr/list_sizes.json
index af78116..cb786da 100644
--- a/libcloud/test/compute/fixtures/vultr/list_sizes.json
+++ b/libcloud/test/compute/fixtures/vultr/list_sizes.json
@@ -1 +1,405 @@
-{"201":{"VPSPLANID":"201","name":"1024 MB RAM,25 GB SSD,1.00 TB BW","vcpu_count":"1","ram":"1024","disk":"25","bandwidth":"1.00","bandwidth_gb":"1024","price_per_month":"5.00","plan_type":"SSD","windows":false,"available_locations":[1,2,3,4,5,6,7,8,9,12,19,24,25,39,40]},"202":{"VPSPLANID":"202","name":"2048 MB RAM,40 GB SSD,2.00 TB BW","vcpu_count":"1","ram":"2048","disk":"40","bandwidth":"2.00","bandwidth_gb":"2048","price_per_month":"10.00","plan_type":"SSD","windows":false,"available_locations":[1,2,3,4,5,6,7,8,9,12,19,24,25,39,40]},"203":{"VPSPLANID":"203","name":"4096 MB RAM,60 GB SSD,3.00 TB BW","vcpu_count":"2","ram":"4096","disk":"60","bandwidth":"3.00","bandwidth_gb":"3072","price_per_month":"20.00","plan_type":"SSD","windows":false,"available_locations":[1,2,3,4,5,6,7,8,9,12,19,24,25,39,40]},"204":{"VPSPLANID":"204","name":"8192 MB RAM,100 GB SSD,4.00 TB BW","vcpu_count":"4","ram":"8192","disk":"100","bandwidth":"4.00","bandwidth_gb":"4096","price_per_month":"40.00","plan_type":"SSD","windows":false,"available_locations":[1,2,3,4,5,6,7,8,9,12,19,24,25,39,40]},"205":{"VPSPLANID":"205","name":"16384 MB RAM,200 GB SSD,5.00 TB BW","vcpu_count":"6","ram":"16384","disk":"200","bandwidth":"5.00","bandwidth_gb":"5120","price_per_month":"80.00","plan_type":"SSD","windows":false,"available_locations":[1,2,3,4,5,6,8,9,12,19,24,25,39,40]},"206":{"VPSPLANID":"206","name":"32768 MB RAM,300 GB SSD,6.00 TB BW","vcpu_count":"8","ram":"32768","disk":"300","bandwidth":"6.00","bandwidth_gb":"6144","price_per_month":"160.00","plan_type":"SSD","windows":false,"available_locations":[1,2,3,4,5,6,8,9,12,19,24,25,39,40]},"207":{"VPSPLANID":"207","name":"65536 MB RAM,400 GB SSD,10.00 TB BW","vcpu_count":"16","ram":"65536","disk":"400","bandwidth":"10.00","bandwidth_gb":"10240","price_per_month":"320.00","plan_type":"SSD","windows":false,"available_locations":[2,3,4,6,8,9,12,19,24,39,40]},"208":{"VPSPLANID":"208","name":"98304 MB RAM,800 GB SSD,15.00 TB BW","vcpu_count":"24","ram":"98304","disk":"800","bandwidth":"15.00","bandwidth_gb":"15360","price_per_month":"640.00","plan_type":"SSD","windows":false,"available_locations":[2,3,4,6,9,12,19,39]},"87":{"VPSPLANID":"87","name":"512 MB RAM,125 GB SATA,1.00 TB BW","vcpu_count":"1","ram":"512","disk":"125","bandwidth":"1.00","bandwidth_gb":"1024","price_per_month":"5.00","plan_type":"SATA","windows":false,"available_locations":[5,7]},"88":{"VPSPLANID":"88","name":"1024 MB RAM,250 GB SATA,2.00 TB BW","vcpu_count":"1","ram":"1024","disk":"250","bandwidth":"2.00","bandwidth_gb":"2048","price_per_month":"10.00","plan_type":"SATA","windows":false,"available_locations":[]},"89":{"VPSPLANID":"89","name":"2048 MB RAM,500 GB SATA,3.00 TB BW","vcpu_count":"1","ram":"2048","disk":"500","bandwidth":"3.00","bandwidth_gb":"3072","price_per_month":"20.00","plan_type":"SATA","windows":false,"available_locations":[]},"90":{"VPSPLANID":"90","name":"3072 MB RAM,750 GB SATA,4.00 TB BW","vcpu_count":"2","ram":"3072","disk":"750","bandwidth":"4.00","bandwidth_gb":"4096","price_per_month":"30.00","plan_type":"SATA","windows":false,"available_locations":[]},"91":{"VPSPLANID":"91","name":"4096 MB RAM,1000 GB SATA,5.00 TB BW","vcpu_count":"2","ram":"4096","disk":"1000","bandwidth":"5.00","bandwidth_gb":"5120","price_per_month":"40.00","plan_type":"SATA","windows":false,"available_locations":[]},"115":{"VPSPLANID":"115","name":"8192 MB RAM,110 GB SSD,10.00 TB BW","vcpu_count":"2","ram":"8192","disk":"110","bandwidth":"10.00","bandwidth_gb":"10240","price_per_month":"60.00","plan_type":"DEDICATED","windows":false,"available_locations":[1,2,25]},"116":{"VPSPLANID":"116","name":"16384 MB RAM,110 GB SSD,20.00 TB BW","vcpu_count":"4","ram":"16384","disk":"110","bandwidth":"20.00","bandwidth_gb":"20480","price_per_month":"120.00","plan_type":"DEDICATED","windows":false,"available_locations":[2]},"117":{"VPSPLANID":"117","name":"24576 MB RAM,110 GB SSD,30.00 TB BW","vcpu_count":"6","ram":"24576","disk":"110","bandwidth":"30.00","bandwidth_gb":"30720","price_per_month":"180.00","plan_type":"DEDICATED","windows":false,"available_locations":[2]},"118":{"VPSPLANID":"118","name":"32768 MB RAM,110 GB SSD,40.00 TB BW","vcpu_count":"8","ram":"32768","disk":"110","bandwidth":"40.00","bandwidth_gb":"40960","price_per_month":"240.00","plan_type":"DEDICATED","windows":false,"available_locations":[2]}}
\ No newline at end of file
+{
+ "201": {
+ "VPSPLANID": "201",
+ "name": "1024 MB RAM,25 GB SSD,1.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "1024",
+ "disk": "25",
+ "bandwidth": "1.00",
+ "bandwidth_gb": "1024",
+ "price_per_month": "5.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "202": {
+ "VPSPLANID": "202",
+ "name": "2048 MB RAM,55 GB SSD,2.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "2048",
+ "disk": "55",
+ "bandwidth": "2.00",
+ "bandwidth_gb": "2048",
+ "price_per_month": "10.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "203": {
+ "VPSPLANID": "203",
+ "name": "4096 MB RAM,80 GB SSD,3.00 TB BW",
+ "vcpu_count": "2",
+ "ram": "4096",
+ "disk": "80",
+ "bandwidth": "3.00",
+ "bandwidth_gb": "3072",
+ "price_per_month": "20.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "204": {
+ "VPSPLANID": "204",
+ "name": "8192 MB RAM,160 GB SSD,4.00 TB BW",
+ "vcpu_count": "4",
+ "ram": "8192",
+ "disk": "160",
+ "bandwidth": "4.00",
+ "bandwidth_gb": "4096",
+ "price_per_month": "40.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "205": {
+ "VPSPLANID": "205",
+ "name": "16384 MB RAM,320 GB SSD,5.00 TB BW",
+ "vcpu_count": "6",
+ "ram": "16384",
+ "disk": "320",
+ "bandwidth": "5.00",
+ "bandwidth_gb": "5120",
+ "price_per_month": "80.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "206": {
+ "VPSPLANID": "206",
+ "name": "32768 MB RAM,640 GB SSD,6.00 TB BW",
+ "vcpu_count": "8",
+ "ram": "32768",
+ "disk": "640",
+ "bandwidth": "6.00",
+ "bandwidth_gb": "6144",
+ "price_per_month": "160.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 39
+ ]
+ },
+ "207": {
+ "VPSPLANID": "207",
+ "name": "65536 MB RAM,1280 GB SSD,10.00 TB BW",
+ "vcpu_count": "16",
+ "ram": "65536",
+ "disk": "1280",
+ "bandwidth": "10.00",
+ "bandwidth_gb": "10240",
+ "price_per_month": "320.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 2,
+ 3,
+ 5,
+ 7,
+ 12,
+ 19,
+ 24,
+ 39
+ ]
+ },
+ "208": {
+ "VPSPLANID": "208",
+ "name": "98304 MB RAM,1600 GB SSD,15.00 TB BW",
+ "vcpu_count": "24",
+ "ram": "98304",
+ "disk": "1600",
+ "bandwidth": "15.00",
+ "bandwidth_gb": "15360",
+ "price_per_month": "640.00",
+ "plan_type": "SSD",
+ "windows": false,
+ "available_locations": [
+ 12
+ ]
+ },
+ "115": {
+ "VPSPLANID": "115",
+ "name": "8192 MB RAM,110 GB SSD,10.00 TB BW",
+ "vcpu_count": "2",
+ "ram": "8192",
+ "disk": "110",
+ "bandwidth": "10.00",
+ "bandwidth_gb": "10240",
+ "price_per_month": "60.00",
+ "plan_type": "DEDICATED",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 12,
+ 25
+ ]
+ },
+ "116": {
+ "VPSPLANID": "116",
+ "name": "16384 MB RAM,2x110 GB SSD,20.00 TB BW",
+ "vcpu_count": "4",
+ "ram": "16384",
+ "disk": "110",
+ "bandwidth": "20.00",
+ "bandwidth_gb": "20480",
+ "price_per_month": "120.00",
+ "plan_type": "DEDICATED",
+ "windows": false,
+ "available_locations": [
+ 1
+ ]
+ },
+ "117": {
+ "VPSPLANID": "117",
+ "name": "24576 MB RAM,3x110 GB SSD,30.00 TB BW",
+ "vcpu_count": "6",
+ "ram": "24576",
+ "disk": "110",
+ "bandwidth": "30.00",
+ "bandwidth_gb": "30720",
+ "price_per_month": "180.00",
+ "plan_type": "DEDICATED",
+ "windows": false,
+ "available_locations": [
+ 1
+ ]
+ },
+ "118": {
+ "VPSPLANID": "118",
+ "name": "32768 MB RAM,4x110 GB SSD,40.00 TB BW",
+ "vcpu_count": "8",
+ "ram": "32768",
+ "disk": "110",
+ "bandwidth": "40.00",
+ "bandwidth_gb": "40960",
+ "price_per_month": "240.00",
+ "plan_type": "DEDICATED",
+ "windows": false,
+ "available_locations": [
+ 1
+ ]
+ },
+ "400": {
+ "VPSPLANID": "400",
+ "name": "1024 MB RAM,32 GB SSD,1.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "1024",
+ "disk": "32",
+ "bandwidth": "1.00",
+ "bandwidth_gb": "1024",
+ "price_per_month": "6.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "401": {
+ "VPSPLANID": "401",
+ "name": "2048 MB RAM,64 GB SSD,2.00 TB BW",
+ "vcpu_count": "1",
+ "ram": "2048",
+ "disk": "64",
+ "bandwidth": "2.00",
+ "bandwidth_gb": "2048",
+ "price_per_month": "12.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24,
+ 25,
+ 39,
+ 40
+ ]
+ },
+ "402": {
+ "VPSPLANID": "402",
+ "name": "4096 MB RAM,128 GB SSD,3.00 TB BW",
+ "vcpu_count": "2",
+ "ram": "4096",
+ "disk": "128",
+ "bandwidth": "3.00",
+ "bandwidth_gb": "3072",
+ "price_per_month": "24.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 4,
+ 5,
+ 7,
+ 12,
+ 19,
+ 22,
+ 24
+ ]
+ },
+ "403": {
+ "VPSPLANID": "403",
+ "name": "8192 MB RAM,256 GB SSD,4.00 TB BW",
+ "vcpu_count": "3",
+ "ram": "8192",
+ "disk": "256",
+ "bandwidth": "4.00",
+ "bandwidth_gb": "4096",
+ "price_per_month": "48.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": [
+ 1,
+ 4,
+ 22
+ ]
+ },
+ "404": {
+ "VPSPLANID": "404",
+ "name": "16384 MB RAM,384 GB SSD,5.00 TB BW",
+ "vcpu_count": "4",
+ "ram": "16384",
+ "disk": "384",
+ "bandwidth": "5.00",
+ "bandwidth_gb": "5120",
+ "price_per_month": "96.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": [
+ 22
+ ]
+ },
+ "405": {
+ "VPSPLANID": "405",
+ "name": "32768 MB RAM,512 GB SSD,6.00 TB BW",
+ "vcpu_count": "8",
+ "ram": "32768",
+ "disk": "512",
+ "bandwidth": "6.00",
+ "bandwidth_gb": "6144",
+ "price_per_month": "192.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": []
+ },
+ "406": {
+ "VPSPLANID": "406",
+ "name": "49152 MB RAM,768 GB SSD,8.00 TB BW",
+ "vcpu_count": "12",
+ "ram": "49152",
+ "disk": "768",
+ "bandwidth": "8.00",
+ "bandwidth_gb": "8192",
+ "price_per_month": "256.00",
+ "plan_type": "HIGHFREQUENCY",
+ "windows": false,
+ "available_locations": []
+ }
+}
diff --git a/libcloud/test/compute/test_vultr.py b/libcloud/test/compute/test_vultr.py
index 9d94fb4..7caff46 100644
--- a/libcloud/test/compute/test_vultr.py
+++ b/libcloud/test/compute/test_vultr.py
@@ -16,8 +16,9 @@
import unittest
try:
- import simplejson as json
+ import simplejson as json # pylint: disable=unused-import
except ImportError:
+ # pylint: disable=unused-import
import json # NOQA
from libcloud.utils.py3 import httplib
@@ -25,6 +26,7 @@
from libcloud.common.types import ServiceUnavailableError
from libcloud.compute.drivers.vultr import VultrNodeDriver
+from libcloud.compute.base import NodeImage, NodeSize
from libcloud.test import LibcloudTestCase, MockHttp
from libcloud.test.file_fixtures import ComputeFileFixtures
@@ -51,19 +53,28 @@
self.assertTrue(image.id is not None)
self.assertTrue(image.name is not None)
+ def test_list_sizes_dont_require_api_key(self):
+ self.driver.list_sizes()
+ self.assertFalse(self.driver.connection.require_api_key())
+
def test_list_sizes_success(self):
+ """count of current plans"""
sizes = self.driver.list_sizes()
- self.assertTrue(len(sizes) == 17)
+ self.assertTrue(len(sizes) == 19)
size = sizes[0]
- self.assertTrue(size.id is not None)
+ self.assertTrue(size.id.isdigit())
self.assertEqual(size.name, '8192 MB RAM,110 GB SSD,10.00 TB BW')
self.assertEqual(size.ram, 8192)
size = sizes[16]
- self.assertTrue(size.id is not None)
- self.assertEqual(size.name, '4096 MB RAM,1000 GB SATA,5.00 TB BW')
- self.assertEqual(size.ram, 4096)
+ self.assertTrue(size.id.isdigit())
+ self.assertEqual(size.name, '16384 MB RAM,384 GB SSD,5.00 TB BW')
+ self.assertEqual(size.ram, 16384)
+
+ def test_list_locations_dont_require_api_key(self):
+ self.driver.list_locations()
+ self.assertFalse(self.driver.connection.require_api_key())
def test_list_locations_success(self):
locations = self.driver.list_locations()
@@ -72,6 +83,21 @@
location = locations[0]
self.assertEqual(location.id, '1')
self.assertEqual(location.name, 'New Jersey')
+ self.assertEqual(location.extra['continent'], 'North America')
+
+ def test_list_locations_extra_success(self):
+ locations = self.driver.list_locations()
+ self.assertTrue(len(locations) >= 1)
+ extra_keys = [
+ 'continent',
+ 'state',
+ 'ddos_protection',
+ 'block_storage',
+ 'regioncode']
+ for location in locations:
+ self.assertTrue(len(location.extra.keys()) >= 5)
+ self.assertTrue(all(item in location.extra.keys()
+ for item in extra_keys))
def test_list_nodes_require_api_key(self):
self.driver.list_nodes()
@@ -79,9 +105,32 @@
def test_list_nodes_success(self):
nodes = self.driver.list_nodes()
- self.assertEqual(len(nodes), 2)
- self.assertEqual(nodes[0].id, '1')
- self.assertEqual(nodes[0].public_ips, ['108.61.206.153'])
+ self.assertEqual(len(nodes), 3)
+ self.assertTrue(nodes[0].id.isdigit())
+ self.assertEqual(nodes[0].id, '41306569')
+ self.assertEqual(nodes[0].public_ips, ['45.76.43.87'])
+ self.assertEqual(nodes[0].private_ips, ['10.7.96.85'])
+ self.assertEqual(nodes[2].private_ips, [])
+
+ def test_list_nodes_image_success(self):
+ nodes = self.driver.list_nodes()
+ node = nodes[0]
+ self.assertTrue(isinstance(node.image, NodeImage))
+
+ def test_list_nodes_size_success(self):
+ nodes = self.driver.list_nodes()
+ node = nodes[0]
+ self.assertTrue(isinstance(node.size, NodeSize))
+
+ def test_list_nodes_success_extra(self):
+ extra_keys = [
+ "default_password", "pending_charges", "cost_per_month",
+ ]
+ nodes = self.driver.list_nodes()
+ for node in nodes:
+ self.assertTrue(len(node.extra.keys()) > 5)
+ self.assertTrue(all(item in node.extra.keys()
+ for item in extra_keys))
def test_reboot_node_success(self):
node = self.driver.list_nodes()[0]
@@ -94,7 +143,7 @@
test_location = self.driver.list_locations()[0]
created_node = self.driver.create_node('test-node', test_size,
test_image, test_location)
- self.assertEqual(created_node.id, "1")
+ self.assertEqual(created_node.id, "41326859")
def test_destroy_node_success(self):
node = self.driver.list_nodes()[0]
@@ -126,47 +175,59 @@
class VultrMockHttp(MockHttp):
fixtures = ComputeFileFixtures('vultr')
+ # pylint: disable=unused-argument
def _v1_regions_list(self, method, url, body, headers):
body = self.fixtures.load('list_locations.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_os_list(self, method, url, body, headers):
body = self.fixtures.load('list_images.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_plans_list(self, method, url, body, headers):
body = self.fixtures.load('list_sizes.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_server_list(self, method, url, body, headers):
body = self.fixtures.load('list_nodes.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_server_list_SERVICE_UNAVAILABLE(self, method, url, body, headers):
body = self.fixtures.load('error_rate_limit.txt')
return (httplib.SERVICE_UNAVAILABLE, body, {},
httplib.responses[httplib.SERVICE_UNAVAILABLE])
+ # pylint: disable=unused-argument
def _v1_server_create(self, method, url, body, headers):
body = self.fixtures.load('create_node.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_server_destroy(self, method, url, body, headers):
return (httplib.OK, "", {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_server_reboot(self, method, url, body, headers):
return (httplib.OK, "", {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_sshkey_list(self, method, url, body, headers):
body = self.fixtures.load('list_key_pairs.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_sshkey_create(self, method, url, body, headers):
body = self.fixtures.load('create_key_pair.json')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ # pylint: disable=unused-argument
def _v1_sshkey_destroy(self, method, url, body, headers):
return (httplib.OK, '', {}, httplib.responses[httplib.OK])
+
if __name__ == '__main__':
sys.exit(unittest.main())