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

Implemented changes to support name and description change

vikramdoda 9 лет назад
Родитель
Сommit
84f6231ef9

+ 4 - 4
azure_integration_test/test_integration_azure_snapshot_service.py

@@ -7,8 +7,8 @@ class AzureIntegrationSnapshotServiceTestCase(helpers.ProviderTestBase):
 
 
     @helpers.skipIfNoService(['block_store'])
     @helpers.skipIfNoService(['block_store'])
     def test_azure_snapshot_service(self):
     def test_azure_snapshot_service(self):
-        snapshot_name = '{0}'.format(uuid.uuid4())
-        volume_name = '{0}'.format(uuid.uuid4())
+        snapshot_name = '{0}'.format(uuid.uuid4().hex[:6])
+        volume_name = '{0}'.format(uuid.uuid4().hex[:6])
 
 
         snapshot_list_before_create = \
         snapshot_list_before_create = \
             self.provider.block_store.snapshots.list()
             self.provider.block_store.snapshots.list()
@@ -64,8 +64,8 @@ class AzureIntegrationSnapshotServiceTestCase(helpers.ProviderTestBase):
             self.provider.block_store.snapshots.list()
             self.provider.block_store.snapshots.list()
         print(str(len(snapshot_list_after_delete)))
         print(str(len(snapshot_list_after_delete)))
 
 
-        self.assertTrue(len(snapshot_list_after_delete),
-                        len(snapshot_list_before_delete) - 1)
+        self.assertEqual(len(snapshot_list_after_delete),
+                         len(snapshot_list_before_delete) - 1)
 
 
         volume.delete()
         volume.delete()
         vol.delete()
         vol.delete()

+ 5 - 9
azure_test/test_azure_snapshots_service.py

@@ -7,12 +7,12 @@ from cloudbridge.cloud.interfaces import SnapshotState
 class AzureSnapshotsServiceTestCase(ProviderTestBase):
 class AzureSnapshotsServiceTestCase(ProviderTestBase):
     @helpers.skipIfNoService(['block_store.snapshots'])
     @helpers.skipIfNoService(['block_store.snapshots'])
     def test_azure_snapshot_create_and_get(self):
     def test_azure_snapshot_create_and_get(self):
-        snapshot_id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
+        volume_id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
             '/resourceGroups/cloudbridge-azure'\
             '/resourceGroups/cloudbridge-azure'\
