diff --git a/rally/osclients.py b/rally/osclients.py index c35682d326..8bffd5f98c 100644 --- a/rally/osclients.py +++ b/rally/osclients.py @@ -25,6 +25,7 @@ from keystoneclient.v2_0 import client as keystone from neutronclient.neutron import client as neutron from novaclient import client as nova from oslo.config import cfg +from saharaclient import client as sahara from rally import consts from rally import exceptions @@ -219,6 +220,17 @@ class Clients(object): cacert=CONF.https_cacert) return client + @cached + def sahara(self, version='1.1'): + """Return Sahara client.""" + client = sahara.Client(version, + username=self.endpoint.username, + api_key=self.endpoint.password, + project_name=self.endpoint.tenant_name, + auth_url=self.endpoint.auth_url) + + return client + @cached def services(self): """Return available services names and types. diff --git a/requirements.txt b/requirements.txt index 50618d9378..9cd626ab0e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ python-cinderclient>=1.0.7 python-heatclient>=0.2.9 python-ceilometerclient>=1.0.6 python-ironicclient +python-saharaclient>=0.6.0 python-subunit>=0.0.18 requests>=1.1 SQLAlchemy>=0.8.4,!=0.9.5,<=0.9.99 diff --git a/tests/fakes.py b/tests/fakes.py index 28a1c83f22..6f6666bbfa 100644 --- a/tests/fakes.py +++ b/tests/fakes.py @@ -807,6 +807,12 @@ class FakeIronicClient(object): pass +class FakeSaharaClient(object): + + def __init__(self): + pass + + class FakeClients(object): def __init__(self, endpoint_=None): @@ -815,6 +821,7 @@ class FakeClients(object): self._keystone = None self._cinder = None self._neutron = None + self._sahara = None self._endpoint = endpoint_ or endpoint.Endpoint( "http://fake.example.org:5000/v2.0/", "fake_username", @@ -849,6 +856,11 @@ class FakeClients(object): self._neutron = FakeNeutronClient() return self._neutron + def sahara(self): + if not self._sahara: + self._sahara = FakeSaharaClient() + return self._sahara + class FakeRunner(object): diff --git a/tests/test_osclients.py b/tests/test_osclients.py index 011fe3f36d..6a3c9b6e58 100644 --- a/tests/test_osclients.py +++ b/tests/test_osclients.py @@ -182,6 +182,22 @@ class OSClientsTestCase(test.TestCase): mock_ironic.Client.assert_called_once_with("1.0", **kw) self.assertEqual(self.clients.cache["ironic"], fake_ironic) + @mock.patch("rally.osclients.sahara") + def test_sahara(self, mock_sahara): + fake_sahara = fakes.FakeSaharaClient() + mock_sahara.Client = mock.MagicMock(return_value=fake_sahara) + self.assertTrue("sahara" not in self.clients.cache) + client = self.clients.sahara() + self.assertEqual(client, fake_sahara) + kw = { + "username": self.endpoint.username, + "api_key": self.endpoint.password, + "project_name": self.endpoint.tenant_name, + "auth_url": self.endpoint.auth_url + } + mock_sahara.Client.assert_called_once_with("1.1", **kw) + self.assertEqual(self.clients.cache["sahara"], fake_sahara) + @mock.patch("rally.osclients.Clients.keystone") def test_services(self, mock_keystone): available_services = {consts.ServiceType.IDENTITY: {},