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

FloatingIP Service and SubService refactored

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

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

@@ -9,6 +9,7 @@ from cloudbridge.cloud.interfaces.services import BucketObjectService
 from cloudbridge.cloud.interfaces.services import BucketService
 from cloudbridge.cloud.interfaces.services import BucketService
 from cloudbridge.cloud.interfaces.services import CloudService
 from cloudbridge.cloud.interfaces.services import CloudService
 from cloudbridge.cloud.interfaces.services import ComputeService
 from cloudbridge.cloud.interfaces.services import ComputeService
+from cloudbridge.cloud.interfaces.services import FloatingIPService
 from cloudbridge.cloud.interfaces.services import GatewayService
 from cloudbridge.cloud.interfaces.services import GatewayService
 from cloudbridge.cloud.interfaces.services import ImageService
 from cloudbridge.cloud.interfaces.services import ImageService
 from cloudbridge.cloud.interfaces.services import InstanceService
 from cloudbridge.cloud.interfaces.services import InstanceService
@@ -336,3 +337,19 @@ class BaseGatewayService(GatewayService, BaseCloudService):
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         self._provider = provider
         self._provider = provider
+
+
+class BaseFloatingIPService(FloatingIPService):
+
+    def __init__(self, provider):
+        self.__provider = provider
+
+    @property
+    def _provider(self):
+        return self.__provider
+
+    def find(self, gateway, **kwargs):
+        obj_list = gateway.floating_ips
+        filters = ['name', 'public_ip']
+        matches = cb_helpers.generic_find(filters, kwargs, obj_list)
+        return ClientPagedResultList(self._provider, list(matches))

+ 19 - 13
cloudbridge/cloud/base/subservices.py

@@ -5,9 +5,7 @@ from cloudbridge.cloud.interfaces.subservices import FloatingIPSubService
 from cloudbridge.cloud.interfaces.subservices import GatewaySubService
 from cloudbridge.cloud.interfaces.subservices import GatewaySubService
 from cloudbridge.cloud.interfaces.subservices import VMFirewallRuleSubService
 from cloudbridge.cloud.interfaces.subservices import VMFirewallRuleSubService
 
 
-from . import helpers as cb_helpers
 from .resources import BasePageableObjectMixin
 from .resources import BasePageableObjectMixin