-            '/providers/Microsoft.Compute/snapshots/MySnapshot123"
+            '/providers/Microsoft.Compute/disks/MySnapshotDisk123"
         snapshot = self.provider.block_store. \
         snapshot = self.provider.block_store. \
             snapshots.create("MySnapshot",
             snapshots.create("MySnapshot",
-                             snapshot_id)
+                             volume_id)
         snapshot.description = 'My snapshot'
         snapshot.description = 'My snapshot'
         print("Create Snapshot - " + str(snapshot))
         print("Create Snapshot - " + str(snapshot))
         self.assertTrue(
         self.assertTrue(
@@ -24,14 +24,10 @@ class AzureSnapshotsServiceTestCase(ProviderTestBase):
         self.assertIsNotNone(snapshot.volume_id)
         self.assertIsNotNone(snapshot.volume_id)
         self.assertIsNotNone(snapshot.create_time)
         self.assertIsNotNone(snapshot.create_time)
         snapshot.name = 'MySnapNewName'
         snapshot.name = 'MySnapNewName'
-        snapshot = self.provider.block_store.snapshots.get(
-                "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
-                '/resourceGroups/cloudbridge-azure'\
-                '/providers/Microsoft.Compute'\
-                /snapshots/MySnapshot")
+        snapshot = self.provider.block_store.snapshots.get(snapshot.id)
         print("Get Snapshot  - " + str(snapshot))
         print("Get Snapshot  - " + str(snapshot))
         self.assertTrue(
         self.assertTrue(
-            snapshot.name == "MySnapshot",
+            snapshot.name == "MySnapNewName",
             "Snapshot name should be MySnapshot")
             "Snapshot name should be MySnapshot")
 
 
         snapshot.delete()
         snapshot.delete()

+ 33 - 104
cloudbridge/cloud/providers/azure/azure_client.py

@@ -1,4 +1,5 @@
 import logging
 import logging
+
 from io import BytesIO
 from io import BytesIO
 
 
 from azure.common.credentials import ServicePrincipalCredentials
 from azure.common.credentials import ServicePrincipalCredentials
@@ -176,62 +177,33 @@ class AzureClient(object):
                                              blob_name, out_stream)
                                              blob_name, out_stream)
         return out_stream
         return out_stream
 
 
-    def create_empty_disk(self, disk_name, size,
-                          region=None, snapshot_id=None,
-                          description=None):
-
-        if snapshot_id:
-            return self.create_snapshot_disk(disk_name,
-                                             snapshot_id, region=region)
-
-        params = {
-            'location': region or self.region_name,
-            'disk_size_gb': size,
-            'creation_data': {
-                'create_option': 'empty'
-            }
-        }
-        if description:
-            params['tags'] = {'Description': description}
-
-        async_creation = self.compute_client.disks.create_or_update(
+    def create_empty_disk(self, disk_name, params):
+        return self.compute_client.disks.create_or_update(
             self.resource_group_name,
             self.resource_group_name,
             disk_name,
             disk_name,
             params,
             params,
             raw=True
             raw=True
         )
         )
-        return async_creation
 
 
-    def create_snapshot_disk(self, disk_name, snapshot_id, region=None):
-        disk_response = self.compute_client.disks.create_or_update(
+    def create_snapshot_disk(self, disk_name, params):
+        return self.compute_client.disks.create_or_update(
             self.resource_group_name,
             self.resource_group_name,
             disk_name,
             disk_name,
-            {
-                'location': region or self.region_name,
-                'creation_data': {
-                    'create_option': 'copy',
-                    'source_uri': snapshot_id
-                }
-            },
+            params,
             raw=True
             raw=True
         )
         )
 
 
-        return disk_response
-
     def list_snapshots(self):
     def list_snapshots(self):
         return self.compute_client.snapshots. \
         return self.compute_client.snapshots. \
             list_by_resource_group(self.resource_group_name)
             list_by_resource_group(self.resource_group_name)
 
 
-    def update_disk_tags(self, disk_name, tags, region=None):
-        disk_result = self.compute_client.disks.update(
+    def update_disk_tags(self, disk_name, tags):
+        return self.compute_client.disks.update(
             self.resource_group_name,
             self.resource_group_name,
             disk_name,
             disk_name,
-            {
-                'tags': tags
-            },
+            {'tags': tags},
             raw=True
             raw=True
         )
         )
-        return disk_result
 
 
     def get_disk(self, disk_name):
     def get_disk(self, disk_name):
         return self.compute_client.disks. \
         return self.compute_client.disks. \
@@ -246,89 +218,46 @@ class AzureClient(object):
             delete(self.resource_group_name, disk_name)
             delete(self.resource_group_name, disk_name)
         async_deletion.wait()
         async_deletion.wait()
 
 
-    def attach_disk(self, vm_name, disk_name, disk_id):
-        vm = self.compute_client.virtual_machines.get(
-            self.resource_group_name,
-            vm_name
-        )
-
-        if vm:
-            vm.storage_profile.data_disks.append({
-                'lun': len(vm.storage_profile.data_disks),
-                'name': disk_name,
-                'create_option': 'attach',
-                'managed_disk': {
-                    'id': disk_id
-                }
-            })
-            self.compute_client.virtual_machines.create_or_update(
-                self.resource_group_name,
-                vm.name,
-                vm,
-                raw=True
-            )
-
-    def detach_disk(self, disk_id):
-        virtual_machine = None
-        for index, vm in enumerate(
-                self.compute_client.virtual_machines.list(
-                    self.resource_group_name)):
-            for index, item in enumerate(vm.storage_profile.data_disks):
-                if item.managed_disk and item.managed_disk.id == disk_id:
-                    vm.storage_profile.data_disks.remove(item)
-                    virtual_machine = vm
-                break
-
-        if virtual_machine:
-            self.compute_client.virtual_machines.create_or_update(
-                self.resource_group_name,
-                virtual_machine.name,
-                virtual_machine,
-                raw=True
-            )
-
     def get_snapshot(self, snapshot_name):
     def get_snapshot(self, snapshot_name):
         return self.compute_client.snapshots.get(self.resource_group_name,
         return self.compute_client.snapshots.get(self.resource_group_name,
                                                  snapshot_name)
                                                  snapshot_name)
 
 
-    def create_snapshot(self, snapshot_name, disk_name,
-                        description=None, region=None):
-
-        managed_disk = self.compute_client.\
-            disks.get(self.resource_group_name,
-                      disk_name)
-        params = {
-                'location': region or self.region_name,
-                'creation_data': {
-                    'create_option': 'Copy',
-                    'source_uri': managed_disk.id
-                }
-            }
-
-        if description:
-            params['tags'] = {'Description': description}
-
-        snapshot_response = self.compute_client.snapshots.create_or_update(
+    def create_snapshot(self, snapshot_name, params):
+        return self.compute_client.snapshots.create_or_update(
             self.resource_group_name,
             self.resource_group_name,
             snapshot_name,
             snapshot_name,
             params,
             params,
             raw=True
             raw=True
         )
         )
 
 
-        return snapshot_response
-
     def delete_snapshot(self, snapshot_name):
     def delete_snapshot(self, snapshot_name):
         async_delete = self.compute_client.snapshots. \
         async_delete = self.compute_client.snapshots. \
             delete(self.resource_group_name, snapshot_name)
             delete(self.resource_group_name, snapshot_name)
         async_delete.wait()
         async_delete.wait()
 
 
-    def update_snapshot_tags(self, snapshot_name, tags, region=None):
-        snapshot_result = self.compute_client.snapshots.update(
+    def update_snapshot_tags(self, snapshot_name, tags):
+        return self.compute_client.snapshots.update(
             self.resource_group_name,
             self.resource_group_name,
             snapshot_name,
             snapshot_name,
-            {
-                'tags': tags
-            },
+            {'tags': tags},
             raw=True
             raw=True
         )
         )
-        return snapshot_result
+
+    def get_vm(self, vm_name):
+        return self.compute_client.virtual_machines.get(
+            self.resource_group_name,
+            vm_name
+        )
+
+    def create_or_update_vm(self, vm_name, params):
+        return self.compute_client\
+            .virtual_machines.create_or_update(
+                self.resource_group_name,
+                vm_name,
+                params,
+                raw=True
+            )
+
+    def list_vm(self):
+        return self.compute_client.\
+            virtual_machines.list(self.resource_group_name)

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

@@ -3,7 +3,7 @@ def filter(list_items, filters):
     if filters:
     if filters:
         for obj in list_items:
         for obj in list_items:
             for key in filters:
             for key in filters:
-                if filters[key] in str(getattr(obj, key)):
+                if obj.tags and filters[key] == obj.tags.get(key, ''):
                     filtered_list.append(obj)
                     filtered_list.append(obj)
 
 
         return filtered_list
         return filtered_list

+ 94 - 41
cloudbridge/cloud/providers/azure/mock_azure_client.py

@@ -1,15 +1,18 @@
+import uuid
 from datetime import datetime
 from datetime import datetime
 
 
 from io import BytesIO
 from io import BytesIO
 
 
 from azure.common import AzureException
 from azure.common import AzureException
-from azure.mgmt.compute.models import CreationData, Disk, DiskCreateOption, \
-    Snapshot
+from azure.mgmt.compute.models import CreationData, DataDisk, \
+    Disk, DiskCreateOption, ManagedDiskParameters, \
+    Snapshot, StorageProfile, VirtualMachine
 from azure.mgmt.network.models import NetworkSecurityGroup
 from azure.mgmt.network.models import NetworkSecurityGroup
 from azure.mgmt.network.models import SecurityRule
 from azure.mgmt.network.models import SecurityRule
 from azure.mgmt.resource.resources.models import ResourceGroup
 from azure.mgmt.resource.resources.models import ResourceGroup
 from azure.mgmt.storage.models import StorageAccount
 from azure.mgmt.storage.models import StorageAccount
-from azure.storage.blob.models import Blob, Container
+from azure.storage.blob.models import Blob, BlobProperties, \
+    Container
 
 
 from msrestazure.azure_exceptions import CloudError
 from msrestazure.azure_exceptions import CloudError
 
 
@@ -37,18 +40,22 @@ class MockAzureClient:
     sec_gr1.name = "sg1"
     sec_gr1.name = "sg1"
     sec_gr1.id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure'\
     sec_gr1.id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure'\
     '/providers/Microsoft.Network/networkSecurityGroups/sg1"
     '/providers/Microsoft.Network/networkSecurityGroups/sg1"
+    sec_gr1.tags = None
+    sec_gr1.resource_guid = uuid.uuid4()
     sec_gr1.security_rules = [sg_rule1, sg_rule2]
     sec_gr1.security_rules = [sg_rule1, sg_rule2]
 
 
     sec_gr2 = NetworkSecurityGroup()
     sec_gr2 = NetworkSecurityGroup()
     sec_gr2.name = "sg2"
     sec_gr2.name = "sg2"
     sec_gr2.id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure'\
     sec_gr2.id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure'\
     '/providers/Microsoft.Network/networkSecurityGroups/sg2"
     '/providers/Microsoft.Network/networkSecurityGroups/sg2"
+    sec_gr2.tags = None
     sec_gr2.security_rules = [sg_rule1, sg_rule2]
     sec_gr2.security_rules = [sg_rule1, sg_rule2]
 
 
     sec_gr3 = NetworkSecurityGroup()
     sec_gr3 = NetworkSecurityGroup()
     sec_gr3.name = "sg3"
     sec_gr3.name = "sg3"
     sec_gr3.id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure'\
     sec_gr3.id = "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure'\
     '/providers/Microsoft.Network/networkSecurityGroups/sg3"
     '/providers/Microsoft.Network/networkSecurityGroups/sg3"
+    sec_gr3.tags = {'Name': 'sg3'}
     sec_gr3.security_rules = [sg_rule1, sg_rule2]
     sec_gr3.security_rules = [sg_rule1, sg_rule2]
 
 
     security_groups = [sec_gr1, sec_gr2, sec_gr3]
     security_groups = [sec_gr1, sec_gr2, sec_gr3]
@@ -73,8 +80,12 @@ class MockAzureClient:
     block3.name = "block3"
     block3.name = "block3"
     block3.content = None
     block3.content = None
 
 
+    block4 = Blob()
+    block4.name = "block4"
+    block4.content = None
+
     blocks = {'container1': [block1, block2, block3],
     blocks = {'container1': [block1, block2, block3],
-              'container2': [block1, block2, block3]}
+              'container2': [block1, block2, block3, block4]}
 
 
     rg = ResourceGroup(location='westus')
     rg = ResourceGroup(location='westus')
     rg.name = "testResourceGroup"
     rg.name = "testResourceGroup"
@@ -90,6 +101,10 @@ class MockAzureClient:
     volume1.owner_id = 'ubuntu-intro1'
     volume1.owner_id = 'ubuntu-intro1'
     volume1.provisioning_state = 'InProgress'
     volume1.provisioning_state = 'InProgress'
     volume1.tags = {'Name': 'Volume1'}
     volume1.tags = {'Name': 'Volume1'}
+    volume1.creation_data.source_uri = \
+        '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
+        '/resourceGroups/CLOUDBRIDGE-AZURE' \
+        '/providers/Microsoft.Compute/snapshots/snapshot1'
 
 
     volume2 = Disk(location='eastus', creation_data=None)
     volume2 = Disk(location='eastus', creation_data=None)
     volume2.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
     volume2.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
@@ -120,7 +135,7 @@ class MockAzureClient:
 
 
     snapshot2 = Snapshot(location='eastus', creation_data=creation_data)
     snapshot2 = Snapshot(location='eastus', creation_data=creation_data)
     snapshot2.name = 'snapshot2'
     snapshot2.name = 'snapshot2'
-    snapshot2.tags = {'Name': 'snapshot1'}
+    snapshot2.tags = None
     snapshot2.disk_size_gb = 2
     snapshot2.disk_size_gb = 2
     snapshot2.creation_data = \
     snapshot2.creation_data = \
         CreationData(create_option=DiskCreateOption.empty)
         CreationData(create_option=DiskCreateOption.empty)
@@ -131,10 +146,30 @@ class MockAzureClient:
     snapshot2.account_type = ' Standard_LRS'
     snapshot2.account_type = ' Standard_LRS'
 
 
     snapshots = [snapshot1, snapshot2]
     snapshots = [snapshot1, snapshot2]
+    vm1 = VirtualMachine(location='eastus')
+    vm1.name = 'VM1'
+
+    vm1.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
+             '/resourceGroups/CLOUDBRIDGE-AZURE'\
+             '/providers/Microsoft.Compute/virtualMachines/VM1'
+    vm1.storage_profile = StorageProfile()
+    data_disk_id = '/subscriptions'\
+                   '/7904d702-e01c-4826-8519-f5a25c866a96' \
+                   '/resourceGroups/CLOUDBRIDGE-AZURE' \
+                   '/providers/Microsoft.Compute/disks/Volume2'
+    data_dik = \
+        DataDisk(managed_disk=ManagedDiskParameters(id=data_disk_id),
+                 lun=0, create_option='attach')
+    vm1.storage_profile.data_disks = [data_dik]
+    virtual_machines = [vm1]
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         self._provider = provider
         self._provider = provider
 
 
+    @property
+    def region_name(self):
+        return 'eastus'
+
     def create_security_group(self, name, parameters):
     def create_security_group(self, name, parameters):
         sg_create = NetworkSecurityGroup()
         sg_create = NetworkSecurityGroup()
         sg_create.name = name
         sg_create.name = name
@@ -223,8 +258,14 @@ class MockAzureClient:
         self.containers.remove(container)
         self.containers.remove(container)
 
 
     def create_blob_from_text(self, container_name, blob_name, text):
     def create_blob_from_text(self, container_name, blob_name, text):
+        if blob_name == 'block4' and text != '':
+            raise AzureException()
         blob = self.get_blob(container_name, blob_name)
         blob = self.get_blob(container_name, blob_name)
         blob.content = text
         blob.content = text
+        blob.properties = BlobProperties()
+        blob.properties.content_length = len(text)
+        blob.properties.last_modified = \
+            datetime(year=2017, month=5, day=2)
         return blob
         return blob
 
 
     def get_blob(self, container_name, blob_name):
     def get_blob(self, container_name, blob_name):
@@ -246,31 +287,37 @@ class MockAzureClient:
         return None
         return None
 
 
     def delete_blob(self, container_name, blob_name):
     def delete_blob(self, container_name, blob_name):
-        for blob in self.blocks.get(container_name):
-            if blob.name == blob_name:
-                self.blocks.get(container_name).remove(blob)
+        blob = self.get_blob(container_name, blob_name)
+        self.blocks.get(container_name).remove(blob)
 
 
     def create_blob_from_file(self, container_name, blob_name, file_path):
     def create_blob_from_file(self, container_name, blob_name, file_path):
+        if blob_name == 'block4':
+            raise AzureException()
+
         blob = self.get_blob(container_name, blob_name)
         blob = self.get_blob(container_name, blob_name)
         blob.content = file_path
         blob.content = file_path
 
 
     def get_blob_url(self, container_name, blob_name):
     def get_blob_url(self, container_name, blob_name):
         return 'https://cloudbridgeazure.blob.core.windows.net/vhds/block1'
         return 'https://cloudbridgeazure.blob.core.windows.net/vhds/block1'
 
 
-    def create_empty_disk(self, disk_name, size,
-                          region=None, snapshot_id=None, description=None):
+    def create_empty_disk(self, disk_name, params):
         volume = Disk(location='eastus', creation_data=None)
         volume = Disk(location='eastus', creation_data=None)
         volume.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/' \
         volume.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/' \
                     'resourceGroups/cloudbridge-azure' \
                     'resourceGroups/cloudbridge-azure' \
                     '/providers/Microsoft.Compute/disks/{0}'.format(disk_name)
                     '/providers/Microsoft.Compute/disks/{0}'.format(disk_name)
         volume.name = disk_name
         volume.name = disk_name
-        volume.disk_size_gb = size
+        volume.disk_size_gb = 30
         volume.creation_data = CreationData(
         volume.creation_data = CreationData(
             create_option=DiskCreateOption.empty)
             create_option=DiskCreateOption.empty)
         volume.time_created = datetime(year=2017, month=5, day=2)
         volume.time_created = datetime(year=2017, month=5, day=2)
         volume.location = 'eastus'
         volume.location = 'eastus'
         volume.provisioning_state = 'Succeeded'
         volume.provisioning_state = 'Succeeded'
-        volume.tags = {'Name': disk_name, 'Description': description}
+        volume.tags = params.get('tags', None)
+        if disk_name.startswith('attach'):
+            volume.owner_id = \
+                '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
+                '/resourceGroups/CLOUDBRIDGE-AZURE'\
+                '/providers/Microsoft.Compute/virtualMachines/VM1'
         self.volumes.append(volume)
         self.volumes.append(volume)
         return volume
         return volume
 
 
@@ -290,26 +337,6 @@ class MockAzureClient:
         self.volumes.remove(disk)
         self.volumes.remove(disk)
         return True
         return True
 
 
-    def attach_disk(self, vm_name, disk_name, disk_id):
-        disk = self.get_disk(disk_name)
-        if disk.owner_id:
-            response = Response()
-            response.status_code = 404
-            raise CloudError(response=response,
-                             error='Resource already in use')
-
-        disk.owner_id = vm_name
-
-    def detach_disk(self, disk_id):
-        for d in self.volumes:
-            if d.id == disk_id and not d.owner_id:
-                response = Response()
-                response.status_code = 404
-                raise CloudError(response=response,
-                                 error='Resource already available')
-            elif d.id == disk_id:
-                d.owner_id = None
-
     def get_storage_account(self, storage_account_name):
     def get_storage_account(self, storage_account_name):
         if storage_account_name == 'cloudbridgeazure':
         if storage_account_name == 'cloudbridgeazure':
             response = Response()
             response = Response()
@@ -328,13 +355,12 @@ class MockAzureClient:
     def update_disk_tags(self, disk_name, tags):
     def update_disk_tags(self, disk_name, tags):
         pass
         pass
 
 
-    def create_snapshot(self, snapshot_name, disk_name,
-                        description=None, region=None):
+    def create_snapshot(self, snapshot_name, params):
         snapshot = Snapshot(location='eastus', creation_data=None)
         snapshot = Snapshot(location='eastus', creation_data=None)
         snapshot.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
         snapshot.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
                       '/resourceGroups/cloudbridge-azure' \
                       '/resourceGroups/cloudbridge-azure' \
                       '/providers/Microsoft.Compute/Snapshots/{0}'.format(
                       '/providers/Microsoft.Compute/Snapshots/{0}'.format(
-                        disk_name)
+                        snapshot_name)
         snapshot.name = snapshot_name
         snapshot.name = snapshot_name
         snapshot.disk_size_gb = 30
         snapshot.disk_size_gb = 30
         snapshot.creation_data = \
         snapshot.creation_data = \
@@ -344,9 +370,8 @@ class MockAzureClient:
             '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
             '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
             '/resourceGroups/CloudBridge-Azure/providers' \
             '/resourceGroups/CloudBridge-Azure/providers' \
             '/Microsoft.Compute/disks/{0}'.format(
             '/Microsoft.Compute/disks/{0}'.format(
-                disk_name)
-        if description:
-            snapshot.tags = {'Description': description}
+                snapshot_name)
+        snapshot.tags = params.get('tags', None)
         self.snapshots.append(snapshot)
         self.snapshots.append(snapshot)
         return snapshot
         return snapshot
 
 
@@ -369,7 +394,7 @@ class MockAzureClient:
         self.snapshots.remove(snapshot)
         self.snapshots.remove(snapshot)
         return True
         return True
 
 
-    def create_snapshot_disk(self, disk_name, snapshot_id, region=None):
+    def create_snapshot_disk(self, disk_name, params):
         volume = Disk(location='eastus', creation_data=None)
         volume = Disk(location='eastus', creation_data=None)
         volume.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
         volume.id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
                     '/resourceGroups/cloudbridge-azure/providers' \
                     '/resourceGroups/cloudbridge-azure/providers' \
@@ -379,11 +404,39 @@ class MockAzureClient:
         volume.disk_size_gb = 50
         volume.disk_size_gb = 50
         volume.creation_data = CreationData(
         volume.creation_data = CreationData(
             create_option=DiskCreateOption.copy,
             create_option=DiskCreateOption.copy,
-            source_uri=snapshot_id)
+            source_uri=params.get('creation_data').get('source_uri'))
         volume.time_created = '01-01-2017'
         volume.time_created = '01-01-2017'
-        volume.tags = {'Name': disk_name}
+        volume.tags = params.get('tags', None)
         self.volumes.append(volume)
         self.volumes.append(volume)
         return volume
         return volume
 
 
     def list_snapshots(self):
     def list_snapshots(self):
         return self.snapshots
         return self.snapshots
+
+    def get_vm(self, vm_name):
+        for virtual_machine in self.virtual_machines:
+            if virtual_machine.name == vm_name:
+                return virtual_machine
+
+        response = Response()
+        response.status_code = 404
+        raise CloudError(response=response, error='Resource Not found')
+
+    def create_or_update_vm(self, vm_name, params):
+        for data_disk in params.storage_profile.data_disks:
+            if isinstance(data_disk, dict):
+                disk_id = data_disk.get('managed_disk').get('id')
+                lun = data_disk.get('lun')
+                create_option = data_disk.get('create_option')
+                managed_disk = \
+                    ManagedDiskParameters(id=disk_id)
+                params.storage_profile.data_disks.remove(data_disk)
+                params.storage_profile.\
+                    data_disks\
+                    .append(DataDisk(managed_disk=managed_disk,
+                            lun=lun, create_option=create_option))
+
+        return params
+
+    def list_vm(self):
+        return self.virtual_machines

+ 76 - 27
cloudbridge/cloud/providers/azure/resources.py

@@ -88,6 +88,21 @@ class AzureSecurityGroup(BaseSecurityGroup):
     def network_id(self):
     def network_id(self):
         return self._security_group.resource_guid
         return self._security_group.resource_guid
 
 
+    @property
+    def resource_name(self):
+        return self._security_group.name
+
+    @property
+    def name(self):
+        return self._security_group.tags.get('Name', self._security_group.name)
+
+    @name.setter
+    def name(self, value):
+        self._security_group.tags.update(Name=value)
+        self._provider.azure_client. \
+            update_security_group_tags(self.resource_name,
+                                       self._security_group.tags)
+
     @property
     @property
     def description(self):
     def description(self):
         return self._security_group.tags.get('Description', None)
         return self._security_group.tags.get('Description', None)
@@ -95,9 +110,9 @@ class AzureSecurityGroup(BaseSecurityGroup):
     @description.setter
     @description.setter
     def description(self, value):
     def description(self, value):
         self._security_group.tags.update(Description=value)
         self._security_group.tags.update(Description=value)
-        print(self._security_group.tags)
         self._provider.azure_client.\
         self._provider.azure_client.\
-            update_security_group_tags(self.name, self._security_group.tags)
+            update_security_group_tags(self.resource_name,
+                                       self._security_group.tags)
 
 
     @property
     @property
     def rules(self):
     def rules(self):
@@ -143,7 +158,6 @@ class AzureSecurityGroup(BaseSecurityGroup):
         rule = self.get_rule(ip_protocol, from_port,
         rule = self.get_rule(ip_protocol, from_port,
                              to_port, cidr_ip, src_group)
                              to_port, cidr_ip, src_group)
         if not rule:
         if not rule:
-            security_group = self._security_group.name
             # resource_group = self._provider.resource_group
             # resource_group = self._provider.resource_group
             count = len(self.rules) + 1
             count = len(self.rules) + 1
             rule_name = "Rule - " + str(count)
             rule_name = "Rule - " + str(count)
@@ -162,7 +176,7 @@ class AzureSecurityGroup(BaseSecurityGroup):
                               destination_address_prefix,
                               destination_address_prefix,
                           "access": access, "direction": direction}
                           "access": access, "direction": direction}
             result = self._provider.azure_client. \
             result = self._provider.azure_client. \
