Refactored to make some things more DRY. Formatted for PEP8 and libcloud style 
guides. Updated tests to use libcloud Node objects


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

Branch: refs/heads/trunk
Commit: 086ad185bbb508bd9ce8df60c2b2c66b021ce716
Parents: 656d43e
Author: Michael Bennett <[email protected]>
Authored: Sun Nov 23 10:18:50 2014 -0500
Committer: Michael Bennett <[email protected]>
Committed: Sun Nov 23 10:18:50 2014 -0500

----------------------------------------------------------------------
 libcloud/compute/drivers/azure.py   | 631 +++++++++++++++++++------------
 libcloud/test/compute/test_azure.py | 100 ++++-
 2 files changed, 466 insertions(+), 265 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/086ad185/libcloud/compute/drivers/azure.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/azure.py 
b/libcloud/compute/drivers/azure.py
index 25e8e54..9804814 100644
--- a/libcloud/compute/drivers/azure.py
+++ b/libcloud/compute/drivers/azure.py
@@ -27,7 +27,8 @@ import base64
 
 from libcloud.utils.py3 import urlquote as url_quote
 from libcloud.utils.py3 import urlunquote as url_unquote
-from libcloud.common.azure import AzureServiceManagementConnection, 
AzureRedirectException
+from libcloud.common.azure import (AzureServiceManagementConnection,
+                                   AzureRedirectException)
 from libcloud.compute.providers import Provider
 from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize
 from libcloud.compute.base import NodeImage, StorageVolume
