almahmoud 7 лет назад
Родитель
Сommit
b43cc458d2

+ 3 - 0
cloudbridge/cloud/base/resources.py

@@ -462,6 +462,9 @@ class BaseVolume(BaseCloudResource, BaseObjectLifeCycleMixin, Volume):
             timeout=timeout,
             interval=interval)
 
+    def delete(self):
+        self._provider.storage.volumes.delete(self.id)
+
 
 class BaseSnapshot(BaseCloudResource, BaseObjectLifeCycleMixin, Snapshot):
 

+ 62 - 0
cloudbridge/cloud/base/services.py

@@ -11,6 +11,7 @@ from cloudbridge.cloud.base.resources import BaseNetwork
 from cloudbridge.cloud.base.resources import BaseRouter
 from cloudbridge.cloud.base.resources import BaseSubnet
 from cloudbridge.cloud.base.resources import BaseVMFirewall
+from cloudbridge.cloud.base.resources import BaseVolume
 from cloudbridge.cloud.interfaces.exceptions import \
     InvalidConfigurationException
 from cloudbridge.cloud.interfaces.resources import Network
@@ -253,6 +254,67 @@ class BaseVolumeService(
         super(BaseVolumeService, self).__init__(provider)
         self._service_event_pattern += ".storage.volumes"
 
+    def get(self, volume_id):
+        """
+        Returns a volume given its ID. Returns ``None`` if the volume
+        does not exist.
+
+        :type volume_id: str
+        :param volume_id: The id of the desired volume.
+
+        :rtype: ``Volume``
+        :return:  ``None`` is returned if the volume does not exist, and
+                  the volume's provider-specific CloudBridge object is
+                  returned if the volume is found.
+        """
+        return self.dispatch(self, "provider.storage.volumes.get",
+                             volume_id)
+
+    def find(self, **kwargs):
+        """
+        Returns a list of volumes filtered by the given keyword arguments.
+        Accepted search arguments are: 'label'
+        """
+        return self.dispatch(self, "provider.storage.volumes.find",
+                             **kwargs)
+
+    def list(self, limit=None, marker=None):
+        """
+        List all volumes.
+        """
+        return self.dispatch(self, "provider.storage.volumes.list",
+                             limit=limit, marker=marker)
+
+    def create(self, label, size, zone, description=None, snapshot=None):
+        """
+        Create a new volume.
+
+        :type label: str
+        :param label: The label of the volume to be created. Note that labels
+                     do not have to be unique, and are changeable.
+        :type size: int
+        :param size: The size (in Gb) of the volume to be created
+
+        :type zone: str
+        :param zone: The availability zone in which to create the volume
+
+        :rtype: ``Volume``
+        :return:  The created volume's provider-specific CloudBridge object.
+        """
+        BaseVolume.assert_valid_resource_label(label)
+        return self.dispatch(self, "provider.storage.volumes.create",
+                             label, size, zone, description, snapshot)
+
+    def delete(self, volume_id):
+        """
+        Delete an existing volume.
+
+        :type volume_id: str
+        :param volume_id: The ID of the volume to be deleted.
+        """
+        return self.dispatch(self, "provider.storage.volumes.delete",
+                             volume_id)
+
 
 class BaseSnapshotService(
         BasePageableObjectMixin, SnapshotService, BaseCloudService):

+ 0 - 3
cloudbridge/cloud/providers/aws/resources.py

@@ -496,9 +496,6 @@ class AWSVolume(BaseVolume):
         snap.wait_till_ready()
         return snap
 
-    def delete(self):
-        self._volume.delete()
-
     @property
     def state(self):
         if self._unknown_state:

+ 18 - 12
cloudbridge/cloud/providers/aws/services.py

@@ -224,12 +224,14 @@ class AWSVolumeService(BaseVolumeService):
                                   cb_resource=AWSVolume,
                                   boto_collection_name='volumes')
 
