Просмотр исходного кода

Moved remaining Azure resources to use ID instead of name and replaced all raw responses

Nuwan Goonasekera 8 лет назад
Родитель
Сommit
83b0d3f60b

+ 119 - 66
cloudbridge/cloud/providers/azure/azure_client.py

@@ -19,6 +19,9 @@ log = logging.getLogger(__name__)
 IMAGE_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
                     '{resourceGroupName}/providers/Microsoft.Compute/' \
                     'images/{imageName}'
+NETWORK_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
+                     '{resourceGroupName}/providers/Microsoft.Network' \
+                     '/virtualNetworks/{virtualNetworkName}'
 NETWORK_INTERFACE_RESOURCE_ID = '/subscriptions/{subscriptionId}/' \
                                 'resourceGroups/{resourceGroupName}' \
                                 '/providers/Microsoft.Network/' \
@@ -29,6 +32,10 @@ PUBLIC_IP_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups' \
 SNAPSHOT_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
                        '{resourceGroupName}/providers/Microsoft.Compute/' \
                        'snapshots/{snapshotName}'
+SUBNET_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
+                     '{resourceGroupName}/providers/Microsoft.Network' \
+                     '/virtualNetworks/{virtualNetworkName}/subnets' \
+                     '/{subnetName}'
 VM_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
                        '{resourceGroupName}/providers/Microsoft.Compute/' \
                        'virtualMachines/{vmName}'
@@ -37,16 +44,25 @@ VM_FIREWALL_RESOURCE_ID = '/subscriptions/{subscriptionId}/' \
                              'providers/Microsoft.Network/' \
                              'networkSecurityGroups/' \
                              '{networkSecurityGroupName}'
+VM_FIREWALL_RULE_RESOURCE_ID = '/subscriptions/{subscriptionId}/' \
+                             'resourceGroups/{resourceGroupName}/' \
+                             'providers/Microsoft.Network/' \
+                             'networkSecurityGroups/' \
+                             '{networkSecurityGroupName}/' \
+                             'securityRules/{securityRuleName}'
 VOLUME_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
                      '{resourceGroupName}/providers/Microsoft.Compute/' \
                      'disks/{diskName}'
 
 IMAGE_NAME = 'imageName'
+NETWORK_NAME = 'virtualNetworkName'
 NETWORK_INTERFACE_NAME = 'networkInterfaceName'
 PUBLIC_IP_NAME = 'publicIpAddressName'
 SNAPSHOT_NAME = 'snapshotName'
+SUBNET_NAME = 'subnetName'
 VM_NAME = 'vmName'
 VM_FIREWALL_NAME = 'networkSecurityGroupName'
+VM_FIREWALL_RULE_NAME = 'securityRuleName'
 VOLUME_NAME = 'diskName'
 
 
@@ -182,22 +198,15 @@ class AzureClient(object):
             create_or_update(self.resource_group, name,
                              parameters).result()
 
-    def update_vm_firewall_tags(self, name, tags):
+    def update_vm_firewall_tags(self, fw_id, tags):
+        url_params = azure_helpers.parse_url(VM_FIREWALL_RESOURCE_ID,
+                                             fw_id)
+        name = url_params.get(VM_FIREWALL_NAME)
         return self.network_management_client.network_security_groups. \
             create_or_update(self.resource_group, name,
                              {'tags': tags,
                               'location': self.region_name}).result()
 
-    def create_vm_firewall_rule(self, vm_firewall,
-                                rule_name, parameters):
-        return self.network_management_client.security_rules. \
-            create_or_update(self.resource_group, vm_firewall,
-                             rule_name, parameters).result()
-
-    def delete_vm_firewall_rule(self, name, vm_firewall):
-        return self.network_management_client.security_rules. \
-            delete(self.resource_group, vm_firewall, name).result()
-
     def get_vm_firewall(self, fw_id):
         url_params = azure_helpers.parse_url(VM_FIREWALL_RESOURCE_ID,
                                              fw_id)
@@ -205,11 +214,28 @@ class AzureClient(object):
         return self.network_management_client.network_security_groups. \
             get(self.resource_group, fw_name)
 