-                create_security_group_rule(security_group,
+                create_security_group_rule(self.resource_name,
                                            rule_name, parameters)
                                            rule_name, parameters)
             self._security_group.security_rules.append(result)
             self._security_group.security_rules.append(result)
             return AzureSecurityGroupRule(self._provider, result, self)
             return AzureSecurityGroupRule(self._provider, result, self)
@@ -432,6 +446,10 @@ class AzureVolume(BaseVolume):
     def id(self):
     def id(self):
         return self._volume.id
         return self._volume.id
 
 
+    @property
+    def resource_name(self):
+        return self._volume.name
+
     @property
     @property
     def name(self):
     def name(self):
         """
         """
@@ -439,7 +457,7 @@ class AzureVolume(BaseVolume):
 
 
         .. note:: an instance must have a (case sensitive) tag ``Name``
         .. note:: an instance must have a (case sensitive) tag ``Name``
         """
         """
-        return self._volume.name
+        return self._volume.tags.get('Name', self._volume.name)
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -448,7 +466,10 @@ class AzureVolume(BaseVolume):
         Set the volume name.
         Set the volume name.
         """
         """
         # self._volume.name = value
         # self._volume.name = value
-        pass
+        self._volume.tags.update(Name=value)
+        self._provider.azure_client.\
+            update_disk_tags(self.resource_name,
+                             self._volume.tags)
 
 
     @property
     @property
     def description(self):
     def description(self):
