Repository: libcloud
Updated Branches:
  refs/heads/trunk 990ecf7c6 -> 5b26ac4dd


LIBCLOUD-775 Update node, update VMware tools, add storage, change storage size 
or speed, remove storage. With tests

Signed-off-by: Anthony Shaw <anthony.p.s...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e8e758d9
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e8e758d9
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e8e758d9

Branch: refs/heads/trunk
Commit: e8e758d9c690916f2c33e8d0afdd2a7cc9a07552
Parents: 990ecf7
Author: Anthony Shaw <anthony.p.s...@gmail.com>
Authored: Mon Nov 30 16:31:53 2015 +1100
Committer: Anthony Shaw <anthony.p.s...@gmail.com>
Committed: Wed Dec 2 14:08:32 2015 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py       | 219 +++++++++++++++++++
 ...bc_8dabe5a7d0e4_server_updateVmwareTools.xml |   8 +
 ...ver_e75ead52_692f_4314_8725_c8a4f4d13a87.xml |  21 ++
 ...75ead52_692f_4314_8725_c8a4f4d13a87_POST.xml |   7 +
 ...ead52_692f_4314_8725_c8a4f4d13a87_disk_1.xml |   7 +
 ...4314_8725_c8a4f4d13a87_disk_1_changeSize.xml |   7 +
 ...314_8725_c8a4f4d13a87_disk_1_changeSpeed.xml |   7 +
 libcloud/test/compute/test_dimensiondata.py     |  71 ++++++
 8 files changed, 347 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py 
b/libcloud/compute/drivers/dimensiondata.py
index 72defdc..1a0ae09 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -36,6 +36,7 @@ from libcloud.common.dimensiondata import 
NetworkDomainServicePlan
 from libcloud.common.dimensiondata import API_ENDPOINTS, DEFAULT_REGION
 from libcloud.common.dimensiondata import TYPES_URN
 from libcloud.common.dimensiondata import SERVER_NS, NETWORK_NS, GENERAL_NS
+from libcloud.utils.py3 import urlencode
 from libcloud.utils.xml import fixxpath, findtext, findall
 from libcloud.compute.types import NodeState, Provider
 
@@ -399,6 +400,63 @@ class DimensionDataNodeDriver(NodeDriver):
         response_code = findtext(body, 'responseCode', TYPES_URN)
         return response_code in ['IN_PROGRESS', 'OK']
 
+    def ex_update_vm_tools(self, node):
+        """
+        This function triggers an update of the VMware Tools
+        software running on the guest OS of a Server.
+
+        :param      node: Node which should be used
+        :type       node: :class:`Node`
+
+        :rtype: ``bool``
+        """
+        request_elm = ET.Element('updateVmwareTools',
+                                 {'xmlns': TYPES_URN, 'id': node.id})
+        body = self.connection.request_with_orgId_api_2(
+            'server/updateVmwareTools',
+            method='POST',
+            data=ET.tostring(request_elm)).object
+        response_code = findtext(body, 'responseCode', TYPES_URN)
+        return response_code in ['IN_PROGRESS', 'OK']
+
+    def ex_update_node(self, node, name=None, description=None,
+                       cpu_count=None, ram_mb=None):
+        """
+        Update the node, the name, CPU or RAM
+
+        :param      node: Node which should be used
+        :type       node: :class:`Node`
+
+        :param      name: The new name (optional)
+        :type       name: ``str``
+
+        :param      description: The new description (optional)
+        :type       description: ``str``
+
+        :param      cpu_count: The new CPU count (optional)
+        :type       cpu_count: ``int``
+
+        :param      ram_mb: The new Memory in MB (optional)
+        :type       ram_mb: ``int``
+
+        :rtype: ``bool``
+        """
+        data = {}
+        if name is not None:
+            data['name'] = name
+        if description is not None:
+            data['description'] = description
+        if cpu_count is not None:
+            data['cpuCount'] = str(cpu_count)
+        if ram_mb is not None:
+            data['memory'] = str(ram_mb)
+        body = self.connection.request_with_orgId_api_1(
+            'server/%s' % (node.id),
+            method='POST',
+            data=urlencode(data, True)).object
+        response_code = findtext(body, 'result', GENERAL_NS)
+        return response_code in ['IN_PROGRESS', 'SUCCESS']
+
     def ex_attach_node_to_vlan(self, node, vlan):
         """
         Attach a node to a VLAN by adding an additional NIC to
@@ -941,6 +999,14 @@ class DimensionDataNodeDriver(NodeDriver):
     def ex_set_firewall_rule_state(self, rule, state):
         """
         Change the state (enabled or disabled) of a rule