-from .resources import ClientPagedResultList
 
 
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
 
 
@@ -80,7 +78,7 @@ class BaseVMFirewallRuleSubService(BasePageableObjectMixin,
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         return self._provider.security._vm_firewall_rules.list(self._firewall,
         return self._provider.security._vm_firewall_rules.list(self._firewall,
-                                                        limit, marker)
+                                                               limit, marker)
 
 
     def create(self, direction, protocol=None, from_port=None,
     def create(self, direction, protocol=None, from_port=None,
                to_port=None, cidr=None, src_dest_fw=None):
                to_port=None, cidr=None, src_dest_fw=None):
@@ -92,7 +90,7 @@ class BaseVMFirewallRuleSubService(BasePageableObjectMixin,
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
         return self._provider.security._vm_firewall_rules.find(self._firewall,
         return self._provider.security._vm_firewall_rules.find(self._firewall,
-                                                        **kwargs)
+                                                               **kwargs)
 
 
     def delete(self, rule_id):
     def delete(self, rule_id):
         return (self._provider
         return (self._provider
@@ -111,13 +109,21 @@ class BaseFloatingIPSubService(FloatingIPSubService, BasePageableObjectMixin):
     def _provider(self):
     def _provider(self):
         return self.__provider
         return self.__provider
 
 
+    def get(self, fip_id):
+        return self._provider.networking._floating_ips.get(self.gateway,
+                                                           fip_id)
+
+    def list(self, limit=None, marker=None):
+        return self._provider.networking._floating_ips.list(self.gateway,
+                                                            limit, marker)
+
     def find(self, **kwargs):
     def find(self, **kwargs):
-        obj_list = self
-        filters = ['name', 'public_ip']
-        matches = cb_helpers.generic_find(filters, kwargs, obj_list)
-        return ClientPagedResultList(self._provider, list(matches))
-
-    def delete(self, fip_id):
-        floating_ip = self.get(fip_id)
-        if floating_ip:
-            floating_ip.delete()
+        return self._provider.networking._floating_ips.find(self.gateway,
+                                                            **kwargs)
+
+    def create(self):
+        return self._provider.networking._floating_ips.create(self.gateway)
+
+    def delete(self, fip):
+        return self._provider.networking._floating_ips.delete(self.gateway,
+                                                              fip)

+ 84 - 0
cloudbridge/cloud/interfaces/services.py

@@ -1581,3 +1581,87 @@ class GatewayService(CloudService):
         :return: Current list of internet gateways.
         :return: Current list of internet gateways.
         """
         """
         pass
         pass
+
+
+class FloatingIPService(CloudService):
+    """
+    Base interface for a FloatingIP Service.
+    """
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
+    def get(self, gateway, fip_id):
+        """
+        Returns a FloatingIP given its ID or ``None`` if not found.
+
+        :type gateway: ``Gateway``
+        :param gateway: The gateway to which the Floating IP is attached
+
+        :type fip_id: ``str``
+        :param fip_id: The ID of the FloatingIP to retrieve.
+
+        :rtype: ``object`` of :class:`.FloatingIP`
+        :return: a FloatingIP object
+        """
+        pass
+
+    @abstractmethod
+    def list(self, gateway, limit=None, marker=None):
+        """
+        List floating (i.e., static) IP addresses.
+
+        :type gateway: ``Gateway``
+        :param gateway: The gateway to which the Floating IPs are attached
+
+        :rtype: ``list`` of :class:`.FloatingIP`
+        :return: list of FloatingIP objects
+        """
+        pass
+
+    @abstractmethod
+    def find(self, gateway, **kwargs):
+        """
+        Searches for a FloatingIP by a given list of attributes.
+
+        Supported attributes: name, public_ip
+
+        Example:
+
+        .. code-block:: python
+
+            fip = provider.networking.gateways.get('id').floating_ips.find(
+                        public_ip='public_ip')
+
+        :type gateway: ``Gateway``
+        :param gateway: The gateway to which the Floating IPs are attached
+
+        :rtype: List of ``object`` of :class:`.FloatingIP`
+        :return: A list of FloatingIP objects matching the supplied attributes.
+        """
+        pass
+
+    @abstractmethod
+    def create(self, gateway):
+        """
+        Allocate a new floating (i.e., static) IP address.
+
+        :type gateway: ``Gateway``
+        :param gateway: The gateway to which the Floating IP should be attached
+
+        :rtype: ``object`` of :class:`.FloatingIP`
+        :return:  A FloatingIP object
+        """
+        pass
+
+    @abstractmethod
+    def delete(self, gateway, fip):
+        """
+        Delete an existing FloatingIP.
+
+        :type gateway: ``Gateway``
+        :param gateway: The gateway to which the Floating IP is attached
+
+        :type fip: ``str``
+        :param fip: The FloatingIP to be deleted.
+        """
+        pass

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

@@ -1003,9 +1003,6 @@ class AWSFloatingIP(BaseFloatingIP):
     def in_use(self):
     def in_use(self):
         return True if self._ip.association_id else False
         return True if self._ip.association_id else False
 
 
-    def delete(self):
-        self._ip.release()
-
     def refresh(self):
     def refresh(self):
         self._ip.reload()
         self._ip.reload()
 
 

+ 34 - 0
cloudbridge/cloud/providers/aws/services.py

@@ -15,6 +15,7 @@ from cloudbridge.cloud.base.resources import ClientPagedResultList
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseComputeService
 from cloudbridge.cloud.base.services import BaseComputeService
+from cloudbridge.cloud.base.services import BaseFloatingIPService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseInstanceService
 from cloudbridge.cloud.base.services import BaseInstanceService
@@ -51,6 +52,7 @@ from .helpers import BotoS3Service
 from .helpers import trim_empty_params
 from .helpers import trim_empty_params
 from .resources import AWSBucket
 from .resources import AWSBucket
 from .resources import AWSBucketObject
 from .resources import AWSBucketObject
+from .resources import AWSFloatingIP
 from .resources import AWSInstance
 from .resources import AWSInstance
 from .resources import AWSInternetGateway
 from .resources import AWSInternetGateway
 from .resources import AWSKeyPair
 from .resources import AWSKeyPair
@@ -1211,3 +1213,35 @@ class AWSGatewayService(BaseGatewayService):
                   network.id)
                   network.id)
         fltr = [{'Name': 'attachment.vpc-id', 'Values': [network.id]}]
         fltr = [{'Name': 'attachment.vpc-id', 'Values': [network.id]}]
         return self.svc.list(limit=None, marker=None, Filters=fltr)
         return self.svc.list(limit=None, marker=None, Filters=fltr)
+
+
+class AWSFloatingIPService(BaseFloatingIPService):
+
+    def __init__(self, provider, gateway):
+        super(AWSFloatingIPService, self).__init__(provider, gateway)
+        self.svc = BotoEC2Service(provider=self.provider,
+                                  cb_resource=AWSFloatingIP,
+                                  boto_collection_name='vpc_addresses')
+
+    def get(self, gateway, fip_id):
+        log.debug("Getting AWS Floating IP Service with the id: %s", fip_id)
+        return self.svc.get(fip_id)
+
+    def list(self, gateway, limit=None, marker=None):
+        log.debug("Listing all floating IPs under gateway %s", gateway)
+        return self.svc.list(limit=limit, marker=marker)
+
+    def create(self, gateway):
+        log.debug("Creating a floating IP under gateway %s", gateway)
+        ip = self.provider.ec2_conn.meta.client.allocate_address(
+            Domain='vpc')
+        return AWSFloatingIP(
+            self.provider,
+            self.provider.ec2_conn.VpcAddress(ip.get('AllocationId')))
+
+    def delete(self, gateway, fip):
+        if isinstance(fip, AWSFloatingIP):
+            os_fip = fip._ip
+        else:
+            os_fip = self.svc.get_raw(fip)
+        os_fip.release()

+ 0 - 22
cloudbridge/cloud/providers/aws/subservices.py

@@ -6,9 +6,6 @@ from cloudbridge.cloud.base.subservices import \
     BaseGatewaySubService
     BaseGatewaySubService
 from cloudbridge.cloud.base.subservices import BaseVMFirewallRuleSubService
 from cloudbridge.cloud.base.subservices import BaseVMFirewallRuleSubService
 
 
-from .helpers import BotoEC2Service
-from .resources import AWSFloatingIP
-
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
 
 
 
 
@@ -34,22 +31,3 @@ class AWSFloatingIPSubService(BaseFloatingIPSubService):
 
 
     def __init__(self, provider, gateway):
     def __init__(self, provider, gateway):
         super(AWSFloatingIPSubService, self).__init__(provider, gateway)
         super(AWSFloatingIPSubService, self).__init__(provider, gateway)
-        self.svc = BotoEC2Service(provider=self._provider,
-                                  cb_resource=AWSFloatingIP,
-                                  boto_collection_name='vpc_addresses')
-
-    def get(self, fip_id):
-        log.debug("Getting AWS Floating IP Service with the id: %s", fip_id)
-        return self.svc.get(fip_id)
-
-    def list(self, limit=None, marker=None):
-        log.debug("Listing all floating IPs under gateway %s", self.gateway)
-        return self.svc.list(limit=limit, marker=marker)
-
-    def create(self):
-        log.debug("Creating a floating IP under gateway %s", self.gateway)
-        ip = self._provider.ec2_conn.meta.client.allocate_address(
-            Domain='vpc')
-        return AWSFloatingIP(
-            self._provider,
-            self._provider.ec2_conn.VpcAddress(ip.get('AllocationId')))

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

@@ -849,12 +849,6 @@ class AzureFloatingIP(BaseFloatingIP):
     def in_use(self):
     def in_use(self):
         return True if self._ip.ip_configuration else False
         return True if self._ip.ip_configuration else False
 
 
-    def delete(self):
-        """
-        Delete an existing floating ip.
-        """
-        self._provider.azure_client.delete_floating_ip(self.id)
-
     def refresh(self):
     def refresh(self):
         net = self._provider.networking.networks.get(self._network_id)
         net = self._provider.networking.networks.get(self._network_id)
         gw = net.gateways.get_or_create_inet_gateway()
         gw = net.gateways.get_or_create_inet_gateway()

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

@@ -14,6 +14,7 @@ from cloudbridge.cloud.base.resources import ServerPagedResultList
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseComputeService
 from cloudbridge.cloud.base.services import BaseComputeService
+from cloudbridge.cloud.base.services import BaseFloatingIPService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseInstanceService
 from cloudbridge.cloud.base.services import BaseInstanceService
@@ -44,6 +45,7 @@ from cloudbridge.cloud.interfaces.resources import Volume
 
 
 from .resources import AzureBucket
 from .resources import AzureBucket
 from .resources import AzureBucketObject
 from .resources import AzureBucketObject
+from .resources import AzureFloatingIP
 from .resources import AzureInstance
 from .resources import AzureInstance
 from .resources import AzureInternetGateway
 from .resources import AzureInternetGateway
 from .resources import AzureKeyPair
 from .resources import AzureKeyPair
@@ -1321,3 +1323,39 @@ class AzureGatewayService(BaseGatewayService):
 
 
     def delete(self, network, gateway):
     def delete(self, network, gateway):
         pass
         pass
+
+
+class AzureFloatingIPService(BaseFloatingIPService):
+
+    def __init__(self, provider):
+        super(AzureFloatingIPService, self).__init__(provider)
+
+    def get(self, gateway, fip_id):
+        log.debug("Getting Azure Floating IP container with the id: %s",
+                  fip_id)
+        fip = [fip for fip in self if fip.id == fip_id]
+        return fip[0] if fip else None
+
+    def list(self, gateway, limit=None, marker=None):
+        floating_ips = [AzureFloatingIP(self.provider, floating_ip,
+                                        gateway.network_id)
+                        for floating_ip in self.provider.azure_client.
+                        list_floating_ips()]
+        return ClientPagedResultList(self.provider, floating_ips,
+                                     limit=limit, marker=marker)
+
+    def create(self, gateway):
+        public_ip_parameters = {
+            'location': self.provider.azure_client.region_name,
+            'public_ip_allocation_method': 'Static'
+        }
+
+        public_ip_name = AzureFloatingIP._generate_name_from_label('cb-fip-')
+
+        floating_ip = self.provider.azure_client.\
+            create_floating_ip(public_ip_name, public_ip_parameters)
+        return AzureFloatingIP(self.provider, floating_ip, gateway.network_id)
+
+    def delete(self, gateway, fip):
+        fip_id = fip if isinstance(fip, AzureFloatingIP) else fip
+        self._provider.azure_client.delete_floating_ip(fip_id)

+ 1 - 32
cloudbridge/cloud/providers/azure/subservices.py

@@ -1,15 +1,11 @@
 import logging
 import logging
-from uuid import uuid4
 
 
-from cloudbridge.cloud.base.resources import ClientPagedResultList
 from cloudbridge.cloud.base.subservices import BaseBucketObjectSubService
 from cloudbridge.cloud.base.subservices import BaseBucketObjectSubService
 from cloudbridge.cloud.base.subservices import \
 from cloudbridge.cloud.base.subservices import \
     BaseFloatingIPSubService
     BaseFloatingIPSubService
 from cloudbridge.cloud.base.subservices import BaseGatewaySubService
 from cloudbridge.cloud.base.subservices import BaseGatewaySubService
 from cloudbridge.cloud.base.subservices import BaseVMFirewallRuleSubService
 from cloudbridge.cloud.base.subservices import BaseVMFirewallRuleSubService
 
 
-from .resources import AzureFloatingIP
-
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
 
 
 
 
@@ -32,32 +28,5 @@ class AzureVMFirewallRuleSubService(BaseVMFirewallRuleSubService):
 
 
 class AzureFloatingIPSubService(BaseFloatingIPSubService):
 class AzureFloatingIPSubService(BaseFloatingIPSubService):
 
 
-    def __init__(self, provider, gateway, network_id):
+    def __init__(self, provider, gateway):
         super(AzureFloatingIPSubService, self).__init__(provider, gateway)
         super(AzureFloatingIPSubService, self).__init__(provider, gateway)
-        self._network_id = network_id
-
-    def get(self, fip_id):
-        log.debug("Getting Azure Floating IP container with the id: %s",
-                  fip_id)
-        fip = [fip for fip in self if fip.id == fip_id]
-        return fip[0] if fip else None
-
-    def list(self, limit=None, marker=None):
-        floating_ips = [AzureFloatingIP(self._provider, floating_ip,
-                                        self._network_id)
-                        for floating_ip in self._provider.azure_client.
-                        list_floating_ips()]
-        return ClientPagedResultList(self._provider, floating_ips,
-                                     limit=limit, marker=marker)
-
-    def create(self):
-        public_ip_parameters = {
-            'location': self._provider.azure_client.region_name,
-            'public_ip_allocation_method': 'Static'
-        }
-
-        public_ip_name = 'cb-fip-' + uuid4().hex[:6]
-
-        floating_ip = self._provider.azure_client.\
-            create_floating_ip(public_ip_name, public_ip_parameters)
-        return AzureFloatingIP(self._provider, floating_ip, self._network_id)

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

@@ -1358,30 +1358,6 @@ class GCEFloatingIP(BaseFloatingIP):
     def in_use(self):
     def in_use(self):
         return True if self._target_instance else False
         return True if self._target_instance else False
 
 
-    def delete(self):
-        project_name = self._provider.project_name
-        # First, delete the forwarding rule, if there is any.
-        if self._rule:
-            response = (self._provider
-                            .gce_compute
-                            .forwardingRules()
-                            .delete(project=project_name,
-                                    region=self.region_name,
-                                    forwardingRule=self._rule['name'])
-                            .execute())
-            self._provider.wait_for_operation(response,
-                                              region=self.region_name)
-
-        # Release the address.
-        response = (self._provider
-                        .gce_compute
-                        .addresses()
-                        .delete(project=project_name,
-                                region=self.region_name,
-                                address=self._ip['name'])
-                        .execute())
-        self._provider.wait_for_operation(response, region=self.region_name)
-
     def refresh(self):
     def refresh(self):
         fip = self._gateway.floating_ips.get(self.id)
         fip = self._gateway.floating_ips.get(self.id)
         # pylint:disable=protected-access
         # pylint:disable=protected-access

+ 72 - 0
cloudbridge/cloud/providers/gce/services.py

@@ -14,6 +14,7 @@ from cloudbridge.cloud.base.resources import ServerPagedResultList
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseComputeService
 from cloudbridge.cloud.base.services import BaseComputeService
+from cloudbridge.cloud.base.services import BaseFloatingIPService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseInstanceService
 from cloudbridge.cloud.base.services import BaseInstanceService
@@ -37,6 +38,7 @@ from cloudbridge.cloud.interfaces.resources import VMFirewall
 from cloudbridge.cloud.providers.gce import helpers
 from cloudbridge.cloud.providers.gce import helpers
 
 
 from .resources import GCEFirewallsDelegate
 from .resources import GCEFirewallsDelegate
+from .resources import GCEFloatingIP
 from .resources import GCEInstance
 from .resources import GCEInstance
 from .resources import GCEInternetGateway
 from .resources import GCEInternetGateway
 from .resources import GCEKeyPair
 from .resources import GCEKeyPair
@@ -1520,3 +1522,73 @@ class GCEGatewayService(BaseGatewayService):
         return ClientPagedResultList(self._provider,
         return ClientPagedResultList(self._provider,
                                      gws,
                                      gws,
                                      limit=limit, marker=marker)
                                      limit=limit, marker=marker)
+
+
+class GCEFloatingIPService(BaseFloatingIPService):
+
+    def __init__(self, provider, gateway):
+        super(GCEFloatingIPService, self).__init__(provider, gateway)
+
+    def get(self, gateway, floating_ip_id):
+        fip = self.provider.get_resource('addresses', floating_ip_id)
+        return (GCEFloatingIP(self.provider, gateway, fip)
+                if fip else None)
+
+    def list(self, gateway, limit=None, marker=None):
+        max_result = limit if limit is not None and limit < 500 else 500
+        response = (self.provider
+                        .gce_compute
+                        .addresses()
+                        .list(project=self.provider.project_name,
+                              region=self.provider.region_name,
+                              maxResults=max_result,
+                              pageToken=marker)
+                        .execute())
+        ips = [GCEFloatingIP(self.provider, gateway, ip)
+               for ip in response.get('items', [])]
+        if len(ips) > max_result:
+            log.warning('Expected at most %d results; got %d',
+                        max_result, len(ips))
+        return ServerPagedResultList('nextPageToken' in response,
+                                     response.get('nextPageToken'),
+                                     False, data=ips)
+
+    def create(self, gateway):
+        region_name = self.provider.region_name
+        ip_name = 'ip-{0}'.format(uuid.uuid4())
+        response = (self.provider
+                    .gce_compute
+                    .addresses()
+                    .insert(project=self.provider.project_name,
+                            region=region_name,
+                            body={'name': ip_name})
+                    .execute())
+        self.provider.wait_for_operation(response, region=region_name)
+        return self.get(ip_name)
+
+    def delete(self, gateway, fip):
+        fip = fip if isinstance(fip, GCEFloatingIP) else \
+            gateway.floating_ips.get(fip)
+        project_name = self.provider.project_name
+        # First, delete the forwarding rule, if there is any.
+        if fip._rule:
+            response = (self.provider
+                        .gce_compute
+                        .forwardingRules()
+                        .delete(project=project_name,
+                                region=fip.region_name,
+                                forwardingRule=fip._rule['name'])
+                        .execute())
+            self.provider.wait_for_operation(response,
+                                             region=fip.region_name)
+
+        # Release the address.
+        response = (self.provider
+                    .gce_compute
+                    .addresses()
+                    .delete(project=project_name,
+                            region=fip.region_name,
+                            address=fip._ip['name'])
+                    .execute())
+        self.provider.wait_for_operation(response,
+                                         region=fip.region_name)

+ 0 - 40
cloudbridge/cloud/providers/gce/subservices.py

@@ -1,14 +1,11 @@
 import logging
 import logging
-import uuid
 
 
-from cloudbridge.cloud.base.resources import ServerPagedResultList
 from cloudbridge.cloud.base.subservices import BaseBucketObjectSubService
 from cloudbridge.cloud.base.subservices import BaseBucketObjectSubService
 from cloudbridge.cloud.base.subservices import BaseFloatingIPSubService
 from cloudbridge.cloud.base.subservices import BaseFloatingIPSubService
 from cloudbridge.cloud.base.subservices import \
 from cloudbridge.cloud.base.subservices import \
     BaseGatewaySubService
     BaseGatewaySubService
 from cloudbridge.cloud.base.subservices import BaseVMFirewallRuleSubService
 from cloudbridge.cloud.base.subservices import BaseVMFirewallRuleSubService
 
 
-from .resources import GCEFloatingIP
 
 
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
 
 
@@ -34,40 +31,3 @@ class GCEFloatingIPSubService(BaseFloatingIPSubService):
 
 
     def __init__(self, provider, gateway):
     def __init__(self, provider, gateway):
         super(GCEFloatingIPSubService, self).__init__(provider, gateway)
         super(GCEFloatingIPSubService, self).__init__(provider, gateway)
-
-    def get(self, floating_ip_id):
-        fip = self._provider.get_resource('addresses', floating_ip_id)
-        return (GCEFloatingIP(self._provider, self.gateway, fip)
-                if fip else None)
-
-    def list(self, limit=None, marker=None):
-        max_result = limit if limit is not None and limit < 500 else 500
-        response = (self._provider
-                        .gce_compute
-                        .addresses()
-                        .list(project=self._provider.project_name,
-                              region=self._provider.region_name,
-                              maxResults=max_result,
-                              pageToken=marker)
-                        .execute())
-        ips = [GCEFloatingIP(self._provider, self.gateway, ip)
-               for ip in response.get('items', [])]
-        if len(ips) > max_result:
-            log.warning('Expected at most %d results; got %d',
-                        max_result, len(ips))
-        return ServerPagedResultList('nextPageToken' in response,
-                                     response.get('nextPageToken'),
-                                     False, data=ips)
-
-    def create(self):
-        region_name = self._provider.region_name
-        ip_name = 'ip-{0}'.format(uuid.uuid4())
-        response = (self._provider
-                    .gce_compute
-                    .addresses()
-                    .insert(project=self._provider.project_name,
-                            region=region_name,
-                            body={'name': ip_name})
-                    .execute())
-        self._provider.wait_for_operation(response, region=region_name)
-        return self.get(ip_name)

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

@@ -925,9 +925,6 @@ class OpenStackFloatingIP(BaseFloatingIP):
     def in_use(self):
     def in_use(self):
         return bool(self._ip.port_id)
         return bool(self._ip.port_id)
 
 
-    def delete(self):
-        self._ip.delete(self._provider.os_conn.session)
-
     def refresh(self):
     def refresh(self):
         net = self._provider.networking.networks.get(
         net = self._provider.networking.networks.get(
             self._ip.floating_network_id)
             self._ip.floating_network_id)

+ 40 - 0
cloudbridge/cloud/providers/openstack/services.py

@@ -23,6 +23,7 @@ from cloudbridge.cloud.base.resources import ClientPagedResultList
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketObjectService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseBucketService
 from cloudbridge.cloud.base.services import BaseComputeService
 from cloudbridge.cloud.base.services import BaseComputeService
+from cloudbridge.cloud.base.services import BaseFloatingIPService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseGatewayService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseImageService
 from cloudbridge.cloud.base.services import BaseInstanceService
 from cloudbridge.cloud.base.services import BaseInstanceService
@@ -57,6 +58,7 @@ from cloudbridge.cloud.interfaces.resources import Volume
 from . import helpers as oshelpers
 from . import helpers as oshelpers
 from .resources import OpenStackBucket
 from .resources import OpenStackBucket
 from .resources import OpenStackBucketObject
 from .resources import OpenStackBucketObject
+from .resources import OpenStackFloatingIP
 from .resources import OpenStackInstance
 from .resources import OpenStackInstance
 from .resources import OpenStackInternetGateway
 from .resources import OpenStackInternetGateway
 from .resources import OpenStackKeyPair
 from .resources import OpenStackKeyPair
@@ -1186,3 +1188,41 @@ class OpenStackGatewayService(BaseGatewayService):
                if n.external and self._check_fip_connectivity(n)]
                if n.external and self._check_fip_connectivity(n)]
         return ClientPagedResultList(self._provider, igl, limit=limit,
         return ClientPagedResultList(self._provider, igl, limit=limit,
                                      marker=marker)
                                      marker=marker)
