ソースを参照

Fixed to support latest openstack client library versions.

Nuwan Goonasekera 9 年 前
コミット
b45b966c76

+ 36 - 98
cloudbridge/cloud/providers/openstack/provider.py

@@ -33,14 +33,13 @@ class OpenStackCloudProvider(BaseCloudProvider):
             'os_username', os.environ.get('OS_USERNAME', None))
         self.password = self._get_config_value(
             'os_password', os.environ.get('OS_PASSWORD', None))
-        self.tenant_name = self._get_config_value(
-            'os_tenant_name', os.environ.get('OS_TENANT_NAME', None))
+        self.project_name = self._get_config_value(
+            'os_project_name', os.environ.get('OS_PROJECT_NAME', None) or
+            os.environ.get('OS_TENANT_NAME', None))
         self.auth_url = self._get_config_value(
             'os_auth_url', os.environ.get('OS_AUTH_URL', None))
         self.region_name = self._get_config_value(
             'os_region_name', os.environ.get('OS_REGION_NAME', None))
-        self.project_name = self._get_config_value(
-            'os_project_name', os.environ.get('OS_PROJECT_NAME', None))
         self.project_domain_name = self._get_config_value(
             'os_project_domain_name',
             os.environ.get('OS_PROJECT_DOMAIN_NAME', None))
@@ -49,23 +48,6 @@ class OpenStackCloudProvider(BaseCloudProvider):
         self.identity_api_version = self._get_config_value(
             'os_identity_api_version',
             os.environ.get('OS_IDENTITY_API_VERSION', None))
-        # Allow individual service connections to have their own values but
-        # default to the ones defined above.
-        self.swift_username = self._get_config_value(
-            'os_swift_username',
-            os.environ.get('OS_SWIFT_USERNAME', self.username))
-        self.swift_password = self._get_config_value(
-            'os_swift_password',
-            os.environ.get('OS_SWIFT_PASSWORD', self.password))
-        self.swift_tenant_name = self._get_config_value(
-            'os_swift_tenant_name',
-            os.environ.get('OS_SWIFT_TENANT_NAME', self.tenant_name))
-        self.swift_auth_url = self._get_config_value(
-            'os_swift_auth_url',
-            os.environ.get('OS_SWIFT_AUTH_URL', self.auth_url))
-        self.swift_region_name = self._get_config_value(
-            'os_swift_region_name',
-            os.environ.get('OS_SWIFT_REGION_NAME', self.region_name))
 
         # Service connections, lazily initialized
         self._nova = None
@@ -75,6 +57,9 @@ class OpenStackCloudProvider(BaseCloudProvider):
         self._swift = None
         self._neutron = None
 
+        # Additional cached variables
+        self._cached_keystone_session = None
+
         # Initialize provider services
         self._compute = OpenStackComputeService(self)
         self._network = OpenStackNetworkService(self)