@@ -64,7 +65,7 @@ _USER_AGENT_STRING = 'libcloudazurecompute/' + __version__
 X_MS_VERSION = '2013-08-01'
 
 """
-Sizes must be hardcoded because Microsoft doesn't provide an API to fetch them.
+Sizes must be hardcoded because Microsoft doesn't provide an API to fetch them
 From http://msdn.microsoft.com/en-us/library/windowsazure/dn197896.aspx
 """
 AZURE_COMPUTE_INSTANCE_TYPES = {
@@ -181,7 +182,10 @@ class AzureNodeDriver(NodeDriver):
     _instance_types = AZURE_COMPUTE_INSTANCE_TYPES
     _blob_url = ".blob.core.windows.net"
     features = {'create_node': ['password']}
-    service_location = collections.namedtuple('service_location', 
['is_affinity_group', 'service_location'])
+    service_location = collections.namedtuple(
+        'service_location',
+        ['is_affinity_group', 'service_location']
+    )
 
     NODE_STATE_MAP = {
         'RoleStateUnknown': NodeState.UNKNOWN,
@@ -240,13 +244,20 @@ class AzureNodeDriver(NodeDriver):
         """        
         data = self._perform_get(self._get_image_path(), Images)
 
-        custom_image_data = self._perform_get(self._get_vmimage_path(), 
VMImages)
+        custom_image_data = self._perform_get(
+            self._get_vmimage_path(),
+            VMImages
+        )
 
         images = [self._to_image(i) for i in data]
         images.extend(self._vm_to_image(j) for j in custom_image_data)
 
         if location is not None:
-            images = [image for image in images if location in 
image.extra["location"]]
+            images = [
+                image
+                for image in images
+                if location in image.extra["location"]
+            ]
 
         return images
 
@@ -256,7 +267,10 @@ class AzureNodeDriver(NodeDriver):
 
         :rtype: ``list`` of :class:`NodeLocation`
         """
-        data = self._perform_get('/' + self.subscription_id + '/locations', 
Locations)
+        data = self._perform_get(
+            '/' + self.subscription_id + '/locations',
+            Locations
+        )
 
         return [self._to_location(l) for l in data]
 
@@ -283,18 +297,14 @@ class AzureNodeDriver(NodeDriver):
             None
         )
 
-        if response.status != 200:
-            raise LibcloudError(
-                'Message: %s, Body: %s, Status code: %d' %
-                (response.error, response.body, response.status),
-                driver=self
-            )
+        self.raise_for_response(response, 200)
 
         data = self._parse_response(response, HostedService)
 
         vips = None
 
-        if len(data.deployments) > 0 and data.deployments[0].virtual_ips is 
not None:
+        if (len(data.deployments) > 0 and
+                data.deployments[0].virtual_ips is not None):
             vips = [vip.address for vip in data.deployments[0].virtual_ips]
 
         try:
@@ -326,10 +336,14 @@ class AzureNodeDriver(NodeDriver):
 
         :rtype: ``bool``
         """
-        if not node:
+        if node is None:
             raise ValueError("node is required.")
 
-        ex_cloud_service_name = ex_cloud_service_name or (node.extra and 
node.extra.get('ex_cloud_service_name'))
+        if ex_cloud_service_name is None:
+            if node.extra is not None:
+                ex_cloud_service_name = node.extra.get(
+                    'ex_cloud_service_name'
+                )
 
         if not ex_cloud_service_name:
             raise ValueError("ex_cloud_service_name is required.")
@@ -351,12 +365,7 @@ class AzureNodeDriver(NodeDriver):
                 ''
             )
 
-            if response.status != 202:
-                raise LibcloudError(
-                    'Message: %s, Body: %s, Status code: %d' %
-                    (response.error, response.body, response.status),
-                    driver=self
-                )
+            self.raise_for_response(response, 202)
 
             if self._parse_response_for_async_op(response):
                 return True
@@ -380,7 +389,17 @@ class AzureNodeDriver(NodeDriver):
         volumes = [self._to_volume(volume=v, node=node) for v in data]
         return volumes
 
-    def create_node(self, ex_cloud_service_name=None, **kwargs):
+    def create_node(self,
+                    name,
+                    image,
+                    size,
+                    ex_cloud_service_name,
+                    ex_storage_service_name=None,
+                    ex_new_deployment=False,
+                    ex_deployment_slot="Production",
+                    ex_admin_user_id="azureuser",
+                    auth=None,
+                    **kwargs):
         """Create Azure Virtual Machine
 
            Reference: http://bit.ly/1fIsCb7
@@ -437,52 +456,31 @@ class AzureNodeDriver(NodeDriver):
 
         """
 
-        auth = self._get_and_check_auth(kwargs["auth"])        
+        auth = self._get_and_check_auth(auth)
         password = auth.password
 
-        if not ex_cloud_service_name:
-            raise ValueError("ex_cloud_service_name is required.")
-
-        ex_new_deployment = kwargs.get("ex_new_deployment", False)
-
-        if "ex_deployment_slot" in kwargs:
-            ex_deployment_slot = kwargs['ex_deployment_slot']
-        else:
-            # We assume production if this is not provided.
-            ex_deployment_slot = "Production"
-
-        if "ex_admin_user_id" in kwargs:
-            ex_admin_user_id = kwargs['ex_admin_user_id']
-        else:
-            # This mimics the Azure UI behavior.
-            ex_admin_user_id = "azureuser"
-
-        if "size" not in kwargs:
-            raise ValueError("size is required. ")
-
-        if not isinstance(kwargs['size'], NodeSize):
+        if not isinstance(size, NodeSize):
             raise ValueError('Size must be an instance of NodeSize')
 
-        if "image" not in kwargs:
-            raise ValueError("image is required.")
-
-        if "name" not in kwargs:
-            raise ValueError("name is required.")
-
-        name = kwargs['name']
-        size = kwargs['size']
-        image = kwargs['image']
-
         if not isinstance(image, NodeImage):
-            raise ValueError("Image must be an instance of NodeImage, produced 
by list_images()")
+            raise ValueError(
+                "Image must be an instance of NodeImage, "
+                "produced by list_images()"
+            )
+
+        node_list = self.list_nodes(
+            ex_cloud_service_name=ex_cloud_service_name
+        )
 
-        node_list = 
self.list_nodes(ex_cloud_service_name=ex_cloud_service_name)
         network_config = ConfigurationSet()
         network_config.configuration_set_type = 'NetworkConfiguration'
 
         # We do this because we need to pass a Configuration to the
         # method. This will be either Linux or Windows.
-        windows_server_regex = 
re.compile(r'Win|SQL|SharePoint|Visual|Dynamics|DynGP|BizTalk')
+        windows_server_regex = re.compile(
+            r'Win|SQL|SharePoint|Visual|Dynamics|DynGP|BizTalk'
+        )
+
         if windows_server_regex.search(image.id, re.I):
             machine_config = WindowsConfigurationSet(
                 computer_name=name,
@@ -502,7 +500,10 @@ class AzureNodeDriver(NodeDriver):
                 )
 
                 for instances in endpoints.role_instance_list:
-                    ports = [ep.public_port for ep in 
instances.instance_endpoints]
+                    ports = [
+                        ep.public_port
+                        for ep in instances.instance_endpoints
+                    ]
 
                     while port in ports:
                         port = random.randint(41952, 65535)
@@ -555,9 +556,7 @@ class AzureNodeDriver(NodeDriver):
             service_name=ex_cloud_service_name
         )
 
-        if "ex_storage_service_name" in kwargs:
-            ex_storage_service_name = kwargs['ex_storage_service_name']
-        else:
+        if ex_storage_service_name is None:
             ex_storage_service_name = ex_cloud_service_name
             ex_storage_service_name = re.sub(
                 ur'[\W_]+',
@@ -596,7 +595,9 @@ class AzureNodeDriver(NodeDriver):
                 vm_image_id = image.id
                 #network_config = None
             else:
-                blob_url = "http://"; + ex_storage_service_name + 
".blob.core.windows.net"
+                blob_url = "http://{0}.blob.core.windows.net".format(
+                    ex_storage_service_name
+                )
 
                 # Azure's pattern in the UI.
                 disk_name = "{0}-{1}-{2}.vhd".format(
@@ -605,7 +606,7 @@ class AzureNodeDriver(NodeDriver):
                     time.strftime("%Y-%m-%d")
                 )
 
-                media_link = blob_url + "/vhds/" + disk_name
+                media_link = "{0}/vhds/{1}".format(blob_url, disk_name)
 
                 disk_config = OSVirtualHardDisk(image.id, media_link)
 
@@ -627,14 +628,7 @@ class AzureNodeDriver(NodeDriver):
                     vm_image_id
                 )
             )
-
-            if response.status != 202:
-                raise LibcloudError(
-                    'Message: %s, Body: %s, Status code: %d' %
-                    (response.error, response.body, response.status),
-                    driver=self
-                )
-
+            self.raise_for_response(response, 202)
             self._ex_complete_async_azure_operation(response)
         else:
             _deployment_name = self._get_deployment(
@@ -649,13 +643,15 @@ class AzureNodeDriver(NodeDriver):
                 vm_image_id = image.id
                 #network_config = None
             else:
-                blob_url = "http://"; + ex_storage_service_name + 
".blob.core.windows.net"
+                blob_url = "http://{0}.blob.core.windows.net".format(
+                    ex_storage_service_name
+                )
                 disk_name = "{0}-{1}-{2}.vhd".format(
                     ex_cloud_service_name,
                     name,
                     time.strftime("%Y-%m-%d")
                 )
-                media_link = blob_url + "/vhds/" + disk_name
+                media_link = "{0}/vhds/{1}".format(blob_url, disk_name)
                 disk_config = OSVirtualHardDisk(image.id, media_link)
 
             response = self._perform_post(
@@ -676,12 +672,7 @@ class AzureNodeDriver(NodeDriver):
                 )
             )
 
-            if response.status != 202:
-                raise LibcloudError(
-                    'Message: %s, Body: %s, Status code: %d' %
-                    (response.error, response.body, response.status),
-                    driver=self.connection.driver
-                )
+            self.raise_for_response(response, 202)
 
             self._ex_complete_async_azure_operation(response)
 
@@ -698,9 +689,9 @@ class AzureNodeDriver(NodeDriver):
         )
 
     def destroy_node(self,
-                     node=None,
+                     node,
                      ex_cloud_service_name=None,
-                     ex_deployment_slot=None):
+                     ex_deployment_slot="Production"):
         """Remove Azure Virtual Machine
 
         This removes the instance, but does not 
@@ -718,16 +709,14 @@ class AzureNodeDriver(NodeDriver):
         :type        ex_deployment_slot:  ``str``
         """
 
-        if not node:
-            raise ValueError("node is required.")
+        if not isinstance(node, Node):
+            raise ValueError("A libcloud Node object is required.")
 
-        ex_cloud_service_name = ex_cloud_service_name or (node.extra and 
node.extra.get('ex_cloud_service_name'))
+        if ex_cloud_service_name is None and node.extra is not None:
+            ex_cloud_service_name = node.extra.get('ex_cloud_service_name')
 
         if not ex_cloud_service_name:
-            raise ValueError("ex_cloud_service_name is required.")
-
-        if not ex_deployment_slot:
-            ex_deployment_slot = "production"
+            raise ValueError("Unable to get ex_cloud_service_name from Node.")
 
         _deployment = self._get_deployment(
             service_name=ex_cloud_service_name,
@@ -757,8 +746,8 @@ class AzureNodeDriver(NodeDriver):
         return True
 
     def create_cloud_service(self,
-                             ex_cloud_service_name=None,
-                             location=None,
+                             ex_cloud_service_name,
+                             location,
                              description=None,
                              extended_properties=None):
         """
@@ -778,11 +767,6 @@ class AzureNodeDriver(NodeDriver):
 
         :rtype: ``bool``
         """
-        if not ex_cloud_service_name:
-            raise ValueError("ex_cloud_service_name is required.")
-
-        if not location:
-            raise ValueError("location is required.")
 
         response = self._perform_cloud_service_create(
             self._get_hosted_service_path(),
@@ -796,16 +780,11 @@ class AzureNodeDriver(NodeDriver):
             )
         )
 
-        if response.status != 201:
-            raise LibcloudError(
-                'Message: %s, Body: %s, Status code: %d'
-                % (response.error, response.body, response.status),
-                driver=self
-            )
+        self.raise_for_response(response, 201)
 
         return True
 
-    def destroy_cloud_service(self, ex_cloud_service_name=None):
+    def destroy_cloud_service(self, ex_cloud_service_name):
 
         """
         deletes an azure cloud service.
@@ -816,20 +795,12 @@ class AzureNodeDriver(NodeDriver):
         :rtype: ``bool``
         """
 
-        if not ex_cloud_service_name:
-            raise ValueError("ex_cloud_service_name is required.")
-
         #add check to ensure all nodes have been deleted
         response = self._perform_cloud_service_delete(
             self._get_hosted_service_path(ex_cloud_service_name)
         )
 
-        if response.status != 200:
-            raise LibcloudError(
-                'Message: %s, Body: %s, Status code: %d' %
-                (response.error, response.body, response.status),
-                driver=self
-            )
+        self.raise_for_response(response, 200)
 
         return True
 
@@ -941,7 +912,7 @@ class AzureNodeDriver(NodeDriver):
 
     def _to_location(self, data):
         """
-        Convert the data from a Azure resonse object into a location
+        Convert the data from a Azure response object into a location
         """
         country = data.display_name
 
@@ -960,13 +931,15 @@ class AzureNodeDriver(NodeDriver):
         if "Brazil" in data.display_name:
             country = "Brazil"
 
+        vm_role_sizes = data.compute_capabilities.virtual_machines_role_sizes
+
         return AzureNodeLocation(
             id=data.name,
             name=data.display_name,
             country=country,
             driver=self.connection.driver,
             available_services=data.available_services,
-            
virtual_machine_role_sizes=data.compute_capabilities.virtual_machines_role_sizes
+            virtual_machine_role_sizes=vm_role_sizes
         )
 
     def _to_node_size(self, data):
@@ -1023,49 +996,46 @@ class AzureNodeDriver(NodeDriver):
         )
 
     def _to_volume(self, volume, node):
+        extra = {
+            'affinity_group': volume.affinity_group,
+            'os': volume.os,
+            'location': volume.location,
+            'media_link': volume.media_link,
+            'source_image_name': volume.source_image_name
+        }
+
+        role_name = getattr(volume.attached_to, 'role_name', None)
+        hosted_service_name = getattr(
+            volume.attached_to,
+            'hosted_service_name',
+            None
+        )
 
-        if node: 
-            if hasattr(volume.attached_to, 'role_name'):
-                if volume.attached_to.role_name == node.id:
-                    extra = {'affinity_group': volume.affinity_group}
-
-                    if hasattr(volume.attached_to, 'hosted_service_name'):
-                        extra['hosted_service_name'] = 
volume.attached_to.hosted_service_name
+        deployment_name = getattr(
+            volume.attached_to,
+            'deployment_name',
+            None
+        )
 
-                    if hasattr(volume.attached_to, 'role_name'):
-                        extra['role_name'] = volume.attached_to.role_name
+        if role_name is not None:
+            extra['role_name'] = role_name
 
-                    if hasattr(volume.attached_to, 'deployment_name'):
-                        extra['deployment_name'] = 
volume.attached_to.deployment_name
+        if hosted_service_name is not None:
+            extra['hosted_service_name'] = hosted_service_name
 
-                    extra['os'] = volume.os
-                    extra['location'] = volume.location
-                    extra['media_link'] = volume.media_link
-                    extra['source_image_name'] = volume.source_image_name
+        if deployment_name is not None:
+            extra['deployment_name'] = deployment_name
 
-                    return StorageVolume(
-                        id=volume.name,
-                        name=volume.name,
-                        size=int(volume.logical_disk_size_in_gb),
-                        driver=self.connection.driver,
-                        extra=extra
-                    )
+        if node:
+            if role_name is not None and role_name == node.id:
+                return StorageVolume(
+                    id=volume.name,
+                    name=volume.name,
+                    size=int(volume.logical_disk_size_in_gb),
+                    driver=self.connection.driver,
+                    extra=extra
+                )
         else:
-            extra = {'affinity_group': volume.affinity_group}
-
-            if hasattr(volume.attached_to, 'hosted_service_name'):
-                extra['hosted_service_name'] = 
volume.attached_to.hosted_service_name
-
-            if hasattr(volume.attached_to, 'role_name'):
-                extra['role_name'] = volume.attached_to.role_name
-
-            if hasattr(volume.attached_to, 'deployment_name'):
-                extra['deployment_name'] = volume.attached_to.deployment_name
-            extra['os'] = volume.os
-            extra['location'] = volume.location
-            extra['media_link'] = volume.media_link
-            extra['source_image_name'] = volume.source_image_name
-
             return StorageVolume(
                 id=volume.name,
                 name=volume.name,
@@ -1086,12 +1056,7 @@ class AzureNodeDriver(NodeDriver):
             None
         )
 
-        if response.status != 200:
-            raise LibcloudError(
-                'Message: %s, Body: %s, Status code: %d' %
-                (response.error, response.body, response.status),
-                driver=self.connection.driver
-            )
+        self.raise_for_response(response, 200)
 
         return self._parse_response(response, Deployment)
 
@@ -1101,7 +1066,9 @@ class AzureNodeDriver(NodeDriver):
             raise ValueError("service_name is required.")
 
         res = self._perform_get(
-            self._get_hosted_service_path(service_name) + 
'?embed-detail=False',
+            '{0}?embed-detail=False'.format(
+                self._get_hosted_service_path(service_name)
+            ),
             HostedService
         )
 
@@ -1120,9 +1087,11 @@ class AzureNodeDriver(NodeDriver):
             raise ValueError("service_name is required.")
 
         _check_availability = self._perform_get(
-            self._get_storage_service_path() +
-            '/operations/isavailable/' +
-            _str(service_name) + '',
+            '{0}/operations/isavailable/{1}{2}'.format(
+                self._get_storage_service_path(),
+                _str(service_name),
+                ''
+            ),
             AvailabilityResponse
         )
                 
@@ -1143,12 +1112,7 @@ class AzureNodeDriver(NodeDriver):
                 )
             )
 
-            if response.status != 202:
-                raise LibcloudError(
-                    'Message: %s, Body: %s, Status code: %d' %
-                    (response.error, response.body, response.status),
-                    driver=self.connection.driver
-                )
+            self.raise_for_response(response, 202)
 
         else:
             response = self._perform_post(
@@ -1164,12 +1128,7 @@ class AzureNodeDriver(NodeDriver):
                 )
             )
 
-            if response.status != 202:
-                raise LibcloudError(
-                    'Message: %s, Body: %s, Status code: %d' %
-                    (response.error, response.body, response.status),
-                    driver=self.connection.driver
-                )
+            self.raise_for_response(response, 202)
 
         # We need to wait for this to be created before we can 
         # create the storage container and the instance.
@@ -1192,7 +1151,7 @@ class AzureNodeDriver(NodeDriver):
         request.path, request.query = self._update_request_uri_query(request)
         request.headers = self._update_management_header(request)
         response = self._perform_request(request)
-
+#TODO
         if response_type is not None:
             return self._parse_response(response, response_type)
 
@@ -1219,12 +1178,7 @@ class AzureNodeDriver(NodeDriver):
         request.headers = self._update_management_header(request)
         response = self._perform_request(request)
 
-        if response.status != 202:
-            raise LibcloudError(
-                'Message: %s, Body: %s, Status code: %d' %
-                (response.error, response.body, response.status),
-                driver=self.connection.driver
-            )
+        self.raise_for_response(response, 202)
 
         if async:
             return self._parse_response_for_async_op(response)
@@ -1243,9 +1197,10 @@ class AzureNodeDriver(NodeDriver):
             parsed_url = urlparse.urlparse(e.location)
             request.host = parsed_url.netloc
             return self._perform_request(request)
-        except Exception, e:
-            import traceback
-            print "Exception performing request: 
{}".format(traceback.format_exc())
+        except Exception:
+            print "Exception performing request:\n{0}".format(
+                sys.exc_info()[1]
+            )
 
     def _update_request_uri_query(self, request):
         """
@@ -1271,7 +1226,11 @@ class AzureNodeDriver(NodeDriver):
             request.path += '?'
             for name, value in request.query:
                 if value is not None:
-                    request.path += name + '=' + url_quote(value, '/()$=\',') 
+ '&'
+                    request.path += '{0}={1}{2}'.format(
+                        name,
+                        url_quote(value, '/()$=\','),
+                        '&'
+                    )
             request.path = request.path[:-1]
 
         return request.path, request.query
@@ -1426,7 +1385,10 @@ class AzureNodeDriver(NodeDriver):
         xmlelements = self._get_child_nodes(xmldoc, parent_xml_element_name)
 
         if xmlelements:
-            xmlelements = self._get_child_nodes(xmlelements[0], 
xml_element_name)
+            xmlelements = self._get_child_nodes(
+                xmlelements[0],
+                xml_element_name
+            )
             return [
                 self._get_node_value(xmlelement, element_type)
                 for xmlelement in xmlelements
@@ -1472,7 +1434,10 @@ class AzureNodeDriver(NodeDriver):
         xmlelements = self._get_child_nodes(xmldoc, parent_xml_element_name)
 
         if xmlelements:
-            xmlelements = self._get_child_nodes(xmlelements[0], 
pair_xml_element_name)
+            xmlelements = self._get_child_nodes(
+                xmlelements[0],
+                pair_xml_element_name
+            )
             for pair in xmlelements:
                 keys = self._get_child_nodes(pair, key_xml_element_name)
                 values = self._get_child_nodes(pair, value_xml_element_name)
@@ -1588,8 +1553,11 @@ class AzureNodeDriver(NodeDriver):
 
             for name, value in vars(source).items():
                 if value is not None:
-                    if isinstance(value, list) or isinstance(value, 
WindowsAzureData):
-                        etree.append(self._construct_element_tree(value, 
etree))
+                    if (isinstance(value, list) or
+                            isinstance(value, WindowsAzureData)):
+                        etree.append(
+                            self._construct_element_tree(value, etree)
+                        )
                     else:
                         ele = ET.Element(self._get_serialization_name(name))
                         ele.text = xml_escape(str(value))
@@ -1636,8 +1604,12 @@ class AzureNodeDriver(NodeDriver):
         return self._get_path('services/hostedservices', service_name)
 
     def _get_deployment_path_using_slot(self, service_name, slot=None):
-        return self._get_path('services/hostedservices/' + _str(service_name) +
-                              '/deploymentslots', slot)
+        return self._get_path(
+            'services/hostedservices/{0}/deploymentslots'.format(
+                _str(service_name)
+            ),
+            slot
+        )
 
     def _get_disk_path(self, disk_name=None):
         return self._get_path('services/disks', disk_name)
@@ -1681,6 +1653,17 @@ class AzureNodeDriver(NodeDriver):
                 driver=self.connection.driver
             )
 
+    def raise_for_response(self, response, valid_response):
+        if response.status != valid_response:
+            raise LibcloudError(
+                'Message: {0}, Body: {1}, Status code: {2}'.format(
+                    response.error,
+                    response.body,
+                    response.status
+                ),
+                driver=self
+            )
+
     #def get_connection(self):
     #    certificate_path = "/Users/baldwin/.azure/managementCertificate.pem"
     #    port = HTTPS_PORT
@@ -1991,21 +1974,44 @@ class AzureXmlSerializer(object):
 
     @staticmethod
     def windows_configuration_to_xml(configuration, xml):
-        AzureXmlSerializer.data_to_xml([('ConfigurationSetType', 
configuration.configuration_set_type)], xml)
-        AzureXmlSerializer.data_to_xml([('ComputerName', 
configuration.computer_name)], xml)
-        AzureXmlSerializer.data_to_xml([('AdminPassword', 
configuration.admin_password)], xml)
-
         AzureXmlSerializer.data_to_xml(
-            [('ResetPasswordOnFirstLogon', 
configuration.reset_password_on_first_logon, _lower)],
+            [('ConfigurationSetType', configuration.configuration_set_type)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('ComputerName', configuration.computer_name)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('AdminPassword', configuration.admin_password)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [
+                (
+                    'ResetPasswordOnFirstLogon',
+                    configuration.reset_password_on_first_logon,
+                    _lower
+                )
+            ],
             xml
         )
 
         AzureXmlSerializer.data_to_xml(
-            [('EnableAutomaticUpdates', 
configuration.enable_automatic_updates, _lower)],
+            [
+                (
+                    'EnableAutomaticUpdates',
+                    configuration.enable_automatic_updates,
+                    _lower
+                )
+            ],
             xml
         )
 
-        AzureXmlSerializer.data_to_xml([('TimeZone', 
configuration.time_zone)], xml)
+        AzureXmlSerializer.data_to_xml(
+            [('TimeZone', configuration.time_zone)],
+            xml
+        )
 
         if configuration.domain_join is not None:
             domain = ET.xml("DomainJoin")
@@ -2018,8 +2024,24 @@ class AzureXmlSerializer(object):
                 creds
             )
 
-            AzureXmlSerializer.data_to_xml([('Username', 
configuration.domain_join.credentials.username)], creds)
-            AzureXmlSerializer.data_to_xml([('Password', 
configuration.domain_join.credentials.password)], creds)
+            AzureXmlSerializer.data_to_xml(
+                [
+                    (
+                        'Username',
+                        configuration.domain_join.credentials.username
+                    )
+                ],
+                creds
+            )
+            AzureXmlSerializer.data_to_xml(
+                [
+                    (
+                        'Password',
+                        configuration.domain_join.credentials.password
+                    )
+                ],
+                creds
+            )
 
             AzureXmlSerializer.data_to_xml(
                 [('JoinDomain', configuration.domain_join.join_domain)],
@@ -2027,22 +2049,33 @@ class AzureXmlSerializer(object):
             )
 
             AzureXmlSerializer.data_to_xml(
-                [('MachineObjectOU', 
configuration.domain_join.machine_object_ou)],
+                [
+                    (
+                        'MachineObjectOU',
+                        configuration.domain_join.machine_object_ou
+                    )
+                ],
                 domain
             )
 
         if configuration.stored_certificate_settings is not None:
-            certsettings = ET.Element("StoredCertificateSettings")
-            xml.append(certsettings)
+            cert_settings = ET.Element("StoredCertificateSettings")
+            xml.append(cert_settings)
             for cert in configuration.stored_certificate_settings:
-                certsetting = ET.Element("CertificateSetting")
-                certsettings.append(certsetting)
+                cert_setting = ET.Element("CertificateSetting")
+                cert_settings.append(cert_setting)
 
-                certsetting.append(AzureXmlSerializer.data_to_xml(
+                cert_setting.append(AzureXmlSerializer.data_to_xml(
                     [('StoreLocation', cert.store_location)])
                 )
-                AzureXmlSerializer.data_to_xml([('StoreName', 
cert.store_name)], certsetting)
-                AzureXmlSerializer.data_to_xml([('Thumbprint', 
cert.thumbprint)], certsetting)
+                AzureXmlSerializer.data_to_xml(
+                    [('StoreName', cert.store_name)],
+                    cert_setting
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('Thumbprint', cert.thumbprint)],
+                    cert_setting
+                )
 
         AzureXmlSerializer.data_to_xml(
             [('AdminUsername', configuration.admin_user_name)],
@@ -2052,13 +2085,30 @@ class AzureXmlSerializer(object):
 
     @staticmethod
     def linux_configuration_to_xml(configuration, xml):
-        AzureXmlSerializer.data_to_xml([('ConfigurationSetType', 
configuration.configuration_set_type)], xml)
-        AzureXmlSerializer.data_to_xml([('HostName', 
configuration.host_name)], xml)
-        AzureXmlSerializer.data_to_xml([('UserName', 
configuration.user_name)], xml)
-        AzureXmlSerializer.data_to_xml([('UserPassword', 
configuration.user_password)], xml)
-
         AzureXmlSerializer.data_to_xml(
-            [('DisableSshPasswordAuthentication', 
configuration.disable_ssh_password_authentication, _lower)],
+            [('ConfigurationSetType', configuration.configuration_set_type)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('HostName', configuration.host_name)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('UserName', configuration.user_name)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('UserPassword', configuration.user_password)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [
+                (
+                    'DisableSshPasswordAuthentication',
+                    configuration.disable_ssh_password_authentication,
+                    _lower
+                )
+            ],
             xml
         )
 
@@ -2073,13 +2123,19 @@ class AzureXmlSerializer(object):
             for key in configuration.ssh.public_keys:
                 pkey = ET.Element("PublicKey")
                 pkeys.append(pkey)
-                AzureXmlSerializer.data_to_xml([('Fingerprint', 
key.fingerprint)], pkey)
+                AzureXmlSerializer.data_to_xml(
+                    [('Fingerprint', key.fingerprint)],
+                    pkey
+                )
                 AzureXmlSerializer.data_to_xml([('Path', key.path)], pkey)
 
             for key in configuration.ssh.key_pairs:
                 kpair = ET.Element("KeyPair")
                 kpairs.append(kpair)
-                AzureXmlSerializer.data_to_xml([('Fingerprint', 
key.fingerprint)], kpair)
+                AzureXmlSerializer.data_to_xml(
+                    [('Fingerprint', key.fingerprint)],
+                    kpair
+                )
                 AzureXmlSerializer.data_to_xml([('Path', key.path)], kpair)
 
         return xml
@@ -2099,37 +2155,69 @@ class AzureXmlSerializer(object):
             input_endpoints.append(input_endpoint)
 
             AzureXmlSerializer.data_to_xml(
-                [('LoadBalancedEndpointSetName', 
endpoint.load_balanced_endpoint_set_name)],
+                [
+                    (
+                        'LoadBalancedEndpointSetName',
+                        endpoint.load_balanced_endpoint_set_name
+                    )
+                ],
                 input_endpoint
             )
 
-            AzureXmlSerializer.data_to_xml([('LocalPort', 
endpoint.local_port)], input_endpoint)
-            AzureXmlSerializer.data_to_xml([('Name', endpoint.name)], 
input_endpoint)
-            AzureXmlSerializer.data_to_xml([('Port', endpoint.port)], 
input_endpoint)
+            AzureXmlSerializer.data_to_xml(
+                [('LocalPort', endpoint.local_port)],
+                input_endpoint
+            )
+            AzureXmlSerializer.data_to_xml(
+                [('Name', endpoint.name)],
+                input_endpoint
+            )
+            AzureXmlSerializer.data_to_xml(
+                [('Port', endpoint.port)],
+                input_endpoint
+            )
 
             if (endpoint.load_balancer_probe.path or
-                endpoint.load_balancer_probe.port or
-                endpoint.load_balancer_probe.protocol):
+                    endpoint.load_balancer_probe.port or
+                    endpoint.load_balancer_probe.protocol):
 
                 load_balancer_probe = ET.Element("LoadBalancerProbe")
                 input_endpoint.append(load_balancer_probe)
-                AzureXmlSerializer.data_to_xml([('Path', 
endpoint.load_balancer_probe.path)], load_balancer_probe)
-                AzureXmlSerializer.data_to_xml([('Port', 
endpoint.load_balancer_probe.port)], load_balancer_probe)
+                AzureXmlSerializer.data_to_xml(
+                    [('Path', endpoint.load_balancer_probe.path)],
+                    load_balancer_probe
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('Port', endpoint.load_balancer_probe.port)],
+                    load_balancer_probe
+                )
                 AzureXmlSerializer.data_to_xml(
                     [('Protocol', endpoint.load_balancer_probe.protocol)],
                     load_balancer_probe
                 )
 
-            AzureXmlSerializer.data_to_xml([('Protocol', endpoint.protocol)], 
input_endpoint)
             AzureXmlSerializer.data_to_xml(
-                [('EnableDirectServerReturn', 
endpoint.enable_direct_server_return, _lower)],
+                [('Protocol', endpoint.protocol)],
+                input_endpoint
+            )
+            AzureXmlSerializer.data_to_xml(
+                [
+                    (
+                        'EnableDirectServerReturn',
+                        endpoint.enable_direct_server_return,
+                        _lower
+                    )
+                ],
                 input_endpoint
             )
 
         subnet_names = ET.Element("SubnetNames")
         xml.append(subnet_names)
         for name in configuration.subnet_names:
-            AzureXmlSerializer.data_to_xml([('SubnetName', name)], 
subnet_names)
+            AzureXmlSerializer.data_to_xml(
+                [('SubnetName', name)],
+                subnet_names
+            )
 
         return xml
 
@@ -2176,7 +2264,10 @@ class AzureXmlSerializer(object):
             )
 
         if availability_set_name is not None:
-            AzureXmlSerializer.data_to_xml([('AvailabilitySetName', 
availability_set_name)], xml)
+            AzureXmlSerializer.data_to_xml(
+                [('AvailabilitySetName', availability_set_name)],
+                xml
+            )
 
         if data_virtual_hard_disks is not None:
             vhds = ET.Element("DataVirtualHardDisks")
@@ -2185,24 +2276,59 @@ class AzureXmlSerializer(object):
             for hd in data_virtual_hard_disks:
                 vhd = ET.Element("DataVirtualHardDisk")
                 vhds.append(vhd)
-                AzureXmlSerializer.data_to_xml([('HostCaching', 
hd.host_caching)], vhd)
-                AzureXmlSerializer.data_to_xml([('DiskLabel', hd.disk_label)], 
vhd)
-                AzureXmlSerializer.data_to_xml([('DiskName', hd.disk_name)], 
vhd)
-                AzureXmlSerializer.data_to_xml([('Lun', hd.lun)], vhd)
-                AzureXmlSerializer.data_to_xml([('LogicalDiskSizeInGB', 
hd.logical_disk_size_in_gb)], vhd)
-                AzureXmlSerializer.data_to_xml([('MediaLink', hd.media_link)], 
vhd)
+                AzureXmlSerializer.data_to_xml(
+                    [('HostCaching', hd.host_caching)],
+                    vhd
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('DiskLabel', hd.disk_label)],
+                    vhd
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('DiskName', hd.disk_name)],
+                    vhd
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('Lun', hd.lun)],
+                    vhd
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('LogicalDiskSizeInGB', hd.logical_disk_size_in_gb)],
+                    vhd
+                )
+                AzureXmlSerializer.data_to_xml(
+                    [('MediaLink', hd.media_link)],
+                    vhd
+                )
 
         if os_virtual_hard_disk is not None:
             hd = ET.Element("OSVirtualHardDisk")
             xml.append(hd)
