libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject [05/10] libcloud git commit: Updated load balancer methods to support editing pool, pool member and nodes.
Date Thu, 08 Oct 2015 12:19:23 GMT
Updated load balancer methods to support editing pool, pool member and nodes.

Closes #593


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

Branch: refs/heads/trunk
Commit: e94846e65bfa4a8f7845fd366bf0b23e1f077fcf
Parents: 9743a72
Author: Anthony Shaw <anthony.p.shaw@gmail.com>
Authored: Tue Oct 6 15:30:05 2015 +1100
Committer: Tomaz Muraus <tomaz@apache.org>
Committed: Thu Oct 8 14:12:13 2015 +0200

----------------------------------------------------------------------
 libcloud/common/dimensiondata.py                | 29 +++++-
 libcloud/compute/drivers/dimensiondata.py       | 67 ++++++++++++++
 libcloud/loadbalancer/drivers/dimensiondata.py  | 93 ++++++++++++++++++--
 ..._9cbc_8dabe5a7d0e4_network_createNatRule.xml |  9 ++
 ..._9cbc_8dabe5a7d0e4_network_deleteNatRule.xml |  8 ++
 ...5_4d8a_9cbc_8dabe5a7d0e4_network_natRule.xml | 21 +++++
 ...ule_2187a636_7ebb_49a1_a2ff_5d617f496dce.xml |  9 ++
 libcloud/test/compute/test_dimensiondata.py     | 46 ++++++++++
 ...c_8dabe5a7d0e4_networkDomainVip_editNode.xml |  8 ++
 ...c_8dabe5a7d0e4_networkDomainVip_editPool.xml |  9 ++
 ...e5a7d0e4_networkDomainVip_editPoolMember.xml |  8 ++
 ...ode_34de6ed6_46a4_4dae_a753_2f8d3840c6f9.xml | 13 +++
 .../test/loadbalancer/test_dimensiondata.py     | 75 +++++++++++++++-
 13 files changed, 382 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/common/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/common/dimensiondata.py b/libcloud/common/dimensiondata.py
index cb41484..fe296e8 100644
--- a/libcloud/common/dimensiondata.py
+++ b/libcloud/common/dimensiondata.py
@@ -359,7 +359,22 @@ class DimensionDataFirewallAddress(object):
         self.ip_prefix_size = ip_prefix_size
         self.port_begin = port_begin
         self.port_end = port_end
-    
+
+
+class DimensionDataNatRule(object):
+    """
+    An IP NAT rule in a network domain
+    """
+    def __init__(self, id, network_domain, internal_ip, external_ip, status):
+        self.id = id
+        self.network_domain = network_domain
+        self.internal_ip = internal_ip
+        self.external_ip = external_ip
+        self.status = status
+
+    def __repr__(self):
+        return (('<DimensionDataNatRule: id=%s, status=%s>')
+                % (self.id, self.status))
 
 class DimensionDataVlan(object):
     """
@@ -388,11 +403,16 @@ class DimensionDataPool(object):
     DimensionData VIP Pool.
     """
 
-    def __init__(self, id, name, description, status):
+    def __init__(self, id, name, description, status, load_balance_method,
+                 health_monitor_id, service_down_action, slow_ramp_time):
         self.id = str(id)
         self.name = name
         self.description = description
         self.status = status