@@ -458,7 +479,7 @@ class AzureVolume(BaseVolume):
     def description(self, value):
     def description(self, value):
         self._volume.tags.update(Description=value)
         self._volume.tags.update(Description=value)
         self._provider.azure_client.\
         self._provider.azure_client.\
-            update_disk_tags(self._url_params.get(VOLUME_NAME),
+            update_disk_tags(self.resource_name,
                              self._volume.tags)
                              self._volume.tags)
 
 
     @property
     @property
@@ -499,8 +520,19 @@ class AzureVolume(BaseVolume):
                 Instance) else instance
                 Instance) else instance
             params = azure_helpers.parse_url(INSTANCE_RESOURCE_ID,
             params = azure_helpers.parse_url(INSTANCE_RESOURCE_ID,
                                              instance_id)
                                              instance_id)
-            self._provider.azure_client.attach_disk(params.get(VM_NAME),
-                                                    self.name, self.id)
+
+            vm = self._provider.azure_client.get_vm(params.get(VM_NAME))
+
+            vm.storage_profile.data_disks.append({
+                'lun': len(vm.storage_profile.data_disks),
+                'name': self.resource_name,
+                'create_option': 'attach',
+                'managed_disk': {
+                    'id': self.id
+                }
+            })
+            self._provider.azure_client\
+                .create_or_update_vm(params.get(VM_NAME), vm)
             return True
             return True
         except CloudError:
         except CloudError:
             return False
             return False
