Add caching to osclients.Clients

Here we add caching capabilities to the osclients.Clients class, so that any
openstack client, created once, gets stored in the cache and is immediately
returned in case of future calls to the corresponding method of Clients.
This is needed for implementing lazy OpenStack clients for temporary users
where it is not convenient to store clients in Scenario classes but making
use of caching in osclients.Clients makes sense.

Blueprint lazy-osclients

Change-Id: I5021ae0c2e11f0a27a6ea94e5a254739ddec869f
This commit is contained in:
Mikhail Dubov 2013-12-02 18:32:28 +04:00
parent da68063db9
commit 348493e191
2 changed files with 71 additions and 24 deletions

View File

@ -27,40 +27,64 @@ class Clients(object):
def __init__(self, username, password, tenant_name, auth_url):
self.kw = {'username': username, 'password': password,
'tenant_name': tenant_name, 'auth_url': auth_url}
self.cache = {}
def get_keystone_client(self):
"""Return keystone client."""
if "keystone" in self.cache:
return self.cache["keystone"]
new_kw = {"endpoint": self._change_port(self.kw["auth_url"], "35357")}
kw = dict(self.kw.items() + new_kw.items())
client = keystone.Client(**kw)
client.authenticate()
self.cache["keystone"] = client
return client
def get_nova_client(self, version='2'):
"""Returns nova client."""
return nova.Client(version,
self.kw['username'],
self.kw['password'],
self.kw['tenant_name'],
auth_url=self.kw['auth_url'],
service_type='compute')
if "nova" in self.cache:
return self.cache["nova"]
def get_glance_client(self, version='1'):
"""Returns glance client."""
kc = self.get_keystone_client()
endpoint = kc.service_catalog.get_endpoints()['image'][0]
return glance.Client(version,
endpoint=endpoint['publicURL'],
token=kc.auth_token)
def get_cinder_client(self, version='1'):
"""Returns cinder client."""
return cinder.Client(version,
client = nova.Client(version,
self.kw['username'],
self.kw['password'],
self.kw['tenant_name'],
auth_url=self.kw['auth_url'],
service_type='volume')
service_type='compute')
self.cache["nova"] = client
return client
def get_glance_client(self, version='1'):
"""Returns glance client."""
if "glance" in self.cache:
return self.cache["glance"]
kc = self.get_keystone_client()
endpoint = kc.service_catalog.get_endpoints()['image'][0]
client = glance.Client(version,
endpoint=endpoint['publicURL'],
token=kc.auth_token)
self.cache["glance"] = client
return client
def get_cinder_client(self, version='1'):
"""Returns cinder client."""
if "cinder" in self.cache:
return self.cache["cinder"]
client = cinder.Client(version,
self.kw['username'],
self.kw['password'],
self.kw['tenant_name'],
auth_url=self.kw['auth_url'],
service_type='volume')
self.cache["cinder"] = client
return client
def _change_port(self, url, new_port):
"""Change the port of a given url.

View File

@ -24,6 +24,18 @@ class FakeServiceCatalog(object):
return {'image': [{'publicURL': 'http://fake.to'}]}
class FakeNova(object):
pass
class FakeGlance(object):
pass
class FakeCinder(object):
pass
class FakeKeystone(object):
def __init__(self):
self.auth_token = 'fake'
@ -52,38 +64,49 @@ class OSClientsTestCase(test.TestCase):
with mock.patch('rally.osclients.keystone') as mock_keystone:
fake_keystone = FakeKeystone()
mock_keystone.Client = mock.MagicMock(return_value=fake_keystone)
self.assertTrue("keystone" not in self.clients.cache)
client = self.clients.get_keystone_client()
self.assertEqual(client, fake_keystone)
endpoint = {"endpoint": "http://auth_url:35357"}
kwargs = dict(self.kwargs.items() + endpoint.items())
mock_keystone.Client.assert_called_once_with(**kwargs)
self.assertEqual(self.clients.cache["keystone"], fake_keystone)
def test_get_nova_client(self):
with mock.patch('rally.osclients.nova') as mock_nova:
mock_nova.Client = mock.MagicMock(return_value={})
fake_nova = FakeNova()
mock_nova.Client = mock.MagicMock(return_value=fake_nova)
self.assertTrue("nova" not in self.clients.cache)
client = self.clients.get_nova_client()
self.assertEqual(client, {})
self.assertEqual(client, fake_nova)
mock_nova.Client.assert_called_once_with('2', *self.args[:3],
auth_url=self.args[-1],
service_type='compute')
self.assertEqual(self.clients.cache["nova"], fake_nova)
def test_get_glance_client(self):
with mock.patch('rally.osclients.glance') as mock_glance:
mock_glance.Client = mock.MagicMock(return_value={})
fake_glance = FakeGlance()
mock_glance.Client = mock.MagicMock(return_value=fake_glance)
kc = FakeKeystone()
self.clients.get_keystone_client = mock.MagicMock(return_value=kc)
self.assertTrue("glance" not in self.clients.cache)
client = self.clients.get_glance_client()
self.assertEqual(client, {})
self.assertEqual(client, fake_glance)
endpoint = kc.service_catalog.get_endpoints()['image'][0]
kw = {'endpoint': endpoint['publicURL'], 'token': kc.auth_token}
mock_glance.Client.assert_called_once_with('1', **kw)
self.assertEqual(self.clients.cache["glance"], fake_glance)
def test_get_cinder_client(self):
with mock.patch('rally.osclients.cinder') as mock_cinder:
mock_cinder.Client = mock.MagicMock(return_value={})
fake_cinder = FakeCinder()
mock_cinder.Client = mock.MagicMock(return_value=fake_cinder)
self.assertTrue("cinder" not in self.clients.cache)
client = self.clients.get_cinder_client()
self.assertEqual(client, {})
self.assertEqual(client, fake_cinder)
mock_cinder.Client.assert_called_once_with('1', *self.args[:3],
auth_url=self.args[-1],
service_type='volume')
self.assertEqual(self.clients.cache["cinder"], fake_cinder)