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

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

@@ -873,6 +873,9 @@ class BaseSubnet(BaseCloudResource, BaseObjectLifeCycleMixin, Subnet):
             timeout=timeout,
             interval=interval)
 
+    def delete(self):
+        self._provider.networking.subnets.delete(self.id)
+
 
 class BaseFloatingIPContainer(FloatingIPContainer, BasePageableObjectMixin):
 

+ 70 - 3
cloudbridge/cloud/base/services.py

@@ -296,8 +296,7 @@ class BaseVolumeService(
                      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
+        :type zone: ``PlacementZone``
         :param zone: The availability zone in which to create the volume
 
         :rtype: ``Volume``
@@ -803,7 +802,9 @@ class BaseSubnetService(
         super(BaseSubnetService, self).__init__(provider)
         self._service_event_pattern += ".networking.subnets"
 
-    def find(self, **kwargs):
+    @implement(event_pattern="provider.networking.subnets.find",
+               priority=BaseCloudService.STANDARD_EVENT_PRIORITY)
+    def _find(self, **kwargs):
         obj_list = self
         filters = ['label']
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
@@ -821,6 +822,72 @@ class BaseSubnetService(
                              BaseSubnet.CB_DEFAULT_SUBNET_IPV4RANGE, zone)
         return subnet
 
+    def get(self, subnet_id):
+        """
+        Returns a subnet given its ID. Returns ``None`` if the subnet
+        does not exist.
+
+        :type subnet_id: str
+        :param subnet_id: The id of the desired subnet.
+
+        :rtype: ``Subnet``
+        :return:  ``None`` is returned if the subnet does not exist, and
+                  the subnet's provider-specific CloudBridge object is
+                  returned if the subnet is found.
+        """
+        return self.dispatch(self, "provider.networking.subnets.get",
+                             subnet_id)
+
+    def find(self, network=None, **kwargs):
+        """
+        Returns a list of subnets filtered by the given keyword arguments.
+        Accepted search arguments are: 'label'
+        """
+        return self.dispatch(self, "provider.networking.subnets.find",
+                             network=network, **kwargs)
+
+    def list(self, network=None, limit=None, marker=None):
+        """
+        List all subnets.
+        """
+        return self.dispatch(self, "provider.networking.subnets.list",
+                             network=network, limit=limit, marker=marker)
+
+    def create(self, label, network, cidr_block, zone):
+        """
+        Create a new subnet.
+
+        :type label: str
+        :param label: The label of the subnet to be created. Note that labels
+                      do not have to be unique and can be changed.
+        :type network: ``Network``
+        :param network: The network in which the subnet should be created
+        :type cidr_block: str
+        :param cidr_block: A string representing a 'Classless Inter-Domain
+                           Routing' notation
+        :type cidr_block: str
+        :param cidr_block: A string representing a 'Classless Inter-Domain
+                           Routing' notation
+        :type zone: ``PlacementZone``
+        :param zone: The availability zone in which to create the subnet
+
+        :rtype: ``Subnet``
+        :return:  The created subnet's provider-specific CloudBridge object.
+        """
+        BaseSubnet.assert_valid_resource_label(label)
+        return self.dispatch(self, "provider.networking.subnets.create",
+                             label, network, cidr_block, zone)
+
+    def delete(self, subnet_id):
+        """
+        Delete an existing subnet.
+
+        :type subnet_id: str
+        :param subnet_id: The ID of the subnet to be deleted.
+        """
+        return self.dispatch(self, "provider.networking.subnets.delete",
+                             subnet_id)
+
 
 class BaseRouterService(
         BasePageableObjectMixin, RouterService, BaseCloudService):

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

@@ -1038,9 +1038,6 @@ class AWSSubnet(BaseSubnet):
         return AWSPlacementZone(self._provider, self._subnet.availability_zone,
                                 self._provider.region_name)
 
-    def delete(self):
-        self._subnet.delete()
-
     @property
     def state(self):
         if self._unknown_state:

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

@@ -859,11 +859,14 @@ class AWSSubnetService(BaseSubnetService):
                                   cb_resource=AWSSubnet,
                                   boto_collection_name='subnets')
 
-    def get(self, subnet_id):
-        log.debug("Getting AWS Subnet Service with the id: %s", subnet_id)
+    @implement(event_pattern="provider.networking.subnets.get",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _get(self, subnet_id):
         return self.svc.get(subnet_id)
 
-    def list(self, network=None, limit=None, marker=None):
+    @implement(event_pattern="provider.networking.subnets.list",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _list(self, network=None, limit=None, marker=None):
         network_id = network.id if isinstance(network, AWSNetwork) else network
         if network_id:
             return self.svc.find(
@@ -872,7 +875,9 @@ class AWSSubnetService(BaseSubnetService):
         else:
             return self.svc.list(limit=limit, marker=marker)
 
-    def find(self, **kwargs):
+    @implement(event_pattern="provider.networking.subnets.find",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _find(self, **kwargs):
         label = kwargs.pop('label', None)
 
         # All kwargs should have been popped at this time.
@@ -883,12 +888,9 @@ class AWSSubnetService(BaseSubnetService):
         log.debug("Searching for AWS Subnet Service %s", label)
         return self.svc.find(filter_name='tag:Name', filter_value=label)
 
-    def create(self, label, network, cidr_block, zone):
-        log.debug("Creating AWS Subnet Service with the params "
-                  "[label: %s network: %s block: %s zone: %s]",
-                  label, network, cidr_block, zone)
-        AWSSubnet.assert_valid_resource_label(label)
-
+    @implement(event_pattern="provider.networking.subnets.create",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, network, cidr_block, zone):
         zone_name = zone.name if isinstance(
             zone, AWSPlacementZone) else zone
 
@@ -902,6 +904,12 @@ class AWSSubnetService(BaseSubnetService):
             subnet.label = label
         return subnet
 
+    @implement(event_pattern="provider.networking.subnets.delete",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, subnet_id):
+        aws_sn = self.svc.get_raw(subnet_id)
+        aws_sn.delete()
+
     def get_or_create_default(self, zone):
         zone_name = zone.name if isinstance(zone, AWSPlacementZone) else zone
 
@@ -1004,11 +1012,6 @@ class AWSSubnetService(BaseSubnetService):
             default_sn = sn
         return default_sn
 
-    def delete(self, subnet):
-        log.debug("Deleting AWS Subnet Service: %s", subnet)
-        subnet_id = subnet.id if isinstance(subnet, AWSSubnet) else subnet
-        self.svc.delete(subnet_id)
-
 
 class AWSRouterService(BaseRouterService):
     """For AWS, a CloudBridge router corresponds to an AWS Route Table."""

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

@@ -1128,9 +1128,6 @@ class AzureSubnet(BaseSubnet):
     def network_id(self):
         return self._provider.azure_client.get_network_id_for_subnet(self.id)
 
-    def delete(self):
-        self._provider.azure_client.delete_subnet(self.id)
-
     @property
     def state(self):
         return self._SUBNET_STATE_MAP.get(self._state, NetworkState.UNKNOWN)

+ 38 - 39
cloudbridge/cloud/providers/azure/services.py

@@ -34,7 +34,6 @@ from cloudbridge.cloud.interfaces.resources import MachineImage
 from cloudbridge.cloud.interfaces.resources import Network
 from cloudbridge.cloud.interfaces.resources import PlacementZone
 from cloudbridge.cloud.interfaces.resources import Snapshot
-from cloudbridge.cloud.interfaces.resources import Subnet
 from cloudbridge.cloud.interfaces.resources import VMFirewall
 from cloudbridge.cloud.interfaces.resources import VMType
 from cloudbridge.cloud.interfaces.resources import Volume
@@ -1043,33 +1042,6 @@ class AzureSubnetService(BaseSubnetService):
     def __init__(self, provider):
         super(AzureSubnetService, self).__init__(provider)
 
-    def get(self, subnet_id):
-        """
-         Azure does not provide an api to get the subnet directly by id.
-         It also requires the network id.
-         To make it consistent across the providers the following code
-         gets the specific code from the subnet list.
-
-        :param subnet_id:
-        :return:
-        """
-        try:
-            azure_subnet = self.provider.azure_client.get_subnet(subnet_id)
-            return AzureSubnet(self.provider,
-                               azure_subnet) if azure_subnet else None
-        except (CloudError, InvalidValueException) as cloud_error:
-            # Azure raises the cloud error if the resource not available
-            log.exception(cloud_error)
-            return None
-
-    def list(self, network=None, limit=None, marker=None):
-        """
-        List subnets
-        """
-        return ClientPagedResultList(self.provider,
-                                     self._list_subnets(network),
-                                     limit=limit, marker=marker)
-
     def _list_subnets(self, network=None):
         result_list = []
         if network:
@@ -1092,7 +1064,34 @@ class AzureSubnetService(BaseSubnetService):
 
         return subnets
 
-    def find(self, network=None, **kwargs):
+    @implement(event_pattern="provider.networking.subnets.get",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _get(self, subnet_id):
+        """
+         Azure does not provide an api to get the subnet directly by id.
+         It also requires the network id.
+         To make it consistent across the providers the following code
+         gets the specific code from the subnet list.
+        """
+        try:
+            azure_subnet = self.provider.azure_client.get_subnet(subnet_id)
+            return AzureSubnet(self.provider,
+                               azure_subnet) if azure_subnet else None
+        except (CloudError, InvalidValueException) as cloud_error:
+            # Azure raises the cloud error if the resource not available
+            log.exception(cloud_error)
+            return None
+
+    @implement(event_pattern="provider.networking.subnets.list",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _list(self, network=None, limit=None, marker=None):
+        return ClientPagedResultList(self.provider,
+                                     self._list_subnets(network),
+                                     limit=limit, marker=marker)
+
+    @implement(event_pattern="provider.networking.subnets.find",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _find(self, network=None, **kwargs):
         obj_list = self._list_subnets(network)
         filters = ['label']
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
@@ -1100,13 +1099,11 @@ class AzureSubnetService(BaseSubnetService):
         return ClientPagedResultList(self.provider,
                                      matches if matches else [])
 
-    def create(self, label, network, cidr_block, zone):
-        """
-        Create subnet
-        """
+    @implement(event_pattern="provider.networking.subnets.create",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, network, cidr_block, zone):
         # Although Subnet doesn't support tags in Azure, we use the parent
         # Network's tags to track its subnets' labels
-        AzureSubnet.assert_valid_resource_label(label)
         subnet_name = AzureSubnet._generate_name_from_label(label, "cb-sn")
 
         network_id = network.id \
@@ -1125,15 +1122,17 @@ class AzureSubnetService(BaseSubnetService):
         subnet.label = label
         return subnet
 
-    def delete(self, subnet):
-        subnet_id = subnet.id if isinstance(subnet, Subnet) else subnet
+    @implement(event_pattern="provider.networking.subnets.delete",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, subnet_id):
+        sn = self.get(subnet_id)
         self.provider.azure_client.delete_subnet(subnet_id)
         # Although Subnet doesn't support labels, we use the parent Network's
         # tags to track the subnet's labels, thus that network-level tag must
         # be deleted with the subnet
-        network = subnet.network
-        az_network = network._network
-        az_network.tags.pop(subnet.tag_name)
+        net_id = sn.network_id
+        az_network = self.provider.azure_client.get_network(net_id)
+        az_network.tags.pop(sn.tag_name)
         self._provider.azure_client.update_network_tags(
             az_network.id, az_network)
 

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

@@ -1739,9 +1739,6 @@ class GCESubnet(BaseSubnet):
     def zone(self):
         return None
 
-    def delete(self):
-        return self._provider.networking.subnets.delete(self)
-
     @property
     def state(self):
         if self._subnet.get('status') == SubnetState.UNKNOWN:

+ 28 - 19
cloudbridge/cloud/providers/gce/services.py

@@ -821,11 +821,15 @@ class GCESubnetService(BaseSubnetService):
     def __init__(self, provider):
         super(GCESubnetService, self).__init__(provider)
 
-    def get(self, subnet_id):
+    @implement(event_pattern="provider.networking.subnets.get",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _get(self, subnet_id):
         subnet = self.provider.get_resource('subnetworks', subnet_id)
         return GCESubnet(self.provider, subnet) if subnet else None
 
-    def list(self, network=None, zone=None, limit=None, marker=None):
+    @implement(event_pattern="provider.networking.subnets.list",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _list(self, network=None, zone=None, limit=None, marker=None):
         """
         If the zone is not given, we list all subnets in the default region.
         """
@@ -851,7 +855,9 @@ class GCESubnetService(BaseSubnetService):
         return ClientPagedResultList(self.provider, subnets,
                                      limit=limit, marker=marker)
 
-    def create(self, label, network, cidr_block, zone):
+    @implement(event_pattern="provider.networking.subnets.create",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, network, cidr_block, zone):
         """
         GCE subnets are regional. The region is inferred from the zone;
         otherwise, the default region, as set in the
@@ -861,7 +867,6 @@ class GCESubnetService(BaseSubnetService):
         instead of creating a new subnet. In this case, other parameters, i.e.
         the name and the zone, are ignored.
         """
-        GCESubnet.assert_valid_resource_label(label)
         name = GCESubnet._generate_name_from_label(label, 'cbsubnet')
         region_name = self._zone_to_region(zone)
 #         for subnet in self.iter(network=network):
@@ -893,6 +898,25 @@ class GCESubnetService(BaseSubnetService):
         cb_subnet.label = label
         return cb_subnet
 
+    @implement(event_pattern="provider.networking.subnets.delete",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, subnet_id):
+        gce_sn = self.provider.get_resource('subnetworks', subnet_id)
+        region_name = self.provider.parse_url(subnet_id).parameters['region']
+        response = (self.provider
+                    .gce_compute
+                    .subnetworks()
+                    .delete(project=self.provider.project_name,
+                            region=region_name,
+                            subnetwork=gce_sn['name'])
+                    .execute())
+        self.provider.wait_for_operation(response, region=region_name)
+        # Remove label
+        tag_name = "_".join(["subnet", gce_sn['name'], "label"])
+        if not helpers.remove_metadata_item(self._provider, tag_name):
+            log.warning('No label was found associated with this subnet '
+                        '"{}" when deleted.'.format(gce_sn['name']))
+
     def get_or_create_default(self, zone):
         """
         Return an existing or create a new subnet for the supplied zone.
@@ -937,21 +961,6 @@ class GCESubnetService(BaseSubnetService):
         router.attach_gateway(gateway)
         return sn
 
-    def delete(self, subnet):
-        response = (self.provider
-                    .gce_compute
-                    .subnetworks()
-                    .delete(project=self.provider.project_name,
-                            region=subnet.region_name,
-                            subnetwork=subnet.name)
-                    .execute())
-        self.provider.wait_for_operation(response, region=subnet.region_name)
-        # Remove label
-        tag_name = "_".join(["subnet", subnet.name, "label"])
-        if not helpers.remove_metadata_item(self._provider, tag_name):
-            log.warning('No label was found associated with this subnet '
-                        '"{}" when deleted.'.format(subnet.name))
-
     def _zone_to_region(self, zone, return_name_only=True):
         """
         Given a GCE zone, return parent region.

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

@@ -936,10 +936,6 @@ class OpenStackSubnet(BaseSubnet):
         """
         return None
 
-    def delete(self):
-        if self.id in str(self._provider.neutron.list_subnets()):
-            self._provider.neutron.delete_subnet(self.id)
-
     @property
     def state(self):
         return SubnetState.UNKNOWN if self._state == SubnetState.UNKNOWN \

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

@@ -963,12 +963,15 @@ class OpenStackSubnetService(BaseSubnetService):
     def __init__(self, provider):
         super(OpenStackSubnetService, self).__init__(provider)
 
-    def get(self, subnet_id):
-        log.debug("Getting OpenStack Subnet with the id: %s", subnet_id)
+    @implement(event_pattern="provider.networking.subnets.get",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _get(self, subnet_id):
         subnet = (s for s in self if s.id == subnet_id)
         return next(subnet, None)
 
-    def list(self, network=None, limit=None, marker=None):
+    @implement(event_pattern="provider.networking.subnets.list",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _list(self, network=None, limit=None, marker=None):
         if network:
             network_id = (network.id if isinstance(network, OpenStackNetwork)
                           else network)
@@ -980,12 +983,10 @@ class OpenStackSubnetService(BaseSubnetService):
         return ClientPagedResultList(self.provider, subnets,
                                      limit=limit, marker=marker)
 
-    def create(self, label, network, cidr_block, zone):
+    @implement(event_pattern="provider.networking.subnets.create",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _create(self, label, network, cidr_block, zone):
         """zone param is ignored."""
-        log.debug("Creating OpenStack Subnet with the params: "
-                  "[Label: %s Network: %s Cinder Block: %s Zone: -ignored-]",
-                  label, network, cidr_block)
-        OpenStackSubnet.assert_valid_resource_label(label)
         network_id = (network.id if isinstance(network, OpenStackNetwork)
                       else network)
         subnet_info = {'name': label, 'network_id': network_id,
@@ -995,6 +996,15 @@ class OpenStackSubnetService(BaseSubnetService):
         cb_subnet = OpenStackSubnet(self.provider, subnet)
         return cb_subnet
 
+    @implement(event_pattern="provider.networking.subnets.delete",
+               priority=BaseSubnetService.STANDARD_EVENT_PRIORITY)
+    def _delete(self, subnet_id):
+        self.provider.neutron.delete_subnet(subnet_id)
+        # Adhere to the interface docs
+        if subnet_id not in self:
+            return True
+        return False
+
     def get_or_create_default(self, zone):
         """
         Subnet zone is not supported by OpenStack and is thus ignored.
@@ -1018,16 +1028,6 @@ class OpenStackSubnetService(BaseSubnetService):
         except NeutronClientException:
             return None
 
-    def delete(self, subnet):
-        log.debug("Deleting subnet: %s", subnet)
-        subnet_id = (subnet.id if isinstance(subnet, OpenStackSubnet)
-                     else subnet)
-        self.provider.neutron.delete_subnet(subnet_id)
-        # Adhere to the interface docs
-        if subnet_id not in self:
-            return True
-        return False
-
 
 class OpenStackRouterService(BaseRouterService):