-    def delete_vm_firewall(self, name):
-        delete_async = self.network_management_client \
-            .network_security_groups. \
-            delete(self.resource_group, name)
-        delete_async.wait()
+    def delete_vm_firewall(self, fw_id):
+        url_params = azure_helpers.parse_url(VM_FIREWALL_RESOURCE_ID,
+                                             fw_id)
+        name = url_params.get(VM_FIREWALL_NAME)
+        self.network_management_client \
+            .network_security_groups.delete(self.resource_group, name).wait()
+
+    def create_vm_firewall_rule(self, fw_id,
+                                rule_name, parameters):
+        url_params = azure_helpers.parse_url(VM_FIREWALL_RESOURCE_ID,
+                                             fw_id)
+        vm_firewall_name = url_params.get(VM_FIREWALL_NAME)
+        return self.network_management_client.security_rules. \
+            create_or_update(self.resource_group, vm_firewall_name,
+                             rule_name, parameters).result()
+
+    def delete_vm_firewall_rule(self, fw_rule_id, vm_firewall):
+        url_params = azure_helpers.parse_url(VM_FIREWALL_RULE_RESOURCE_ID,
+                                             fw_rule_id)
+        name = url_params.get(VM_FIREWALL_RULE_NAME)
+        return self.network_management_client.security_rules. \
+            delete(self.resource_group, vm_firewall, name).result()
 
     def list_containers(self, prefix=None):
         return self.blob_service.list_containers(prefix=prefix)
@@ -260,17 +286,15 @@ class AzureClient(object):
         return self.compute_client.disks.create_or_update(
             self.resource_group,
             disk_name,
-            params,
-            raw=True
-        )
+            params
+        ).result()
 
     def create_snapshot_disk(self, disk_name, params):
         return self.compute_client.disks.create_or_update(
             self.resource_group,
             disk_name,
-            params,
-            raw=True
-        )
+            params
+        ).result()
 
     def get_disk(self, disk_id):
         url_params = azure_helpers.parse_url(VOLUME_RESOURCE_ID,
@@ -314,9 +338,8 @@ class AzureClient(object):
         return self.compute_client.snapshots.create_or_update(
             self.resource_group,
             snapshot_name,
-            params,
-            raw=True
-        )
+            params
+        ).result()
 
     def delete_snapshot(self, snapshot_id):
         url_params = azure_helpers.parse_url(SNAPSHOT_RESOURCE_ID,
@@ -339,7 +362,7 @@ class AzureClient(object):
     def create_image(self, name, params):
         return self.compute_client.images. \
             create_or_update(self.resource_group, name,
-                             params, raw=True)
+                             params).result()
 
     def delete_image(self, image_id):
         url_params = azure_helpers.parse_url(IMAGE_RESOURCE_ID,
@@ -376,7 +399,10 @@ class AzureClient(object):
         return self.network_management_client.virtual_networks.list(
             self.resource_group)
 
-    def get_network(self, network_name):
+    def get_network(self, network_id):
+        url_params = azure_helpers.parse_url(NETWORK_RESOURCE_ID,
+                                             network_id)
+        network_name = url_params.get(NETWORK_NAME)
         return self.network_management_client.virtual_networks.get(
             self.resource_group, network_name)
 
@@ -384,53 +410,45 @@ class AzureClient(object):
         return self.network_management_client.virtual_networks. \
             create_or_update(self.resource_group,
                              name,
-                             parameters=params,
-                             raw=True)
+                             parameters=params).result()
 
-    def delete_network(self, network_name):
+    def delete_network(self, network_id):
+        url_params = azure_helpers.parse_url(NETWORK_RESOURCE_ID, network_id)
+        network_name = url_params.get(NETWORK_NAME)
         return self.network_management_client.virtual_networks. \
             delete(self.resource_group, network_name).wait()
 