@@ -509,11 +541,24 @@ class AzureVolume(BaseVolume):
         """
         """
         Detach this volume from an instance.
         Detach this volume from an instance.
         """
         """
-        try:
-            self._provider.azure_client.detach_disk(self.id)
+        virtual_machine = None
+        for index, vm in enumerate(
+                self._provider.azure_client.list_vm()):
+            for item in vm.storage_profile.data_disks:
+                if item.managed_disk and item.managed_disk.id == self.id:
+                    vm.storage_profile.data_disks.remove(item)
+                    virtual_machine = vm
+                    break
+            if virtual_machine:
+                break
+
+        if virtual_machine:
+            self._provider.azure_client.create_or_update_vm(
+                virtual_machine.name,
+                virtual_machine
+            )
             return True
             return True
-        except CloudError:
-            return False
+        return False
 
 
     def create_snapshot(self, name, description=None):
     def create_snapshot(self, name, description=None):
         """
         """
@@ -527,7 +572,7 @@ class AzureVolume(BaseVolume):
         """
         """
         try:
         try:
             self._provider.azure_client.\
             self._provider.azure_client.\
-                delete_disk(self._url_params.get(VOLUME_NAME))
+                delete_disk(self.resource_name)
             return True
             return True
         except CloudError:
         except CloudError:
             return False
             return False
@@ -543,9 +588,8 @@ class AzureVolume(BaseVolume):
         for its latest state.
         for its latest state.
         """
         """
         try:
         try:
-            print('Volume status ' + self._status)
             self._volume = self._provider.azure_client.\
             self._volume = self._provider.azure_client.\
-                get_disk(self._url_params.get(VOLUME_NAME))
+                get_disk(self.resource_name)
             self.update_status()
             self.update_status()
         except (CloudError, ValueError):
         except (CloudError, ValueError):
             # The volume no longer exists and cannot be refreshed.
             # The volume no longer exists and cannot be refreshed.
@@ -578,6 +622,10 @@ class AzureSnapshot(BaseSnapshot):
     def id(self):
     def id(self):
         return self._snapshot.id
         return self._snapshot.id
 
 
+    @property
+    def resource_name(self):
+        return self._snapshot.name
+
     @property
     @property
     def name(self):
     def name(self):
         """
         """
@@ -585,7 +633,7 @@ class AzureSnapshot(BaseSnapshot):
 
 
         .. note:: an instance must have a (case sensitive) tag ``Name``
         .. note:: an instance must have a (case sensitive) tag ``Name``
         """
         """
-        return self._snapshot.name
+        return self._snapshot.tags.get('Name', self._snapshot.name)
 
 
     @name.setter
     @name.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
@@ -594,7 +642,10 @@ class AzureSnapshot(BaseSnapshot):
         Set the snapshot name.
         Set the snapshot name.
         """
         """
         # self._snapshot.name = value
         # self._snapshot.name = value
-        pass
+        self._snapshot.tags.update(Name=value)
+        self._provider.azure_client. \
+            update_snapshot_tags(self.resource_name,
+                                 self._snapshot.tags)
 
 
     @property
     @property
     def description(self):
     def description(self):
@@ -604,7 +655,8 @@ class AzureSnapshot(BaseSnapshot):
     def description(self, value):
     def description(self, value):
         self._snapshot.tags.update(Description=value)
         self._snapshot.tags.update(Description=value)
         self._provider.azure_client.\
         self._provider.azure_client.\
-            update_snapshot_tags(self.name, self._snapshot.tags)
+            update_snapshot_tags(self.resource_name,
+                                 self._snapshot.tags)
 
 
     @property
     @property
     def size(self):
     def size(self):
@@ -630,7 +682,7 @@ class AzureSnapshot(BaseSnapshot):
         """
         """
         try:
         try:
             self._snapshot = self._provider.azure_client.\
             self._snapshot = self._provider.azure_client.\
-                get_snapshot(self.name)
+                get_snapshot(self.resource_name)
             self._status = self._snapshot.provisioning_state
             self._status = self._snapshot.provisioning_state
         except (CloudError, ValueError):
         except (CloudError, ValueError):
             # The snapshot no longer exists and cannot be refreshed.
             # The snapshot no longer exists and cannot be refreshed.
