You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by an...@apache.org on 2016/03/07 10:46:55 UTC
[4/9] libcloud git commit: Dimension Data: Adding Additional Nics to
create_node Adding ex_primary_ipv4 to create_node so you can set static ips
Adding more filters to ex_list_vlans Adding more filters to
ex_list_network_domains Adding tests to cover all
Dimension Data: Adding Additional Nics to create_node Adding ex_primary_ipv4 to create_node so you can set static ips Adding more filters to ex_list_vlans Adding more filters to ex_list_network_domains Adding tests to cover all changes
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e9b973ef
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e9b973ef
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e9b973ef
Branch: refs/heads/trunk
Commit: e9b973ef270d1e43d3db0e1769ed171451966ee5
Parents: 00f27cb
Author: Jeffrey Dunham <je...@gmail.com>
Authored: Mon Feb 29 21:07:07 2016 -0500
Committer: anthony-shaw <an...@gmail.com>
Committed: Mon Mar 7 20:46:16 2016 +1100
----------------------------------------------------------------------
libcloud/compute/drivers/dimensiondata.py | 216 +++++++++++++++--------
libcloud/test/compute/test_dimensiondata.py | 200 ++++++++++++++++++++-
2 files changed, 341 insertions(+), 75 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9b973ef/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 4b1039e..0194524 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -110,10 +110,11 @@ class DimensionDataNodeDriver(NodeDriver):
def create_node(self, name, image, auth, ex_description,
ex_network=None, ex_network_domain=None,
- ex_vlan=None,
+ ex_vlan=None, ex_primary_ipv4=None,
ex_memory_gb=None,
ex_cpu_specification=None,
- ex_is_started=True, **kwargs):
+ ex_is_started=True, ex_additional_nics_vlan=None,
+ ex_additional_nics_ipv4=None, **kwargs):
"""
Create a new DimensionData node
@@ -130,15 +131,23 @@ class DimensionDataNodeDriver(NodeDriver):
:keyword ex_description: description for this node (required)
:type ex_description: ``str``
- :keyword ex_network: Network to create the node within (required,
- unless using Network Domain)
+ :keyword ex_network: Network to create the node within
+ (required unless using ex_network_domain
+ or ex_primary_ipv4)
+
:type ex_network: :class:`DimensionDataNetwork` or ``str``
:keyword ex_network_domain: Network Domain to create the node
- (required unless using network)
+ (required unless using network
+ or ex_primary_ipv4)
:type ex_network_domain: :class:`DimensionDataNetworkDomain`
or ``str``
+ :keyword ex_primary_ipv4: Primary nics IPv4 Address
+ MCP1: (required unless ex_network)
+ MCP2: (required unless ex_vlan)
+ :type ex_primary_ipv4: ``str``
+
:keyword ex_vlan: VLAN to create the node within
(required unless using network)
:type ex_vlan: :class:`DimensionDataVlan` or ``str``
@@ -154,6 +163,15 @@ class DimensionDataNodeDriver(NodeDriver):
true (required)
:type ex_is_started: ``bool``
+ :keyword ex_additional_nics_vlan: (MCP2 Only) List of additional
+ nics to add by vlan
+ :type ex_additional_nics_vlan: ``list`` of
+ :class:`DimensionDataVlan` or ``list`` of ``str``
+
+ :keyword ex_additional_nics_ipv4: (MCP2 Only) List of additional
+ nics to add by ipv4 address
+ :type ex_additional_nics_ipv4: ``list`` of ``str``
+
:return: The newly created :class:`Node`.
:rtype: :class:`Node`
"""
@@ -165,24 +183,17 @@ class DimensionDataNodeDriver(NodeDriver):
auth_obj = self._get_and_check_auth(auth)
password = auth_obj.password
- if not isinstance(ex_network, (DimensionDataNetwork, basestring)):
- if not isinstance(ex_network_domain,
- (DimensionDataNetworkDomain, basestring)):
- raise ValueError(
- 'ex_network must be of DimensionDataNetwork'
- ' or str '
- 'type or ex_network_domain must be of '
- 'DimensionDataNetworkDomain type or str')
+ if (ex_network_domain is None and
+ ex_network is None and
+ ex_primary_ipv4 is None):
+ raise ValueError("One of ex_network_domain, ex_network, "
+ "or ex_ipv6_primary must be specified")
server_elm = ET.Element('deployServer', {'xmlns': TYPES_URN})
ET.SubElement(server_elm, "name").text = name
ET.SubElement(server_elm, "description").text = ex_description
-
- if isinstance(image, NodeImage):
- ET.SubElement(server_elm, "imageId").text = image.id
- else:
- ET.SubElement(server_elm, "imageId").text = image
-
+ image_id = self._image_to_image_id(image)
+ ET.SubElement(server_elm, "imageId").text = image_id
ET.SubElement(server_elm, "start").text = str(ex_is_started).lower()
ET.SubElement(server_elm, "administratorPassword").text = password
@@ -198,27 +209,47 @@ class DimensionDataNodeDriver(NodeDriver):
if ex_network is not None:
network_elm = ET.SubElement(server_elm, "network")
- if isinstance(ex_network, DimensionDataNetwork):
- ET.SubElement(network_elm, "networkId").text = ex_network.id
- else:
- ET.SubElement(network_elm, "networkId").text = ex_network
- if ex_network_domain is not None:
- network_domain_id = None
- if isinstance(ex_network_domain, DimensionDataNetworkDomain):
- network_domain_id = ex_network_domain.id
- else:
- network_domain_id = ex_network_domain
- network_inf_elm = ET.SubElement(server_elm, "networkInfo",
- {'networkDomainId':
- network_domain_id})
- vlan_id = None
- if isinstance(ex_vlan, DimensionDataVlan):
- vlan_id = ex_vlan.id
- else:
- vlan_id = ex_vlan
- pri_nic = ET.SubElement(network_inf_elm, "primaryNic")
- ET.SubElement(pri_nic, "vlanId").text = vlan_id
+ network_id = self._network_to_network_id(ex_network)
+ ET.SubElement(network_elm, "networkId").text = network_id
+ elif ex_network_domain is None and ex_primary_ipv4 is not None:
+ network_elm = ET.SubElement(server_elm, "network")
+ ET.SubElement(network_elm, "privateIpv4").text = ex_primary_ipv4
+ elif ex_network_domain is not None:
+ net_domain_id = self._network_domain_to_network_domain_id(
+ ex_network_domain)
+ network_inf_elm = ET.SubElement(
+ server_elm, "networkInfo",
+ {'networkDomainId': net_domain_id}
+ )
+ if ex_vlan is not None:
+ vlan_id = self._vlan_to_vlan_id(ex_vlan)
+ pri_nic = ET.SubElement(network_inf_elm, "primaryNic")
+ ET.SubElement(pri_nic, "vlanId").text = vlan_id
+ elif ex_primary_ipv4 is not None:
+ pri_nic = ET.SubElement(network_inf_elm, "primaryNic")
+ ET.SubElement(pri_nic, "privateIpv4").text = ex_primary_ipv4
+ else:
+ raise ValueError("One of ex_vlan or ex_primary_ipv4 "
+ "must be specified")
+
+ if isinstance(ex_additional_nics_ipv4, list):
+ for ipv4_nic in ex_additional_nics_ipv4:
+ add_nic = ET.SubElement(network_inf_elm, "additionalNic")
+ ET.SubElement(add_nic, "privateIpv4").text = ipv4_nic
+ elif ex_additional_nics_ipv4 is not None:
+ raise TypeError("ex_additional_nics_ipv4 must "
+ "be None or a list")
+
+ if isinstance(ex_additional_nics_vlan, list):
+ for vlan_nic in ex_additional_nics_vlan:
+ print("vlan nic {}".format(vlan_nic))
+ add_nic = ET.SubElement(network_inf_elm, "additionalNic")
+ ET.SubElement(add_nic, "vlanId").text = vlan_nic
+ elif ex_additional_nics_vlan is not None:
+ raise TypeError("ex_additional_nics_vlan"
+ "must be None or a list")
+ print(ET.tostring(server_elm))
response = self.connection.request_with_orgId_api_2(
'server/deployServer',
method='POST',
@@ -481,7 +512,6 @@ class DimensionDataNodeDriver(NodeDriver):
params = {}
if location is not None:
params['datacenterId'] = self._location_to_location_id(location)
-
if ipv6 is not None:
params['ipv6'] = ipv6
if ipv4 is not None:
@@ -494,30 +524,15 @@ class DimensionDataNodeDriver(NodeDriver):
params['deployed'] = deployed
if name is not None:
params['name'] = name
-
if network_domain is not None:
- if isinstance(network_domain, DimensionDataNetworkDomain):
- params['networkDomainId'] = network_domain.id
- else:
- params['networkDomainId'] = network_domain
-
+ params['networkDomainId'] = \
+ self._network_domain_to_network_domain_id(network_domain)
if network is not None:
- if isinstance(network, DimensionDataNetwork):
- params['networkId'] = network.id
- else:
- params['networkId'] = network
-
+ params['networkId'] = self._network_to_network_id(network)
if vlan is not None:
- if isinstance(vlan, DimensionDataVlan):
- params['vlanId'] = vlan.id
- else:
- params['vlanId'] = vlan
-
+ params['vlanId'] = self._vlan_to_vlan_id(vlan)
if image is not None:
- if isinstance(image, NodeImage):
- params['sourceImageId'] = image.id
- else:
- params['sourceImageId'] = image
+ params['sourceImageId'] = self._image_to_image_id(image)
nodes_obj = self._list_nodes_single_page(params)
yield self._to_nodes(nodes_obj)
@@ -810,21 +825,37 @@ class DimensionDataNodeDriver(NodeDriver):
'network/networkDomain/%s' % network_domain_id).object
return self._to_network_domain(net, locations)
- def ex_list_network_domains(self, location=None):
+ def ex_list_network_domains(self, location=None, name=None,
+ service_plan=None, state=None):
"""
List networks domains deployed across all data center locations
for your organization.
The response includes the location of each network domain.
- :param location: The data center to list (optional)
+ :param location: Only network domains in the location (optional)
:type location: :class:`NodeLocation` or ``str``
+ :param name: Only network domains of this name (optional)
+ :type name: ``str``
+
+ :param service_plan: Only network domains of this type (optional)
+ :type service_plan: ``str``
+
+ :param state: Only network domains in this state (optional)
+ :type state: ``str``
+
:return: a list of `DimensionDataNetwork` objects
:rtype: ``list`` of :class:`DimensionDataNetwork`
"""
params = {}
if location is not None:
params['datacenterId'] = self._location_to_location_id(location)
+ if name is not None:
+ params['name'] = name
+ if service_plan is not None:
+ params['type'] = service_plan
+ if state is not None:
+ params['state'] = state
response = self.connection \
.request_with_orgId_api_2('network/networkDomain',
@@ -1064,7 +1095,8 @@ class DimensionDataNodeDriver(NodeDriver):
response_code = findtext(result, 'responseCode', TYPES_URN)
return response_code in ['IN_PROGRESS', 'OK']
- def ex_list_vlans(self, location=None, network_domain=None):
+ def ex_list_vlans(self, location=None, network_domain=None, name=None,
+ ipv4_address=None, ipv6_address=None, state=None):
"""
List VLANs available, can filter by location and/or network domain
@@ -1074,6 +1106,18 @@ class DimensionDataNodeDriver(NodeDriver):
:param network_domain: Only VLANs in this domain (optional)
:type network_domain: :class:`DimensionDataNetworkDomain`
+ :param name: Only VLANs with this name (optional)
+ :type name: ``str``
+
+ :param ipv4_address: Only VLANs with this ipv4 address (optional)
+ :type ipv4_address: ``str``
+
+ :param ipv6_address: Only VLANs with this ipv6 address (optional)
+ :type ipv6_address: ``str``
+
+ :param state: Only VLANs with this state (optional)
+ :type state: ``str``
+
:return: a list of DimensionDataVlan objects
:rtype: ``list`` of :class:`DimensionDataVlan`
"""
@@ -1081,7 +1125,16 @@ class DimensionDataNodeDriver(NodeDriver):
if location is not None:
params['datacenterId'] = self._location_to_location_id(location)
if network_domain is not None:
- params['networkDomainId'] = network_domain.id
+ params['networkDomainId'] = \
+ self._network_domain_to_network_domain_id(network_domain)
+ if name is not None:
+ params['name'] = name
+ if ipv4_address is not None:
+ params['privateIpv4Address'] = ipv4_address
+ if ipv6_address is not None:
+ params['ipv6Address'] = ipv6_address
+ if state is not None:
+ params['state'] = state
response = self.connection.request_with_orgId_api_2('network/vlan',
params=params) \
.object
@@ -1138,10 +1191,8 @@ class DimensionDataNodeDriver(NodeDriver):
def ex_list_firewall_rules(self, network_domain, page_size=50,
page_number=1):
params = {'pageSize': page_size, 'pageNumber': page_number}
- if isinstance(network_domain, str):
- params['networkDomainId'] = network_domain
- else:
- params['networkDomainId'] = network_domain.id
+ params['networkDomainId'] = self._network_domain_to_network_domain_id(
+ network_domain)
response = self.connection \
.request_with_orgId_api_2('network/firewallRule',
@@ -1976,13 +2027,30 @@ class DimensionDataNodeDriver(NodeDriver):
else:
return NodeState.TERMINATED
+ def _location_to_location_id(self, location):
+ return self._dd_object_to_id(location, NodeLocation)
+
+ def _vlan_to_vlan_id(self, vlan):
+ return self._dd_object_to_id(vlan, DimensionDataVlan)
+
+ def _image_to_image_id(self, image):
+ return self._dd_object_to_id(image, NodeImage)
+
+ def _network_to_network_id(self, network):
+ return self._dd_object_to_id(network, DimensionDataNetwork)
+
+ def _network_domain_to_network_domain_id(self, network_domain):
+ return self._dd_object_to_id(network_domain,
+ DimensionDataNetworkDomain)
+
@staticmethod
- def _location_to_location_id(location):
- if isinstance(location, NodeLocation):
- return location.id
- elif isinstance(location, basestring):
- return location
+ def _dd_object_to_id(obj, obj_type):
+ if isinstance(obj, obj_type):
+ return obj.id
+ elif isinstance(obj, basestring):
+ return obj
else:
raise TypeError(
- "Invalid location type for _location_to_location_id()"
+ "Invalid type for %s looking for basestring or Object Type %s"
+ % obj_type.__name__
)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/e9b973ef/libcloud/test/compute/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_dimensiondata.py b/libcloud/test/compute/test_dimensiondata.py
index 0852d86..50bbe20 100644
--- a/libcloud/test/compute/test_dimensiondata.py
+++ b/libcloud/test/compute/test_dimensiondata.py
@@ -24,13 +24,14 @@ from libcloud.utils.py3 import httplib
from libcloud.common.types import InvalidCredsError
from libcloud.common.dimensiondata import DimensionDataAPIException, NetworkDomainServicePlan
from libcloud.common.dimensiondata import DimensionDataServerCpuSpecification, DimensionDataServerDisk
+from libcloud.common.dimensiondata import TYPES_URN
from libcloud.compute.drivers.dimensiondata import DimensionDataNodeDriver as DimensionData
from libcloud.compute.base import Node, NodeAuthPassword, NodeLocation
-
from libcloud.test import MockHttp, unittest
from libcloud.test.compute import TestCaseMixin
from libcloud.test.file_fixtures import ComputeFileFixtures
from libcloud.test.secrets import DIMENSIONDATA_PARAMS
+from libcloud.utils.xml import fixxpath, findtext
class DimensionDataTests(unittest.TestCase, TestCaseMixin):
@@ -237,6 +238,110 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
ex_network=None,
ex_isStarted=False)
+ def test_create_node_mcp1_ipv4(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ node = self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_primary_ipv4='10.0.0.1',
+ ex_isStarted=False)
+ self.assertEqual(node.id, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
+ self.assertEqual(node.extra['status'].action, 'DEPLOY_SERVER')
+
+ def test_create_node_mcp1_network(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ node = self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network='fakenetwork',
+ ex_isStarted=False)
+ self.assertEqual(node.id, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
+ self.assertEqual(node.extra['status'].action, 'DEPLOY_SERVER')
+
+ def test_create_node_mcp2_vlan(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ node = self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network_domain='fakenetworkdomain',
+ ex_vlan='fakevlan',
+ ex_isStarted=False)
+ self.assertEqual(node.id, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
+ self.assertEqual(node.extra['status'].action, 'DEPLOY_SERVER')
+
+ def test_create_node_mcp2_ipv4(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ node = self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network_domain='fakenetworkdomain',
+ ex_primary_ipv4='10.0.0.1',
+ ex_isStarted=False)
+ self.assertEqual(node.id, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
+ self.assertEqual(node.extra['status'].action, 'DEPLOY_SERVER')
+
+ def test_create_node_network_domain_no_vlan_or_ipv4(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ with self.assertRaises(ValueError):
+ self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network_domain='fake_network_domain',
+ ex_isStarted=False)
+
+ def test_create_node_mcp2_additional_nics(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ additional_vlans = ['fakevlan1', 'fakevlan2']
+ additional_ipv4 = ['10.0.0.2', '10.0.0.3']
+ node = self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network_domain='fakenetworkdomain',
+ ex_primary_ipv4='10.0.0.1',
+ ex_additional_nics_vlan=additional_vlans,
+ ex_additional_nics_ipv4=additional_ipv4,
+ ex_isStarted=False)
+ self.assertEqual(node.id, 'e75ead52-692f-4314-8725-c8a4f4d13a87')
+ self.assertEqual(node.extra['status'].action, 'DEPLOY_SERVER')
+
+ def test_create_node_bad_additional_nics_ipv4(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ with self.assertRaises(TypeError):
+ self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network_domain='fake_network_domain',
+ ex_vlan='fake_vlan',
+ ex_additional_nics_ipv4='badstring',
+ ex_isStarted=False)
+
+ def test_create_node_bad_additional_nics_vlan(self):
+ rootPw = NodeAuthPassword('pass123')
+ image = self.driver.list_images()[0]
+ with self.assertRaises(TypeError):
+ self.driver.create_node(name='test2',
+ image=image,
+ auth=rootPw,
+ ex_description='test2 node',
+ ex_network_domain='fake_network_domain',
+ ex_vlan='fake_vlan',
+ ex_additional_nics_vlan='badstring',
+ ex_isStarted=False)
+
def test_ex_shutdown_graceful(self):
node = Node(id='11', name=None, state=None,
public_ips=None, private_ips=None, driver=self.driver)
@@ -371,10 +476,23 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
self.assertEqual(nets[0].name, 'Aurora')
self.assertTrue(isinstance(nets[0].location, NodeLocation))
+ def test_ex_list_network_domains_ALLFILTERS(self):
+ DimensionDataMockHttp.type = 'ALLFILTERS'
+ nets = self.driver.ex_list_network_domains(location='fake_location', name='fake_name',
+ service_plan='fake_plan', state='fake_state')
+ self.assertEqual(nets[0].name, 'Aurora')
+ self.assertTrue(isinstance(nets[0].location, NodeLocation))
+
def test_ex_list_vlans(self):
vlans = self.driver.ex_list_vlans()
self.assertEqual(vlans[0].name, "Primary")
+ def test_ex_list_vlans_ALLFILTERS(self):
+ DimensionDataMockHttp.type = 'ALLFILTERS'
+ vlans = self.driver.ex_list_vlans(location='fake_location', network_domain='fake_network_domain',
+ name='fake_name', ipv4_address='fake_ipv4', ipv6_address='fake_ipv6', state='fake_state')
+ self.assertEqual(vlans[0].name, "Primary")
+
def test_ex_create_vlan(self,):
net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
vlan = self.driver.ex_create_vlan(network_domain=net,
@@ -862,6 +980,16 @@ class DimensionDataMockHttp(MockHttp):
'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter_ALLFILTERS(self, method, url, body, headers):
+ if url.endswith('id=NA9'):
+ body = self.fixtures.load(
+ 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter_NA9.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ body = self.fixtures.load(
+ 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_infrastructure_datacenter.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _caas_2_1_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":
@@ -931,15 +1059,80 @@ class DimensionDataMockHttp(MockHttp):
'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain_ALLFILTERS(self, method, url, body, headers):
+ (_, params) = url.split('?')
+ parameters = params.split('&')
+ for parameter in parameters:
+ (key, value) = parameter.split('=')
+ if key == 'datacenterId':
+ assert value == 'fake_location'
+ elif key == 'type':
+ assert value == 'fake_plan'
+ elif key == 'name':
+ assert value == 'fake_name'
+ elif key == 'state':
+ assert value == 'fake_state'
+ else:
+ raise ValueError("Could not find in url parameters {0}:{1}".format(key, value))
+ body = self.fixtures.load(
+ 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan(self, method, url, body, headers):
body = self.fixtures.load(
'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan_ALLFILTERS(self, method, url, body, headers):
+ (_, params) = url.split('?')
+ parameters = params.split('&')
+ for parameter in parameters:
+ (key, value) = parameter.split('=')
+ if key == 'datacenterId':
+ assert value == 'fake_location'
+ elif key == 'networkDomainId':
+ assert value == 'fake_network_domain'
+ elif key == 'ipv6Address':
+ assert value == 'fake_ipv6'
+ elif key == 'privateIpv4Address':
+ assert value == 'fake_ipv4'
+ elif key == 'name':
+ assert value == 'fake_name'
+ elif key == 'state':
+ assert value == 'fake_state'
+ else:
+ raise ValueError("Could not find in url parameters {0}:{1}".format(key, value))
+ body = self.fixtures.load(
+ 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_vlan.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deployServer(self, method, url, body, headers):
request = ET.fromstring(body)
if request.tag != "{urn:didata.com:api:cloud:types}deployServer":
raise InvalidRequestError(request.tag)
+
+ # Make sure the we either have a network tag with an IP or networkId
+ # Or Network info with a primary nic that has privateip or vlanid
+ network = request.find(fixxpath('network', TYPES_URN))
+ network_info = request.find(fixxpath('networkInfo', TYPES_URN))
+ if network is not None:
+ if network_info is not None:
+ raise InvalidRequestError("Request has both MCP1 and MCP2 values")
+ ipv4 = findtext(network, 'privateIpv4', TYPES_URN)
+ networkId = findtext(network, 'networkId', TYPES_URN)
+ if ipv4 is None and networkId is None:
+ raise InvalidRequestError('Invalid request MCP1 requests need privateIpv4 or networkId')
+ elif network_info is not None:
+ if network is not None:
+ raise InvalidRequestError("Request has both MCP1 and MCP2 values")
+ primary_nic = network_info.find(fixxpath('primaryNic', TYPES_URN))
+ ipv4 = findtext(primary_nic, 'privateIpv4', TYPES_URN)
+ vlanId = findtext(primary_nic, 'vlanId', TYPES_URN)
+ if ipv4 is None and vlanId is None:
+ raise InvalidRequestError('Invalid request MCP2 requests need privateIpv4 or vlanId')
+ else:
+ raise InvalidRequestError('Invalid request, does not have network or network_info in XML')
+
body = self.fixtures.load(
'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_deployServer.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
@@ -962,6 +1155,11 @@ class DimensionDataMockHttp(MockHttp):
'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain_8cdfd607_f429_4df6_9352_162cfc0891be.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain_8cdfd607_f429_4df6_9352_162cfc0891be_ALLFILTERS(self, method, url, body, headers):
+ body = self.fixtures.load(
+ 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_networkDomain_8cdfd607_f429_4df6_9352_162cfc0891be.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editNetworkDomain(self, method, url, body, headers):
request = ET.fromstring(body)
if request.tag != "{urn:didata.com:api:cloud:types}editNetworkDomain":