]> git.apps.os.sepia.ceph.com Git - teuthology.git/commitdiff
cloud.openstack: Cache authentication tokens
authorZack Cerza <zack@redhat.com>
Fri, 10 Feb 2017 17:25:53 +0000 (10:25 -0700)
committerZack Cerza <zack@redhat.com>
Fri, 24 Feb 2017 16:03:33 +0000 (09:03 -0700)
Constantly causing Keystone to regenerate auth tokens was the cause of
our hitting rate limits during testing. This will let us reuse auth
tokens - including across processes - to avoid hitting those limits.

Signed-off-by: Zack Cerza <zack@redhat.com>
teuthology/provision/cloud/base.py
teuthology/provision/cloud/openstack.py
teuthology/provision/cloud/test/test_openstack.py

index c403829c1bc62f36eb645bb15af0f6094b6955dd..e06972e072dac12ed68869b07fef44cb964b27ac 100644 (file)
@@ -20,17 +20,20 @@ class Provider(object):
         self.conf = conf
         self.driver_name = self.conf['driver']
 
-    @property
-    def driver(self):
+    def _get_driver(self):
         driver_type = get_driver(
             getattr(lc_Provider, self.driver_name.upper())
         )
-        driver_args = deepcopy(self.conf['driver_args'])
+        driver_args = self._get_driver_args()
         driver = driver_type(
             *[driver_args.pop(arg_name) for arg_name in self._driver_posargs],
             **driver_args
         )
         return driver
+    driver = property(fget=_get_driver)
+
+    def _get_driver_args(self):
+        return deepcopy(self.conf['driver_args'])
 
 
 class Provisioner(object):
index 71e3962ebe6bf1901e03a0c2ab9c6cc7ec11067f..3a78d71a441c6636771b36509d20994014be5d05 100644 (file)
@@ -50,6 +50,29 @@ def retry(function, *args, **kwargs):
 class OpenStackProvider(Provider):
     _driver_posargs = ['username', 'password']
 
+    def _get_driver(self):
+        self._auth_token = util.AuthToken(name='teuthology_%s' % self.name)
+        with self._auth_token as token:
+            driver = super(OpenStackProvider, self)._get_driver()
+            # We must apparently call get_service_catalog() so that
+            # get_endpoint() works.
+            driver.connection.get_service_catalog()
+            if not token.value:
+                token.write(
+                    driver.connection.auth_token,
+                    driver.connection.auth_token_expires,
+                    driver.connection.get_endpoint(),
+                )
+        return driver
+    driver = property(fget=_get_driver)
+
+    def _get_driver_args(self):
+        driver_args = super(OpenStackProvider, self)._get_driver_args()
+        if self._auth_token.value:
+            driver_args['ex_force_auth_token'] = self._auth_token.value
+            driver_args['ex_force_base_url'] = self._auth_token.endpoint
+        return driver_args
+
     @property
     def images(self):
         if not hasattr(self, '_images'):
@@ -132,7 +155,7 @@ class OpenStackProvisioner(base.Provisioner):
 
         :return: None
         """
-        driver_name = self.provider.driver.name.lower()
+        driver_name = self.provider.driver_name.lower()
         full_conf = conf or dict()
         driver_conf = full_conf.get(driver_name, dict())
         legacy_conf = getattr(config, driver_name) or dict()
index ac07fdf8968d9000fe2dfdf2d447c3674ad6d03d..d2f259580e9b288f13e5365abafa2356ff2c707e 100644 (file)
@@ -123,6 +123,17 @@ class TestOpenStackBase(object):
             'libcloud.compute.drivers.openstack'
             '.OpenStackNodeDriver.destroy_volume'
         )
+        self.patchers['m_get_service_catalog'] = patch(
+            'libcloud.common.openstack'
+            '.OpenStackBaseConnection.get_service_catalog'
+        )
+        self.patchers['m_auth_token'] = patch(
+            'teuthology.provision.cloud.util.AuthToken'
+        )
+        self.patchers['m_get_endpoint'] = patch(
+            'libcloud.common.openstack'
+            '.OpenStackBaseConnection.get_endpoint',
+        )
         self.patchers['m_sleep'] = patch(
             'time.sleep'
         )
@@ -132,6 +143,7 @@ class TestOpenStackBase(object):
         self.mocks = dict()
         for name, patcher in self.patchers.items():
             self.mocks[name] = patcher.start()
+        self.mocks['m_get_endpoint'].return_value = 'endpoint'
 
     def teardown(self):
         for patcher in self.patchers.values():
@@ -148,8 +160,12 @@ class TestOpenStackProvider(TestOpenStackBase):
         assert obj.conf == test_config['providers']['my_provider']
 
     def test_driver(self):
+        token = self.mocks['m_auth_token'].return_value
+        self.mocks['m_auth_token'].return_value.__enter__.return_value = token
+        token.value = None
         obj = cloud.get_provider('my_provider')
         assert isinstance(obj.driver, get_driver('openstack'))
+        assert obj._auth_token.value is None
 
     def test_images(self):
         obj = cloud.get_provider('my_provider')