+
+
+class OpenStackFloatingIPService(BaseFloatingIPService):
+
+    def __init__(self, provider, gateway):
+        super(OpenStackFloatingIPService, self).__init__(provider, gateway)
+
+    def get(self, gateway, fip_id):
+        try:
+            return OpenStackFloatingIP(
+                self.provider, self.provider.os_conn.network.get_ip(fip_id))
+        except (ResourceNotFound, NotFoundException):
+            log.debug("Floating IP %s not found.", fip_id)
+            return None
+
+    def list(self, gateway, limit=None, marker=None):
+        fips = [OpenStackFloatingIP(self.provider, fip)
+                for fip in self.provider.os_conn.network.ips(
+                    floating_network_id=gateway.id
+                )]
+        return ClientPagedResultList(self.provider, fips,
+                                     limit=limit, marker=marker)
+
+    def create(self, gateway):
+        return OpenStackFloatingIP(
+            self.provider, self.provider.os_conn.network.create_ip(
+                floating_network_id=gateway.id))
+
+    def delete(self, gateway, fip):
+        if isinstance(fip, OpenStackFloatingIP):
+            os_ip = fip._ip
+        else:
+            try:
+                os_ip = self.provider.os_conn.network.get_ip(fip)
+            except (ResourceNotFound, NotFoundException):
+                log.debug("Floating IP %s not found.", fip)
+                return True
+        os_ip.delete(self._provider.os_conn.session)

