Methods for adding, deleting and renaming "networks" which are the MCP 1 
network separation feature. Create network does include the ID in the message, 
but not by convention, just convenience so I decided to rely on the uniqueness 
of the name within a location to fetch the ID.
Included tests


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

Branch: refs/heads/trunk
Commit: 4e26ef0d1c40ac4ecfc091d5189df7549dac70f1
Parents: c923de3
Author: Anthony Shaw <anthony.p.s...@gmail.com>
Authored: Fri Oct 30 11:36:34 2015 +1100
Committer: Anthony Shaw <anthony.p.s...@gmail.com>
Committed: Fri Oct 30 11:36:34 2015 +1100

----------------------------------------------------------------------
 libcloud/common/dimensiondata.py                |  1 +
 libcloud/compute/drivers/dimensiondata.py       | 75 ++++++++++++++++++--
 ...8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml |  2 +-
 ...ork_4bba37be_506f_11e3_b29c_001517c4643e.xml | 16 +++++
 libcloud/test/compute/test_dimensiondata.py     | 26 +++++++
 5 files changed, 115 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/4e26ef0d/libcloud/common/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/common/dimensiondata.py b/libcloud/common/dimensiondata.py
index d6792d9..715d5fd 100644
--- a/libcloud/common/dimensiondata.py
+++ b/libcloud/common/dimensiondata.py
@@ -33,6 +33,7 @@ ORGANIZATION_NS = NAMESPACE_BASE + "/organization"
 SERVER_NS = NAMESPACE_BASE + "/server"
 NETWORK_NS = NAMESPACE_BASE + "/network"
 DIRECTORY_NS = NAMESPACE_BASE + "/directory"
+GENERAL_NS = NAMESPACE_BASE + "/general"
 
 # API 2.0 Namespaces and URNs
 TYPES_URN = "urn:didata.com:api:cloud:types"

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4e26ef0d/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py 
b/libcloud/compute/drivers/dimensiondata.py
index 1015562..51a21d5 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -33,11 +33,9 @@ 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
+from libcloud.common.dimensiondata import API_ENDPOINTS, DEFAULT_REGION
 from libcloud.common.dimensiondata import TYPES_URN
-from libcloud.common.dimensiondata import SERVER_NS
-from libcloud.common.dimensiondata import NETWORK_NS
+from libcloud.common.dimensiondata import SERVER_NS, NETWORK_NS, GENERAL_NS
 from libcloud.utils.xml import fixxpath, findtext, findall
 from libcloud.compute.types import NodeState, Provider
 
@@ -465,6 +463,75 @@ class DimensionDataNodeDriver(NodeDriver):
                                       params=params).object
         return self._to_networks(response)
 
