You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2015/08/30 14:32:50 UTC
[02/21] libcloud git commit: [LIBCLOUD-736] Updated driver to use 2.0
for all new API calls, start/stop/restart server. list servers using new API,
updated extra calls for VLAN and network domain. Fixed up unit tests and added
new fixtures
[LIBCLOUD-736] Updated driver to use 2.0 for all new API calls, start/stop/restart server. list servers using new API, updated extra calls for VLAN and network domain. Fixed up unit tests and added new fixtures
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0ba9ae48
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0ba9ae48
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0ba9ae48
Branch: refs/heads/trunk
Commit: 0ba9ae48c6aed9d94a0cf1b0e57c995e6ca71f37
Parents: 9a9fafe
Author: Anthony Shaw <an...@gmail.com>
Authored: Tue Aug 25 16:42:13 2015 +1000
Committer: Anthony Shaw <an...@gmail.com>
Committed: Tue Aug 25 16:42:13 2015 +1000
----------------------------------------------------------------------
libcloud/compute/drivers/dimensiondata.py | 312 ++++++++++++++-----
...c_8dabe5a7d0e4_infrastructure_datacenter.xml | 44 +++
..._9cbc_8dabe5a7d0e4_network_networkDomain.xml | 13 +
...2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml | 17 +
...8a_9cbc_8dabe5a7d0e4_server_deleteServer.xml | 9 +
...5a7d0e4_server_deleteServer_RESOURCEBUSY.xml | 8 +
..._9cbc_8dabe5a7d0e4_server_powerOffServer.xml | 8 +
...5a7d0e4_server_powerOffServer_INPROGRESS.xml | 8 +
...8a_9cbc_8dabe5a7d0e4_server_rebootServer.xml | 8 +
...5a7d0e4_server_rebootServer_RESOURCEBUSY.xml | 7 +
...d8a_9cbc_8dabe5a7d0e4_server_resetServer.xml | 8 +
...745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml | 59 ++++
..._9cbc_8dabe5a7d0e4_server_shutdownServer.xml | 8 +
...5a7d0e4_server_shutdownServer_INPROGRESS.xml | 8 +
...d8a_9cbc_8dabe5a7d0e4_server_startServer.xml | 8 +
...abe5a7d0e4_server_startServer_INPROGRESS.xml | 8 +
...8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml | 2 +-
.../dimensiondata/oec_0_9_base_image.xml | 140 +--------
libcloud/test/compute/test_dimensiondata.py | 120 ++++++-
19 files changed, 583 insertions(+), 212 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 0a95255..9819111 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -30,7 +30,7 @@ from libcloud.compute.base import NodeDriver, Node
from libcloud.compute.base import NodeSize, NodeImage, NodeLocation
from libcloud.common.types import LibcloudError, InvalidCredsError
from libcloud.common.base import ConnectionUserAndKey, XmlResponse
-from libcloud.utils.xml import fixxpath, findtext, findall
+from libcloud.utils.xml import fixxpath, findtext, findall, findattr
from libcloud.compute.types import NodeState, Provider
# Roadmap / TODO:
@@ -52,6 +52,9 @@ GENERAL_NS = NAMESPACE_BASE + "/general"
IPPLAN_NS = NAMESPACE_BASE + "/ipplan"
WHITELABEL_NS = NAMESPACE_BASE + "/whitelabel"
+# API 2.0 Namespaces and URNs
+TYPES_URN = "urn:didata.com:api:cloud:types"
+
# API end-points
API_ENDPOINTS = {
'dd-na': {
@@ -104,9 +107,10 @@ class DimensionDataResponse(XmlResponse):
body = self.parse_body()
+ # TODO: The path is not fixed as server.
if self.status == httplib.BAD_REQUEST:
- code = findtext(body, 'resultCode', SERVER_NS)
- message = findtext(body, 'resultDetail', SERVER_NS)
+ code = findtext(body, 'responseCode', SERVER_NS)
+ message = findtext(body, 'message', SERVER_NS)
raise DimensionDataAPIException(code,
message,
driver=DimensionDataNodeDriver)
@@ -133,8 +137,11 @@ class DimensionDataConnection(ConnectionUserAndKey):
Connection class for the DimensionData driver
"""
- api_path = '/oec'
- api_version = '0.9'
+ api_path_version_1 = '/oec'
+ api_path_version_2 = '/caas'
+ api_version_1 = '0.9'
+ api_version_2 = '2.0'
+
_orgId = None
responseCls = DimensionDataResponse
@@ -159,31 +166,58 @@ class DimensionDataConnection(ConnectionUserAndKey):
self.key))).decode('utf-8'))
return headers
- def request(self, action, params=None, data='',
+ def request_api_1(self, action, params=None, data='',
headers=None, method='GET'):
- action = "%s/%s/%s" % (self.api_path, self.api_version, action)
+ action = "%s/%s/%s" % (self.api_path_version_1, self.api_version_1, action)
return super(DimensionDataConnection, self).request(
action=action,
params=params, data=data,
method=method, headers=headers)
+
+ def request_api_2(self, path, action, params=None, data='',
+ headers=None, method='GET'):
+ action = "%s/%s/%s/%s" % (self.api_path_version_2, self.api_version_2, path, action)
- def request_with_orgId(self, action, params=None, data='',
+ return super(DimensionDataConnection, self).request(
+ action=action,
+ params=params, data=data,
+ method=method, headers=headers)
+
+ def request_with_orgId_api_1(self, action, params=None, data='',
+ headers=None, method='GET'):
+ action = "%s/%s" % (self.get_resource_path_api_1(), action)
+
+ return super(DimensionDataConnection, self).request(
+ action=action,
+ params=params, data=data,
+ method=method, headers=headers)
+
+ def request_with_orgId_api_2(self, action, params=None, data='',
headers=None, method='GET'):
- action = "%s/%s" % (self.get_resource_path(), action)
+ action = "%s/%s" % (self.get_resource_path_api_2(), action)
return super(DimensionDataConnection, self).request(
action=action,
params=params, data=data,
method=method, headers=headers)
- def get_resource_path(self):
+ def get_resource_path_api_1(self):
"""
This method returns a resource path which is necessary for referencing
resources that require a full path instead of just an ID, such as
networks, and customer snapshots.
"""
- return ("%s/%s/%s" % (self.api_path, self.api_version,
+ return ("%s/%s/%s" % (self.api_path_version_1, self.api_version_1,
+ self._get_orgId()))
+
+ def get_resource_path_api_2(self):
+ """
+ This method returns a resource path which is necessary for referencing
+ resources that require a full path instead of just an ID, such as
+ networks, and customer snapshots.
+ """
+ return ("%s/%s/%s" % (self.api_path_version_2, self.api_version_2,
self._get_orgId()))
def _get_orgId(self):
@@ -193,7 +227,7 @@ class DimensionDataConnection(ConnectionUserAndKey):
of the other API functions
"""
if self._orgId is None:
- body = self.request('myaccount').object
+ body = self.request_api_1('myaccount').object
self._orgId = findtext(body, 'orgId', DIRECTORY_NS)
return self._orgId
@@ -250,6 +284,39 @@ class DimensionDataNetwork(object):
% (self.id, self.name, self.description, self.location,
self.private_net, self.multicast))
+class DimensionDataNetworkDomain(object):
+ """
+ DimensionData network domain with location.
+ """
+
+ def __init__(self, id, name, description, location, status):
+ self.id = str(id)
+ self.name = name
+ self.description = description
+ self.location = location
+ self.status = status
+
+ def __repr__(self):
+ return (('<DimensionDataNetworkDomain: id=%s, name=%s, description=%s, '
+ 'location=%s, status=%s>')
+ % (self.id, self.name, self.description, self.location, self.status))
+
+class DimensionDataVlan(object):
+ """
+ DimensionData VLAN.
+ """
+
+ def __init__(self, id, name, description, location, status):
+ self.id = str(id)
+ self.name = name
+ self.location = location
+ self.description = description
+ self.status = status
+
+ def __repr__(self):
+ return (('<DimensionDataNetworkDomain: id=%s, name=%s, description=%s, '
+ 'location=%s, status=%s>')
+ % (self.id, self.name, self.description, self.location, self.status))
class DimensionDataNodeDriver(NodeDriver):
"""
@@ -332,14 +399,14 @@ class DimensionDataNodeDriver(NodeDriver):
if not isinstance(ex_network, DimensionDataNetwork):
raise ValueError('ex_network must be of DimensionDataNetwork type')
- vlanResourcePath = "%s/%s" % (self.connection.get_resource_path(),
+ vlanResourcePath = "%s/%s" % (self.connection.get_resource_path_api_1(),
ex_network.id)
imageResourcePath = None
if 'resourcePath' in image.extra:
imageResourcePath = image.extra['resourcePath']
else:
- imageResourcePath = "%s/%s" % (self.connection.get_resource_path(),
+ imageResourcePath = "%s/%s" % (self.connection.get_resource_path_api_1(),
image.id)
server_elm = ET.Element('Server', {'xmlns': SERVER_NS})
@@ -350,7 +417,7 @@ class DimensionDataNodeDriver(NodeDriver):
ET.SubElement(server_elm, "administratorPassword").text = password
ET.SubElement(server_elm, "isStarted").text = str(ex_is_started)
- self.connection.request_with_orgId('server',
+ self.connection.request_with_orgId_api_1('server',
method='POST',
data=ET.tostring(server_elm)).object
@@ -366,23 +433,23 @@ class DimensionDataNodeDriver(NodeDriver):
return node
def destroy_node(self, node):
- body = self.connection.request_with_orgId(
- 'server/%s?delete' % (node.id)).object
-
- result = findtext(body, 'result', GENERAL_NS)
- return result == 'SUCCESS'
+ request_elm = ET.Element('deleteServer', {'xmlns': TYPES_URN, 'id': node.id})
+ body = self.connection.request_with_orgId_api_2(
+ 'server/deleteServer', method='POST', data=ET.tostring(request_elm) ).object
+ result = findtext(body, 'responseCode', TYPES_URN)
+ return result == 'IN_PROGRESS'
def reboot_node(self, node):
- body = self.connection.request_with_orgId(
- 'server/%s?restart' % (node.id)).object
- result = findtext(body, 'result', GENERAL_NS)
- return result == 'SUCCESS'
+ request_elm = ET.Element('rebootServer', {'xmlns': TYPES_URN, 'id': node.id})
+ body = self.connection.request_with_orgId_api_2(
+ 'server/rebootServer', method='POST', data=ET.tostring(request_elm) ).object
+ result = findtext(body, 'responseCode', TYPES_URN)
+ return result == 'IN_PROGRESS'
def list_nodes(self):
nodes = self._to_nodes(
- self.connection.request_with_orgId('server/deployed').object)
- nodes.extend(self._to_nodes(
- self.connection.request_with_orgId('server/pendingDeploy').object))
+ self.connection.request_with_orgId_api_2('server/server').object)
+
return nodes
def list_images(self, location=None):
@@ -394,9 +461,16 @@ class DimensionDataNodeDriver(NodeDriver):
@inherits: :class:`NodeDriver.list_images`
"""
return self._to_base_images(
- self.connection.request('base/image').object)
+ self.connection.request_api_1('base/image').object)
def list_sizes(self, location=None):
+ """
+ return a list of available sizes
+ Currently, the size of the node is dictated by the chosen OS base
+ image, they cannot be set explicitly.
+
+ @inherits: :class:`NodeDriver.list_sizes`
+ """
return [
NodeSize(id=1,
name="default",
@@ -415,7 +489,7 @@ class DimensionDataNodeDriver(NodeDriver):
@inherits: :class:`NodeDriver.list_locations`
"""
return self._to_locations(
- self.connection.request_with_orgId('datacenter').object)
+ self.connection.request_with_orgId_api_2('infrastructure/datacenter').object)
def list_networks(self, location=None):
"""
@@ -430,7 +504,7 @@ class DimensionDataNodeDriver(NodeDriver):
:rtype: ``list`` of :class:`DimensionDataNetwork`
"""
return self._to_networks(
- self.connection.request_with_orgId('networkWithLocation').object)
+ self.connection.request_with_orgId_api_1('networkWithLocation').object)
def _to_base_images(self, object):
images = []
@@ -476,10 +550,11 @@ class DimensionDataNodeDriver(NodeDriver):
:rtype: ``bool``
"""
- body = self.connection.request_with_orgId(
- 'server/%s?start' % node.id).object
- result = findtext(body, 'result', GENERAL_NS)
- return result == 'SUCCESS'
+ request_elm = ET.Element('startServer', {'xmlns': TYPES_URN, 'id': node.id})
+ body = self.connection.request_with_orgId_api_2(
+ 'server/startServer', method='POST', data=ET.tostring(request_elm) ).object
+ result = findtext(body, 'responseCode', TYPES_URN)
+ return result == 'IN_PROGRESS'
def ex_shutdown_graceful(self, node):
"""
@@ -493,10 +568,11 @@ class DimensionDataNodeDriver(NodeDriver):
:rtype: ``bool``
"""
- body = self.connection.request_with_orgId(
- 'server/%s?shutdown' % (node.id)).object
- result = findtext(body, 'result', GENERAL_NS)
- return result == 'SUCCESS'
+ request_elm = ET.Element('shutdownServer', {'xmlns': TYPES_URN, 'id': node.id})
+ body = self.connection.request_with_orgId_api_2(
+ 'server/shutdownServer', method='POST', data=ET.tostring(request_elm) ).object
+ result = findtext(body, 'responseCode', TYPES_URN)
+ return result == 'IN_PROGRESS'
def ex_power_off(self, node):
"""
@@ -510,10 +586,29 @@ class DimensionDataNodeDriver(NodeDriver):
:rtype: ``bool``
"""
- body = self.connection.request_with_orgId(
- 'server/%s?poweroff' % node.id).object
- result = findtext(body, 'result', GENERAL_NS)
- return result == 'SUCCESS'
+ request_elm = ET.Element('powerOffServer', {'xmlns': TYPES_URN, 'id': node.id})
+ body = self.connection.request_with_orgId_api_2(
+ 'server/powerOffServer', method='POST', data=ET.tostring(request_elm) ).object
+ result = findtext(body, 'responseCode', TYPES_URN)
+ return result == 'IN_PROGRESS'
+
+ def ex_reset(self, node):
+ """
+ This function will abruptly reset a server. Unlike
+ reboot_node, success ensures the node will restart but some OS
+ and application configurations may be adversely affected by the
+ equivalent of pulling the power plug out of the machine.
+
+ :param node: Node which should be used
+ :type node: :class:`Node`
+
+ :rtype: ``bool``
+ """
+ request_elm = ET.Element('resetServer', {'xmlns': TYPES_URN, 'id': node.id})
+ body = self.connection.request_with_orgId_api_2(
+ 'server/resetServer', method='POST', data=ET.tostring(request_elm) ).object
+ result = findtext(body, 'responseCode', TYPES_URN)
+ return result == 'IN_PROGRESS'
def ex_list_networks(self):
"""
@@ -523,10 +618,33 @@ class DimensionDataNodeDriver(NodeDriver):
:return: a list of DimensionDataNetwork objects
:rtype: ``list`` of :class:`DimensionDataNetwork`
"""
- response = self.connection.request_with_orgId('networkWithLocation') \
+ response = self.connection.request_with_orgId_api_1('networkWithLocation') \
.object
return self._to_networks(response)
+ def ex_list_network_domains(self):
+ """
+ List networks deployed across all data center locations for your
+ organization. The response includes the location of each network.
+
+ :return: a list of DimensionDataNetwork objects
+ :rtype: ``list`` of :class:`DimensionDataNetwork`
+ """
+ response = self.connection.request_with_orgId_api_2('network/networkDomain') \
+ .object
+ return self._to_network_domains(response)
+
+ def ex_list_vlans(self):
+ """
+ List VLANs available in a given networkDomain
+
+ :return: a list of DimensionDataVlan objects
+ :rtype: ``list`` of :class:`DimensionDataVlan`
+ """
+ response = self.connection.request_with_orgId_api_2('network/vlan') \
+ .object
+ return self._to_vlans(response)
+
def ex_get_location_by_id(self, id):
"""
Get location by ID.
@@ -569,67 +687,107 @@ class DimensionDataNodeDriver(NodeDriver):
NETWORK_NS),
multicast=multicast,
status=status)
+
+ def _to_network_domains(self, object):
+ network_domains = []
+ for element in findall(object, 'networkDomain', TYPES_URN):
+ network_domains.append(self._to_network_domain(element))
+
+ return network_domains
+
+ def _to_network_domain(self, element):
+ status = self._to_status(element.find(fixxpath('state', TYPES_URN)))
+
+ location_id = element.get('datacenter')
+ location = self.ex_get_location_by_id(location_id)
+
+ return DimensionDataNetworkDomain(
+ id=element.get('id'),
+ name=findtext(element, 'name', TYPES_URN),
+ description=findtext(element, 'description',
+ TYPES_URN),
+ location=location,
+ status=status)
+
+ def _to_vlans(self, object):
+ vlans = []
+ for element in findall(object, 'vlan', TYPES_URN):
+ vlans.append(self._to_vlan(element))
+
+ return vlans
+
+ def _to_vlan(self, element):
+ status = self._to_status(element.find(fixxpath('state', TYPES_URN)))
+
+ location_id = element.get('location')
+ location = self.ex_get_location_by_id(location_id)
+
+ return DimensionDataVlan(
+ id=element.get('id'),
+ name=findtext(element, 'name', TYPES_URN),
+ description=findtext(element, 'description',
+ TYPES_URN),
+ location=location,
+ status=status)
def _to_locations(self, object):
locations = []
- for element in object.findall(fixxpath('datacenter', DATACENTER_NS)):
+ for element in object.findall(fixxpath('datacenter', TYPES_URN)):
locations.append(self._to_location(element))
return locations
def _to_location(self, element):
- l = NodeLocation(id=findtext(element, 'location', DATACENTER_NS),
- name=findtext(element, 'displayName', DATACENTER_NS),
- country=findtext(element, 'country', DATACENTER_NS),
+ l = NodeLocation(id=element.get('id'),
+ name=findtext(element, 'displayName', TYPES_URN),
+ country=findtext(element, 'country', TYPES_URN),
driver=self)
return l
def _to_nodes(self, object):
- node_elements = object.findall(fixxpath('DeployedServer', SERVER_NS))
- node_elements.extend(object.findall(
- fixxpath('PendingDeployServer', SERVER_NS)))
+ node_elements = object.findall(fixxpath('Server', TYPES_URN))
+
return [self._to_node(el) for el in node_elements]
def _to_node(self, element):
- if findtext(element, 'isStarted', SERVER_NS) == 'true':
+ if findtext(element, 'started', TYPES_URN) == 'true':
state = NodeState.RUNNING
else:
state = NodeState.TERMINATED
- status = self._to_status(element.find(fixxpath('status', SERVER_NS)))
+ status = self._to_status(element.find(fixxpath('state', TYPES_URN)))
extra = {
- 'description': findtext(element, 'description', SERVER_NS),
- 'sourceImageId': findtext(element, 'sourceImageId', SERVER_NS),
- 'networkId': findtext(element, 'networkId', SERVER_NS),
- 'machineName': findtext(element, 'machineName', SERVER_NS),
- 'deployedTime': findtext(element, 'deployedTime', SERVER_NS),
- 'cpuCount': findtext(element, 'machineSpecification/cpuCount',
- SERVER_NS),
- 'memoryMb': findtext(element, 'machineSpecification/memoryMb',
- SERVER_NS),
- 'osStorageGb': findtext(element,
- 'machineSpecification/osStorageGb',
- SERVER_NS),
- 'additionalLocalStorageGb': findtext(
- element, 'machineSpecification/additionalLocalStorageGb',
- SERVER_NS),
- 'OS_type': findtext(element,
- 'machineSpecification/operatingSystem/type',
- SERVER_NS),
- 'OS_displayName': findtext(
- element, 'machineSpecification/operatingSystem/displayName',
- SERVER_NS),
+ 'description': findtext(element, 'description', TYPES_URN),
+ 'sourceImageId': findtext(element, 'sourceImageId', TYPES_URN),
+ 'networkId': findtext(element, 'networkId', TYPES_URN),
+ 'networkDomainId': element.find(fixxpath('networkInfo', TYPES_URN))
+ .get('networkDomainId'),
+ 'datacenterId': element.get('datacenterId'),
+ 'deployedTime': findtext(element, 'createTime', TYPES_URN),
+ 'cpuCount': int(findtext(element, 'cpuCount',
+ TYPES_URN)),
+ 'memoryMb': int(findtext(element, 'memoryGb',
+ TYPES_URN)) * 1024,
+ 'OS_id': element.find(fixxpath('operatingSystem', TYPES_URN))
+ .get('id'),
+ 'OS_type': element.find(fixxpath('operatingSystem', TYPES_URN))
+ .get('family'),
+ 'OS_displayName': element.find(fixxpath('operatingSystem', TYPES_URN))
+ .get('displayName'),
'status': status,
}
- public_ip = findtext(element, 'publicIpAddress', SERVER_NS)
+ public_ip = findtext(element, 'publicIpAddress', TYPES_URN)
+
+ private_ip = findtext(element, 'networkInfo/primaryNic/privateIpv4',
+ TYPES_URN)
- n = Node(id=findtext(element, 'id', SERVER_NS),
- name=findtext(element, 'name', SERVER_NS),
+ n = Node(id=element.get('id'),
+ name=findtext(element, 'name', TYPES_URN),
state=state,
public_ips=[public_ip] if public_ip is not None else [],
- private_ips=findtext(element, 'privateIpAddress', SERVER_NS),
+ private_ips=[private_ip] if private_ip is not None else [],
driver=self.connection.driver,
extra=extra)
return n
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml
new file mode 100644
index 0000000..66ae1db
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<datacenters pageNumber="1" pageCount="1" totalCount="2" pageSize="50"
+xmlns="urn:didata.com:api:cloud:types">
+<datacenter id="NA10" type="MCP 2.0">
+<displayName>US - West</displayName>
+<city>Santa Clara</city>
+<state>California</state>
+<country>US</country>
+<vpnUrl>https://na10.cloud-vpn.net</vpnUrl>
+<ftpsHost>ftps-na.cloud-vpn.net</ftpsHost>
+<networking type="2" maintenanceStatus="NORMAL">
+<!-- 0-to-many optional property elements -->
+<property name="MAX_NODE_CONNECTION_LIMIT" value="100000"/>
+<property name="MAX_NODE_CONNECTION_RATE_LIMIT" value="4000"/>
+<property name="MAX_VIRTUAL_LISTENER_CONNECTION_LIMIT" value="100000"/>
+<property name="MAX_VIRTUAL_LISTENER_CONNECTION_RATE_LIMIT"
+value="4000"/>
+</networking>
+<hypervisor type="VMWARE" maintenanceStatus="PENDING_MAINTENANCE">
+<diskSpeed available="false" default="false" id="ARCHIVE">
+<displayName>Archive Speed</displayName>
+<abbreviation>ARCH</abbreviation>
+<description>Archive Disk Speed</description>
+<unavailableReason>Replaced with HPF and ECN</unavailableReason>
+</diskSpeed>
+<property name="MIN_DISK_SIZE_GB" value="10"/>
+<property name="MAX_DISK_SIZE_GB" value="1000"/>
+<property name="MAX_TOTAL_ADDITIONAL_STORAGE_GB" value="2500"/>
+<property name="MAX_CPU_COUNT" value="8"/>
+<property name="MIN_MEMORY_MB" value="1024"/>
+<property name="MAX_MEMORY_MB" value="65536"/>
+</hypervisor>
+<!-- Optional: if Cloud Backup is enabled at the Data Center it will be returned -->
+<backup type="COMMVAULT" maintenanceStatus="IN_MAINTENANCE">
+<!-- 0-to-many optional property elements -->
+</backup>
+<consoleAccess maintenanceStatus="IN_MAINTENANCE">
+<!-- 0-to-many optional property elements -->
+</consoleAccess>
+<monitoring maintenanceStatus="IN_MAINTENANCE">
+<!-- 0-to-many optional property elements -->
+</monitoring>
+</datacenter>
+</datacenters>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml
new file mode 100644
index 0000000..22680d1
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<networkDomains
+xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="1"
+totalCount="1" pageSize="250">
+<networkDomain id="484174a2-ae74-4658-9e56-50fc90e086cf" datacenter="NA10">
+<name>Production Network Domain</name>
+<description></description>
+<type>ESSENTIALS</type>
+<snatIpv4Address>165.180.8.8</snatIpv4Address>
+<createTime>2015-02-12T18:18:14.000Z</createTime>
+<state>NORMAL</state>
+</networkDomain>
+</networkDomains>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml
new file mode 100644
index 0000000..b489284
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<vlans
+xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="1"
+totalCount="1" pageSize="250">
+<vlan id="0e56433f-d808-4669-821d-812769517ff8" location="NA10">
+<networkDomain id="484174a2-ae74-4658-9e56-50fc90e086cf"
+name="Production Network Domain"/>
+<name>Production VLAN</name>
+<description>For hosting our Production Cloud Servers</description>
+<privateIpv4Range address="10.0.3.0" prefixSize="24"/>
+<ipv4GatewayAddress>10.0.3.1</ipv4GatewayAddress>
+<ipv6Range address="2607:f480:1111:1153:0:0:0:0" prefixSize="64"/>
+<ipv6GatewayAddress>2607:f480:1111:1153:0:0:0:1</ipv6GatewayAddress>
+<createTime>2015-02-13T10:56:44.000Z</createTime>
+<state>NORMAL</state>
+</vlan>
+</vlans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer.xml
new file mode 100644
index 0000000..c8e70da
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-03-
+08T05:49:07.774-04:00/f0a53414-e991-4c9b-b52f-5770ff5b606b">
+<operation>DELETE_SERVER</operation>
+<responseCode>IN_PROGRESS</responseCode>
+<message>Request to Delete Server (Id:d577a691-e116-4913-a440-
+022d2729fc84) has been accepted and is being processed</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer_RESOURCEBUSY.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer_RESOURCEBUSY.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer_RESOURCEBUSY.xml
new file mode 100644
index 0000000..2df9e07
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer_RESOURCEBUSY.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-03-
+08T05:49:07.774-04:00/f0a53414-e991-4c9b-b52f-5770ff5b606b">
+<operation>DELETE_SERVER</operation>
+<responseCode>RESOURCE_BUSY</responseCode>
+<message>Server is already busy</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer.xml
new file mode 100644
index 0000000..549ea79
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T11:49:17.375-04:00/d5bb0975-1ade-4350-aaec-24807bdf7038">
+<operation>POWER_OFF_SERVER</operation>
+<responseCode>IN_PROGRESS</responseCode>
+<message>Request to power off Server 'Production Server' has been accepted
+and is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer_INPROGRESS.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer_INPROGRESS.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer_INPROGRESS.xml
new file mode 100644
index 0000000..8ddcca9
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer_INPROGRESS.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T11:49:17.375-04:00/d5bb0975-1ade-4350-aaec-24807bdf7038">
+<operation>POWER_OFF_SERVER</operation>
+<responseCode>RESOURCE_BUSY</responseCode>
+<message>Request to power off Server 'Production Server' has been accepted
+and is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer.xml
new file mode 100644
index 0000000..38f098a
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T09:52:43.365-04:00/5260a4e5-ea21-49f4-909a-22341d8c39cb">
+<operation>REBOOT_SERVER</operation>
+<responseCode>IN_PROGRESS</responseCode>
+<message>Request to reboot Server 'Production Server' has been accepted
+and is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer_RESOURCEBUSY.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer_RESOURCEBUSY.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer_RESOURCEBUSY.xml
new file mode 100644
index 0000000..3defba4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer_RESOURCEBUSY.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T09:52:43.365-04:00/5260a4e5-ea21-49f4-909a-22341d8c39cb">
+<operation>REBOOT_SERVER</operation>
+<responseCode>RESOURCE_BUSY</responseCode>
+<message>Request to reboot Server 'Production Server' did not work, server is busy.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_resetServer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_resetServer.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_resetServer.xml
new file mode 100644
index 0000000..ece1a8b
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_resetServer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T11:37:13.823-04:00/7b264a73-d73b-424c-bec8-5debba8b4626">
+<operation>RESET_SERVER</operation>
+<responseCode>IN_PROGRESS</responseCode>
+<message>Request to reset Server 'Production Server' has been accepted and
+is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml
new file mode 100644
index 0000000..bc98272
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<servers
+xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="1"
+totalCount="2" pageSize="250">
+<Server id="d577a691-e116-4913-a440-022d2729fc84" datacenterId="NA9">
+<name>Test Server</name>
+<description>Test Description</description>
+<operatingSystem id="REDHAT664" displayName="REDHAT6/64"
+family="UNIX"/>
+<cpuCount>1</cpuCount>
+<memoryGb>2</memoryGb>
+<disk id="338c1163-5348-4572-962d-185c97bd0d65" scsiId="0" sizeGb="10"
+speed="STANDARD" state="NORMAL"/>
+<networkInfo networkDomainId="484174a2-ae74-4658-9e56-50fc90e086cf">
+<primaryNic id="4c8d5f67-c6df-421d-b8ac-45dd1b141334"
+privateIpv4="10.0.3.11" ipv6="2607:f480:1111:1153:dee:4666:1130:7484"
+vlanId="0e56433f-d808-4669-821d-812769517ff8" vlanName="Production VLAN"
+state="NORMAL"/>
+</networkInfo>
+<sourceImageId>02250336-de2b-4e99-ab96-78511b7f8f4b</sourceImageId>
+<createTime>2015-02-17T10:59:18.000Z</createTime>
+<deployed>true</deployed>
+<started>true</started>
+<state>NORMAL</state>
+<machineStatus name="vmwareToolsVersionStatus" value="CURRENT"/>
+<machineStatus name="vmwareToolsRunningStatus" value="RUNNING"/>
+<machineStatus name="vmwareToolsApiVersion" value="9354"/>
+</Server>
+<Server id="abadbc7e-9e10-46ca-9d4a-194bcc6b6c16" datacenterId="NA9">
+<name>Production Web Server 2</name>
+<description>This server hosts our production web
+applications.</description>
+<operatingSystem id="REDHAT664" displayName="REDHAT6/64"
+family="UNIX"/>
+<cpuCount>1</cpuCount>
+<memoryGb>2</memoryGb>
+<disk id="338c1163-5348-4572-962d-185c97bd0d65" scsiId="0" sizeGb="10"
+speed="STANDARD" state="NORMAL"/>
+<networkInfo networkDomainId="484174a2-ae74-4658-9e56-50fc90e086cf">
+<primaryNic id="4c8d5f67-c6df-421d-b8ac-45dd1b141334"
+privateIpv4="10.0.3.11" ipv6="2607:f480:1111:1153:dee:4666:1130:7484"
+vlanId="0e56433f-d808-4669-821d-812769517ff8" vlanName="Production VLAN"
+state="NORMAL"/>
+</networkInfo>
+<sourceImageId>02250336-de2b-4e99-ab96-78511b7f8f4b</sourceImageId>
+<createTime>2015-02-17T10:59:18.000Z</createTime>
+<deployed>true</deployed>
+<started>true</started>
+<state>PENDING_CHANGE</state>
+<progress>
+<action>SHUTDOWN_SERVER</action>
+<requestTime>2015-03-06T18:05:33.000Z</requestTime>
+<userName>myuser</userName>
+</progress>
+<machineStatus name="vmwareToolsVersionStatus" value="CURRENT"/>
+<machineStatus name="vmwareToolsRunningStatus" value="RUNNING"/>
+<machineStatus name="vmwareToolsApiVersion" value="9354"/>
+</Server>
+</servers>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer.xml
new file mode 100644
index 0000000..937cb0d
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T09:06:01.949-04:00/fd2650a9-3473-41eb-9c6e-1eef29c0bb27">
+<operation>SHUTDOWN_SERVER</operation>
+<responseCode>IN_PROGRESS</responseCode>
+<message>Request to shutdown Server 'Production Server' has been accepted
+and is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer_INPROGRESS.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer_INPROGRESS.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer_INPROGRESS.xml
new file mode 100644
index 0000000..386489c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer_INPROGRESS.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T09:06:01.949-04:00/fd2650a9-3473-41eb-9c6e-1eef29c0bb27">
+<operation>SHUTDOWN_SERVER</operation>
+<responseCode>RESOURCE_BUSY</responseCode>
+<message>Request to shutdown Server 'Production Server' has been accepted
+and is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer.xml
new file mode 100644
index 0000000..4fb4589
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T08:27:00.176-04:00/14b0a61f-7e85-49c9-8e7e-146fa3e562b7">
+<operation>START_SERVER</operation>
+<responseCode>IN_PROGRESS</responseCode>
+<message>Request to start Server 'Production Server' has been accepted and
+is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer_INPROGRESS.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer_INPROGRESS.xml b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer_INPROGRESS.xml
new file mode 100644
index 0000000..f5c3070
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer_INPROGRESS.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-08-
+12T08:27:00.176-04:00/14b0a61f-7e85-49c9-8e7e-146fa3e562b7">
+<operation>START_SERVER</operation>
+<responseCode>RESOURCE_BUSY</responseCode>
+<message>Request to start Server 'Production Server' has been accepted and
+is being processed.</message>
+</response>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml
index ca27554..88364b6 100644
--- a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml
+++ b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml
@@ -4,7 +4,7 @@
<ns4:id>53b4c05b-341e-4ac3-b688-bdd74e53ca9b</ns4:id>
<ns4:name>test-net1</ns4:name>
<ns4:description>test-net1 description</ns4:description>
- <ns4:location>NA1</ns4:location>
+ <ns4:location>NA10</ns4:location>
<ns4:privateNet>10.162.1.0</ns4:privateNet>
<ns4:multicast>false</ns4:multicast>
</ns4:network>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_base_image.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_base_image.xml b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_base_image.xml
index 3be14f0..d758343 100644
--- a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_base_image.xml
+++ b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_base_image.xml
@@ -9,7 +9,7 @@
<type>UNIX</type>
<displayName>REDHAT5/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>1</cpuCount>
<memory>2048</memory>
<osStorage>10</osStorage>
@@ -25,7 +25,7 @@
<type>UNIX</type>
<displayName>REDHAT5/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>2</cpuCount>
<memory>4096</memory>
<osStorage>10</osStorage>
@@ -41,7 +41,7 @@
<type>UNIX</type>
<displayName>REDHAT5/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>4</cpuCount>
<memory>6144</memory>
<osStorage>10</osStorage>
@@ -57,7 +57,7 @@
<type>UNIX</type>
<displayName>REDHAT5/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>1</cpuCount>
<memory>2048</memory>
<osStorage>10</osStorage>
@@ -73,7 +73,7 @@
<type>UNIX</type>
<displayName>UBUNTU8/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>2</cpuCount>
<memory>4096</memory>
<osStorage>10</osStorage>
@@ -89,7 +89,7 @@
<type>WINDOWS</type>
<displayName>WIN2008R2E/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>2</cpuCount>
<memory>4096</memory>
<osStorage>50</osStorage>
@@ -105,7 +105,7 @@
<type>WINDOWS</type>
<displayName>WIN2008R2E/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>4</cpuCount>
<memory>8192</memory>
<osStorage>50</osStorage>
@@ -121,7 +121,7 @@
<type>WINDOWS</type>
<displayName>WIN2008R2S/64</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>2</cpuCount>
<memory>4096</memory>
<osStorage>50</osStorage>
@@ -137,7 +137,7 @@
<type>WINDOWS</type>
<displayName>WIN2008S/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>1</cpuCount>
<memory>2048</memory>
<osStorage>50</osStorage>
@@ -153,7 +153,7 @@
<type>WINDOWS</type>
<displayName>WIN2008S/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>2</cpuCount>
<memory>4096</memory>
<osStorage>50</osStorage>
@@ -169,7 +169,7 @@
<type>WINDOWS</type>
<displayName>WIN2008S/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>4</cpuCount>
<memory>4096</memory>
<osStorage>50</osStorage>
@@ -185,7 +185,7 @@
<type>WINDOWS</type>
<displayName>WIN2008E/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>2</cpuCount>
<memory>4096</memory>
<osStorage>50</osStorage>
@@ -201,7 +201,7 @@
<type>UNIX</type>
<displayName>REDHAT4/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>1</cpuCount>
<memory>2048</memory>
<osStorage>10</osStorage>
@@ -217,123 +217,11 @@
<type>UNIX</type>
<displayName>CENTOS5/32</displayName>
</operatingSystem>
- <location>NA1</location>
+ <location>NA10</location>
<cpuCount>1</cpuCount>
<memory>2048</memory>
<osStorage>10</osStorage>
<additionalLocalStorage>0</additionalLocalStorage>
<created>1970-01-01T00:00:02.010Z</created>
</ServerImage>
- <ServerImage>
- <id>52ed91da-ebea-11df-bdc1-001517c46384</id>
- <resourcePath>/oec/base/image/52ed91da-ebea-11df-bdc1-001517c46384</resourcePath>
- <name>CentOS 5.5 64-bit 1 CPU</name>
- <description>CentOS release 5.5, 64-bit</description>
- <operatingSystem>
- <type>UNIX</type>
- <displayName>CENTOS5/64</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>1</cpuCount>
- <memory>2048</memory>
- <osStorage>10</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>1970-01-01T00:00:02.010Z</created>
- </ServerImage>
- <ServerImage>
- <id>52ed766e-ebea-11df-bdc1-001517c46384</id>
- <resourcePath>/oec/base/image/52ed766e-ebea-11df-bdc1-001517c46384</resourcePath>
- <name>Win2003 Ent 32-bit 1 CPU</name>
- <description>Windows 2003 Enterprise SP2 32-bit</description>
- <operatingSystem>
- <type>WINDOWS</type>
- <displayName>WIN2003E/32</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>1</cpuCount>
- <memory>2048</memory>
- <osStorage>16</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>1970-01-01T00:00:02.010Z</created>
- </ServerImage>
- <ServerImage>
- <id>52ed7876-ebea-11df-bdc1-001517c46384</id>
- <resourcePath>/oec/base/image/52ed7876-ebea-11df-bdc1-001517c46384</resourcePath>
- <name>Win2003 Ent 32-bit 2 CPU</name>
- <description>Windows 2003 Enterprise SP2 32-bit</description>
- <operatingSystem>
- <type>WINDOWS</type>
- <displayName>WIN2003E/32</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>2</cpuCount>
- <memory>4096</memory>
- <osStorage>16</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>1970-01-01T00:00:02.010Z</created>
- </ServerImage>
- <ServerImage>
- <id>52ed7984-ebea-11df-bdc1-001517c46384</id>
- <resourcePath>/oec/base/image/52ed7984-ebea-11df-bdc1-001517c46384</resourcePath>
- <name>Win2003 Ent 32-bit 4 CPU</name>
- <description>Windows 2003 Enterprise SP2 32-bit</description>
- <operatingSystem>
- <type>WINDOWS</type>
- <displayName>WIN2003E/32</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>4</cpuCount>
- <memory>4096</memory>
- <osStorage>16</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>1970-01-01T00:00:02.010Z</created>
- </ServerImage>
- <ServerImage>
- <id>52ed7a88-ebea-11df-bdc1-001517c46384</id>
- <resourcePath>/oec/base/image/52ed7a88-ebea-11df-bdc1-001517c46384</resourcePath>
- <name>Win2003 Std 64-bit 2 CPU</name>
- <description>Windows 2003 Standard x64 SP2, 64-bit</description>
- <operatingSystem>
- <type>WINDOWS</type>
- <displayName>WIN2003S/64</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>2</cpuCount>
- <memory>4096</memory>
- <osStorage>16</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>1970-01-01T00:00:02.010Z</created>
- </ServerImage>
- <ServerImage>
- <id>0c231ef0-2a42-11e0-bfb5-001517c46384</id>
- <resourcePath>/oec/base/image/0c231ef0-2a42-11e0-bfb5-001517c46384</resourcePath>
- <name>RedHat 64-bit 2 CPU with MySQL</name>
- <description>RedHat 5.5 Enterprise with MySQL 5.5 installed</description>
- <operatingSystem>
- <type>UNIX</type>
- <displayName>REDHAT5/64</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>2</cpuCount>
- <memory>8192</memory>
- <osStorage>10</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>2011-01-27T18:19:58.000Z</created>
- </ServerImage>
- <ServerImage>
- <id>2fb5261a-2a42-11e0-bfb5-001517c46384</id>
- <resourcePath>/oec/base/image/2fb5261a-2a42-11e0-bfb5-001517c46384</resourcePath>
- <name>RedHat 64-bit 2 CPU with PostgreSQL</name>
- <description>RedHat 5.5 Enterprise with PostgreSQL 9.0 installed</description>
- <operatingSystem>
- <type>UNIX</type>
- <displayName>REDHAT5/64</displayName>
- </operatingSystem>
- <location>NA1</location>
- <cpuCount>2</cpuCount>
- <memory>8192</memory>
- <osStorage>10</osStorage>
- <additionalLocalStorage>0</additionalLocalStorage>
- <created>2011-01-27T18:20:57.000Z</created>
- </ServerImage>
</ServerImages>
http://git-wip-us.apache.org/repos/asf/libcloud/blob/0ba9ae48/libcloud/test/compute/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_dimensiondata.py b/libcloud/test/compute/test_dimensiondata.py
index 47a8e16..d6c4dba 100644
--- a/libcloud/test/compute/test_dimensiondata.py
+++ b/libcloud/test/compute/test_dimensiondata.py
@@ -20,6 +20,7 @@ from libcloud.common.types import InvalidCredsError
from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver as DimensionData
from libcloud.compute.drivers.dimensiondata import DimensionDataAPIException
from libcloud.compute.base import Node, NodeAuthPassword, NodeLocation
+from libcloud.compute.types import NodeState
from libcloud.test import MockHttp
from libcloud.test.compute import TestCaseMixin
@@ -44,6 +45,21 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
except InvalidCredsError:
pass
+ def test_list_locations_response(self):
+ DimensionDataMockHttp.type = None
+ ret = self.driver.list_locations()
+ self.assertEqual(len(ret), 1)
+ first_node = ret[0]
+ self.assertEqual(first_node.id, 'NA10')
+ self.assertEqual(first_node.name, 'US - West')
+ self.assertEqual(first_node.country, 'US')
+
+ def test_list_nodes_response(self):
+ DimensionDataMockHttp.type = None
+ ret = self.driver.list_nodes()
+ self.assertEqual(len(ret), 2)
+ first_node = ret[0]
+
def test_list_sizes_response(self):
DimensionDataMockHttp.type = None
ret = self.driver.list_sizes()
@@ -74,7 +90,7 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
ret = node.destroy()
self.assertTrue(ret is True)
- def test_destroy_node_response_INPROGRESS(self):
+ def test_destroy_node_response_RESOURCE_BUSY(self):
DimensionDataMockHttp.type = 'INPROGRESS'
node = Node(id='11', name=None, state=None,
public_ips=None, private_ips=None, driver=self.driver)
@@ -146,17 +162,26 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
except DimensionDataAPIException:
pass
+ def test_ex_reset(self):
+ node = Node(id='11', name=None, state=None,
+ public_ips=None, private_ips=None, driver=self.driver)
+ ret = self.driver.ex_reset(node)
+ self.assertTrue(ret is True)
+
def test_ex_list_networks(self):
nets = self.driver.ex_list_networks()
self.assertEqual(nets[0].name, 'test-net1')
self.assertTrue(isinstance(nets[0].location, NodeLocation))
+
+ def test_ex_list_network_domains(self):
+ nets = self.driver.ex_list_network_domains()
+ self.assertEqual(nets[0].name, 'Production Network Domain')
+ self.assertTrue(isinstance(nets[0].location, NodeLocation))
- def test_node_public_ip(self):
- nodes = self.driver.list_nodes()
- node = [n for n in nodes if n.id ==
- 'abadbc7e-9e10-46ca-9d4a-194bcc6b6c16'][0]
- self.assertEqual(node.public_ips[0], '200.16.132.7')
-
+ def test_ex_list_vlans(self):
+ vlans = self.driver.ex_list_vlans()
+ self.assertEqual(vlans[0].name, "Production VLAN")
+
class DimensionDataMockHttp(MockHttp):
@@ -245,7 +270,86 @@ class DimensionDataMockHttp(MockHttp):
body = self.fixtures.load(
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer_INPROGRESS(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deleteServer_RESOURCEBUSY.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer_INPROGRESS(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_rebootServer_RESOURCEBUSY.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer_INPROGRESS(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_startServer_INPROGRESS.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer_INPROGRESS(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_shutdownServer_INPROGRESS.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_resetServer(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_resetServer.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer_INPROGRESS(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_powerOffServer_INPROGRESS.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
if __name__ == '__main__':
sys.exit(unittest.main())