-    def create_floating_ip(self, public_ip_name, public_ip_parameters):
-        return self.network_management_client.public_ip_addresses. \
-            create_or_update(self.resource_group,
-                             public_ip_name,
-                             public_ip_parameters).result()
-
-    def get_floating_ip(self, public_ip_id):
-        url_params = azure_helpers.parse_url(PUBLIC_IP_RESOURCE_ID,
-                                             public_ip_id)
-        public_ip_name = url_params.get(PUBLIC_IP_NAME)
-        return self.network_management_client. \
-            public_ip_addresses.get(self.resource_group, public_ip_name)
-
-    def delete_floating_ip(self, public_ip_id):
-        url_params = azure_helpers.parse_url(PUBLIC_IP_RESOURCE_ID,
-                                             public_ip_id)
-        public_ip_name = url_params.get(PUBLIC_IP_NAME)
-        self.network_management_client. \
-            public_ip_addresses.delete(self.resource_group,
-                                       public_ip_name).wait()
-
-    def list_floating_ips(self):
-        return self.network_management_client.public_ip_addresses.list(
-            self.resource_group)
-
-    def update_network_tags(self, network_name, tags):
+    def update_network_tags(self, network_id, tags):
+        url_params = azure_helpers.parse_url(NETWORK_RESOURCE_ID, network_id)
+        network_name = url_params.get(NETWORK_NAME)
         return self.network_management_client.virtual_networks. \
             create_or_update(self.resource_group,
                              network_name, tags).result()
 
-    def list_subnets(self, network_name):
+    def get_network_id_for_subnet(self, subnet_id):
+        url_params = azure_helpers.parse_url(SUBNET_RESOURCE_ID, subnet_id)
+        network_id = NETWORK_RESOURCE_ID
+        for key, val in url_params.items():
+            network_id = network_id.replace("{" + key + "}", val)
+        return network_id
+
+    def list_subnets(self, network_id):
+        url_params = azure_helpers.parse_url(NETWORK_RESOURCE_ID, network_id)
+        network_name = url_params.get(NETWORK_NAME)
         return self.network_management_client.subnets. \
             list(self.resource_group, network_name)
 
-    def get_subnet(self, network_name, subnet_name):
+    def get_subnet(self, subnet_id):
+        url_params = azure_helpers.parse_url(SUBNET_RESOURCE_ID,
+                                             subnet_id)
+        network_name = url_params.get(NETWORK_NAME)
+        subnet_name = url_params.get(SUBNET_NAME)
         return self.network_management_client.subnets. \
             get(self.resource_group, network_name, subnet_name)
 