-            AzureXmlSerializer.data_to_xml([('HostCaching', 
os_virtual_hard_disk.host_caching)], hd)
-            AzureXmlSerializer.data_to_xml([('DiskLabel', 
os_virtual_hard_disk.disk_label)], hd)
-            AzureXmlSerializer.data_to_xml([('DiskName', 
os_virtual_hard_disk.disk_name)], hd)
-            AzureXmlSerializer.data_to_xml([('MediaLink', 
os_virtual_hard_disk.media_link)], hd)
-            AzureXmlSerializer.data_to_xml([('SourceImageName', 
os_virtual_hard_disk.source_image_name)], hd)
+            AzureXmlSerializer.data_to_xml(
+                [('HostCaching', os_virtual_hard_disk.host_caching)],
+                hd
+            )
+            AzureXmlSerializer.data_to_xml(
+                [('DiskLabel', os_virtual_hard_disk.disk_label)],
+                hd
+            )
+            AzureXmlSerializer.data_to_xml(
+                [('DiskName', os_virtual_hard_disk.disk_name)],
+                hd
+            )
+            AzureXmlSerializer.data_to_xml(
+                [('MediaLink', os_virtual_hard_disk.media_link)],
+                hd
+            )
+            AzureXmlSerializer.data_to_xml(
+                [('SourceImageName', os_virtual_hard_disk.source_image_name)],
+                hd
+            )
 
         if vm_image_name is not None:
-            xml += AzureXmlSerializer.data_to_xml([('VMImageName', 
vm_image_name)])
+            xml += AzureXmlSerializer.data_to_xml(
+                [('VMImageName', vm_image_name)]
+            )
 
         if role_size is not None:
             AzureXmlSerializer.data_to_xml([('RoleSize', role_size)], xml)
@@ -2265,8 +2391,13 @@ class AzureXmlSerializer(object):
                             target_image_name,
                             target_image_label,
                             provisioning_configuration):
-        xml = AzureXmlSerializer.data_to_xml([('OperationType', 
'CaptureRoleOperation')])
-        AzureXmlSerializer.data_to_xml([('PostCaptureAction', 
post_capture_action)], xml)
+        xml = AzureXmlSerializer.data_to_xml(
+            [('OperationType', 'CaptureRoleOperation')]
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('PostCaptureAction', post_capture_action)],
+            xml
+        )
 
         if provisioning_configuration is not None:
             provisioning_config = ET.Element("ProvisioningConfiguration")
@@ -2283,8 +2414,14 @@ class AzureXmlSerializer(object):
                     provisioning_config
                 )
 
-        AzureXmlSerializer.data_to_xml([('TargetImageLabel', 
target_image_label)], xml)
-        AzureXmlSerializer.data_to_xml([('TargetImageName', 
target_image_name)], xml)
+        AzureXmlSerializer.data_to_xml(
+            [('TargetImageLabel', target_image_label)],
+            xml
+        )
+        AzureXmlSerializer.data_to_xml(
+            [('TargetImageName', target_image_name)],
+            xml
+        )
         doc = AzureXmlSerializer.doc_from_xml('CaptureRoleOperation', xml)
         return ET.tostring(doc, "UTF-8").replace("\n", "")
 
