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

Merging forgotten to commit local code with the repo

Enis Afgan 10 лет назад
Родитель
Сommit
ab58ed4a6a

+ 16 - 13
cloudbridge/providers/ec2/__init__.py

@@ -17,7 +17,7 @@ class EC2CloudProviderV1(CloudProvider):
         self.config = config
         self.cloud_type = 'ec2'
 
-        # Initialize optional fields
+        # Initialize cloud connection fields
         if isinstance(config, dict):
             self.a_key = config.get('access_key', os.environ.get('EC2_ACCESS_KEY', None))
             self.s_key = config.get('secret_key', os.environ.get('EC2_SECRET_KEY', None))
@@ -27,24 +27,27 @@ class EC2CloudProviderV1(CloudProvider):
             self.ec2_port = config.get('ec2_port', '')
             self.ec2_conn_path = config.get('ec2_conn_path', '/')
         else:
-            self.a_key = config.access_key if hasattr(
-                config, 'access_key') and config.access_key else os.environ.get('EC2_ACCESS_KEY', None)
-            self.s_key = config.secret_key if hasattr(
-                config, 'secret_key') and config.secret_key else os.environ.get('EC2_ACCESS_KEY', None)
+            self.a_key = config.access_key if hasattr(config, 'access_key') and \
+                config.access_key else os.environ.get('EC2_ACCESS_KEY', None)
+            self.s_key = config.secret_key if hasattr(config, 'secret_key') and \
+                config.secret_key else os.environ.get('EC2_ACCESS_KEY', None)
             self.is_secure = config.is_secure if hasattr(config, 'is_secure') else True
-            self.region_name = config.region_name if hasattr(config, 'region_name') else 'us-east-1'
-            self.region_endpoint = config.region_endpoint if hasattr(
-                config, 'region_endpoint') else 'ec2.us-east-1.amazonaws.com'
+            self.region_name = config.region_name if hasattr(config, 'region_name') \
+                else 'us-east-1'
+            self.region_endpoint = config.region_endpoint if hasattr(config, 'region_endpoint') \
+                else 'ec2.us-east-1.amazonaws.com'
             self.ec2_port = config.ec2_port if hasattr(config, 'ec2_port') else ''
             self.ec2_conn_path = config.ec2_conn_path if hasattr(config, 'ec2_conn_path') else "/"
 
+        # Create a connection object
         self.ec2_conn = self._connect_ec2()
 
-        # self.Compute = EC2ComputeService(self)
-        # self.Images = EC2ImageService(self)
+        # Initialize provider services
+        self.compute = None  # EC2ComputeService(self)
+        self.images = None  # EC2ImageService(self)
         self.security = EC2SecurityService(self)
-        # self.BlockStore = EC2BlockStore(self)
-        # self.ObjectStore = EC2ObjectStore(self)
+        self.block_store = None  # EC2BlockStore(self)
+        self.object_store = None  # EC2ObjectStore(self)
 
     def _connect_ec2(self):
         """
@@ -70,7 +73,7 @@ class EC2SecurityService(SecurityService):
 
     def list_key_pairs(self):
         """
-        List all key pairs.
+        List all key pairs associated with this account.
 
         :rtype: ``list`` of :class:`.KeyPair`
         :return:  list of KeyPair objects

+ 28 - 23
cloudbridge/providers/interfaces.py

@@ -1,18 +1,21 @@
 class CloudProviderServiceType():
 
     """
-    Defines possible service types that
-    are offered by providers. Providers can implement the
-    has_service method and clients can check for the availability
-    of a service with
-    if (provider.has_service(CloudProviderServiceTypes.OBJECTSTORE))
-        provider.ObjectStore.
+    Defines possible service types that are offered by providers.
+
+    Providers can implement the ``has_service`` method and clients can check
+    for the availability of a service with::
+
+        if (provider.has_service(CloudProviderServiceTypes.OBJECTSTORE))
+            ...
+
     """
     COMPUTE = 'compute'
     IMAGE = 'image'
     SECURITY = 'security'
     VOLUME = 'volume'
-    OBJECTSTORE = 'objectstore'
+    BLOCKSTORE = 'block_store'
+    OBJECTSTORE = 'object_store'
 
 
 class CloudProvider():