-    def create_subnet(self, network_name,
-                      subnet_name, params):
+    def create_subnet(self, network_id, subnet_name, params):
+        url_params = azure_helpers.parse_url(NETWORK_RESOURCE_ID, network_id)
+        network_name = url_params.get(NETWORK_NAME)
         result_create = self.network_management_client \
             .subnets.create_or_update(
                 self.resource_group,
@@ -442,7 +460,11 @@ class AzureClient(object):
 
         return subnet_info
 
-    def delete_subnet(self, network_name, subnet_name):
+    def delete_subnet(self, subnet_id):
+        url_params = azure_helpers.parse_url(SUBNET_RESOURCE_ID,
+                                             subnet_id)
+        network_name = url_params.get(NETWORK_NAME)
+        subnet_name = url_params.get(SUBNET_NAME)
         result_delete = self.network_management_client \
             .subnets.delete(
                 self.resource_group,
@@ -451,6 +473,31 @@ class AzureClient(object):
             )
         result_delete.wait()
 
+    def create_floating_ip(self, public_ip_name, public_ip_parameters):
+        return self.network_management_client.public_ip_addresses. \
+            create_or_update(self.resource_group,
+                             public_ip_name,
+                             public_ip_parameters).result()
+
+    def get_floating_ip(self, public_ip_id):
+        url_params = azure_helpers.parse_url(PUBLIC_IP_RESOURCE_ID,
+                                             public_ip_id)
+        public_ip_name = url_params.get(PUBLIC_IP_NAME)
+        return self.network_management_client. \
+            public_ip_addresses.get(self.resource_group, public_ip_name)
+
+    def delete_floating_ip(self, public_ip_id):
+        url_params = azure_helpers.parse_url(PUBLIC_IP_RESOURCE_ID,
+                                             public_ip_id)
+        public_ip_name = url_params.get(PUBLIC_IP_NAME)
+        self.network_management_client. \
+            public_ip_addresses.delete(self.resource_group,
+                                       public_ip_name).wait()
+
+    def list_floating_ips(self):
+        return self.network_management_client.public_ip_addresses.list(
+            self.resource_group)
+
     def list_vm(self):
         return self.compute_client.virtual_machines.list(
             self.resource_group
@@ -483,7 +530,7 @@ class AzureClient(object):
     def create_vm(self, vm_name, params):
         return self.compute_client.virtual_machines. \
             create_or_update(self.resource_group,
-                             vm_name, params, raw=True)
+                             vm_name, params).result()
 
     def update_vm(self, vm_id, params):
         url_params = azure_helpers.parse_url(VM_RESOURCE_ID,
@@ -588,8 +635,11 @@ class AzureClient(object):
             route_tables.delete(self.resource_group, route_table_name
                                 ).wait()
 
-    def attach_subnet_to_route_table(self, network_name,
-                                     subnet_name, route_table_id):
+    def attach_subnet_to_route_table(self, subnet_id, route_table_id):
+        url_params = azure_helpers.parse_url(SUBNET_RESOURCE_ID,
+                                             subnet_id)
+        network_name = url_params.get(NETWORK_NAME)
+        subnet_name = url_params.get(SUBNET_NAME)
 
         subnet_info = self.network_management_client.subnets.get(
             self.resource_group,
@@ -611,8 +661,11 @@ class AzureClient(object):
 
         return subnet_info
 
-    def detach_subnet_to_route_table(self, network_name,
-                                     subnet_name, route_table_id):
+    def detach_subnet_to_route_table(self, subnet_id, route_table_id):
+        url_params = azure_helpers.parse_url(SUBNET_RESOURCE_ID,
+                                             subnet_id)
+        network_name = url_params.get(NETWORK_NAME)
+        subnet_name = url_params.get(SUBNET_NAME)
 
         subnet_info = self.network_management_client.subnets.get(
             self.resource_group,

+ 4 - 1
cloudbridge/cloud/providers/azure/helpers.py

@@ -1,3 +1,6 @@
+from cloudbridge.cloud.interfaces.exceptions import InvalidValueException
+
+
 def filter_by_tag(list_items, filters):
     """
     This function filter items on the tags
@@ -29,7 +32,7 @@ def parse_url(template_url, original_url):
     template_url_parts = template_url.split('/')
     original_url_parts = original_url.split('/')
     if len(template_url_parts) != len(original_url_parts):
-        raise Exception('Invalid url parameter passed')
+        raise InvalidValueException(template_url, original_url)
     resource_param = {}
     for key, value in zip(template_url_parts, original_url_parts):
         if key.startswith('{') and key.endswith('}'):

+ 29 - 57
cloudbridge/cloud/providers/azure/resources.py

@@ -25,24 +25,14 @@ from msrestazure.azure_exceptions import CloudError
 
 import pysftp
 
-from . import helpers as azure_helpers
-
 log = logging.getLogger(__name__)
 
-SUBNET_RESOURCE_ID = '/subscriptions/{subscriptionId}/resourceGroups/' \
-                     '{resourceGroupName}/providers/Microsoft.Network' \
-                     '/virtualNetworks/{virtualNetworkName}/subnets' \
-                     '/{subnetName}'
-
-NETWORK_NAME = 'virtualNetworkName'
-
 
 class AzureVMFirewall(BaseVMFirewall):
     def __init__(self, provider, vm_firewall):
         super(AzureVMFirewall, self).__init__(provider, vm_firewall)
         self._vm_firewall = vm_firewall
-        if not self._vm_firewall.tags:
-            self._vm_firewall.tags = {}
+        self._vm_firewall.tags = self._vm_firewall.tags or {}
         self._rule_container = AzureVMFirewallRuleContainer(provider, self)
 
     @property
@@ -65,13 +55,12 @@ class AzureVMFirewall(BaseVMFirewall):
     def name(self, value):
         self.assert_valid_resource_name(value)
         self._vm_firewall.tags.update(Name=value)
-        self._provider.azure_client. \
-            update_vm_firewall_tags(self.id,
-                                    self._vm_firewall.tags)
+        self._provider.azure_client.update_vm_firewall_tags(
+            self.id, self._vm_firewall.tags)
 
     @property
     def description(self):
-        return self._vm_firewall.tags.get('Description', None)
+        return self._vm_firewall.tags.get('Description')
 
     @description.setter
     def description(self, value):
@@ -183,7 +172,7 @@ class AzureVMFirewallRule(BaseVMFirewallRule):
 
     @property
     def id(self):
-        return self._rule.name
+        return self._rule.id
 
     @property
     def direction(self):
@@ -231,7 +220,7 @@ class AzureVMFirewallRule(BaseVMFirewallRule):
         self._provider.azure_client. \
             delete_vm_firewall_rule(self.id, vm_firewall)
         for i, o in enumerate(self.firewall._vm_firewall.security_rules):
-            if o.name == self.name:
+            if o.id == self.id:
                 del self.firewall._vm_firewall.security_rules[i]
                 break
 
@@ -516,7 +505,7 @@ class AzureVolume(BaseVolume):
 
         vm.storage_profile.data_disks.append({
             'lun': len(vm.storage_profile.data_disks),
-            'name': self.id,
+            'name': self._volume.name,
             'create_option': 'attach',
             'managed_disk': {
                 'id': self.resource_id
@@ -671,7 +660,7 @@ class AzureSnapshot(BaseSnapshot):
         Create a new Volume from this Snapshot.
         """
         return self._provider.storage.volumes. \
-            create(self.id, self.size,
+            create(self.name, self.size,
                    zone=placement, snapshot=self)
 
 
@@ -823,7 +812,7 @@ class AzureNetwork(BaseNetwork):
 
     @property
     def id(self):
-        return self._network.name
+        return self._network.id
 
     @property
     def resource_id(self):
@@ -983,7 +972,7 @@ class AzureFloatingIP(BaseFloatingIP):
 
     def refresh(self):
         net = self._provider.networking.networks.get(self._network_id)
-        gw = net.gateways.get_or_create_inet_gateway(net)
+        gw = net.gateways.get_or_create_inet_gateway()
         fip = gw.floating_ips.get(self.id)
         self._ip = fip._ip
 
@@ -1062,14 +1051,10 @@ class AzureSubnet(BaseSubnet):
         super(AzureSubnet, self).__init__(provider)
         self._subnet = subnet
         self._state = self._subnet.provisioning_state
-        self._url_params = azure_helpers\
-            .parse_url(SUBNET_RESOURCE_ID, subnet.id)
-        self._network = self._provider.azure_client.\
-            get_network(self._url_params.get(NETWORK_NAME))
 
     @property
     def id(self):
-        return self.network_id + '|$|' + self._subnet.name
+        return self._subnet.id
 
     @property
     def resource_id(self):
@@ -1086,8 +1071,9 @@ class AzureSubnet(BaseSubnet):
 
     @property
     def zone(self):
-        region = self._provider.\
-            compute.regions.get(self._network.location)
+        # pylint:disable=protected-access
+        region = self._provider.compute.regions.get(
+            self._network._network.location)
         return region.zones[0]
 
     @property
@@ -1096,21 +1082,18 @@ class AzureSubnet(BaseSubnet):
 
     @property
     def network_id(self):
-        return self._url_params.get(NETWORK_NAME)
+        return self._provider.azure_client.get_network_id_for_subnet(self.id)
+
+    @property
+    def _network(self):
+        return self._provider.networking.networks.get(self.network_id)
 
     def delete(self):
-        """
-        Delete the subnet
-        :return:
-        """
-        subnet_id_parts = self.id.split('|$|')
-        self._provider.azure_client. \
-            delete_subnet(subnet_id_parts[0], subnet_id_parts[1])
+        self._provider.azure_client.delete_subnet(self.id)
 
     @property
     def state(self):
-        return self._SUBNET_STATE_MAP.get(
-            self._state, NetworkState.UNKNOWN)
+        return self._SUBNET_STATE_MAP.get(self._state, NetworkState.UNKNOWN)
 
     def refresh(self):
         """
@@ -1118,12 +1101,12 @@ class AzureSubnet(BaseSubnet):
         for its latest state.
         """
         try:
-            self._network = self._provider.azure_client. \
-                get_network(self.id)
-            self._state = self._network.provisioning_state
+            self._subnet = self._provider.azure_client. \
+                get_subnet(self.id)
+            self._state = self._subnet.provisioning_state
         except (CloudError, ValueError) as cloudError:
             log.exception(cloudError.message)
-            # The network no longer exists and cannot be refreshed.
+            # The subnet no longer exists and cannot be refreshed.
             # set the state to unknown
             self._state = 'unknown'
 
@@ -1166,7 +1149,7 @@ class AzureInstance(BaseInstance):
 
     @property
     def _public_ip_ids(self):
-        return (ip_config.public_ip_address
+        return (ip_config.public_ip_address.id
                 for nic in self._nics
                 for ip_config in nic.ip_configurations
                 if nic.ip_configurations and ip_config.public_ip_address)
@@ -1331,11 +1314,8 @@ class AzureInstance(BaseInstance):
             },
             'tags': {'Name': name}
         }
-        self._provider.azure_client.\
-            create_image(name, create_params)
-        image = self._provider.azure_client.\
-            get_image(name)
 
+        image = self._provider.azure_client.create_image(name, create_params)
         return AzureMachineImage(self._provider, image)
 
     def _deprovision(self, private_key_path):
@@ -1600,22 +1580,14 @@ class AzureRouter(BaseRouter):
         self._provider.azure_client.delete_route_table(self.name)
 
     def attach_subnet(self, subnet):
-        subnet_id_parts = subnet.id.split('|$|')
-        if (len(subnet_id_parts) != 2):
-            pass
         self._provider.azure_client. \
-            attach_subnet_to_route_table(subnet_id_parts[0],
-                                         subnet_id_parts[1],
+            attach_subnet_to_route_table(subnet.id,
                                          self.resource_id)
         self.refresh()
 
     def detach_subnet(self, subnet):
-        subnet_id_parts = subnet.id.split('|$|')
-        if (len(subnet_id_parts) != 2):
-            pass
         self._provider.azure_client. \
-            detach_subnet_to_route_table(subnet_id_parts[0],
-                                         subnet_id_parts[1],
+            detach_subnet_to_route_table(subnet.id,
                                          self.resource_id)
         self.refresh()
 

+ 51 - 80
cloudbridge/cloud/providers/azure/services.py

@@ -15,7 +15,8 @@ from cloudbridge.cloud.base.services import BaseBucketService, \
     BaseStorageService, BaseSubnetService, BaseVMFirewallService, \
     BaseVMTypeService, BaseVolumeService
 from cloudbridge.cloud.interfaces.exceptions import \
-    DuplicateResourceException, InvalidConfigurationException
+    DuplicateResourceException, InvalidConfigurationException, \
+    InvalidValueException
 from cloudbridge.cloud.interfaces.resources import MachineImage, \
     Network, PlacementZone, Snapshot, Subnet, VMFirewall, VMType, Volume
 
@@ -56,9 +57,9 @@ class AzureVMFirewallService(BaseVMFirewallService):
         try:
             fws = self.provider.azure_client.get_vm_firewall(fw_id)
             return AzureVMFirewall(self.provider, fws)
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def list(self, limit=None, marker=None):
@@ -86,7 +87,7 @@ class AzureVMFirewallService(BaseVMFirewallService):
             rule.priority = rule.priority - 61440
             rule.access = "Deny"
             self._provider.azure_client.create_vm_firewall_rule(
-                fw.name, rule_name, rule)
+                fw.id, rule_name, rule)
 
         # Add a new custom rule allowing all outbound traffic to the internet
         parameters = {"priority": 3000,
@@ -98,7 +99,7 @@ class AzureVMFirewallService(BaseVMFirewallService):
                       "access": "Allow",
                       "direction": "Outbound"}
         result = self._provider.azure_client.create_vm_firewall_rule(
-            fw.name, "cb-default-internet-outbound", parameters)
+            fw.id, "cb-default-internet-outbound", parameters)
         fw.security_rules.append(result)
 
         cb_fw = AzureVMFirewall(self.provider, fw)
@@ -269,9 +270,9 @@ class AzureVolumeService(BaseVolumeService):
         try:
             volume = self.provider.azure_client.get_disk(volume_id)
             return AzureVolume(self.provider, volume)
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def find(self, **kwargs):
@@ -320,7 +321,8 @@ class AzureVolumeService(BaseVolumeService):
                 'tags': tags
             }
 
-            self.provider.azure_client.create_snapshot_disk(disk_name, params)
+            disk = self.provider.azure_client.create_snapshot_disk(disk_name,
+                                                                   params)
 
         else:
             params = {
@@ -332,9 +334,10 @@ class AzureVolumeService(BaseVolumeService):
                 },
                 'tags': tags}
 
-            self.provider.azure_client.create_empty_disk(disk_name, params)
+            disk = self.provider.azure_client.create_empty_disk(disk_name,
+                                                                params)
 
-        azure_vol = self.provider.azure_client.get_disk(disk_name)
+        azure_vol = self.provider.azure_client.get_disk(disk.id)
         cb_vol = AzureVolume(self.provider, azure_vol)
 
         return cb_vol
@@ -351,9 +354,9 @@ class AzureSnapshotService(BaseSnapshotService):
         try:
             snapshot = self.provider.azure_client.get_snapshot(ss_id)
             return AzureSnapshot(self.provider, snapshot)
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def find(self, **kwargs):
@@ -403,12 +406,9 @@ class AzureSnapshotService(BaseSnapshotService):
             'tags': tags
         }
 
-        self.provider.azure_client. \
-            create_snapshot(snapshot_name, params)
-        azure_snap = self.provider.azure_client.get_snapshot(snapshot_name)
-        cb_snap = AzureSnapshot(self.provider, azure_snap)
-
-        return cb_snap
+        azure_snap = self.provider.azure_client.create_snapshot(snapshot_name,
+                                                                params)
+        return AzureSnapshot(self.provider, azure_snap)
 
 
 class AzureComputeService(BaseComputeService):
@@ -470,8 +470,8 @@ class AzureInstanceService(BaseInstanceService):
                     name=default_kp_name)
                 temp_key_pair = key_pair
 