@@ -642,7 +694,7 @@ class AzureSnapshot(BaseSnapshot):
         Delete this snapshot.
         Delete this snapshot.
         """
         """
         try:
         try:
-            self._provider.azure_client.delete_snapshot(self.name)
+            self._provider.azure_client.delete_snapshot(self.resource_name)
             return True
             return True
         except CloudError:
         except CloudError:
             return False
             return False
@@ -652,9 +704,6 @@ class AzureSnapshot(BaseSnapshot):
         """
         """
         Create a new Volume from this Snapshot.
         Create a new Volume from this Snapshot.
         """
         """
-        self._provider.azure_client.\
-            create_snapshot_disk(self.name + '_disk',
-                                 self.id, region=placement)
-        azure_vol = self._provider.azure_client.get_disk(self.name + '_disk')
-        cb_vol = AzureVolume(self._provider, azure_vol)
-        return cb_vol
+        return self._provider.block_store.volumes.\
+            create(self.resource_name, self.size,
+                   zone=placement, snapshot=self)

+ 52 - 11
cloudbridge/cloud/providers/azure/services.py

@@ -1,4 +1,5 @@
 import logging
 import logging
+import uuid
 
 
 from azure.common import AzureException
 from azure.common import AzureException
 
 
@@ -73,10 +74,11 @@ class AzureSecurityGroupService(BaseSecurityGroupService):
         return ClientPagedResultList(self.provider, sgs, limit, marker)
         return ClientPagedResultList(self.provider, sgs, limit, marker)
 
 
     def create(self, name, description, network_id):
     def create(self, name, description, network_id):
-        parameters = {"location": self.provider.region_name}
+        parameters = {"location": self.provider.region_name,
+                      'tags': {'Name': name}}
 
 
         if description:
         if description:
-            parameters['tags'] = {'Description': description}
+            parameters['tags'].update(Description=description)
 
 
         sg = self.provider.azure_client.create_security_group(name, parameters)
         sg = self.provider.azure_client.create_security_group(name, parameters)
         cb_sg = AzureSecurityGroup(self.provider, sg)
         cb_sg = AzureSecurityGroup(self.provider, sg)
@@ -87,7 +89,7 @@ class AzureSecurityGroupService(BaseSecurityGroupService):
         """
         """
         Searches for a security group by a given list of attributes.
         Searches for a security group by a given list of attributes.
         """
         """
-        filters = {'name': name}
+        filters = {'Name': name}
         sgs = [AzureSecurityGroup(self.provider, security_group)
         sgs = [AzureSecurityGroup(self.provider, security_group)
                for security_group in azure_helpers.filter(
                for security_group in azure_helpers.filter(
                 self.provider.azure_client.list_security_group(), filters)]
                 self.provider.azure_client.list_security_group(), filters)]
@@ -181,7 +183,7 @@ class AzureVolumeService(BaseVolumeService):
         """
         """
         Searches for a volume by a given list of attributes.
         Searches for a volume by a given list of attributes.
         """
         """
-        filters = {'name': name}
+        filters = {'Name': name}
         cb_vols = [AzureVolume(self.provider, volume)
         cb_vols = [AzureVolume(self.provider, volume)
                    for volume in azure_helpers.filter(
                    for volume in azure_helpers.filter(
                 self.provider.azure_client.list_disks(), filters)]
                 self.provider.azure_client.list_disks(), filters)]
@@ -198,9 +200,34 @@ class AzureVolumeService(BaseVolumeService):
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         snapshot_id = snapshot.id if isinstance(
         snapshot_id = snapshot.id if isinstance(
             snapshot, Snapshot) and snapshot else snapshot
             snapshot, Snapshot) and snapshot else snapshot
-        self.provider.azure_client.create_empty_disk(
-            name, size, zone_id, snapshot_id, description=description)
-        azure_vol = self.provider.azure_client.get_disk(name)
+        disk_name = "{0}-{1}".format(name, uuid.uuid4().hex[:6])
+        tags = {'Name': name}
+        if description:
+            tags.update(Description=description)
+        if snapshot_id:
+            params = {
+                'location': zone_id or self.provider.azure_client.region_name,
+                'creation_data': {
+                    'create_option': 'copy',
+                    'source_uri': snapshot_id
+                },
+                'tags': tags
+            }
+
+            self.provider.azure_client.create_snapshot_disk(disk_name, params)
+
+        else:
+            params = {
+                'location': zone_id or self.provider.azure_client.region_name,
+                'disk_size_gb': size,
+                'creation_data': {
+                  'create_option': 'empty'
+                  },
+                'tags': tags}
+
+            self.provider.azure_client.create_empty_disk(disk_name, params)
+
+        azure_vol = self.provider.azure_client.get_disk(disk_name)
         cb_vol = AzureVolume(self.provider, azure_vol)
         cb_vol = AzureVolume(self.provider, azure_vol)
 
 
         return cb_vol
         return cb_vol
@@ -236,11 +263,25 @@ class AzureSnapshotService(BaseSnapshotService):
 
 
     def create(self, name, volume, description=None):
     def create(self, name, volume, description=None):
         volume_id = volume.id if isinstance(volume, Volume) else volume
         volume_id = volume.id if isinstance(volume, Volume) else volume
-        params = azure_helpers.parse_url(VOLUME_RESOURCE_ID, volume_id)
+
+        tags = {'Name': name}
+        snapshot_name = "{0}-{1}".format(name, uuid.uuid4().hex[:6])
+
+        if description:
+            tags.update(Description=description)
+
+        params = {
+            'location': self.provider.azure_client.region_name,
+            'creation_data': {
+                'create_option': 'Copy',
+                'source_uri': volume_id
+            },
+            'tags': tags
+        }
+
         self.provider.azure_client. \
         self.provider.azure_client. \
-            create_snapshot(name, params.get(VOLUME_NAME),
-                            description=description)
-        azure_snap = self.provider.azure_client.get_snapshot(name)
+            create_snapshot(snapshot_name, params)
+        azure_snap = self.provider.azure_client.get_snapshot(snapshot_name)
         cb_snap = AzureSnapshot(self.provider, azure_snap)
         cb_snap = AzureSnapshot(self.provider, azure_snap)
 
 
         return cb_snap
         return cb_snap

+ 12 - 8
integration_test/test_integration_azure_volume_service.py

@@ -6,8 +6,8 @@ import azure_integration_test.helpers as helpers
 class AzureIntegrationVolumeServiceTestCase(helpers.ProviderTestBase):
 class AzureIntegrationVolumeServiceTestCase(helpers.ProviderTestBase):
     @helpers.skipIfNoService(['block_store'])
     @helpers.skipIfNoService(['block_store'])
     def test_azure_volume_service(self):
     def test_azure_volume_service(self):
-        volume_name = '{0}'.format(uuid.uuid4())
-        snapshot_name = '{0}'.format(uuid.uuid4())
+        volume_name = '{0}'.format(uuid.uuid4().hex[:6])
+        snapshot_name = '{0}'.format(uuid.uuid4().hex[:6])
 
 
         volume_list_before_create = self.provider.block_store.volumes.list()
         volume_list_before_create = self.provider.block_store.volumes.list()
         print(str(len(volume_list_before_create)))
         print(str(len(volume_list_before_create)))