@@ -37,20 +40,22 @@ class CloudProvider():
         raise NotImplementedError(
             '__init__ not implemented by this provider')
 
-    def has_service(self, service):
+    def has_service(self, service_type):
         """
-        Checks whether this provider supports a given service"
+        Checks whether this provider supports a given service.
 
-        :type config: an object with required fields
-        :param config: This can be a Bunch or any other object whose fields can
-                       be accessed using dot notation. See specific provider
-                       implementation for the required fields.
+        :type service_type: str or :class:``.CloudProviderServiceType``
+        :param service_type: Type of service the check support for.
 
-        :rtype: ``object`` of :class:`.CloudProvider`
-        :return:  a concrete provider instance
+        :rtype: bool
+        :return: ``True`` if the service type is supported.
         """
-        raise NotImplementedError(
-            'has_service not implemented by this provider')
+        try:
+            if getattr(self, service_type):
+                return True
+        except AttributeError:
+            pass  # Undefined service type
+        return False
 
     def compute(self):
         """
@@ -60,7 +65,7 @@ class CloudProvider():
         :return:  a ComputeService object
         """
         raise NotImplementedError(
-            'CloudProvider.Compute not implemented by this provider')
+            'CloudProvider.compute not implemented by this provider')
 
     def image(self):
         """
@@ -71,7 +76,7 @@ class CloudProvider():
         :return: an ImageService object
         """
         raise NotImplementedError(
-            'CloudProvider.Images not implemented by this provider')
+            'CloudProvider.image not implemented by this provider')
 
     def security(self):
         """
@@ -81,7 +86,7 @@ class CloudProvider():
         :return: a SecurityService object
         """
         raise NotImplementedError(
-            'CloudProvider.Security not implemented by this provider')
+            'CloudProvider.security not implemented by this provider')
 
     def volume(self):
         """
@@ -92,7 +97,7 @@ class CloudProvider():
         :return: a VolumeService object
         """
         raise NotImplementedError(
-            'CloudProvider.VolumeService not implemented by this provider')
+            'CloudProvider.volume not implemented by this provider')
 
     def object_store(self):
         """
@@ -102,7 +107,7 @@ class CloudProvider():
         :return: an ObjectStoreService object
         """
         raise NotImplementedError(
-            'CloudProvider.ObjectStore not implemented by this provider')
+            'CloudProvider.object_store not implemented by this provider')
 
 
 class ComputeService():
@@ -379,7 +384,7 @@ class SecurityService():
 
     def list_key_pairs(self):
         """
-        List all key pairs.
+        List all key pairs associated with this account.
 
         :rtype: ``list`` of :class:`.KeyPair`
         :return:  list of KeyPair objects

+ 19 - 17
cloudbridge/providers/openstack/__init__.py

@@ -14,7 +14,7 @@ class OpenStackCloudProviderV1(CloudProvider):
     def __init__(self, config):
         self.config = config
 
-        # Initialize optional fields
+        # Initialize cloud connection fields
         if isinstance(config, dict):
             self.api_version = config.get(
                 'api_version', os.environ.get('OS_COMPUTE_API_VERSION', 2))
@@ -23,24 +23,26 @@ class OpenStackCloudProviderV1(CloudProvider):
             self.tenant_name = config.get('tenant_name', os.environ.get('OS_TENANT_NAME', None))
             self.auth_url = config.get('auth_url', os.environ.get('OS_AUTH_URL', None))
         else:
-            self.api_version = config.api_version if hasattr(
-                config, 'api_version') and config.api_version else os.environ.get('OS_COMPUTE_API_VERSION', None)
-            self.username = config.username if hasattr(
-                config, 'username') and config.username else os.environ.get('OS_USERNAME', None)
-            self.password = config.password if hasattr(
-                config, 'password') and config.password else os.environ.get('OS_PASSWORD', None)
-            self.tenant_name = config.tenant_name if hasattr(
-                config, 'tenant_name') and config.tenant_name else os.environ.get('OS_TENANT_NAME', None)
-            self.auth_url = config.auth_url if hasattr(
-                config, 'auth_url') and config.auth_url else os.environ.get('OS_AUTH_URL', None)
+            self.username = config.username if hasattr(config, 'username') and \
+                config.username else os.environ.get('OS_USERNAME')
+            self.password = config.password if hasattr(config, 'password') and \
+                config.password else os.environ.get('OS_PASSWORD')
+            self.tenant_name = config.tenant_name if hasattr(config, 'tenant_name') \
+                and config.tenant_name else os.environ.get('OS_TENANT_NAME')
+            self.auth_url = config.auth_url if hasattr(config, 'auth_url') and \
+                config.auth_url else os.environ.get('OS_AUTH_URL')
+            self.region_name = config.region_name if hasattr(config, 'region_name') \
+                and config.region_name else os.environ.get('OS_REGION_NAME')
 
+        # Create a connection object
         self.nova = self._connect_nova()
 
-        # self.Compute = EC2ComputeService(self)
-        # self.Images = EC2ImageService(self)
+        # Initialize provider services
+        self.compute = None  # OpenStackComputeService(self)
+        self.images = None  # OpenStackImageService(self)
         self.security = OpenStackSecurityService(self)
-        # self.BlockStore = EC2BlockStore(self)
-        # self.ObjectStore = EC2ObjectStore(self)
+        self.block_store = None  # OpenStackBlockStore(self)
+        self.object_store = None  # OpenStackObjectStore(self)
 
     def _connect_nova(self):
         """