@@ -2305,7 +2442,10 @@ class AzureXmlSerializer(object):
 
         doc = AzureXmlSerializer.doc_from_xml('Deployment')
         AzureXmlSerializer.data_to_xml([('Name', deployment_name)], doc)
-        AzureXmlSerializer.data_to_xml([('DeploymentSlot', deployment_slot)], 
doc)
+        AzureXmlSerializer.data_to_xml(
+            [('DeploymentSlot', deployment_slot)],
+            doc
+        )
         AzureXmlSerializer.data_to_xml([('Label', label)], doc)
 
         role_list = ET.Element("RoleList")
@@ -2521,7 +2661,7 @@ class CertificateSetting(WindowsAzureData):
         Specifies the name of the certificate store from which retrieve
         certificate.
     store_location:
-        Specifies the target certificate store location on the virtual machine.
+        Specifies the target certificate store location on the virtual machine
         The only supported value is LocalMachine.
     """
 
@@ -3041,7 +3181,8 @@ class _dict_of(dict):
 
 class AzureNodeLocation(NodeLocation):
 
-    # we can also have something in here for available services which is an 
extra to the API with Azure
+    # we can also have something in here for available services which is an
+    # extra to the API with Azure
     def __init__(self,
                  id,
                  name,

http://git-wip-us.apache.org/repos/asf/libcloud/blob/086ad185/libcloud/test/compute/test_azure.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_azure.py 
b/libcloud/test/compute/test_azure.py
index 0538604..ae16757 100644
--- a/libcloud/test/compute/test_azure.py
+++ b/libcloud/test/compute/test_azure.py
@@ -15,6 +15,7 @@ import libcloud.security
 
 from libcloud.test import MockHttp
 from libcloud.test.file_fixtures import ComputeFileFixtures
+from libcloud.compute.base import Node, NodeState
 from libcloud.compute.types import Provider
 from libcloud.compute.providers import get_driver
 
@@ -54,7 +55,12 @@ class AzureNodeDriverTests(unittest.TestCase):
             if location.name == 'Southeast Asia'
         )
         services_result = matched_location.available_services
-        services_expected = 
['Compute','Storage','PersistentVMRole','HighMemory']
+        services_expected = [
+            'Compute',
+            'Storage',
+            'PersistentVMRole',
+            'HighMemory'
+        ]
         self.assertListEqual(services_result, services_expected)
 
         vm_role_sizes_result = matched_location.virtual_machine_role_sizes
@@ -112,11 +118,18 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_list_nodes_returned_no_cloud_service(self):
         with self.assertRaises(LibcloudError):
-           self.driver.list_nodes(ex_cloud_service_name="dcoddkinztest04")
+            self.driver.list_nodes(ex_cloud_service_name="dcoddkinztest04")
 
     def test_restart_node_success(self):
 
-        node = type('Node', (object,), dict(id="dc03"))
+        node = Node(
+            id="dc03",
+            name="dc03",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
         result = self.driver.reboot_node(
             node=node,
             ex_cloud_service_name="dcoddkinztest01",
@@ -128,7 +141,14 @@ class AzureNodeDriverTests(unittest.TestCase):
     #simulating attempting to reboot a node that ifas already rebooting
     def test_restart_node_fail_no_deployment(self):
 
-        node = type('Node', (object,), dict(id="dc03"))
+        node = Node(
+            id="dc03",
+            name="dc03",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         with self.assertRaises(LibcloudError):
             self.driver.reboot_node(
@@ -139,7 +159,14 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_restart_node_fail_no_cloud_service(self):
 
-        node = type('Node', (object,), dict(id="dc03"))
+        node = Node(
+            id="dc03",
+            name="dc03",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         with self.assertRaises(LibcloudError):
             self.driver.reboot_node(
@@ -150,7 +177,14 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_restart_node_fail_node_not_found(self):
 
-        node = type('Node', (object,), dict(id="dc13"))
+        node = Node(
+            id="dc13",
+            name="dc13",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         result = self.driver.reboot_node(
             node=node,
@@ -161,7 +195,14 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_destroy_node_success_single_node_in_cloud_service(self):
 
-        node = type('Node', (object,), dict(id="oddkinz1"))
+        node = Node(
+            id="oddkinz1",
+            name="oddkinz1",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         result = self.driver.destroy_node(
             node=node,
@@ -172,7 +213,14 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_destroy_node_success_multiple_nodes_in_cloud_service(self):
 
-        node = type('Node', (object,), dict(id="oddkinz1"))
+        node = Node(
+            id="oddkinz1",
+            name="oddkinz1",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         result = self.driver.destroy_node(
             node=node,
@@ -183,7 +231,14 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_destroy_node_fail_node_does_not_exist(self):
 
-        node = type('Node', (object,), dict(id="oddkinz2"))
+        node = Node(
+            id="oddkinz2",
+            name="oddkinz2",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         with self.assertRaises(LibcloudError):
             self.driver.destroy_node(
@@ -194,8 +249,14 @@ class AzureNodeDriverTests(unittest.TestCase):
 
     def test_destroy_node_success_cloud_service_not_found(self):
 
-        node = dict()
-        node["name"]="cloudredis"
+        node = Node(
+            id="cloudredis",
+            name="cloudredis",
+            state=NodeState.RUNNING,
+            public_ips=[],
+            private_ips=[],
+            driver=self.driver
+        )
 
         with self.assertRaises(LibcloudError):
             self.driver.destroy_node(
@@ -296,7 +357,6 @@ class AzureNodeDriverTests(unittest.TestCase):
         )
         kwargs["name"] = "dcoddkinztest03"
 
-        node = type('Node', (object,), dict(id="dc14"))
         result = self.driver.create_node(
             ex_cloud_service_name="testdcabc2",
             **kwargs
@@ -304,15 +364,15 @@ class AzureNodeDriverTests(unittest.TestCase):
         self.assertIsNotNone(result)
 
     def test_create_node_and_deployment_second_node_307_response(self):
-        kwargs = {}
-
-        kwargs["ex_storage_service_name"]="mtlytics"
-        kwargs["ex_deployment_name"]="dcoddkinztest04"
-        kwargs["ex_deployment_slot"]="Production"
-        kwargs["ex_admin_user_id"]="azurecoder"
+        kwargs = {
+            "ex_storage_service_name": "mtlytics",
+            "ex_deployment_name": "dcoddkinztest04",
+            "ex_deployment_slot": "Production",
+            "ex_admin_user_id": "azurecoder"
+        }
 
         auth = NodeAuthPassword("Pa55w0rd", False)
-        kwargs["auth"]= auth
+        kwargs["auth"] = auth
 
         kwargs["size"] = NodeSize(
             id="ExtraSmall",
@@ -458,7 +518,7 @@ class AzureMockHttp(MockHttp):
         return (httplib.OK, body, headers, httplib.responses[httplib.OK])
 
     def 
_3761b98b_673d_526c_8d55_fee918758e6e_services_hostedservices_testdcabc_deployments(self,
 method, url, body, headers):
-        headers["x-ms-request-id"]="acc33f6756cda6fd96826394fce4c9f3"
+        headers["x-ms-request-id"] = "acc33f6756cda6fd96826394fce4c9f3"
         if method == "GET":
             body = 
self.fixtures.load('_3761b98b_673d_526c_8d55_fee918758e6e_services_hostedservices_testdcabc_deployments.xml')
 

Reply via email to