+
+        :param rule: The rule to delete
+        :type  rule: :class:`DimensionDataFirewallRule`
+
+        :param state: The desired state enabled (True) or disabled (False)
+        :type  state: ``bool``
+
+        :rtype: ``bool``
         """
         update_node = ET.Element('editFirewallRule', {'xmlns': TYPES_URN})
         update_node.set('id', rule.id)
@@ -954,6 +1020,14 @@ class DimensionDataNodeDriver(NodeDriver):
         return response_code in ['IN_PROGRESS', 'OK']
 
     def ex_delete_firewall_rule(self, rule):
+        """
+        Delete a firewall rule
+
+        :param rule: The rule to delete
+        :type  rule: :class:`DimensionDataFirewallRule`
+
+        :rtype: ``bool``
+        """
         update_node = ET.Element('deleteFirewallRule', {'xmlns': TYPES_URN})
         update_node.set('id', rule.id)
         result = self.connection.request_with_orgId_api_2(
@@ -965,6 +1039,20 @@ class DimensionDataNodeDriver(NodeDriver):
         return response_code in ['IN_PROGRESS', 'OK']
 
     def ex_create_nat_rule(self, network_domain, internal_ip, external_ip):
+        """
+        Create a NAT rule
+
+        :param  network_domain: The network domain the rule belongs to
+        :type   network_domain: :class:`DimensionDataNetworkDomain`
+
+        :param  internal_ip: The IPv4 address internally
+        :type   internal_ip: ``str``
+
+        :param  external_ip: The IPv4 address externally
+        :type   external_ip: ``str``
+
+        :rtype: :class:`DimensionDataNatRule`
+        """
         create_node = ET.Element('createNatRule', {'xmlns': TYPES_URN})
         ET.SubElement(create_node, 'networkDomainId').text = network_domain.id
         ET.SubElement(create_node, 'internalIp').text = internal_ip
@@ -988,6 +1076,14 @@ class DimensionDataNodeDriver(NodeDriver):
         )
 
     def ex_list_nat_rules(self, network_domain):
+        """
+        Get NAT rules for the network domain
+
+        :param  network_domain: The network domain the rules belongs to
+        :type   network_domain: :class:`DimensionDataNetworkDomain`
+
+        :rtype: ``list`` of :class:`DimensionDataNatRule`
+        """
         params = {}
         params['networkDomainId'] = network_domain.id
 
@@ -997,6 +1093,17 @@ class DimensionDataNodeDriver(NodeDriver):
         return self._to_nat_rules(response, network_domain)
 
     def ex_get_nat_rule(self, network_domain, rule_id):
+        """
+        Get a NAT rule by ID
+
+        :param  network_domain: The network domain the rule belongs to
+        :type   network_domain: :class:`DimensionDataNetworkDomain`
+
+        :param  rule_id: The ID of the NAT rule to fetch
+        :type   rule_id: ``str``
+
+        :rtype: :class:`DimensionDataNatRule`
+        """
         rule = self.connection.request_with_orgId_api_2(
             'network/natRule/%s' % rule_id).object
         return self._to_nat_rule(rule, network_domain)
@@ -1134,6 +1241,118 @@ class DimensionDataNodeDriver(NodeDriver):
         response_code = findtext(result, 'responseCode', TYPES_URN)
         return response_code in ['IN_PROGRESS', 'OK']
 
+    def ex_add_storage_to_node(self, node, amount, speed='STANDARD'):
+        """
+        Add storage to the node
+
+        :param  node: The server to add storage to
+        :type   node: :class:`Node`
+
+        :param  amount: The amount of storage to add, in GB
+        :type   amount: ``int``
+
+        :param  speed: The disk speed type
+        :type   speed: ``str``
+
+        :rtype: ``bool``
+        """
+        result = self.connection.request_with_orgId_api_1(
+            'server/%s?addLocalStorage&amount=%s&speed=%s' %
+            (node.id, amount, speed)).object
+        response_code = findtext(result, 'result', GENERAL_NS)
+        return response_code in ['IN_PROGRESS', 'SUCCESS']
+
+    def ex_remove_storage_from_node(self, node, disk_id):
+        """
+        Remove storage from a node
+
+        :param  node: The server to add storage to
+        :type   node: :class:`Node`
+
+        :param  disk_id: The ID of the disk to remove
+        :type   disk_id: ``str``
+
+        :rtype: ``bool``
+        """
+        result = self.connection.request_with_orgId_api_1(
+            'server/%s/disk/%s?delete' %
+            (node.id, disk_id)).object
+        response_code = findtext(result, 'result', GENERAL_NS)
+        return response_code in ['IN_PROGRESS', 'SUCCESS']
+
+    def ex_change_storage_speed(self, node, disk_id, speed):
+        """
+        Remove storage from a node
+
+        :param  node: The server to add storage to
+        :type   node: :class:`Node`
+
+        :param  disk_id: The ID of the disk to remove
+        :type   disk_id: ``str``
+
+        :param  speed: The disk speed type e.g. STANDARD
+        :type   speed: ``str``
+
+        :rtype: ``bool``
+        """
+        create_node = ET.Element('ChangeDiskSpeed', {'xmlns': SERVER_NS})
+        ET.SubElement(create_node, 'speed').text = speed
+        result = self.connection.request_with_orgId_api_1(
+            'server/%s/disk/%s/changeSpeed' %
+            (node.id, disk_id),
+            method='POST',
+            data=ET.tostring(create_node)).object
+        response_code = findtext(result, 'result', GENERAL_NS)
+        return response_code in ['IN_PROGRESS', 'SUCCESS']
+
+    def ex_change_storage_size(self, node, disk_id, size):
+        """
+        Remove storage from a node
+
+        :param  node: The server to add storage to
+        :type   node: :class:`Node`
+
+        :param  disk_id: The ID of the disk to remove
+        :type   disk_id: ``str``
+
+        :param  size: The disk size in GB
+        :type   size: ``int``
+
+        :rtype: ``bool``
+        """
+        create_node = ET.Element('ChangeDiskSize', {'xmlns': SERVER_NS})
+        ET.SubElement(create_node, 'newSizeGb').text = str(size)
+        result = self.connection.request_with_orgId_api_1(
+            'server/%s/disk/%s/changeSize' %
+            (node.id, disk_id),
+            method='POST',
+            data=ET.tostring(create_node)).object
+        response_code = findtext(result, 'result', GENERAL_NS)
+        return response_code in ['IN_PROGRESS', 'SUCCESS']
+
+    def ex_clone_node_to_image(self, node, image_name, image_description=None):
+        """
+        Clone a server into a customer image.
+
+        :param  node: The server to clone
+        :type   node: :class:`Node`
+
+        :param  image_name: The name of the clone image
+        :type   image_name: ``str``
+
+        :param  description: The description of the image
+        :type   description: ``str``
+
+        :rtype: ``bool``
+        """
+        if image_description is None:
+            image_description = ''
+        result = self.connection.request_with_orgId_api_1(
+            'server/%s?clone=%s&desc=%s' %
+            (node.id, image_name, image_description)).object
+        response_code = findtext(result, 'result', GENERAL_NS)
+        return response_code in ['IN_PROGRESS', 'SUCCESS']
+
     def _to_nat_rules(self, object, network_domain):
         rules = []
         for element in findall(object, 'natRule', TYPES_URN):

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_updateVmwareTools.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_updateVmwareTools.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_updateVmwareTools.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_updateVmwareTools.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/e8e758d9/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
new file mode 100644
index 0000000..f9a0c9c
--- /dev/null
+++ 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns4:Status xmlns:ns16="http://oec.api.opsource.net/schemas/reset";
+            xmlns="http://oec.api.opsource.net/schemas/server";
+            xmlns:ns14="http://oec.api.opsource.net/schemas/backup";
+            xmlns:ns15="http://oec.api.opsource.net/schemas/storage";
+            xmlns:ns9="http://oec.api.opsource.net/schemas/multigeo";
+            xmlns:ns5="http://oec.api.opsource.net/schemas/network";
+            xmlns:ns12="http://oec.api.opsource.net/schemas/support";
+            xmlns:ns13="http://oec.api.opsource.net/schemas/serverbootstrap";
+            xmlns:ns6="http://oec.api.opsource.net/schemas/vip";
+            xmlns:ns7="http://oec.api.opsource.net/schemas/datacenter";
+            xmlns:ns10="http://oec.api.opsource.net/schemas/whitelabel";
+            xmlns:ns8="http://oec.api.opsource.net/schemas/manualimport";
+            xmlns:ns11="http://oec.api.opsource.net/schemas/admin";
+            xmlns:ns2="http://oec.api.opsource.net/schemas/organization";
+            xmlns:ns4="http://oec.api.opsource.net/schemas/general"; 
xmlns:ns3="http://oec.api.opsource.net/schemas/directory";>
+    <ns4:operation>Add Local Storage</ns4:operation>
+    <ns4:result>SUCCESS</ns4:result>
+    <ns4:resultDetail>100 GB of STANDARD local storage is being added to 
server "abc" on SCSI ID 1</ns4:resultDetail>
+    <ns4:resultCode>REASON_0</ns4:resultCode>
+</ns4:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_POST.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_POST.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_POST.xml
new file mode 100644
index 0000000..abbbadb
--- /dev/null
+++ 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_POST.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns6:Status xmlns:ns6="http://oec.api.opsource.net/schemas/general";>
+    <ns6:operation>Edit Server</ns6:operation>
+    <ns6:result>SUCCESS</ns6:result>
+<ns6:resultDetail>Server edited</ns6:resultDetail>
+<ns6:resultCode>REASON_0</ns6:resultCode>
+</ns6:Status>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1.xml
new file mode 100644
index 0000000..7214eb7
--- /dev/null
+++ 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns12:Status xmlns="http://oec.api.opsource.net/schemas/server"; 
xmlns:ns9="http://oec.api.opsource.net/schemas/reset"; 
xmlns:ns5="http://oec.api.opsource.net/schemas/vip"; 
xmlns:ns12="http://oec.api.opsource.net/schemas/general"; 
xmlns:ns6="http://oec.api.opsource.net/schemas/imageimportexport"; 
xmlns:ns13="http://oec.api.opsource.net/schemas/support"; 
xmlns:ns7="http://oec.api.opsource.net/schemas/whitelabel"; 
xmlns:ns10="http://oec.api.opsource.net/schemas/ipplan"; 
xmlns:ns8="http://oec.api.opsource.net/schemas/datacenter"; 
xmlns:ns11="http://oec.api.opsource.net/schemas/storage"; 
xmlns:ns2="http://oec.api.opsource.net/schemas/organization"; 
xmlns:ns4="http://oec.api.opsource.net/schemas/network"; 
xmlns:ns3="http://oec.api.opsource.net/schemas/directory";>
+    <ns12:operation> Delete Local Storage</ns12:operation>
+    <ns12:result>SUCCESS</ns12:result>
+    <ns12:resultDetail> Server "Disk Delete" issued</ns12:resultDetail>
+    <ns12:resultCode>REASON_0</ns12:resultCode>
+</ns12:Status>  
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSize.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSize.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSize.xml
new file mode 100644
index 0000000..7c6258d
--- /dev/null
+++ 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSize.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns4:Status xmlns:ns16="http://oec.api.opsource.net/schemas/reset"; 
xmlns="http://oec.api.opsource.net/schemas/server"; 
xmlns:ns14="http://oec.api.opsource.net/schemas/backup"; 
xmlns:ns15="http://oec.api.opsource.net/schemas/storage"; 
xmlns:ns9="http://oec.api.opsource.net/schemas/multigeo"; 
xmlns:ns5="http://oec.api.opsource.net/schemas/network"; 
xmlns:ns12="http://oec.api.opsource.net/schemas/support"; 
xmlns:ns13="http://oec.api.opsource.net/schemas/serverbootstrap"; 
xmlns:ns6="http://oec.api.opsource.net/schemas/vip"; 
xmlns:ns7="http://oec.api.opsource.net/schemas/datacenter"; 
xmlns:ns10="http://oec.api.opsource.net/schemas/whitelabel"; 
xmlns:ns8="http://oec.api.opsource.net/schemas/manualimport"; 
xmlns:ns11="http://oec.api.opsource.net/schemas/admin"; 
xmlns:ns2="http://oec.api.opsource.net/schemas/organization"; 
xmlns:ns4="http://oec.api.opsource.net/schemas/general"; 
xmlns:ns3="http://oec.api.opsource.net/schemas/directory";>
+    <ns4:operation>Change Server Disk Size</ns4:operation>
+    <ns4:result>SUCCESS</ns4:result>
+    <ns4:resultDetail>Server "Change Server Disk Size" 
issued</ns4:resultDetail>
+    <ns4:resultCode>REASON_0</ns4:resultCode>
+</ns4:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSpeed.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSpeed.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSpeed.xml
new file mode 100644
index 0000000..e525df1
--- /dev/null
+++ 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSpeed.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns4:Status xmlns:ns16="http://oec.api.opsource.net/schemas/reset"; 
xmlns="http://oec.api.opsource.net/schemas/server"; 
xmlns:ns14="http://oec.api.opsource.net/schemas/backup"; 
xmlns:ns15="http://oec.api.opsource.net/schemas/storage"; 
xmlns:ns9="http://oec.api.opsource.net/schemas/multigeo"; 
xmlns:ns5="http://oec.api.opsource.net/schemas/network"; 
xmlns:ns12="http://oec.api.opsource.net/schemas/support"; 
xmlns:ns13="http://oec.api.opsource.net/schemas/serverbootstrap"; 
xmlns:ns6="http://oec.api.opsource.net/schemas/vip"; 
xmlns:ns7="http://oec.api.opsource.net/schemas/datacenter"; 
xmlns:ns10="http://oec.api.opsource.net/schemas/whitelabel"; 
xmlns:ns8="http://oec.api.opsource.net/schemas/manualimport"; 
xmlns:ns11="http://oec.api.opsource.net/schemas/admin"; 
xmlns:ns2="http://oec.api.opsource.net/schemas/organization"; 
xmlns:ns4="http://oec.api.opsource.net/schemas/general"; 
xmlns:ns3="http://oec.api.opsource.net/schemas/directory";>
+    <ns4:operation>Change Server Disk Speed</ns4:operation>
+    <ns4:result>SUCCESS</ns4:result>
+    <ns4:resultDetail>Server "Change Server Disk Speed" 
issued</ns4:resultDetail>
+    <ns4:resultCode>REASON_0</ns4:resultCode>
+</ns4:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e8e758d9/libcloud/test/compute/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_dimensiondata.py 
b/libcloud/test/compute/test_dimensiondata.py
index 8fbe89c..f78f5d7 100644
--- a/libcloud/test/compute/test_dimensiondata.py
+++ b/libcloud/test/compute/test_dimensiondata.py
@@ -185,6 +185,12 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
         ret = self.driver.ex_power_off(node)
         self.assertTrue(ret is True)
 
+    def test_ex_update_vm_tools(self):
+        node = Node(id='11', name=None, state=None,
+                    public_ips=None, private_ips=None, driver=self.driver)
+        ret = self.driver.ex_update_vm_tools(node)
+        self.assertTrue(ret is True)
+
     def test_ex_power_off_INPROGRESS(self):
         DimensionDataMockHttp.type = 'INPROGRESS'
         node = Node(id='11', name=None, state=None,
@@ -417,6 +423,36 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
         result = self.driver.ex_update_monitoring_plan(node, "ESSENTIALS")
         self.assertTrue(result)
 
+    def test_ex_add_storage_to_node(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_add_storage_to_node(node, 30, 'PERFORMANCE')
+        self.assertTrue(result)
+
+    def test_ex_remove_storage_from_node(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_remove_storage_from_node(node, 1)
+        self.assertTrue(result)
+
+    def test_ex_change_storage_speed(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_change_storage_speed(node, 1, 'PERFORMANCE')
+        self.assertTrue(result)
+
+    def test_ex_change_storage_size(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_change_storage_size(node, 1, 100)
+        self.assertTrue(result)
+
+    def test_ex_clone_node_to_image(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_clone_node_to_image(node, 'my image', 'a 
description')
+        self.assertTrue(result)
+
+    def test_ex_update_node(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_update_node(node, 'my new name', 'a 
description', 2, 4048)
+        self.assertTrue(result)
+
 
 class InvalidRequestError(Exception):
     def __init__(self, tag):
@@ -525,6 +561,33 @@ class DimensionDataMockHttp(MockHttp):
             
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def 
_oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSize(self,
 method, url, body, headers):
+        body = self.fixtures.load(
+            
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSize.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def 
_oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSpeed(self,
 method, url, body, headers):
+        body = self.fixtures.load(
+            
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1_changeSpeed.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def 
_oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1(self,
 method, url, body, headers):
+        action = url.split('?')[-1]
+        if action == 'delete':
+            body = self.fixtures.load(
+                
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_disk_1.xml')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def 
_oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87(self,
 method, url, body, headers):
+        if method == 'GET':
+            body = self.fixtures.load(
+                
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+        if method == 'POST':
+            body = self.fixtures.load(
+                
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_POST.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')
@@ -572,6 +635,14 @@ class DimensionDataMockHttp(MockHttp):
             
'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_updateVmwareTools(self, 
method, url, body, headers):
+        request = ET.fromstring(body)
+        if request.tag != "{urn:didata.com:api:cloud:types}updateVmwareTools":
+            raise InvalidRequestError(request.tag)
+        body = self.fixtures.load(
+            
'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_updateVmwareTools.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):
         request = ET.fromstring(body)
         if request.tag != "{urn:didata.com:api:cloud:types}startServer":

Reply via email to