+        self.load_balance_method = load_balance_method
+        self.health_monitor_id = health_monitor_id
+        self.service_down_action = service_down_action
+        self.slow_ramp_time = slow_ramp_time
 
     def __repr__(self):
         return (('<DimensionDataPool: id=%s, name=%s, '
@@ -423,11 +443,14 @@ class DimensionDataPoolMember(object):
 
 
 class DimensionDataVIPNode(object):
-    def __init__(self, id, name, status, ip):
+    def __init__(self, id, name, status, ip, connection_limit='10000',
+                 connection_rate_limit='10000'):
         self.id = str(id)
         self.name = name
         self.status = status
         self.ip = ip
+        self.connection_limit = connection_limit
+        self.connection_rate_limit = connection_rate_limit
 
     def __repr__(self):
         return (('<DimensionDataVIPNode: id=%s, name=%s, '

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 1aa3e9f..b86146c 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -31,6 +31,7 @@ from libcloud.common.dimensiondata import DimensionDataVlan
 from libcloud.common.dimensiondata import DimensionDataPublicIpBlock
 from libcloud.common.dimensiondata import DimensionDataFirewallRule
 from libcloud.common.dimensiondata import DimensionDataFirewallAddress
+from libcloud.common.dimensiondata import DimensionDataNatRule
 from libcloud.common.dimensiondata import NetworkDomainServicePlan
 from libcloud.common.dimensiondata import API_ENDPOINTS
 from libcloud.common.dimensiondata import DEFAULT_REGION
@@ -726,6 +727,54 @@ class DimensionDataNodeDriver(NodeDriver):
         responseCode = findtext(result, 'responseCode', TYPES_URN)
         return responseCode == 'IN_PROGRESS' or responseCode == 'OK'
 
+    def ex_create_nat_rule(self, network_domain, internal_ip, external_ip):
+        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
+        ET.SubElement(create_node, 'externalIp').text = external_ip
+        result = self.connection.request_with_orgId_api_2(
+            'network/createNatRule',
+            method='POST',
+            data=ET.tostring(create_node)).object
+
+        rule_id = None
+        for info in findall(result, 'info', TYPES_URN):
+            if info.get('name') == 'natRuleId':
+                rule_id = info.get('value')
+
+        return DimensionDataNatRule(
+            id=rule_id,
+            network_domain=network_domain,
+            internal_ip=internal_ip,
+            external_ip=external_ip,
+            status=NodeState.RUNNING
+        )
+
+    def ex_list_nat_rules(self, network_domain):
+        params = {}
+        params['networkDomainId'] = network_domain.id
+
+        response = self.connection \
+            .request_with_orgId_api_2('network/natRule',
+                                      params=params).object
+        return self._to_nat_rules(response, network_domain)
+
+    def ex_get_nat_rule(self, network_domain, rule_id):
+        rule = self.connection.request_with_orgId_api_2(
+            'network/natRule/%s' % rule_id).object
+        return self._to_nat_rule(rule, network_domain)
+
+    def ex_delete_nat_rule(self, rule):
+        update_node = ET.Element('deleteNatrule', {'xmlns': TYPES_URN})
+        update_node.set('id', rule.id)
+        result = self.connection.request_with_orgId_api_2(
+            'network/deleteNatRule',
+            method='POST',
+            data=ET.tostring(update_node)).object
+
+        responseCode = findtext(result, 'responseCode', TYPES_URN)
+        return responseCode == 'IN_PROGRESS' or responseCode == 'OK'
+
     def ex_get_location_by_id(self, id):
         """
         Get location by ID.
@@ -741,6 +790,24 @@ class DimensionDataNodeDriver(NodeDriver):
                 filter(lambda x: x.id == id, self.list_locations()))[0]
         return location
 
+    def _to_nat_rules(self, object, network_domain):
+        rules = []
+        for element in findall(object, 'natRule', TYPES_URN):
+            rules.append(
+                self._to_nat_rule(element, network_domain))
+
+        return rules
+
+    def _to_nat_rule(self, element, network_domain):
+        status = self._to_status(element.find(fixxpath('state', TYPES_URN)))
+
+        return DimensionDataNatRule(
+            id=element.get('id'),
+            network_domain=network_domain,
+            internal_ip=findtext(element, 'internalIp', TYPES_URN),
+            external_ip=findtext(element, 'externalIp', TYPES_URN),
+            status=status)
+
     def _to_firewall_rules(self, object, network_domain):
         rules = []
         locations = self.list_locations()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/loadbalancer/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/loadbalancer/drivers/dimensiondata.py b/libcloud/loadbalancer/drivers/dimensiondata.py
index bd72e7f..8c8c001 100644
--- a/libcloud/loadbalancer/drivers/dimensiondata.py
+++ b/libcloud/loadbalancer/drivers/dimensiondata.py
@@ -275,7 +275,7 @@ class DimensionDataLBDriver(Driver):
             method='POST',
             data=ET.tostring(create_pool_m)).object
         responseCode = findtext(result, 'responseCode', TYPES_URN)
-        return responseCode == 'OK'
+        return responseCode == 'OK' or responseCode == 'IN_PROGRESS'
 
     def destroy_balancer(self, balancer):
         """
@@ -296,7 +296,7 @@ class DimensionDataLBDriver(Driver):
             method='POST',
             data=ET.tostring(delete_listener)).object
         responseCode = findtext(result, 'responseCode', TYPES_URN)
-        return responseCode == 'OK'
+        return responseCode == 'OK' or responseCode == 'IN_PROGRESS'
 
     def ex_set_current_network_domain(self, network_domain_id):
         """
@@ -423,6 +423,30 @@ class DimensionDataLBDriver(Driver):
             ip=ip
         )
 
+    def ex_update_node(self, node):
+        create_node_elm = ET.Element('editNode', {'xmlns': TYPES_URN})
+        ET.SubElement(create_node_elm, "connectionLimit") \
+            .text = str(node.connection_limit)
+        ET.SubElement(create_node_elm, "connectionRateLimit") \
+            .text = str(node.connection_rate_limit)
+
+        response = self.connection.request_with_orgId_api_2(
+            action='networkDomainVip/createNode',
+            method='POST',
+            data=ET.tostring(create_node_elm)).object
+        return node
+
+    def ex_set_node_state(self, node, enabled):
+        create_node_elm = ET.Element('editNode', {'xmlns': TYPES_URN})
+        ET.SubElement(create_node_elm, "status") \
+            .text = "ENABLED" if enabled is True else "DISABLED"
+
+        response = self.connection.request_with_orgId_api_2(
+            action='networkDomainVip/editNode',
+            method='POST',
+            data=ET.tostring(create_node_elm)).object
+        return node
+
     def ex_create_pool(self,
                        network_domain_id,
                        name,
@@ -484,7 +508,11 @@ class DimensionDataLBDriver(Driver):
             id=pool_id,
             name=name,
             description=ex_description,
-            status=State.RUNNING
+            status=State.RUNNING,
+            load_balance_method=str(balancer_method),
+            health_monitor_id=None,
+            service_down_action=service_down_action,
+            slow_ramp_time=str(slow_ramp_time)
         )
 
     def ex_create_virtual_listener(self,
@@ -607,6 +635,23 @@ class DimensionDataLBDriver(Driver):
                                       % pool_id).object
         return self._to_pool(pool)
 
+    def ex_update_pool(self, pool):
+        create_node_elm = ET.Element('editPool', {'xmlns': TYPES_URN})
+
+        ET.SubElement(create_node_elm, "loadBalanceMethod") \
+            .text = str(pool.load_balance_method)
+        ET.SubElement(create_node_elm, "serviceDownAction") \
+            .text = pool.service_down_action
+        ET.SubElement(create_node_elm, "slowRampTime").text \
+            = str(pool.slow_ramp_time)
+
+        response = self.connection.request_with_orgId_api_2(
+            action='networkDomainVip/editPool',
+            method='POST',
+            data=ET.tostring(create_node_elm)).object
+        responseCode = findtext(response, 'responseCode', TYPES_URN)
+        return responseCode == 'OK' or responseCode == 'IN_PROGRESS'
+
     def ex_destroy_pool(self, pool):
         """
         Destroy an existing pool
@@ -626,7 +671,7 @@ class DimensionDataLBDriver(Driver):
             method='POST',
             data=ET.tostring(destroy_request)).object
         responseCode = findtext(result, 'responseCode', TYPES_URN)
-        return responseCode == 'OK'
+        return responseCode == 'OK' or responseCode == 'IN_PROGRESS'
 
     def ex_get_pool_members(self, pool_id):
         """
@@ -658,6 +703,21 @@ class DimensionDataLBDriver(Driver):
                                       % pool_member_id).object
         return self._to_member(member)
 
+    def ex_set_pool_member_state(self, member, enabled=True):
+        request = ET.Element('editPoolMember',
+                             {'xmlns': TYPES_URN,
+                              'id': member.id})
+        state = "ENABLED" if enabled == True else "DISABLED"
+        ET.SubElement(request, 'status').text = state
+
+        result = self.connection.request_with_orgId_api_2(
+            action='networkDomainVip/editPoolMember',
+            method='POST',
+            data=ET.tostring(request)).object
+
+        responseCode = findtext(result, 'responseCode', TYPES_URN)
+        return responseCode == 'OK' or responseCode == 'IN_PROGRESS'
+
     def ex_destroy_pool_member(self, member, destroy_node=False):
         """
         Destroy a specific member of a pool
@@ -698,6 +758,18 @@ class DimensionDataLBDriver(Driver):
             .request_with_orgId_api_2('networkDomainVip/node').object
         return self._to_nodes(nodes)
 
+    def ex_get_node(self, node_id):
+        """
+        Get the node specified by node_id
+
+        :return: Returns an instance of ``DimensionDataVIPNode``
+        :rtype: Instance of ``DimensionDataVIPNode``
+        """
+        nodes = self.connection \
+            .request_with_orgId_api_2('networkDomainVip/node/%s'
+                                      % node_id).object
+        return self._to_node(nodes)
+
     def ex_destroy_node(self, node_id):
         """
         Destroy a specific node
@@ -718,7 +790,7 @@ class DimensionDataLBDriver(Driver):
             method='POST',
             data=ET.tostring(destroy_request)).object
         responseCode = findtext(result, 'responseCode', TYPES_URN)
-        return responseCode == 'OK'
+        return responseCode == 'OK' or responseCode == 'IN_PROGRESS'
 
     def _to_nodes(self, object):
         nodes = []
@@ -740,6 +812,9 @@ class DimensionDataLBDriver(Driver):
             status=self._VALUE_TO_STATE_MAP.get(
                 findtext(element, 'state', TYPES_URN),
                 State.UNKNOWN),
+            connection_rate_limit=findtext(element,
+                                           'connectionRateLimit', TYPES_URN),
+            connection_limit=findtext(element, 'connectionLimit', TYPES_URN),
             ip=ipaddress)
 
         return node
@@ -816,6 +891,12 @@ class DimensionDataLBDriver(Driver):
             id=element.get('id'),
             name=findtext(element, 'name', TYPES_URN),
             status=findtext(element, 'state', TYPES_URN),
-            description=findtext(element, 'description', TYPES_URN)
+            description=findtext(element, 'description', TYPES_URN),
+            load_balance_method=findtext(element, 'loadBalanceMethod',
+                                         TYPES_URN),
+            health_monitor_id=findtext(element, 'healthMonitorId', TYPES_URN),
+            service_down_action=findtext(element, 'serviceDownAction',
+                                         TYPES_URN),
+            slow_ramp_time=findtext(element, 'slowRampTime', TYPES_URN),
         )
         return pool

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createNatRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createNatRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createNatRule.xml
new file mode 100644
index 0000000..ff652a4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createNatRule.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-06T05:53:37.334-05:00/fb842265-fa06-4ca9-a2af-a8a6815735fc">
+<operation>CREATE_NAT_RULE</operation>
+<responseCode>OK</responseCode>
+<message>NAT Rule with Id d31c2db0-be6b-4d50-8744-9a7a534b5fba has been
+created.</message>
+<info name="natRuleId" value="d31c2db0-be6b-4d50-8744-9a7a534b5fba"/>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteNatRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteNatRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteNatRule.xml
new file mode 100644
index 0000000..2d2cebc
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteNatRule.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-06T12:24:57.820-05:00/5974fe37-bac5-4345-8a88-4c93a874bf4a">
+<operation>DELETE_NAT_RULE</operation>
+<responseCode>OK</responseCode>
+<message>NAT Rule with Id 2187a636-7ebb-49a1-a2ff-5d617f496dce has been
+deleted.</message>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule.xml
new file mode 100644
index 0000000..7478df6
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<natRules
+xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="2"
+totalCount="2" pageSize="250">
+<natRule id="2187a636-7ebb-49a1-a2ff-5d617f496dce" datacenterId="NA9">
+<networkDomainId>484174a2-ae74-4658-9e56-
+50fc90e086cf</networkDomainId>
+<internalIp>10.0.0.15</internalIp>
+<externalIp>165.180.12.18</externalIp>
+<createTime>2015-03-06T13:43:45.000Z</createTime>
+<state>NORMAL</state>
+</natRule>
+<natRule id="2169a38e-5692-497e-a22a-701a838a6539" datacenterId="NA9">
+<networkDomainId>484174a2-ae74-4658-9e56-
+50fc90e086cf</networkDomainId>
+<internalIp>10.0.0.16</internalIp>
+<externalIp>165.180.12.19</externalIp>
+<createTime>2015-03-06T13:45:10.000Z</createTime>
+<state>NORMAL</state>
+</natRule>
+</natRules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule_2187a636_7ebb_49a1_a2ff_5d617f496dce.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule_2187a636_7ebb_49a1_a2ff_5d617f496dce.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule_2187a636_7ebb_49a1_a2ff_5d617f496dce.xml
new file mode 100644
index 0000000..6bf447d
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule_2187a636_7ebb_49a1_a2ff_5d617f496dce.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<natRule
+xmlns="urn:didata.com:api:cloud:types" id="2187a636-7ebb-49a1-a2ff-5d617f496dce" datacenterId="NA9">
+<networkDomainId>484174a2-ae74-4658-9e56-50fc90e086cf</networkDomainId>
+<internalIp>10.0.0.16</internalIp>
+<externalIp>165.180.12.19</externalIp>
+<createTime>2015-03-06T13:45:10.000Z</createTime>
+<state>NORMAL</state>
+</natRule>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/compute/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_dimensiondata.py b/libcloud/test/compute/test_dimensiondata.py
index 2e16dab..2581d62 100644
--- a/libcloud/test/compute/test_dimensiondata.py
+++ b/libcloud/test/compute/test_dimensiondata.py
@@ -336,6 +336,31 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
         result = self.driver.ex_delete_firewall_rule(rule)
         self.assertTrue(result)
 
+    def test_ex_create_nat_rule(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rule = self.driver.ex_create_nat_rule(net, '1.2.3.4', '4.3.2.1')
+        self.assertEqual(rule.id, 'd31c2db0-be6b-4d50-8744-9a7a534b5fba')
+
+    def test_ex_list_nat_rules(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rules = self.driver.ex_list_nat_rules(net)
+        self.assertEqual(rules[0].id, '2187a636-7ebb-49a1-a2ff-5d617f496dce')
+        self.assertEqual(rules[0].internal_ip, '10.0.0.15')
+        self.assertEqual(rules[0].external_ip, '165.180.12.18')
+
+    def test_ex_get_nat_rule(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rule = self.driver.ex_get_nat_rule(net, '2187a636-7ebb-49a1-a2ff-5d617f496dce')
+        self.assertEqual(rule.id, '2187a636-7ebb-49a1-a2ff-5d617f496dce')
+        self.assertEqual(rule.internal_ip, '10.0.0.16')
+        self.assertEqual(rule.external_ip, '165.180.12.19')
+
+    def test_ex_delete_nat_rule(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rule = self.driver.ex_get_nat_rule(net, '2187a636-7ebb-49a1-a2ff-5d617f496dce')
+        result = self.driver.ex_delete_nat_rule(rule)
+        self.assertTrue(result)
+
 
 class DimensionDataMockHttp(MockHttp):
 
@@ -614,5 +639,26 @@ class DimensionDataMockHttp(MockHttp):
             'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createNatRule(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createNatRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule(self, method, url,
body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule_2187a636_7ebb_49a1_a2ff_5d617f496dce(self,
method, url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_natRule_2187a636_7ebb_49a1_a2ff_5d617f496dce.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteNatRule(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteNatRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+
 if __name__ == '__main__':
     sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editNode.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editNode.xml
b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editNode.xml
new file mode 100644
index 0000000..ae3e2af
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editNode.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-05-29T11:57:29.793-04:00/9f7191df-de3a-4cf3-a0a1-6321e88b5af5">
+<operation>EDIT_NODE</operation>
+<responseCode>OK</responseCode>
+<message>Node 'ProductionNode.2' has been edited successfully.</message>
+<info name="nodeId" value="34de6ed6-46a4-4dae-a753-2f8d3840c6f9"/>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPool.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPool.xml
b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPool.xml
new file mode 100644
index 0000000..78eb686
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPool.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-05-29T11:57:29.793-04:00/9f7191df-de3a-4cf3-a0a1-6321e88b5af5">
+<operation>EDIT_POOL</operation>
+<responseCode>OK</responseCode>
+<message>Pool 'ProductionPool.2' has been updated.</message>
+<info name="name" value="ProductionPool.2"/>
+<info name="poolId" value="4d360b1f-bc2c-4ab7-9884-1f03ba2768f7"/>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPoolMember.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPoolMember.xml
b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPoolMember.xml
new file mode 100644
index 0000000..89ce41d
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPoolMember.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-06-09T09:29:46.249-04:00/c128c717-b3b4-480a-ba93-e3fb2e32a9be">
+<operation>EDIT_POOL_MEMBER</operation>
+<responseCode>OK</responseCode>
+<message>Pool Member (10.0.3.13:9889) has been edited.</message>
+<info name="poolMemberId" value="3dd806a2-c2c8-4c0c-9a4f-5219ea9266c0"/>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node_34de6ed6_46a4_4dae_a753_2f8d3840c6f9.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node_34de6ed6_46a4_4dae_a753_2f8d3840c6f9.xml
b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node_34de6ed6_46a4_4dae_a753_2f8d3840c6f9.xml
new file mode 100644
index 0000000..ace9123
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node_34de6ed6_46a4_4dae_a753_2f8d3840c6f9.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node xmlns="urn:didata.com:api:cloud:types" id="34de6ed6-46a4-4dae-a753-2f8d3840c6f9"
datacenterId="NA9">
+<networkDomainId>553f26b6-2a73-42c3-a78b-6116f11291d0</networkDomainId>
+<name>ProductionNode.2</name>
+<description>Production Server 2</description>
+<ipv4Address>10.10.10.101</ipv4Address>
+<state>NORMAL</state>
+<status>ENABLED</status>
+<healthMonitor id="0168b83a-d487-11e4-811f-005056806999" name="ICMP"/>
+<connectionLimit>10000</connectionLimit>
+<connectionRateLimit>2000</connectionRateLimit>
+<createTime>2015-05-27T13:56:13.000Z</createTime>
+</node>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e94846e6/libcloud/test/loadbalancer/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/test_dimensiondata.py b/libcloud/test/loadbalancer/test_dimensiondata.py
index 725f153..31ecd75 100644
--- a/libcloud/test/loadbalancer/test_dimensiondata.py
+++ b/libcloud/test/loadbalancer/test_dimensiondata.py
@@ -216,7 +216,11 @@ class DimensionDataTests(unittest.TestCase):
             id='4d360b1f-bc2c-4ab7-9884-1f03ba2768f7',
             name='test',
             description='test',
-            status=State.RUNNING
+            status=State.RUNNING,
+            health_monitor_id=None,
+            load_balance_method=None,
+            service_down_action=None,
+            slow_ramp_time=None
         )
         node = DimensionDataVIPNode(
             id='2344',
@@ -266,7 +270,11 @@ class DimensionDataTests(unittest.TestCase):
                 id='1234',
                 name='test',
                 description='test',
-                status=State.RUNNING
+                status=State.RUNNING,
+                health_monitor_id=None,
+                load_balance_method=None,
+                service_down_action=None,
+                slow_ramp_time=None
             ))
         self.assertEqual(listener.id, '8334f461-0df0-42d5-97eb-f4678eb26bea')
         self.assertEqual(listener.name, 'test')
@@ -281,7 +289,11 @@ class DimensionDataTests(unittest.TestCase):
                 id='1234',
                 name='test',
                 description='test',
-                status=State.RUNNING
+                status=State.RUNNING,
+                health_monitor_id=None,
+                load_balance_method=None,
+                service_down_action=None,
+                slow_ramp_time=None
             ))
         self.assertEqual(listener.id, '8334f461-0df0-42d5-97eb-f4678eb26bea')
         self.assertEqual(listener.name, 'test')
@@ -305,6 +317,27 @@ class DimensionDataTests(unittest.TestCase):
         self.assertEqual(nodes[0].id, '34de6ed6-46a4-4dae-a753-2f8d3840c6f9')
         self.assertEqual(nodes[0].ip, '10.10.10.101')
 
+    def test_ex_get_node(self):
+        node = self.driver.ex_get_node('34de6ed6-46a4-4dae-a753-2f8d3840c6f9')
+        self.assertEqual(node.name, 'ProductionNode.2')
+        self.assertEqual(node.id, '34de6ed6-46a4-4dae-a753-2f8d3840c6f9')
+        self.assertEqual(node.ip, '10.10.10.101')
+
+    def test_ex_update_node(self):
+        node = self.driver.ex_get_node('34de6ed6-46a4-4dae-a753-2f8d3840c6f9')
+        node.connection_limit = '100'
+        result = self.driver.ex_update_node(node)
+        self.assertEqual(result.connection_limit, '100')
+
+    def test_ex_destroy_node(self):
+        result = self.driver.ex_destroy_node('34de6ed6-46a4-4dae-a753-2f8d3840c6f9')
+        self.assertTrue(result)
+
+    def test_ex_set_node_state(self):
+        node = self.driver.ex_get_node('34de6ed6-46a4-4dae-a753-2f8d3840c6f9')
+        result = self.driver.ex_set_node_state(node, False)
+        self.assertEqual(result.connection_limit, '10000')
+
     def test_ex_get_pools(self):
         pools = self.driver.ex_get_pools()
         self.assertNotEqual(0, len(pools))
@@ -316,13 +349,23 @@ class DimensionDataTests(unittest.TestCase):
         self.assertEqual(pool.name, 'myDevelopmentPool.1')
         self.assertEqual(pool.id, '4d360b1f-bc2c-4ab7-9884-1f03ba2768f7')
 
+    def test_ex_update_pool(self):
+        pool = self.driver.ex_get_pool('4d360b1f-bc2c-4ab7-9884-1f03ba2768f7')
+        pool.slow_ramp_time = '120'
+        result = self.driver.ex_update_pool(pool)
+        self.assertTrue(result)
+
     def test_ex_destroy_pool(self):
         response = self.driver.ex_destroy_pool(
             pool=DimensionDataPool(
                 id='4d360b1f-bc2c-4ab7-9884-1f03ba2768f7',
                 name='test',
                 description='test',
-                status=State.RUNNING))
+                status=State.RUNNING,
+                health_monitor_id=None,
+                load_balance_method=None,
+                service_down_action=None,
+                slow_ramp_time=None))
         self.assertTrue(response)
 
     def test_get_pool_members(self):
@@ -343,6 +386,11 @@ class DimensionDataTests(unittest.TestCase):
         self.assertEqual(member.ip, '10.0.3.13')
         self.assertEqual(member.port, 9889)
 
+    def test_set_pool_member_state(self):
+        member = self.driver.ex_get_pool_member('3dd806a2-c2c8-4c0c-9a4f-5219ea9266c0')
+        result = self.driver.ex_set_pool_member_state(member, True)
+        self.assertTrue(result)
+
     def test_ex_destroy_pool_member(self):
         response = self.driver.ex_destroy_pool_member(
             member=DimensionDataPoolMember(
@@ -457,7 +505,26 @@ class DimensionDataMockHttp(MockHttp):
         body = self.fixtures.load(
             'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+    
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node_34de6ed6_46a4_4dae_a753_2f8d3840c6f9(self,
method, url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_node_34de6ed6_46a4_4dae_a753_2f8d3840c6f9.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editNode(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editNode.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPool(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPool.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPoolMember(self,
method, url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_editPoolMember.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
 if __name__ == '__main__':
     sys.exit(unittest.main())


Mime
View raw message