+    def ex_create_network(self, location, name, description=None):
+        """
+        Create a new network in an MCP 1.0 location
+
+        :param   location: The target location (MCP1)
+        :type    location: :class:`NodeLocation`
+
+        :param   name: The name of the network
+        :type    name: ``str``
+
+        :param   description: Additional description of the network
+        :type    description: ``str``
+
+        :return: A new instance of `DimensionDataNetwork`
+        :rtype:  Instance of :class:`DimensionDataNetwork`
+        """
+        create_node = ET.Element('NewNetworkWithLocation',
+                                 {'xmlns': NETWORK_NS})
+        ET.SubElement(create_node, "name").text = name
+        if description is not None:
+            ET.SubElement(create_node, "description").text = description
+        ET.SubElement(create_node, "location").text = location.id
+
+        response = self.connection.request_with_orgId_api_1(
+            'networkWithLocation',
+            method='POST',
+            data=ET.tostring(create_node)).object
+
+        # MCP1 API does not return the ID, but name is unique for location
+        network = list(
+            filter(lambda x: x.name == name,
+                   self.ex_list_networks(location)))[0]
+
+        return network
+
+    def ex_delete_network(self, network):
+        """
+        Delete a network from an MCP 1 data center
+
+        :param  network: The network to delete
+        :type   network: :class:`DimensionDataNetwork`
+
+        :rtype: ``bool``
+        """
+        response = self.connection.request_with_orgId_api_1(
+            'network/%s?delete' % network.id,
+            method='GET').object
+        response_code = findtext(response, 'result', GENERAL_NS)
+        return response_code == "SUCCESS"
+
+    def ex_rename_network(self, network, new_name):
+        """
+        Rename a network in MCP 1 data center
+
+        :param  network: The network to rename
+        :type   network: :class:`DimensionDataNetwork`
+
+        :param  new_name: The new name of the network
+        :type   new_name: ``str``
+
+        :rtype: ``bool``
+        """
+        response = self.connection.request_with_orgId_api_1(
+            'network/%s' % network.id,
+            method='POST',
+            data='name=%s' % new_name).object
+        response_code = findtext(response, 'result', GENERAL_NS)
+        return response_code == "SUCCESS"
+
     def ex_get_network_domain(self, network_domain_id):
         """
         Get an individual Network Domain, by identifier

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4e26ef0d/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 5a8dfee..227def2 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
@@ -12,7 +12,7 @@
         <ns3:id>208e3a8e-9d2f-11e2-b29c-001517c4643e</ns3:id>
         <ns3:name>Test Network</ns3:name>
         <ns3:description>Network description</ns3:description>
-        <ns3:location>NA1</ns3:location>
+        <ns3:location>NA9</ns3:location>
         <ns3:privateNet>10.172.74.0</ns3:privateNet>
         <ns3:multicast>false</ns3:multicast>
     </ns3:network>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4e26ef0d/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e.xml
 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e.xml
new file mode 100644
index 0000000..1e28e0d
--- /dev/null
+++ 
b/libcloud/test/compute/fixtures/dimensiondata/oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<ns7:Status xmlns:ns16="http://oec.api.opsource.net/schemas/serverbootstrap";
+            xmlns="http://oec.api.opsource.net/schemas/network";
+            xmlns:ns14="http://oec.api.opsource.net/schemas/storage";
+            xmlns:ns15="http://oec.api.opsource.net/schemas/backup";
+            xmlns:ns9="http://oec.api.opsource.net/schemas/admin";
+            xmlns:ns5="http://oec.api.opsource.net/schemas/organization";
+            xmlns:ns12="http://oec.api.opsource.net/schemas/support";
+            xmlns:ns13="http://oec.api.opsource.net/schemas/multigeo";
+            xmlns:ns6="http://oec.api.opsource.net/schemas/directory";
+            xmlns:ns7="http://oec.api.opsource.net/schemas/general"; 
xmlns:ns10="http://oec.api.opsource.net/schemas/reset"; 
xmlns:ns8="http://oec.api.opsource.net/schemas/vip"; 
xmlns:ns11="http://oec.api.opsource.net/schemas/whitelabel"; 
xmlns:ns2="http://oec.api.opsource.net/schemas/manualimport"; 
xmlns:ns4="http://oec.api.opsource.net/schemas/datacenter"; 
xmlns:ns3="http://oec.api.opsource.net/schemas/server";>
+    <ns7:operation>Add Network</ns7:operation>
+    <ns7:result>SUCCESS</ns7:result>
+    <ns7:resultDetail>Network created successfully (Network ID: 
9eb15060-e2f7-11e1-9153-001b21cfdbe0)</ns7:resultDetail>
+    <ns7:resultCode>REASON_0</ns7:resultCode>
+</ns7:Status>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4e26ef0d/libcloud/test/compute/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_dimensiondata.py 
b/libcloud/test/compute/test_dimensiondata.py
index cbaa22f..d779900 100644
--- a/libcloud/test/compute/test_dimensiondata.py
+++ b/libcloud/test/compute/test_dimensiondata.py
@@ -217,6 +217,22 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
         self.assertEqual(nets[0].name, 'test-net1')
         self.assertTrue(isinstance(nets[0].location, NodeLocation))
 
+    def test_ex_create_network(self):
+        location = self.driver.ex_get_location_by_id('NA9')
+        net = self.driver.ex_create_network(location, "Test Network", "test")
+        self.assertEqual(net.id, "208e3a8e-9d2f-11e2-b29c-001517c4643e")
+        self.assertEqual(net.name, "Test Network")
+
+    def test_ex_delete_network(self):
+        net = self.driver.ex_list_networks()[0]
+        result = self.driver.ex_delete_network(net)
+        self.assertTrue(result)
+
+    def test_ex_rename_network(self):
+        net = self.driver.ex_list_networks()[0]
+        result = self.driver.ex_rename_network(net, "barry")
+        self.assertTrue(result)
+
     def test_ex_create_network_domain(self):
         location = self.driver.ex_get_location_by_id('NA9')
         plan = NetworkDomainServicePlan.ADVANCED
@@ -474,10 +490,20 @@ class DimensionDataMockHttp(MockHttp):
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
     def 
_oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation(self, method, 
url, body, headers):
+        if method is "POST":
+            request = ET.fromstring(body)
+            if request.tag != 
"{http://oec.api.opsource.net/schemas/network}NewNetworkWithLocation":
+                raise InvalidRequestError(request.tag)
         body = self.fixtures.load(
             
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkWithLocation.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def 
_oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e(self,
 method,
+                                                                               
                    url, body, headers):
+        body = self.fixtures.load(
+            
'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_4bba37be_506f_11e3_b29c_001517c4643e.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')

Reply via email to