@@ -115,14 +100,10 @@ class OpenStackCloudProvider(BaseCloudProvider):
         :rtype: :class:`keystoneauth1.session.Session`
         :return: A Keystone session object.
         """
-        def connect_v2():
-            from keystoneauth1.identity.v2 import Password as Password_v2
-            auth = Password_v2(self.auth_url, username=self.username,
-                               password=self.password,
-                               tenant_name=self.tenant_name)
-            return session.Session(auth=auth)
+        if self._cached_keystone_session:
+            return self._cached_keystone_session
 
-        def connect_v3():
+        if self._keystone_version == 3:
             from keystoneauth1.identity.v3 import Password as Password_v3
             auth = Password_v3(auth_url=self.auth_url,
                                username=self.username,
@@ -130,9 +111,14 @@ class OpenStackCloudProvider(BaseCloudProvider):
                                user_domain_name=self.user_domain_name,
                                project_domain_name=self.project_domain_name,
                                project_name=self.project_name)
-            return session.Session(auth=auth)
-
-        return connect_v3() if self._keystone_version == 3 else connect_v2()
+            self._cached_keystone_session = session.Session(auth=auth)
+        else:
+            from keystoneauth1.identity.v2 import Password as Password_v2
+            auth = Password_v2(self.auth_url, username=self.username,
+                               password=self.password,
+                               tenant_name=self.project_name)
+            self._cached_keystone_session = session.Session(auth=auth)
+        return self._cached_keystone_session
 
 #     @property
 #     def glance(self):
@@ -183,22 +169,8 @@ class OpenStackCloudProvider(BaseCloudProvider):
 
     def _connect_nova_region(self, region_name):
         """Get an OpenStack Nova (compute) client object."""
-        def connect_pwd():
-            """Connect using username and password parameters."""
-            nova = nova_client.Client(
-                api_version, username=self.username, api_key=self.password,
-                project_id=self.tenant_name, auth_url=self.auth_url,
-                region_name=region_name, service_name=service_name,
-                http_log_debug=True if self.config.debug_mode else False)
-            nova.authenticate()
-            return nova
-
-        def connect_sess():
-            """Connect using a Keystone session object."""
-            return nova_client.Client(
-                api_version, session=self._keystone_session,
-                service_name=service_name,
-                http_log_debug=True if self.config.debug_mode else False)
+        # Force reauthentication with Keystone
+        self._cached_keystone_session = None
 
         api_version = self._get_config_value(
             'os_compute_api_version',
@@ -210,11 +182,19 @@ class OpenStackCloudProvider(BaseCloudProvider):
         if self.config.debug_mode:
             nova_shell.OpenStackComputeShell().setup_debugging(True)
 
-        return connect_sess() if self._keystone_version == 3 else connect_pwd()
+        nova = nova_client.Client(
+                api_version, session=self._keystone_session,
+                region_name=region_name,
+                service_name=service_name,
+                http_log_debug=True if self.config.debug_mode else False)
+        return nova
 
     def _connect_keystone(self):
         """Get an OpenStack Keystone (identity) client object."""
-        def connect_v2():
+        if self._keystone_version == 3:
+            return keystone_client.Client(session=self._keystone_session,
+                                          auth_url=self.auth_url)
+        else:
             # Wow, the internal keystoneV2 implementation is terribly buggy. It
             # needs both a separate Session object and the username, password
             # again for things to work correctly. Plus, a manual call to
@@ -225,35 +205,20 @@ class OpenStackCloudProvider(BaseCloudProvider):
                 auth_url=self.auth_url,
                 username=self.username,
                 password=self.password,
-                tenant_name=self.tenant_name,
+                project_name=self.project_name,
                 region_name=self.region_name)
             keystone.authenticate()
             return keystone
 
-        def connect_v3():
-            return keystone_client.Client(session=self._keystone_session,
-                                          auth_url=self.auth_url)
-
-        return connect_v3() if self._keystone_version == 3 else connect_v2()
-
     def _connect_cinder(self):
         """Get an OpenStack Cinder (block storage) client object."""
-        def connect_pwd():
-            """Connect using username and password parameters."""
-            return cinder_client.Client(
-                api_version, username=self.username, api_key=self.password,
-                project_id=self.tenant_name, auth_url=self.auth_url)
-
-        def connect_sess():
-            """Connect using a Keystone session object."""
-            return cinder_client.Client(
-                api_version, session=self._keystone_session)
-
         api_version = self._get_config_value(
             'os_volume_api_version',
             os.environ.get('OS_VOLUME_API_VERSION', 2))
 
-        return connect_sess() if self._keystone_version == 3 else connect_pwd()
+        return cinder_client.Client(api_version,
+                                    session=self._keystone_session,
+                                    region_name=self.region_name)
 
 #     def _connect_glance(self):
 #         """
@@ -269,36 +234,9 @@ class OpenStackCloudProvider(BaseCloudProvider):
 
     def _connect_swift(self):
         """Get an OpenStack Swift (object store) client object cloud."""
-        def connect_v2():
-            os_options = {'region_name': self.swift_region_name}
-            return swift_client.Connection(
-                authurl=self.swift_auth_url, auth_version='2',
-                user=self.swift_username, key=self.swift_password,
-                tenant_name=self.swift_tenant_name,
-                os_options=os_options)
-
-        def connect_v3():
-            os_options = {'region_name': self.swift_region_name,
-                          'user_domain_name': self.user_domain_name,
-                          'project_domain_name': self.project_domain_name,
-                          'project_name': self.project_name}
-            return swift_client.Connection(
-                authurl=self.swift_auth_url, auth_version='3',
-                user=self.swift_username, key=self.swift_password,
-                os_options=os_options)
-
-        return connect_v3() if self._keystone_version == 3 else connect_v2()
+        return swift_client.Connection(session=self._keystone_session)
 
     def _connect_neutron(self):
         """Get an OpenStack Neutron (networking) client object cloud."""