@@ -32,16 +32,20 @@ class AzureIntegrationVolumeServiceTestCase(helpers.ProviderTestBase):
         print("Find Volume  - " + str(volume))
         print("Find Volume  - " + str(volume))
         self.assertEqual(
         self.assertEqual(
             len(volume_find), 1)
             len(volume_find), 1)
-        # volume.attach('/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/CloudBridge-Azure/providers/Microsoft.Compute/virtualMachines/ubuntu-intro2')
+        instance_id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96' \
+                      '/resourceGroups/CloudBridge-Azure/providers'\
+                      '/Microsoft.Compute/virtualMachines/ubuntu-intro1'
+        volume.attach(instance_id)
         # TODO: Add logic to verify that disk is attached to instance
         # TODO: Add logic to verify that disk is attached to instance
 
 
-        # volume.detach()
+        volume.detach()
         # TODO: Add logic to verify that disk is not in use
         # TODO: Add logic to verify that disk is not in use
 
 
-        with self.assertRaises(NotImplementedError):
-            volume.create_snapshot(snapshot_name)
-        # self.assertTrue(snapshot is not None,
-        # 'Snapshot {0} not created'.format(snapshot_name))
+        snapshot = volume.create_snapshot(snapshot_name)
+        self.assertTrue(snapshot is not None,
+                        'Snapshot {0} not created'.format(snapshot_name))
+
+        snapshot.delete()
 
 
         volume.refresh()
         volume.refresh()
         self.assertTrue(volume.id == volume_id,
         self.assertTrue(volume.id == volume_id,

+ 8 - 8
test/test_azure_helpers.py

@@ -16,29 +16,29 @@ class AzureHelpersTestCase(ProviderTestBase):
 
 
     def test_filter_matched(self):
     def test_filter_matched(self):
         ex1 = Expando()
         ex1 = Expando()
-        ex1.name = 'test'
+        ex1.tags = {'Name': 'test'}
 
 
         ex2 = Expando()
         ex2 = Expando()
-        ex2.name = 'abc'
+        ex2.tags = {'Name': 'abc'}
 
 
-        result = azure_helpers.filter([ex1, ex2], {'name': 'test'})
+        result = azure_helpers.filter([ex1, ex2], {'Name': 'test'})
         self.assertTrue(len(result) == 1, 'Result count should be one')
         self.assertTrue(len(result) == 1, 'Result count should be one')
 
 
     def test_filter_not_matched(self):
     def test_filter_not_matched(self):
         ex1 = Expando()
         ex1 = Expando()
-        ex1.name = 'pqr'
+        ex1.tags = {'Name': 'pqr'}
 
 
         ex2 = Expando()
         ex2 = Expando()
-        ex2.name = 'abc'
-        result = azure_helpers.filter([ex1, ex2], {'name': 'test123'})
+        ex2.tags = {'Name': 'abc'}
+        result = azure_helpers.filter([ex1, ex2], {'Name': 'test123'})
         self.assertTrue(len(result) == 0, 'Result count should be zero')
         self.assertTrue(len(result) == 0, 'Result count should be zero')
 
 
     def test_filter_None(self):
     def test_filter_None(self):
         ex1 = Expando()
         ex1 = Expando()
-        ex1.name = 'pqr'
+        ex1.tags = {'Name': 'test'}
 
 
         ex2 = Expando()
         ex2 = Expando()
-        ex2.name = 'abc'
+        ex2.tags = {'Name': 'abc'}
         result = azure_helpers.filter([ex1, ex2], None)
         result = azure_helpers.filter([ex1, ex2], None)
         self.assertTrue(len(result) == 2, 'Result count should be two')
         self.assertTrue(len(result) == 2, 'Result count should be two')
 
 

+ 27 - 5
test/test_azure_object_store_service.py

@@ -9,6 +9,7 @@ class AzureObjectStoreServiceTestCase(ProviderTestBase):
         print("Create - " + str(container))
         print("Create - " + str(container))
         self.assertEqual(
         self.assertEqual(
             str(container), "<CB-AzureBucket: container3>")
             str(container), "<CB-AzureBucket: container3>")
+        self.assertIsNotNone(container.id)
 
 
     @helpers.skipIfNoService(['object_store'])
     @helpers.skipIfNoService(['object_store'])
     def test_azure_bucket_list(self):
     def test_azure_bucket_list(self):
@@ -55,15 +56,21 @@ class AzureObjectStoreServiceTestCase(ProviderTestBase):
         print("Bucket delete - " + str(contDel))
         print("Bucket delete - " + str(contDel))
         self.assertEqual(
         self.assertEqual(
             contDel, True)
             contDel, True)
+        contDel = cont.delete()
+        self.assertEqual(
+            contDel, False)
 
 
     @helpers.skipIfNoService(['object_store'])
     @helpers.skipIfNoService(['object_store'])
     def test_azure_bucket_create_object(self):
     def test_azure_bucket_create_object(self):
         containers = self.provider.object_store.find("container1")
         containers = self.provider.object_store.find("container1")
         cont = containers[0]
         cont = containers[0]
-        contDel = cont.create_object("block1")
-        print("Create object  - " + str(contDel))
+        obj = cont.create_object("block1")
+        self.assertIsNotNone(obj.id)
+        self.assertIsNotNone(obj.size)
+        self.assertIsNotNone(obj.last_modified)
+        print("Create object  - " + str(obj))
         self.assertEqual(
         self.assertEqual(
-            str(contDel), '<CB-AzureBucketObject: block1>')
+            str(obj), '<CB-AzureBucketObject: block1>')
 
 
     @helpers.skipIfNoService(['object_store'])
     @helpers.skipIfNoService(['object_store'])
     def test_azure_bucket_object_exists__internalE(self):
     def test_azure_bucket_object_exists__internalE(self):
@@ -90,7 +97,7 @@ class AzureObjectStoreServiceTestCase(ProviderTestBase):
         contDel = cont.list()
         contDel = cont.list()
         print("List object  - " + str(contDel))
         print("List object  - " + str(contDel))
         self.assertEqual(
         self.assertEqual(
-            len(contDel), 2)
+            len(contDel), 3)
 
 
     @helpers.skipIfNoService(['object_store'])
     @helpers.skipIfNoService(['object_store'])
     def test_azure_bucket_object_get(self):
     def test_azure_bucket_object_get(self):
@@ -139,7 +146,9 @@ class AzureObjectStoreServiceTestCase(ProviderTestBase):
         block = blocks[0]
         block = blocks[0]
         block.delete()
         block.delete()
         self.assertEqual(
         self.assertEqual(
-            len(cont.list()), 2)
+            len(cont.list()), 3)
+        deleted = block.delete()
+        self.assertEqual(deleted, False)
 
 
     @helpers.skipIfNoService(['object_store'])
     @helpers.skipIfNoService(['object_store'])
     def test_azure_bucket_object_upload_from_file(self):
     def test_azure_bucket_object_upload_from_file(self):
@@ -151,6 +160,19 @@ class AzureObjectStoreServiceTestCase(ProviderTestBase):
         self.assertEqual(
         self.assertEqual(
             block.iter_content().getvalue(), b'blob2Content')
             block.iter_content().getvalue(), b'blob2Content')
 
 
+    @helpers.skipIfNoService(['object_store'])
+    def test_azure_bucket_object_upload_exception(self):
+        containers = self.provider.object_store.find("container2")
+        cont = containers[0]
+        blob = cont.create_object('block4')
+        uploaded = blob.upload_from_file('E:\\blob2Content.txt')
+        self.assertEqual(uploaded, False)
+
+        uploaded = blob.upload('blob2Content')
+        self.assertEqual(uploaded, False)
+
+        blob.delete()
+
     @helpers.skipIfNoService(['object_store'])
     @helpers.skipIfNoService(['object_store'])
     def test_azure_bucket_object_generate_url(self):
     def test_azure_bucket_object_generate_url(self):
         containers = self.provider.object_store.find("container2")
         containers = self.provider.object_store.find("container2")

+ 5 - 1
test/test_azure_security_service.py

@@ -24,6 +24,7 @@ class AzureSecurityServiceTestCase(ProviderTestBase):
         print("Create - " + str(sg))
         print("Create - " + str(sg))
         self.assertEqual(name, sg.name)
         self.assertEqual(name, sg.name)
         sg.description = name
         sg.description = name
+        sg.name = 'NewName'
         self.assertEqual(name, sg.description)
         self.assertEqual(name, sg.description)
         self.provider.security.security_groups.delete(
         self.provider.security.security_groups.delete(
             "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
             "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
@@ -33,7 +34,7 @@ class AzureSecurityServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['security.security_groups'])
     @helpers.skipIfNoService(['security.security_groups'])
     def test_azure_security_group_find_exists(self):
     def test_azure_security_group_find_exists(self):
-        sgl = self.provider.security.security_groups.find("sg")
+        sgl = self.provider.security.security_groups.find("sg3")
         for sg in sgl:
         for sg in sgl:
             self.assertTrue("sg" in sg.name)
             self.assertTrue("sg" in sg.name)
         self.assertTrue(sgl.total_results > 0)
         self.assertTrue(sgl.total_results > 0)
@@ -142,6 +143,9 @@ class AzureSecurityServiceTestCase(ProviderTestBase):
         rule = cb.to_json()
         rule = cb.to_json()
         print("Get Rule -  " + str(rule))
         print("Get Rule -  " + str(rule))
         self.assertIsNotNone(rule)
         self.assertIsNotNone(rule)
+        cb = list.data[1]
+        rule = cb.to_json()
+        self.assertIsNotNone(rule)
 
 
     @helpers.skipIfNoService(['security.security_groups'])
     @helpers.skipIfNoService(['security.security_groups'])
     def test_azure_security_group_rule_to_json(self):
     def test_azure_security_group_rule_to_json(self):

+ 23 - 25
test/test_azure_volume_service.py

@@ -23,12 +23,12 @@ class AzureVolumeServiceTestCase(ProviderTestBase):
         volume.name = 'newname'
         volume.name = 'newname'
 
 
         volume = self.provider.block_store.volumes.get(
         volume = self.provider.block_store.volumes.get(
-            "/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96/resourceGroups/cloudbridge-azure/providers'\
-            '/Microsoft.Compute/disks/MyVolume")
+            volume.id)
         volume.description = 'My Volume desc'
         volume.description = 'My Volume desc'
         print("Get Volume  - " + str(volume))
         print("Get Volume  - " + str(volume))
         self.assertTrue(
         self.assertTrue(
-            volume.name == "MyVolume", "Volume name should be MyVolume")
+            volume.description == "My Volume desc",
+            "Volume description should be My Volume desc")
 
 
         volume.delete()
         volume.delete()
 
 
@@ -54,33 +54,28 @@ class AzureVolumeServiceTestCase(ProviderTestBase):
             volume1 is None, "Volume still exists")
             volume1 is None, "Volume still exists")
 
 
     @helpers.skipIfNoService(['block_store.volumes'])
     @helpers.skipIfNoService(['block_store.volumes'])
-    def test_azure_volume_attach(self):
+    def test_azure_volume_attach_and_detach(self):
         volume = self.provider.block_store.volumes.create(
         volume = self.provider.block_store.volumes.create(
-            "MyVolume", 1, description='My volume')
+            "attach", 1, description='My volume')
         self.assertTrue(
         self.assertTrue(
-            volume.name == "MyVolume", "Volume name should be MyVolume")
-        attached = volume.attach("/subscriptions'\
-        '/7904d702-e01c-4826-8519-f5a25c866a96'\
-        '/resourceGroups/CloudBridge-Azure/providers'\
-        '/Microsoft.Compute/virtualMachines/ubuntu-intro1")
+            volume.name == "attach", "Volume name should be MyVolume")
+        instance_id = '/subscriptions/7904d702-e01c-4826-8519-f5a25c866a96'\
+                      '/resourceGroups/CLOUDBRIDGE-AZURE'\
+                      '/providers/Microsoft.Compute/virtualMachines/VM1'
+        attached = volume.attach(instance_id)
 
 
         self.assertEqual(attached, True)
         self.assertEqual(attached, True)
-
-        attach_volume = volume.attach("/subscriptions'\
-        '/7904d702-e01c-4826-8519-f5a25c866a96'\
-        '/resourceGroups/CloudBridge-Azure/providers'\
-        '/Microsoft.Compute/virtualMachines/ubuntu-intro1")
+        self.assertIsNotNone(volume.attachments)
+        instance_id = instance_id + '1'
+        attach_volume = volume.attach(instance_id)
         self.assertEqual(attach_volume, False)
         self.assertEqual(attach_volume, False)
 
 
-        volume.delete()
+        detached = volume.detach()
+        self.assertEqual(detached, True)
+
+        detached = volume.detach()
+        self.assertEqual(detached, False)
 
 
-    @helpers.skipIfNoService(['block_store.volumes'])
-    def test_azure_volume_dettach(self):
-        volume = self.provider.block_store.volumes.create(
-            "MyVolume", 1, description='My volume')
-        self.assertTrue(
-            volume.name == "MyVolume", "Volume name should be MyVolume")
-        volume.detach()
         volume.delete()
         volume.delete()
 
 
     @helpers.skipIfNoService(['block_store.volumes'])
     @helpers.skipIfNoService(['block_store.volumes'])
@@ -106,9 +101,12 @@ class AzureVolumeServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['block_store.volumes'])
     @helpers.skipIfNoService(['block_store.volumes'])
     def test_azure_volume_find(self):
     def test_azure_volume_find(self):
-        volumes = self.provider.block_store.volumes.find("Volume")
+        volumes = self.provider.block_store.volumes.find("Volume1")
+        print(len(volumes))
+        print('after find')
         self.assertTrue(
         self.assertTrue(
-            len(volumes) == 2, "Volume should not be available")
+            len(volumes) == 1, "Volume should not be available")
+        self.assertIsNotNone(volumes[0].source)
 
 
     @helpers.skipIfNoService(['block_store.volumes'])
     @helpers.skipIfNoService(['block_store.volumes'])
     def test_azure_volume_find_ifNotExist(self):
     def test_azure_volume_find_ifNotExist(self):