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/12/27 08:26:43 UTC

[01/11] libcloud git commit: perform runtime check for python version to support iteration

Repository: libcloud
Updated Branches:
  refs/heads/trunk 3e14f05a1 -> f13933ed7


perform runtime check for python version to support iteration


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

Branch: refs/heads/trunk
Commit: a0ad69ebb6a9f325becd0358603f7a7415295b60
Parents: e91e66c
Author: Samuel Chong <sa...@gmail.com>
Authored: Thu Dec 22 16:45:01 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/a0ad69eb/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 1ce61dc..4619b1b 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -4056,7 +4056,12 @@ class DimensionDataNodeDriver(NodeDriver):
                     "ex_tagid_value_pairs must be a dictionary."
                 )
 
-            for k, v in ex_tagid_value_pairs.items():
+            if sys.version_info[0] < 3:
+                tagid_items = ex_tagid_value_pairs.iteritems()
+            else:
+                tagid_items = ex_tagid_value_pairs.items()
+
+            for k, v in tagid_items:
                 tag_elem = ET.SubElement(server_uncustomized_elm, 'tagById')
                 ET.SubElement(tag_elem, 'tagKeyId').text = k
 
@@ -4069,7 +4074,12 @@ class DimensionDataNodeDriver(NodeDriver):
                     "ex_tagname_value_pairs must be a dictionary"
                 )
 
-            for k, v in ex_tagname_value_pairs.items():
+            if sys.version_info[0] < 3:
+                tags_items = ex_tagname_value_pairs.iteritems()
+            else:
+                tags_items = ex_tagname_value_pairs.items()
+
+            for k, v in tags_items:
                 tag_name_elem = ET.SubElement(server_uncustomized_elm, 'tag')
                 ET.SubElement(tag_name_elem, 'tagKeyName').text = k
 


[08/11] libcloud git commit: fix lint error Closes #961

Posted by an...@apache.org.
fix lint error
Closes #961


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

Branch: refs/heads/trunk
Commit: f66ad0bea2e25a707f3a0cdfcb8a4fbeaaf5bf27
Parents: a0ad69e
Author: Samuel Chong <sa...@gmail.com>
Authored: Thu Dec 22 17:10:57 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:10 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/f66ad0be/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 4619b1b..c47eedd 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -3944,9 +3944,10 @@ class DimensionDataNodeDriver(NodeDriver):
                   "to True")
 
         server_uncustomized_elm = ET.Element('deployUncustomizedServer',
-                                {'xmlns': TYPES_URN})
+                                             {'xmlns': TYPES_URN})
         ET.SubElement(server_uncustomized_elm, "name").text = name
-        ET.SubElement(server_uncustomized_elm, "description").text = ex_description
+        ET.SubElement(server_uncustomized_elm, "description").text = \
+            ex_description
         image_id = self._image_to_image_id(image)
         ET.SubElement(server_uncustomized_elm, "imageId").text = image_id
 
@@ -3966,7 +3967,8 @@ class DimensionDataNodeDriver(NodeDriver):
                     str(ex_cpu_specification.cores_per_socket))
 
         if ex_memory_gb is not None:
-            ET.SubElement(server_uncustomized_elm, "memoryGb").text = str(ex_memory_gb)
+            ET.SubElement(server_uncustomized_elm, "memoryGb").text = \
+                str(ex_memory_gb)
 
         if (ex_primary_nic_private_ipv4 is None and
                 ex_primary_nic_vlan is None):


[09/11] libcloud git commit: change for #961

Posted by an...@apache.org.
change for #961


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

Branch: refs/heads/trunk
Commit: bef3ed6ec46b936dabd0c7dd47f5e6e2f651004c
Parents: f66ad0b
Author: Anthony Shaw <an...@apache.org>
Authored: Tue Dec 27 19:23:54 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:23:54 2016 +1100

----------------------------------------------------------------------
 CHANGES.rst | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/bef3ed6e/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 25b2569..30fa94c 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,13 @@
 Changes in current version of Apache Libcloud
 ---------------------------------------------
 
+Common
+~~~~~~
+
+- Set Dimension Data compute, backup and load balancer to default to 2.4 API
+  [GITHUB-961]
+  [Samuel Chong]
+
 Compute
 ~~~~~~~
 


[10/11] libcloud git commit: Adding m4 instances to us-gov and brazil, m4.16xlarge to all regions Closes #964

Posted by an...@apache.org.
Adding m4 instances to us-gov and brazil, m4.16xlarge to all regions
Closes #964


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

Branch: refs/heads/trunk
Commit: 731aa1b5a92976d40c0cd374c3917fcc12622d1c
Parents: bef3ed6
Author: Matthew Tyas <ma...@Matthews-MacBook-Air.local>
Authored: Wed Dec 21 17:12:51 2016 +0000
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:25:01 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/ec2.py   | 33 +++++++++++++++++++++++++++++++++
 libcloud/test/compute/test_ec2.py | 14 ++++++++------
 2 files changed, 41 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/731aa1b5/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index e38dcf3..26656eb 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -284,6 +284,16 @@ INSTANCE_TYPES = {
             'cpu': 40
         }
     },