-    def get(self, volume_id):
-        log.debug("Getting AWS Volume Service with the id: %s",
-                  volume_id)
+    @implement(event_pattern="provider.storage.volumes.get",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _get(self, volume_id):
         return self.svc.get(volume_id)
 
-    def find(self, **kwargs):
+    @implement(event_pattern="provider.storage.volumes.find",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _find(self, **kwargs):
         label = kwargs.pop('label', None)
 
         # All kwargs should have been popped at this time.
@@ -240,16 +242,14 @@ class AWSVolumeService(BaseVolumeService):
         log.debug("Searching for AWS Volume Service %s", label)
         return self.svc.find(filter_name='tag:Name', filter_value=label)
 
-    def list(self, limit=None, marker=None):
+    @implement(event_pattern="provider.storage.volumes.list",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _list(self, limit=None, marker=None):
         return self.svc.list(limit=limit, marker=marker)
 
-    def create(self, label, size, zone, snapshot=None, description=None):
-        log.debug("Creating AWS Volume Service with the parameters "
-                  "[label: %s size: %s zone: %s snapshot: %s "
-                  "description: %s]", label, size, zone, snapshot,
-                  description)
-        AWSVolume.assert_valid_resource_label(label)
-
+    @implement(event_pattern="provider.storage.volumes.create",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, size, zone, snapshot=None, description=None):
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         snapshot_id = snapshot.id if isinstance(
             snapshot, AWSSnapshot) and snapshot else snapshot
@@ -264,6 +264,12 @@ class AWSVolumeService(BaseVolumeService):
             cb_vol.description = description
         return cb_vol
 
+    @implement(event_pattern="provider.storage.volumes.delete",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, volume_id):
+        aws_vol = self.svc.get_raw(volume_id)
+        aws_vol.delete()
+
 
 class AWSSnapshotService(BaseSnapshotService):
 

+ 0 - 6
cloudbridge/cloud/providers/azure/resources.py

@@ -518,12 +518,6 @@ class AzureVolume(BaseVolume):
         return self._provider.storage.snapshots.create(label, self,
                                                        description)
 
-    def delete(self):
-        """
-        Delete this volume.
-        """
-        self._provider.azure_client.delete_disk(self.id)
-
     @property
     def state(self):
         return AzureVolume.VOLUME_STATE_MAP.get(

+ 17 - 14
cloudbridge/cloud/providers/azure/services.py

@@ -259,10 +259,9 @@ class AzureVolumeService(BaseVolumeService):
     def __init__(self, provider):
         super(AzureVolumeService, self).__init__(provider)
 
-    def get(self, volume_id):
-        """
-        Returns a volume given its id.
-        """
+    @implement(event_pattern="provider.storage.volumes.get",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _get(self, volume_id):
         try:
             volume = self.provider.azure_client.get_disk(volume_id)
             return AzureVolume(self.provider, volume)
@@ -271,7 +270,9 @@ class AzureVolumeService(BaseVolumeService):
             log.exception(cloud_error)
             return None
 
-    def find(self, **kwargs):
+    @implement(event_pattern="provider.storage.volumes.find",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _find(self, **kwargs):
         obj_list = self
         filters = ['label']
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
@@ -285,20 +286,17 @@ class AzureVolumeService(BaseVolumeService):
         return ClientPagedResultList(self.provider,
                                      matches if matches else [])
 
-    def list(self, limit=None, marker=None):
-        """
-        List all volumes.
-        """
+    @implement(event_pattern="provider.storage.volumes.list",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _list(self, limit=None, marker=None):
         azure_vols = self.provider.azure_client.list_disks()
         cb_vols = [AzureVolume(self.provider, vol) for vol in azure_vols]
         return ClientPagedResultList(self.provider, cb_vols,
                                      limit=limit, marker=marker)
 
-    def create(self, label, size, zone, description=None, snapshot=None):
-        """
-        Creates a new volume.
-        """
-        AzureVolume.assert_valid_resource_label(label)
+    @implement(event_pattern="provider.storage.volumes.create",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, size, zone, description=None, snapshot=None):
         disk_name = AzureVolume._generate_name_from_label(label, "cb-vol")
         tags = {'Label': label}
 
@@ -342,6 +340,11 @@ class AzureVolumeService(BaseVolumeService):
 
         return cb_vol
 
+    @implement(event_pattern="provider.storage.volumes.delete",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, volume_id):
+        self.provider.azure_client.delete_disk(volume_id)
+
 
 class AzureSnapshotService(BaseSnapshotService):
     def __init__(self, provider):

+ 0 - 12
cloudbridge/cloud/providers/gce/resources.py

@@ -1937,18 +1937,6 @@ class GCEVolume(BaseVolume):
         return self._provider.storage.snapshots.create(
             label, self, description)
 
-    def delete(self):
-        """
-        Delete this volume.
-        """
-        (self._provider
-         .gce_compute
-         .disks()
-         .delete(project=self._provider.project_name,
-                 zone=self.zone_name,
-                 disk=self.name)
-         .execute())
-
     @property
     def state(self):
         if len(self._volume.get('users', [])) > 0:

+ 24 - 32
cloudbridge/cloud/providers/gce/services.py

@@ -973,17 +973,15 @@ class GCEVolumeService(BaseVolumeService):
     def __init__(self, provider):
         super(GCEVolumeService, self).__init__(provider)
 
-    def get(self, volume_id):
-        """
-        Returns a volume given its id.
-        """
+    @implement(event_pattern="provider.storage.volumes.get",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _get(self, volume_id):
         vol = self.provider.get_resource('disks', volume_id)
         return GCEVolume(self.provider, vol) if vol else None
 
-    def find(self, label, limit=None, marker=None):
-        """
-        Searches for a volume by a given list of attributes.
-        """
+    @implement(event_pattern="provider.storage.volumes.find",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _find(self, label, limit=None, marker=None):
         filtr = 'labels.cblabel eq ' + label
         max_result = limit if limit is not None and limit < 500 else 500
         response = (self.provider
@@ -1004,14 +1002,9 @@ class GCEVolumeService(BaseVolumeService):
                                      response.get('nextPageToken'),
                                      False, data=gce_vols)
 
-    def list(self, limit=None, marker=None):
-        """
-        List all volumes.
-
-        limit: The maximum number of volumes to return. The returned
-               ResultList's is_truncated property can be used to determine
-               whether more records are available.
-        """
+    @implement(event_pattern="provider.storage.volumes.list",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _list(self, limit=None, marker=None):
         # For GCE API, Acceptable values are 0 to 500, inclusive.
         # (Default: 500).
         max_result = limit if limit is not None and limit < 500 else 500
@@ -1032,22 +1025,9 @@ class GCEVolumeService(BaseVolumeService):
                                      response.get('nextPageToken'),
                                      False, data=gce_vols)
 
-    def create(self, label, size, zone, snapshot=None, description=None):
-        """
-        Creates a new volume.
-
-        Argument `name` must be 1-63 characters long, and comply with RFC1035.
-        Specifically, the name must be 1-63 characters long and match the
-        regular expression [a-z]([-a-z0-9]*[a-z0-9])? which means the first
-        character must be a lowercase letter, and all following characters must
-        be a dash, lowercase letter, or digit, except the last character, which
-        cannot be a dash.
-        """
-        log.debug("Creating GCE Volume with parameters "
-                  "[label: %s size: %s zone: %s snapshot: %s "
-                  "description: %s]", label, size, zone, snapshot,
-                  description)
-        GCEVolume.assert_valid_resource_label(label)
+    @implement(event_pattern="provider.storage.volumes.create",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, size, zone, snapshot=None, description=None):
         name = GCEVolume._generate_name_from_label(label, 'cb-vol')
         if not isinstance(zone, GCEPlacementZone):
             zone = GCEPlacementZone(
@@ -1075,6 +1055,18 @@ class GCEVolumeService(BaseVolumeService):
         cb_vol = self.get(operation.get('targetLink'))
         return cb_vol
 
+    @implement(event_pattern="provider.storage.volumes.delete",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, volume_id):
+        vol = self.provider.get_resource('disks', volume_id)
+        zone_name = self.provider.parse_url(vol.get('zone')).parameters['zone']
+        (self._provider.gce_compute
+                       .disks()
+                       .delete(project=self.provider.project_name,
+                               zone=zone_name,
+                               disk=vol.get('name'))
+                       .execute())
+
 
 class GCESnapshotService(BaseSnapshotService):
 

+ 0 - 6
cloudbridge/cloud/providers/openstack/resources.py

@@ -663,12 +663,6 @@ class OpenStackVolume(BaseVolume):
         return self._provider.storage.snapshots.create(
             label, self, description=description)
 
-    def delete(self):
-        """
-        Delete this volume.
-        """
-        self._volume.delete()
-
     @property
     def state(self):
         return OpenStackVolume.VOLUME_STATE_MAP.get(

+ 18 - 19
cloudbridge/cloud/providers/openstack/services.py

@@ -297,11 +297,9 @@ class OpenStackVolumeService(BaseVolumeService):
     def __init__(self, provider):
         super(OpenStackVolumeService, self).__init__(provider)
 
-    def get(self, volume_id):
-        """
-        Returns a volume given its id.
-        """
-        log.debug("Getting OpenStack Volume with the id: %s", volume_id)
+    @implement(event_pattern="provider.storage.volumes.get",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _get(self, volume_id):
         try:
             return OpenStackVolume(
                 self.provider, self.provider.cinder.volumes.get(volume_id))
@@ -309,7 +307,9 @@ class OpenStackVolumeService(BaseVolumeService):
             log.debug("Volume %s was not found.", volume_id)
             return None
 
-    def find(self, **kwargs):
+    @implement(event_pattern="provider.storage.volumes.find",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _find(self, **kwargs):
         label = kwargs.pop('label', None)
 
         # All kwargs should have been popped at this time.
@@ -328,10 +328,9 @@ class OpenStackVolumeService(BaseVolumeService):
 
         return oshelpers.to_server_paged_list(self.provider, cb_vols)
 
-    def list(self, limit=None, marker=None):
-        """
-        List all volumes.
-        """
+    @implement(event_pattern="provider.storage.volumes.list",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _list(self, limit=None, marker=None):
         cb_vols = [
             OpenStackVolume(self.provider, vol)
             for vol in self.provider.cinder.volumes.list(
@@ -340,15 +339,9 @@ class OpenStackVolumeService(BaseVolumeService):
 
         return oshelpers.to_server_paged_list(self.provider, cb_vols, limit)
 
-    def create(self, label, size, zone, snapshot=None, description=None):
-        """
-        Creates a new volume.
-        """
-        log.debug("Creating a new volume with the params: "
-                  "[label: %s size: %s zone: %s snapshot: %s description: %s]",
-                  label, size, zone, snapshot, description)
-        OpenStackVolume.assert_valid_resource_label(label)
-
+    @implement(event_pattern="provider.storage.volumes.create",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, size, zone, snapshot=None, description=None):
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         snapshot_id = snapshot.id if isinstance(
             snapshot, OpenStackSnapshot) and snapshot else snapshot
@@ -358,6 +351,12 @@ class OpenStackVolumeService(BaseVolumeService):
             availability_zone=zone_id, snapshot_id=snapshot_id)
         return OpenStackVolume(self.provider, os_vol)
 
+    @implement(event_pattern="provider.storage.volumes.delete",
+               priority=BaseVolumeService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, volume_id):
+        os_vol = self.provider.cinder.volumes.get(volume_id)
+        os_vol.delete()
+
 
 class OpenStackSnapshotService(BaseSnapshotService):