@@ -56,10 +58,10 @@ class OpenStackSecurityService(SecurityService):
 
     def list_key_pairs(self):
         """
-        List all key pairs.
+        List all key pairs associated with this account.
 
         :rtype: ``list`` of :class:`.KeyPair`
         :return:  list of KeyPair objects
         """
         key_pairs = self.provider.nova.keypairs.list()
-        return [KeyPair(kp.id) for kp in key_pairs]
+        return [KeyPair(kp.id) for kp in key_pairs]

+ 26 - 0
cloudbridge/util/__init__.py

@@ -0,0 +1,26 @@
+"""
+A utility class with convenience classes.
+"""
+
+
+class Bunch(object):
+    """
+    A convenience class to allow dict keys to be represented as object fields.
+
+    The end result is that this allows a dict to be to be represented the same
+    as a database class, thus the two become interchangeable as a data source.
+    """
+    def __init__(self, **kwargs):
+        self.__dict__.update(kwargs)
+
+    def __repr__(self):
+        """
+        Return the contents of the dict in a printable representation
+        """
+        return str(self.__dict__)
+
+    def get(self, key, default=None):
+        """
+        Returns a value for the given key, if found or `'default` otherwise.
+        """
+        return self.__dict__.get(key, default)

+ 21 - 5
tests/TestProviderSecurityService.py

@@ -1,8 +1,10 @@
 """
-Tests the functionality of the Blend CloudMan API. These tests require working
-credentials to supported cloud infrastructure.
+Test the functionality of the CloudBridge API.
 
-Use ``nose tests`` to run these unit tests.
+These tests require working credentials exported as environment variables for
+supported cloud infrastructure.
+
+Use ``nosetests`` to run these unit tests.
 """
 import unittest
 from cloudbridge.providers.factory import CloudProviderFactory
@@ -10,11 +12,25 @@ from cloudbridge.providers.factory import ProviderList
 from cloudbridge.providers import interfaces
 
 
-class TestProviderSecurityService(unittest.TestCase):
+class TestProviderSecurityService_EC2(unittest.TestCase):
+
+    def setUp(self):
+        config = {}
+        self.provider = CloudProviderFactory().create_provider(
+            ProviderList.EC2, config)
+
+    def test_list_key_pairs(self):
+        key_pairs = self.provider.security.list_key_pairs()
+        # Assume there's always one keypair at least
+        assert(isinstance(key_pairs[0], interfaces.KeyPair))
+
+
+class TestProviderSecurityService_OS(unittest.TestCase):
 
     def setUp(self):
         config = {}
-        self.provider = CloudProviderFactory().create_provider(ProviderList.EC2, config)
+        self.provider = CloudProviderFactory().create_provider(
+            ProviderList.OPENSTACK, config)
 
     def test_list_key_pairs(self):
         key_pairs = self.provider.security.list_key_pairs()