-        def connect_pwd():
-            """Connect using username and password parameters."""
-            return neutron_client.Client(
-                username=self.username, password=self.password,
-                tenant_name=self.tenant_name, auth_url=self.auth_url)
-
-        def connect_sess():
-            """Connect using a Keystone session object."""
-            return neutron_client.Client(session=self._keystone_session)
-
-        return connect_sess() if self._keystone_version == 3 else connect_pwd()
+        return neutron_client.Client(session=self._keystone_session,
+                                     region_name=self.region_name)

+ 7 - 10
cloudbridge/cloud/providers/openstack/services.py

@@ -496,7 +496,13 @@ class OpenStackRegionService(BaseRegionService):
         return next(region, None)
 
     def list(self, limit=None, marker=None):
-        def keystone_v2():
+        # pylint:disable=protected-access
+        if self.provider._keystone_version == 3:
+            os_regions = [OpenStackRegion(self.provider, region)
+                          for region in self.provider.keystone.regions.list()]
+            return ClientPagedResultList(self.provider, os_regions,
+                                         limit=limit, marker=marker)
+        else:
             # Keystone v3 onwards supports directly listing regions
             # but for v2, this convoluted method is necessary.
             regions = (
@@ -511,15 +517,6 @@ class OpenStackRegionService(BaseRegionService):
             return ClientPagedResultList(self.provider, os_regions,
                                          limit=limit, marker=marker)
 
-        def keystone_v3():
-            os_regions = [OpenStackRegion(self.provider, region)
-                          for region in self.provider.keystone.regions.list()]
-            return ClientPagedResultList(self.provider, os_regions,
-                                         limit=limit, marker=marker)
-
-        return keystone_v3() if self.provider._keystone_version == 3 else \
-            keystone_v2()  # pylint:disable=protected-access
-
     @property
     def current(self):
         nova_region = self.provider.nova.client.region_name

+ 1 - 20
docs/topics/setup.rst

@@ -28,29 +28,10 @@ Mandatory variables  Optional Variables
 OS_AUTH_URL			 NOVA_SERVICE_NAME
 OS_USERNAME			 OS_COMPUTE_API_VERSION
 OS_PASSWORD			 OS_VOLUME_API_VERSION
-OS_TENANT_NAME
+OS_PROJECT_NAME
 OS_REGION_NAME
 ===================  ==================
 
-If you'd like, you can specify service-specific variables for OpenStack.
-This can be used to create a multi-cloud provider object for example where
-the compute service is using one cloud while the object store service uses
-another. This can be useful is a given cloud does not supply all the desired
-services. If these variables are not supplied, the default ones from above
-are used across all OpenStack services.
-
-=================================== ==============
-Optional service-specific variables Example values
------------------------------------ --------------
-Swift service
-==================================================
-OS_SWIFT_AUTH_URL                   https://keystone.rc.nectar.org.au:5000/v2.0/
-OS_SWIFT_USERNAME                   your.name@example.com
-OS_SWIFT_PASSWORD                   GcsGgcbsdilcbUIYGcsdc
-OS_SWIFT_REGION_NAME                RegionOne
-OS_SWIFT_TENANT_NAME                GalaxyProject
-=================================== ==============
-
 
 Once the environment variables are set, you can create a connection as follows:
 

+ 6 - 6
setup.py

@@ -14,12 +14,12 @@ with open(os.path.join('cloudbridge', '__init__.py')) as f:
             break
 
 base_reqs = ['bunch>=1.0.1', 'six>=1.10.0', 'retrying>=1.3.3']
-openstack_reqs = ['python-novaclient>=2.33.0',
-                  'python-glanceclient',
-                  'python-cinderclient>=1.4.0',
-                  'python-swiftclient>=2.6.0',
-                  'python-neutronclient>=3.1.0',
-                  'python-keystoneclient>=2.0.0']
+openstack_reqs = ['python-novaclient>=7.0.0',
+                  'python-glanceclient>=2.5.0',
+                  'python-cinderclient>=1.9.0',
+                  'python-swiftclient>=3.2.0',
+                  'python-neutronclient>=6.0.0',
+                  'python-keystoneclient>=3.8.0']
 aws_reqs = ['boto>=2.38.0']
 full_reqs = base_reqs + aws_reqs + openstack_reqs
 dev_reqs = (['tox>=2.1.1', 'moto>=0.4.20', 'sphinx>=1.3.1'] + full_reqs)