-        image = (self.provider.compute.images.get(image)
-                 if isinstance(image, str) else image)
+        image = (image if isinstance(image, AzureMachineImage) else
+                 self.provider.compute.images.get(image))
         if not isinstance(image, AzureMachineImage):
             raise Exception("Provided image %s is not a valid azure image"
                             % image)
@@ -572,8 +572,7 @@ class AzureInstanceService(BaseInstanceService):
             custom_data = base64.b64encode(bytes(ud, 'utf-8'))
             params['os_profile']['custom_data'] = str(custom_data, 'utf-8')
 
-        self.provider.azure_client.create_vm(instance_name, params)
-        vm = self._provider.azure_client.get_vm(instance_name)
+        vm = self.provider.azure_client.create_vm(instance_name, params)
         if temp_key_pair:
             temp_key_pair.delete()
         return AzureInstance(self.provider, vm)
@@ -623,7 +622,7 @@ class AzureInstanceService(BaseInstanceService):
         def attach_volume(volume, delete_on_terminate):
             disks.append({
                 'lun': volumes_count,
-                'name': volume.id,
+                'name': volume.name,
                 'create_option': 'attach',
                 'managed_disk': {
                     'id': volume.resource_id
@@ -702,9 +701,9 @@ class AzureInstanceService(BaseInstanceService):
         try:
             vm = self.provider.azure_client.get_vm(instance_id)
             return AzureInstance(self.provider, vm)
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def find(self, **kwargs):
@@ -733,9 +732,9 @@ class AzureImageService(BaseImageService):
         try:
             image = self.provider.azure_client.get_image(image_id)
             return AzureMachineImage(self.provider, image)
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def find(self, **kwargs):
@@ -811,10 +810,9 @@ class AzureNetworkService(BaseNetworkService):
         try:
             network = self.provider.azure_client.get_network(network_id)
             return AzureNetwork(self.provider, network)
-
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def list(self, limit=None, marker=None):
@@ -856,9 +854,9 @@ class AzureNetworkService(BaseNetworkService):
             },
             'tags': {'Name': name or AzureNetwork.CB_DEFAULT_NETWORK_NAME}
         }
-        self.provider.azure_client.create_network(network_name, params)
-        network = self.provider.azure_client.get_network(network_name)
-        cb_network = AzureNetwork(self.provider, network)
+        az_network = self.provider.azure_client.create_network(network_name,
+                                                               params)
+        cb_network = AzureNetwork(self.provider, az_network)
         return cb_network
 
     def delete(self, network_id):
@@ -907,16 +905,12 @@ class AzureSubnetService(BaseSubnetService):
         :return:
         """
         try:
-            subnet_id_parts = subnet_id.split('|$|')
-            if (len(subnet_id_parts) != 2):
-                return None
-            azure_subnet = self.provider.azure_client.\
-                get_subnet(subnet_id_parts[0], subnet_id_parts[1])
+            azure_subnet = self.provider.azure_client.get_subnet(subnet_id)
             return AzureSubnet(self.provider,
                                azure_subnet) if azure_subnet else None
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def list(self, network=None, limit=None, marker=None):
@@ -936,7 +930,7 @@ class AzureSubnetService(BaseSubnetService):
         else:
             for net in self.provider.azure_client.list_networks():
                 result_list.extend(self.provider.azure_client.list_subnets(
-                    net.name
+                    net.id
                 ))
         subnets = [AzureSubnet(self.provider, subnet)
                    for subnet in result_list]
@@ -968,52 +962,30 @@ class AzureSubnetService(BaseSubnetService):
         return AzureSubnet(self.provider, subnet_info)
 
     def get_or_create_default(self, zone=None):
-        default_cdir = '10.0.1.0/24'
-        network = None
-        subnet = None
+        default_cidr = '10.0.1.0/24'
 
         # No provider-default Subnet exists, look for a library-default one
-        try:
-            subnet = self.provider.azure_client.get_subnet(
-                AzureNetwork.CB_DEFAULT_NETWORK_NAME,
-                AzureSubnet.CB_DEFAULT_SUBNET_NAME
-            )
-        except CloudError:
-            # Azure raises the cloud error if the resource not available
-            pass
-
-        if subnet:
-            return AzureSubnet(self.provider, subnet)
+        matches = self.find(name=AzureSubnet.CB_DEFAULT_SUBNET_NAME)
+        if matches:
+            return matches[0]
 
         # No provider-default Subnet exists, try to create it (net + subnets)
-        default_net_name = AzureNetwork.CB_DEFAULT_NETWORK_NAME
-        try:
-            network = self.provider.azure_client \
-                .get_network(default_net_name)
-        except CloudError:
-            # Azure raises the cloud error if the resource not available
-            pass
+        networks = self.provider.networking.networks.find(
+            name=AzureNetwork.CB_DEFAULT_NETWORK_NAME)
 
-        if not network:
+        if networks:
+            network = networks[0]
+        else:
             network = self.provider.networking.networks.create(
-                name=default_net_name, cidr_block='10.0.0.0/16')
+                AzureNetwork.CB_DEFAULT_NETWORK_NAME, '10.0.0.0/16')
 
-        subnet = self.provider.azure_client.create_subnet(
-            network.id,
-            AzureSubnet.CB_DEFAULT_SUBNET_NAME,
-            {'address_prefix': default_cdir}
-        )
-
-        return AzureSubnet(self.provider, subnet)
+        subnet = self.create(network, default_cidr,
+                             name=AzureSubnet.CB_DEFAULT_SUBNET_NAME)
+        return subnet
 
     def delete(self, subnet):
-        # Azure does not provide an api to delete the subnet by id
-        # It also requires network id. To get the network id
-        # code is doing an explicit get and retrieving the network id
         subnet_id = subnet.id if isinstance(subnet, Subnet) else subnet
-        subnet_id_parts = subnet_id.split('|$|')
-        self.provider.azure_client.\
-            delete_subnet(subnet_id_parts[0], subnet_id_parts[1])
+        self.provider.azure_client.delete_subnet(subnet_id)
 
 
 class AzureRouterService(BaseRouterService):
@@ -1024,10 +996,9 @@ class AzureRouterService(BaseRouterService):
         try:
             route = self.provider.azure_client.get_route_table(router_id)
             return AzureRouter(self.provider, route)
-
-        except CloudError as cloudError:
+        except (CloudError, InvalidValueException) as cloudError:
             # Azure raises the cloud error if the resource not available
-            log.exception(cloudError.message)
+            log.exception(cloudError)
             return None
 
     def find(self, **kwargs):

+ 4 - 1
test/helpers/__init__.py

@@ -94,7 +94,10 @@ TEST_DATA_CONFIG = {
         "placement":
             os.environ.get('CB_PLACEMENT_AZURE', 'eastus'),
         "image":
-            os.environ.get('CB_IMAGE_AZURE', 'cb-test-image'),
+            os.environ.get('CB_IMAGE_AZURE',
+                           '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a9'
+                           '6/resourceGroups/cloudbridge/providers/Microsoft.C'
+                           'ompute/images/cb-test-image'),
         "vm_type":
             os.environ.get('CB_VM_TYPE_AZURE', 'Basic_A0'),
     }