+ 0 - 26
cloudbridge/cloud/providers/openstack/subservices.py

@@ -1,16 +1,11 @@
 import logging
 import logging
 
 
-from openstack.exceptions import NotFoundException
-from openstack.exceptions import ResourceNotFound
-
-from cloudbridge.cloud.base.resources import ClientPagedResultList
 from cloudbridge.cloud.base.subservices import BaseBucketObjectSubService
 from cloudbridge.cloud.base.subservices import BaseBucketObjectSubService
 from cloudbridge.cloud.base.subservices import BaseFloatingIPSubService
 from cloudbridge.cloud.base.subservices import BaseFloatingIPSubService
 from cloudbridge.cloud.base.subservices import BaseGatewaySubService
 from cloudbridge.cloud.base.subservices import BaseGatewaySubService
 from cloudbridge.cloud.base.subservices import \
 from cloudbridge.cloud.base.subservices import \
     BaseVMFirewallRuleSubService
     BaseVMFirewallRuleSubService
 
 
-from .resources import OpenStackFloatingIP
 
 
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
 
 
@@ -32,27 +27,6 @@ class OpenStackFloatingIPSubService(BaseFloatingIPSubService):
     def __init__(self, provider, gateway):
     def __init__(self, provider, gateway):
         super(OpenStackFloatingIPSubService, self).__init__(provider, gateway)
         super(OpenStackFloatingIPSubService, self).__init__(provider, gateway)
 
 
-    def get(self, fip_id):
-        try:
-            return OpenStackFloatingIP(
-                self._provider, self._provider.os_conn.network.get_ip(fip_id))
-        except (ResourceNotFound, NotFoundException):
-            log.debug("Floating IP %s not found.", fip_id)
-            return None
-
-    def list(self, limit=None, marker=None):
-        fips = [OpenStackFloatingIP(self._provider, fip)
-                for fip in self._provider.os_conn.network.ips(
-                    floating_network_id=self.gateway.id
-                )]
-        return ClientPagedResultList(self._provider, fips,
-                                     limit=limit, marker=marker)
-
-    def create(self):
-        return OpenStackFloatingIP(
-            self._provider, self._provider.os_conn.network.create_ip(
-                floating_network_id=self.gateway.id))
-
 
 
 class OpenStackVMFirewallRuleSubService(BaseVMFirewallRuleSubService):
 class OpenStackVMFirewallRuleSubService(BaseVMFirewallRuleSubService):