+    'm4.16xlarge': {
+        'id': 'm4.16xlarge',
+        'name': '16 Extra Large Instance',
+        'ram': GiB(256),
+        'disk': 0,  # EBS only
+        'bandwidth': None,
+        'extra': {
+            'cpu': 64
+        }
+    },
     'cg1.4xlarge': {
         'id': 'cg1.4xlarge',
         'name': 'Cluster GPU Quadruple Extra Large Instance',
@@ -683,6 +693,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'cc2.8xlarge',
@@ -746,6 +757,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'g2.2xlarge',
@@ -800,6 +812,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'cc2.8xlarge',
@@ -863,6 +876,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'g2.2xlarge',
@@ -924,6 +938,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'g2.2xlarge',
@@ -986,6 +1001,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c3.8xlarge',
             'i2.xlarge',
             'i2.2xlarge',
@@ -1024,6 +1040,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c4.large',
             'c4.xlarge',
             'c4.2xlarge',
@@ -1068,6 +1085,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'c3.large',
@@ -1135,6 +1153,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'hs1.8xlarge',
             'i2.xlarge',
             'i2.2xlarge',
@@ -1174,6 +1193,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'i2.xlarge',
             'i2.2xlarge',
             'i2.4xlarge',
@@ -1214,6 +1234,12 @@ REGION_DETAILS = {
             'm3.large',
             'm3.xlarge',
             'm3.2xlarge',
+            'm4.large',
+            'm4.xlarge',
+            'm4.2xlarge',
+            'm4.4xlarge',
+            'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             't2.nano',
@@ -1247,6 +1273,7 @@ REGION_DETAILS = {
             'm4.2xlarge',
             'm4.4xlarge',
             'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'c3.large',
@@ -1298,6 +1325,12 @@ REGION_DETAILS = {
             'm3.large',
             'm3.xlarge',
             'm3.2xlarge',
+            'm4.large',
+            'm4.xlarge',
+            'm4.2xlarge',
+            'm4.4xlarge',
+            'm4.10xlarge',
+            'm4.16xlarge',
             'c1.medium',
             'c1.xlarge',
             'g2.2xlarge',

http://git-wip-us.apache.org/repos/asf/libcloud/blob/731aa1b5/libcloud/test/compute/test_ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py
index 466c0df..aceb05b 100644
--- a/libcloud/test/compute/test_ec2.py
+++ b/libcloud/test/compute/test_ec2.py
@@ -429,21 +429,23 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
                 self.assertTrue('m2.4xlarge' in ids)
 
             if region_name == 'us-east-1':
-                self.assertEqual(len(sizes), 54)
+                self.assertEqual(len(sizes), 55)
                 self.assertTrue('cg1.4xlarge' in ids)
                 self.assertTrue('cc2.8xlarge' in ids)
                 self.assertTrue('cr1.8xlarge' in ids)
                 self.assertTrue('x1.32xlarge' in ids)
             elif region_name == 'us-west-1':
-                self.assertEqual(len(sizes), 45)
+                self.assertEqual(len(sizes), 46)
             if region_name == 'us-west-2':
-                self.assertEqual(len(sizes), 52)
+                self.assertEqual(len(sizes), 53)
             elif region_name == 'ap-southeast-1':
-                self.assertEqual(len(sizes), 44)
+                self.assertEqual(len(sizes), 45)
             elif region_name == 'ap-southeast-2':
-                self.assertEqual(len(sizes), 48)
+                self.assertEqual(len(sizes), 49)
             elif region_name == 'eu-west-1':
-                self.assertEqual(len(sizes), 52)
+                self.assertEqual(len(sizes), 53)
+            elif region_name == 'ap-south-1':
+                self.assertEqual(len(sizes), 29)
 
         self.driver.region_name = region_old
 


[11/11] libcloud git commit: change for #964

Posted by an...@apache.org.
change for #964


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

Branch: refs/heads/trunk
Commit: f13933ed75e921b7ca669960fe180d0b1f27f0b9
Parents: 731aa1b
Author: Anthony Shaw <an...@apache.org>
Authored: Tue Dec 27 19:26:33 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:26:33 2016 +1100

----------------------------------------------------------------------
 CHANGES.rst | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/f13933ed/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 30fa94c..88e7087 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -15,6 +15,10 @@ Common
 Compute
 ~~~~~~~
 
+- [ec2] Added m4 instances to us-gov and brazil, added m4.16xlarge to all
+  [GITHUB-964]
+  (Matthew Tyas)
+
 - Added new CloudScale.ch driver
 
 - [google compute] Bug fix for ex_create_multiple_nodes Google Cloud disk auto delete


[04/11] libcloud git commit: Update default api version

Posted by an...@apache.org.
Update default api version


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

Branch: refs/heads/trunk
Commit: f011a2a2b58f8f991a14d4ad5e98e46ea3b0b60b
Parents: 3e14f05
Author: Samuel Chong <sa...@gmail.com>
Authored: Thu Dec 15 15:09:44 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/common/dimensiondata.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/f011a2a2/libcloud/common/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/common/dimensiondata.py b/libcloud/common/dimensiondata.py
index bcfd576..f76d52a 100644
--- a/libcloud/common/dimensiondata.py
+++ b/libcloud/common/dimensiondata.py
@@ -389,7 +389,7 @@ class DimensionDataConnection(ConnectionUserAndKey):
     latest_api_version = '2.4'
 
     # Default api version
-    active_api_version = '2.3'
+    active_api_version = '2.4'
 
     _orgId = None
     responseCls = DimensionDataResponse


[07/11] libcloud git commit: add to node_state_map

Posted by an...@apache.org.
add to node_state_map


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

Branch: refs/heads/trunk
Commit: a094ac7bf213f77ae991cd731444da7b9f79439e
Parents: 6a4ab59
Author: Samuel Chong <sa...@gmail.com>
Authored: Fri Dec 16 17:07:41 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 14 ++++++++++++--
 libcloud/compute/types.py                 |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/a094ac7b/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 499f569..be471f0 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -62,10 +62,20 @@ from libcloud.compute.types import NodeState, Provider
 # These tuples represent:
 # (<state_of_node_from_didata>, <is node started?>, <action happening>)
 NODE_STATE_MAP = {
-    ('NORMAL', 'true', None):
-        NodeState.RUNNING,
     ('NORMAL', 'false', None):
         NodeState.STOPPED,
+    ('PENDING_CHANGE', 'false', None):
+        NodeState.PENDING,
+    ('PENDING_CHANGE', 'false', 'CHANGE_NETWORK_ADAPTER'):
+        NodeState.PENDING,
+    ('PENDING_CHANGE', 'true', 'CHANGE_NETWORK_ADAPTER'):
+        NodeState.PENDING,
+    ('PENDING_CHANGE', 'false', 'EXCHANGE_NIC_VLANS'):
+        NodeState.PENDING,
+    ('PENDING_CHANGE', 'true', 'EXCHANGE_NIC_VLANS'):
+        NodeState.PENDING,
+    ('NORMAL', 'true', None):
+        NodeState.RUNNING,
     ('PENDING_CHANGE', 'true', 'START_SERVER'):
         NodeState.STARTING,
     ('PENDING_ADD', 'true', 'DEPLOY_SERVER'):

http://git-wip-us.apache.org/repos/asf/libcloud/blob/a094ac7b/libcloud/compute/types.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/types.py b/libcloud/compute/types.py
index 658907e..646725d 100644
--- a/libcloud/compute/types.py
+++ b/libcloud/compute/types.py
@@ -280,6 +280,7 @@ class NodeState(Type):
     PAUSED = 'paused'
     RECONFIGURING = 'reconfiguring'
     MIGRATING = 'migrating'
+    NORMAL = 'normal'
 
 
 class StorageVolumeState(Type):


[05/11] libcloud git commit: Deploy server uncustomized

Posted by an...@apache.org.
Deploy server uncustomized


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

Branch: refs/heads/trunk
Commit: 9d631881d997a40c62f15e347d8fe9b25cd881f8
Parents: a094ac7
Author: Samuel Chong <sa...@gmail.com>
Authored: Tue Dec 20 16:35:49 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 307 ++++++++++++++++++++++++-
 1 file changed, 302 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/9d631881/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index be471f0..8dbcb14 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -57,6 +57,7 @@ from libcloud.utils.py3 import urlencode, ensure_string
 from libcloud.utils.xml import fixxpath, findtext, findall
 from libcloud.utils.py3 import basestring
 from libcloud.compute.types import NodeState, Provider
+import sys
 
 # Node state map is a dictionary with the keys as tuples
 # These tuples represent:
@@ -1838,10 +1839,10 @@ class DimensionDataNodeDriver(NodeDriver):
         response_code = findtext(result, 'responseCode', TYPES_URN)
         return response_code in ['IN_PROGRESS', 'OK']
 
-    def ex_get_node_by_id(self, id):
+    def ex_get_node_by_id(self, id, os_customization=True):
         node = self.connection.request_with_orgId_api_2(
             'server/server/%s' % id).object
-        return self._to_node(node)
+        return self._to_node(node, os_customization)
 
     def ex_list_firewall_rules(self, network_domain, page_size=50,
                                page_number=1):
@@ -3804,6 +3805,297 @@ class DimensionDataNodeDriver(NodeDriver):
         response_code = findtext(response, 'responseCode', TYPES_URN)
         return response_code in ['IN_PROGRESS', 'OK']
 
+    def ex_create_node_uncustomized(self,
+                                    name,
+                                    image,
+                                    ex_network_domain,
+                                    ex_is_started=True,
+                                    ex_description=None,
+                                    ex_cluster_id=None,
+                                    ex_cpu_specification=None,
+                                    ex_memory_gb=None,
+                                    ex_primary_nic_private_ipv4=None,
+                                    ex_primary_nic_vlan=None,
+                                    ex_primary_nic_network_adapter=None,
+                                    ex_additional_nics=None,
+                                    ex_disks=None,
+                                    ex_tagid_value_pairs=None,
+                                    ex_tagname_value_pairs=None
+                                    ):
+
+        """
+        This MCP 2.0 only function deploys a new Cloud Server from a
+        CloudControl compatible Server Image, which does not utilize
+        VMware Guest OS Customization process.
+
+        Create Node in MCP2 Data Center
+
+
+        :keyword    name:   (required) String with a name for this new node
+        :type       name:   ``str``
+
+        :keyword    image:  (UUID of the Server Image being used as the target
+                            for the new Server deployment. The source Server
+                            Image (OS Image or Customer Image) must have
+                            osCustomization set to true. See Get/List OS
+                            Image(s) and Get/List Customer Image(s).
+        :type       image:  :class:`NodeImage` or ``str``
+
+
+        :keyword    ex_network_domain:  (required) Network Domain or Network
+                                        Domain ID to create the node
+        :type       ex_network_domain: :class:`DimensionDataNetworkDomain`
+                                        or ``str``
+
+        :keyword    ex_description:  (optional) description for this node
+        :type       ex_description:  ``str``
+
+        :keyword    ex_cluster_id:  (optional) For multiple cluster
+        environments, it is possible to set a destination cluster for the new
+        Customer Image. Note that performance of this function is optimal when
+        either the Server cluster and destination are the same or when shared
+        data storage is in place for the multiple clusters.
+        :type       ex_cluster_id:  ``str``
+
+
+        :keyword    ex_primary_nic_private_ipv4:  Provide private IPv4. Ignore
+                                                  if ex_primary_nic_vlan is
+                                                  provided. Use one or the
+                                                  other. Not both.
+        :type       ex_primary_nic_private_ipv4: :``str``
+
+        :keyword    ex_primary_nic_vlan:  Provide VLAN for the node if
+                                          ex_primary_nic_private_ipv4 NOT
+                                          provided. One or the other. Not both.
+        :type       ex_primary_nic_vlan: :class: DimensionDataVlan or ``str``
+
+        :keyword    ex_primary_nic_network_adapter: (Optional) Default value
+                                                    for the Operating System
+                                                    will be used if leave
+                                                    empty. Example: "E1000".
+        :type       ex_primary_nic_network_adapter: :``str``
+
+        :keyword    ex_additional_nics: (optional) List
+                                        :class:'DimensionDataNic' or None
+        :type       ex_additional_nics: ``list`` of :class:'DimensionDataNic'
+                                        or ``str``
+
+        :keyword    ex_memory_gb:  (optional) The amount of memory in GB for
+                                   the server Can be used to override the
+                                   memory value inherited from the source
+                                   Server Image.
+        :type       ex_memory_gb: ``int``
+
+        :keyword    ex_cpu_specification: (optional) The spec of CPU to deploy
+        :type       ex_cpu_specification:
+                        :class:`DimensionDataServerCpuSpecification`
+
+        :keyword    ex_is_started: (required) Start server after creation.
+                                   Default is set to true.
+        :type       ex_is_started:  ``bool``
+
+        :keyword    ex_disks: (optional) Dimensiondata disks. Optional disk
+                            elements can be used to define the disk speed
+                            that each disk on the Server; inherited from the
+                            source Server Image will be deployed to. It is
+                            not necessary to include a diskelement for every
+                            disk; only those that you wish to set a disk
+                            speed value for. Note that scsiId 7 cannot be
+                            used.Up to 13 disks can be present in addition to
+                            the required OS disk on SCSI ID 0. Refer to
+                            https://docs.mcp-services.net/x/UwIu for disk
+
+        :type       ex_disks: List or tuple of :class:'DimensionDataServerDisk`
+
+        :keyword    ex_tagid_value_pairs:
+                            (Optional) up to 10 tag elements may be provided.
+                            A combination of tagById and tag name cannot be
+                            supplied in the same request.
+                            Note: ex_tagid_value_pairs and
+                            ex_tagname_value_pairs is
+                            mutually exclusive. Use one or other.
+
+        :type       ex_tagname_value_pairs: ``list`` of dictionary of tag name
+        and value pair. Value can be None.
+
+        :keyword    ex_tagname_value_pairs:
+                            (Optional) up to 10 tag elements may be provided.
+                            A combination of tagById and tag name cannot be
+                            supplied in the same request.
+                            Note: ex_tagid_value_pairs and
+                            ex_tagname_value_pairs is
+                            mutually exclusive. Use one or other.
+
+        :type       ex_tagname_value_pairs: ``list`` of dictionary of tag name
+        and value pair. Value can be None.
+
+        :return: The newly created :class:`Node`.
+        :rtype: :class:`Node`
+        """
+
+        # Unsupported for version lower than 2.4
+        if LooseVersion(self.connection.active_api_version) < LooseVersion(
+                '2.4'):
+            raise Exception("This feature is NOT supported in  "
+                            "earlier api version of 2.4")
+
+        # Default start to true if input is invalid
+        if not isinstance(ex_is_started, bool):
+            ex_is_started = True
+            print("Warning: ex_is_started input value is invalid. Default"
+                  "to True")
+
+        server_elm = ET.Element('deployUncustomizedServer',
+                                {'xmlns': TYPES_URN})
+        ET.SubElement(server_elm, "name").text = name
+        ET.SubElement(server_elm, "description").text = ex_description
+        image_id = self._image_to_image_id(image)
+        ET.SubElement(server_elm, "imageId").text = image_id
+
+        if ex_cluster_id:
+            dns_elm = ET.SubElement(server_elm, "primaryDns")
+            dns_elm.text = ex_cluster_id
+
+        if ex_is_started is not None:
+            ET.SubElement(server_elm, "start").text = str(
+                ex_is_started).lower()
+
+        if ex_cpu_specification is not None:
+            cpu = ET.SubElement(server_elm, "cpu")
+            cpu.set('speed', ex_cpu_specification.performance)
+            cpu.set('count', str(ex_cpu_specification.cpu_count))
+            cpu.set('coresPerSocket',
+                    str(ex_cpu_specification.cores_per_socket))
+
+        if ex_memory_gb is not None:
+            ET.SubElement(server_elm, "memoryGb").text = str(ex_memory_gb)
+
+        if (ex_primary_nic_private_ipv4 is None and
+                ex_primary_nic_vlan is None):
+            raise ValueError("Missing argument. Either "
+                             "ex_primary_nic_private_ipv4 or "
+                             "ex_primary_nic_vlan "
+                             "must be specified.")
+
+        if (ex_primary_nic_private_ipv4 is not None and
+                ex_primary_nic_vlan is not None):
+            raise ValueError("Either ex_primary_nic_private_ipv4 or "
+                             "ex_primary_nic_vlan "
+                             "be specified. Not both.")
+
+        network_elm = ET.SubElement(server_elm, "networkInfo")
+
+        net_domain_id = self._network_domain_to_network_domain_id(
+            ex_network_domain)
+        network_elm.set('networkDomainId', net_domain_id)
+
+        pri_nic = ET.SubElement(network_elm, 'primaryNic')
+
+        if ex_primary_nic_private_ipv4 is not None:
+            ET.SubElement(pri_nic,
+                          'privateIpv4').text = ex_primary_nic_private_ipv4
+
+        if ex_primary_nic_vlan is not None:
+            vlan_id = self._vlan_to_vlan_id(ex_primary_nic_vlan)
+            ET.SubElement(pri_nic, 'vlanId').text = vlan_id
+
+        if ex_primary_nic_network_adapter is not None:
+            ET.SubElement(pri_nic,
+                          "networkAdapter").text = \
+                ex_primary_nic_network_adapter
+
+        if isinstance(ex_additional_nics, (list, tuple)):
+            for nic in ex_additional_nics:
+                additional_nic = ET.SubElement(network_elm,
+                                               'additionalNic')
+
+                if (nic.private_ip_v4 is None and
+                        nic.vlan is None):
+                    raise ValueError("Either a vlan or private_ip_v4 "
+                                     "must be specified for each "
+                                     "additional nic.")
+
+                if (nic.private_ip_v4 is not None and
+                        nic.vlan is not None):
+                    raise ValueError("Either a vlan or private_ip_v4 "
+                                     "must be specified for each "
+                                     "additional nic. Not both.")
+
+                if nic.private_ip_v4 is not None:
+                    ET.SubElement(additional_nic,
+                                  'privateIpv4').text = nic.private_ip_v4
+
+                if nic.vlan is not None:
+                    vlan_id = self._vlan_to_vlan_id(nic.vlan)
+                    ET.SubElement(additional_nic, 'vlanId').text = vlan_id
+
+                if nic.network_adapter_name is not None:
+                    ET.SubElement(additional_nic,
+                                  "networkAdapter").text = \
+                        nic.network_adapter_name
+        elif ex_additional_nics is not None:
+            raise TypeError(
+                "ex_additional_NICs must be None or tuple/list")
+
+        if isinstance(ex_disks, (list, tuple)):
+            for disk in ex_disks:
+                disk_elm = ET.SubElement(server_elm, 'disk')
+                disk_elm.set('scsiId', disk.scsi_id)
+                disk_elm.set('speed', disk.speed)
+        elif ex_disks is not None:
+            raise TypeError("ex_disks must be None or tuple/list")
+
+        # tagid and tagname value pair should not co-exists
+        if ex_tagid_value_pairs is not None and ex_tagname_value_pairs is \
+                not None:
+            raise ValueError("ex_tagid_value_pairs and ex_tagname_value_pairs"
+                             "is mutually exclusive. Use one or the other.")
+
+        # Tag by ID
+        if ex_tagid_value_pairs is not None:
+            if not isinstance(ex_tagid_value_pairs, (list, tuple)):
+                raise ValueError(
+                    "ex_tagid_value_pairs should be a list of tag ID and "
+                    "value dictionary."
+                )
+
+            tag_elem = ET.SubElement(server_elm, 'tagById')
+
+            for k, v in ex_tagid_value_pairs.items():
+                ET.SubElement(tag_elem, 'tagKeyId').text = k
+
+                if v is not None:
+                    ET.SubElement(tag_elem, 'value').text = v
+
+        if ex_tagname_value_pairs is not None:
+            if not isinstance(ex_tagname_value_pairs, (list, tuple)):
+                raise ValueError(
+                    "ex_tagname_value_pairs should be a list of tag ID and "
+                    "value dictionary."
+                )
+
+            tag_elem = ET.SubElement(server_elm, 'tag')
+
+            for k, v in ex_tagid_value_pairs.items():
+                ET.SubElement(tag_elem, 'tagKeyName').text = k
+
+                if v is not None:
+                    ET.SubElement(tag_elem, 'value').text = v
+
+        response = self.connection.request_with_orgId_api_2(
+            'server/deployUncustomizedServer',
+            method='POST',
+            data=ET.tostring(server_elm)).object
+
+        node_id = None
+        for info in findall(response, 'info', TYPES_URN):
+            if info.get('name') == 'serverId':
+                node_id = info.get('value')
+
+        new_node = self.ex_get_node_by_id(node_id, os_customization=False)
+
+        return new_node
+
     def _format_csv(self, http_response):
         text = http_response.read()
         lines = str.splitlines(ensure_string(text))
@@ -4158,7 +4450,7 @@ class DimensionDataNodeDriver(NodeDriver):
         node_elements = object.findall(fixxpath('server', TYPES_URN))
         return [self._to_node(el) for el in node_elements]
 
-    def _to_node(self, element):
+    def _to_node(self, element, os_customization=True):
         started = findtext(element, 'started', TYPES_URN)
         status = self._to_status(element.find(fixxpath('progress', TYPES_URN)))
         dd_state = findtext(element, 'state', TYPES_URN)
@@ -4170,6 +4462,9 @@ class DimensionDataNodeDriver(NodeDriver):
         cpu_spec = self._to_cpu_spec(element.find(fixxpath('cpu', TYPES_URN)))
         disks = self._to_disks(element)
 
+        # Vmware Tools
+        vmware_tools = None
+
         # Version 2.3 or earlier
         if LooseVersion(self.connection.active_api_version) < LooseVersion(
                 '2.4'):
@@ -4177,9 +4472,11 @@ class DimensionDataNodeDriver(NodeDriver):
                 element.find(fixxpath('vmwareTools', TYPES_URN)))
             operation_system = element.find(fixxpath(
                 'operatingSystem', TYPES_URN))
+        # Version 2.4 or later
         else:
-            vmware_tools = self._to_vmware_tools(
-                element.find(fixxpath('guest/vmTools', TYPES_URN)))
+            if os_customization:
+                vmware_tools = self._to_vmware_tools(
+                    element.find(fixxpath('guest/vmTools', TYPES_URN)))
 
             operation_system = element.find(fixxpath(
                 'guest/operatingSystem', TYPES_URN))


[06/11] libcloud git commit: Validate create_node method ex_is_started parameter. Set to False by default

Posted by an...@apache.org.
Validate create_node method ex_is_started parameter. Set to False by default


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

Branch: refs/heads/trunk
Commit: 6a4ab59f7eee3768ad3c9fed94b071016e5a2625
Parents: f011a2a
Author: Samuel Chong <sa...@gmail.com>
Authored: Fri Dec 16 11:01:29 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/6a4ab59f/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index bf532f9..499f569 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -481,6 +481,10 @@ class DimensionDataNodeDriver(NodeDriver):
                              'ex_network_domain '
                              'for MCP2 or ex_network for legacy MCP1')
 
+        # Set ex_is_started to False by default if none bool data type provided
+        if not isinstance(ex_is_started, bool):
+            ex_is_started = True
+
         # Handle MCP1 legacy
         if 'ex_network' in kwargs:
             new_node = self._create_node_mcp1(


[03/11] libcloud git commit: Fix deserialization method to take vmtools element that doesn't has running status and version status attributes

Posted by an...@apache.org.
Fix deserialization method to take vmtools element that doesn't has running status and version status attributes


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

Branch: refs/heads/trunk
Commit: 80ff417256dc254e43e7d8d153c4c2a0905805e0
Parents: 9d63188
Author: Samuel Chong <sa...@gmail.com>
Authored: Wed Dec 21 12:05:46 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 33 +++++++++++++++++---------
 1 file changed, 22 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/80ff4172/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 8dbcb14..ec30bc1 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -1839,10 +1839,10 @@ class DimensionDataNodeDriver(NodeDriver):
         response_code = findtext(result, 'responseCode', TYPES_URN)
         return response_code in ['IN_PROGRESS', 'OK']
 
-    def ex_get_node_by_id(self, id, os_customization=True):
+    def ex_get_node_by_id(self, id):
         node = self.connection.request_with_orgId_api_2(
             'server/server/%s' % id).object
-        return self._to_node(node, os_customization)
+        return self._to_node(node)
 
     def ex_list_firewall_rules(self, network_domain, page_size=50,
                                page_number=1):
@@ -4092,7 +4092,7 @@ class DimensionDataNodeDriver(NodeDriver):
             if info.get('name') == 'serverId':
                 node_id = info.get('value')
 
-        new_node = self.ex_get_node_by_id(node_id, os_customization=False)
+        new_node = self.ex_get_node_by_id(node_id)
 
         return new_node
 
@@ -4428,10 +4428,22 @@ class DimensionDataNodeDriver(NodeDriver):
             performance=element.get('speed'))
 
     def _to_vmware_tools(self, element):
+        status = None
+        if hasattr(element, 'runningStatus'):
+            status = element.get('runningStatus')
+
+        version_status = None
+        if hasattr(element, 'version_status'):
+            version_status = element.get('version_status')
+
+        api_version = None
+        if hasattr(element, 'apiVersion'):
+            api_version = element.get('apiVersion')
+
         return DimensionDataServerVMWareTools(
-            status=element.get('runningStatus'),
-            version_status=element.get('versionStatus'),
-            api_version=element.get('apiVersion'))
+            status=status,
+            version_status=version_status,
+            api_version=api_version)
 
     def _to_disks(self, object):
         disk_elements = object.findall(fixxpath('disk', TYPES_URN))
@@ -4450,7 +4462,7 @@ class DimensionDataNodeDriver(NodeDriver):
         node_elements = object.findall(fixxpath('server', TYPES_URN))
         return [self._to_node(el) for el in node_elements]
 
-    def _to_node(self, element, os_customization=True):
+    def _to_node(self, element):
         started = findtext(element, 'started', TYPES_URN)
         status = self._to_status(element.find(fixxpath('progress', TYPES_URN)))
         dd_state = findtext(element, 'state', TYPES_URN)
@@ -4463,7 +4475,6 @@ class DimensionDataNodeDriver(NodeDriver):
         disks = self._to_disks(element)
 
         # Vmware Tools
-        vmware_tools = None
 
         # Version 2.3 or earlier
         if LooseVersion(self.connection.active_api_version) < LooseVersion(
@@ -4474,9 +4485,9 @@ class DimensionDataNodeDriver(NodeDriver):
                 'operatingSystem', TYPES_URN))
         # Version 2.4 or later
         else:
-            if os_customization:
-                vmware_tools = self._to_vmware_tools(
-                    element.find(fixxpath('guest/vmTools', TYPES_URN)))
+            vmtools_elm = fixxpath('guest/vmTools', TYPES_URN)
+            if vmtools_elm is not None:
+                vmware_tools = self._to_vmware_tools(vmtools_elm)
 
             operation_system = element.find(fixxpath(
                 'guest/operatingSystem', TYPES_URN))


[02/11] libcloud git commit: Fix tags for deploy uncustomised image

Posted by an...@apache.org.
Fix tags for deploy uncustomised image


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

Branch: refs/heads/trunk
Commit: e91e66c857dccebcc106542a88169f91f27dd9ba
Parents: 80ff417
Author: Samuel Chong <sa...@gmail.com>
Authored: Wed Dec 21 13:27:21 2016 +1100
Committer: Anthony Shaw <an...@apache.org>
Committed: Tue Dec 27 19:22:04 2016 +1100

----------------------------------------------------------------------
 libcloud/compute/drivers/dimensiondata.py | 50 ++++++++++++--------------
 1 file changed, 22 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/e91e66c8/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index ec30bc1..1ce61dc 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -3915,8 +3915,7 @@ class DimensionDataNodeDriver(NodeDriver):
                             ex_tagname_value_pairs is
                             mutually exclusive. Use one or other.
 
-        :type       ex_tagname_value_pairs: ``list`` of dictionary of tag name
-        and value pair. Value can be None.
+        :type       ex_tagname_value_pairs: ``dict``.  Value can be None.
 
         :keyword    ex_tagname_value_pairs:
                             (Optional) up to 10 tag elements may be provided.
@@ -3926,8 +3925,7 @@ class DimensionDataNodeDriver(NodeDriver):
                             ex_tagname_value_pairs is
                             mutually exclusive. Use one or other.
 
-        :type       ex_tagname_value_pairs: ``list`` of dictionary of tag name
-        and value pair. Value can be None.
+        :type       ex_tagname_value_pairs: ``dict```.
 
         :return: The newly created :class:`Node`.
         :rtype: :class:`Node`
@@ -3945,30 +3943,30 @@ class DimensionDataNodeDriver(NodeDriver):
             print("Warning: ex_is_started input value is invalid. Default"
                   "to True")
 
-        server_elm = ET.Element('deployUncustomizedServer',
+        server_uncustomized_elm = ET.Element('deployUncustomizedServer',
                                 {'xmlns': TYPES_URN})
-        ET.SubElement(server_elm, "name").text = name
-        ET.SubElement(server_elm, "description").text = ex_description
+        ET.SubElement(server_uncustomized_elm, "name").text = name
+        ET.SubElement(server_uncustomized_elm, "description").text = ex_description
         image_id = self._image_to_image_id(image)
-        ET.SubElement(server_elm, "imageId").text = image_id
+        ET.SubElement(server_uncustomized_elm, "imageId").text = image_id
 
         if ex_cluster_id:
-            dns_elm = ET.SubElement(server_elm, "primaryDns")
+            dns_elm = ET.SubElement(server_uncustomized_elm, "primaryDns")
             dns_elm.text = ex_cluster_id
 
         if ex_is_started is not None:
-            ET.SubElement(server_elm, "start").text = str(
+            ET.SubElement(server_uncustomized_elm, "start").text = str(
                 ex_is_started).lower()
 
         if ex_cpu_specification is not None:
-            cpu = ET.SubElement(server_elm, "cpu")
+            cpu = ET.SubElement(server_uncustomized_elm, "cpu")
             cpu.set('speed', ex_cpu_specification.performance)
             cpu.set('count', str(ex_cpu_specification.cpu_count))
             cpu.set('coresPerSocket',
                     str(ex_cpu_specification.cores_per_socket))
 
         if ex_memory_gb is not None:
-            ET.SubElement(server_elm, "memoryGb").text = str(ex_memory_gb)
+            ET.SubElement(server_uncustomized_elm, "memoryGb").text = str(ex_memory_gb)
 
         if (ex_primary_nic_private_ipv4 is None and
                 ex_primary_nic_vlan is None):
@@ -3983,7 +3981,7 @@ class DimensionDataNodeDriver(NodeDriver):
                              "ex_primary_nic_vlan "
                              "be specified. Not both.")
 
-        network_elm = ET.SubElement(server_elm, "networkInfo")
+        network_elm = ET.SubElement(server_uncustomized_elm, "networkInfo")
 
         net_domain_id = self._network_domain_to_network_domain_id(
             ex_network_domain)
@@ -4039,7 +4037,7 @@ class DimensionDataNodeDriver(NodeDriver):
 
         if isinstance(ex_disks, (list, tuple)):
             for disk in ex_disks:
-                disk_elm = ET.SubElement(server_elm, 'disk')
+                disk_elm = ET.SubElement(server_uncustomized_elm, 'disk')
                 disk_elm.set('scsiId', disk.scsi_id)
                 disk_elm.set('speed', disk.speed)
         elif ex_disks is not None:
@@ -4053,39 +4051,35 @@ class DimensionDataNodeDriver(NodeDriver):
 
         # Tag by ID
         if ex_tagid_value_pairs is not None:
-            if not isinstance(ex_tagid_value_pairs, (list, tuple)):
+            if not isinstance(ex_tagid_value_pairs, dict):
                 raise ValueError(
-                    "ex_tagid_value_pairs should be a list of tag ID and "
-                    "value dictionary."
+                    "ex_tagid_value_pairs must be a dictionary."
                 )
 
-            tag_elem = ET.SubElement(server_elm, 'tagById')
-
             for k, v in ex_tagid_value_pairs.items():
+                tag_elem = ET.SubElement(server_uncustomized_elm, 'tagById')
                 ET.SubElement(tag_elem, 'tagKeyId').text = k
 
                 if v is not None:
                     ET.SubElement(tag_elem, 'value').text = v
 
         if ex_tagname_value_pairs is not None:
-            if not isinstance(ex_tagname_value_pairs, (list, tuple)):
+            if not isinstance(ex_tagname_value_pairs, dict):
                 raise ValueError(
-                    "ex_tagname_value_pairs should be a list of tag ID and "
-                    "value dictionary."
+                    "ex_tagname_value_pairs must be a dictionary"
                 )
 
-            tag_elem = ET.SubElement(server_elm, 'tag')
-
-            for k, v in ex_tagid_value_pairs.items():
-                ET.SubElement(tag_elem, 'tagKeyName').text = k
+            for k, v in ex_tagname_value_pairs.items():
+                tag_name_elem = ET.SubElement(server_uncustomized_elm, 'tag')
+                ET.SubElement(tag_name_elem, 'tagKeyName').text = k
 
                 if v is not None:
-                    ET.SubElement(tag_elem, 'value').text = v
+                    ET.SubElement(tag_name_elem, 'value').text = v
 
         response = self.connection.request_with_orgId_api_2(
             'server/deployUncustomizedServer',
             method='POST',
-            data=ET.tostring(server_elm)).object
+            data=ET.tostring(server_uncustomized_elm)).object
 
         node_id = None
         for info in findall(response, 'info', TYPES_URN):