From bd4317e7b9760b55c70477472fc3f1c0997dc036 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Mon, 9 Jun 2014 11:42:16 +1200 Subject: [PATCH] Implement keystone client plugin This moves the client creation code out of Clients._keystone() into its own client plugin. This is the last client to convert to a plugin, so supporting code to fetch a client from a non-plugin has been removed. In a later change it would be worth considering moving methods in heat_keystoneclient.KeystoneClient into KeystoneClientPlugin so that calling Clients.client('keystone') returns the actual keystone client rather than a wrapper. The barbican TestClient has been removed; it had limited practical value since it mocked all of the internal calls of the method it was testing. Change-Id: Ie4a616d6a2b056fe59877e2bec325f02b6d7a693 --- .../barbican/barbican/tests/test_clients.py | 44 ------------------- heat/engine/clients/__init__.py | 4 -- heat/engine/clients/os/keystone.py | 21 +++++++++ heat/tests/common.py | 4 +- heat/tests/test_engine_service.py | 5 ++- heat/tests/test_parser.py | 21 ++++----- heat/tests/test_signal.py | 10 ++--- setup.cfg | 1 + 8 files changed, 43 insertions(+), 67 deletions(-) delete mode 100644 contrib/barbican/barbican/tests/test_clients.py create mode 100644 heat/engine/clients/os/keystone.py diff --git a/contrib/barbican/barbican/tests/test_clients.py b/contrib/barbican/barbican/tests/test_clients.py deleted file mode 100644 index 9a4fd5561a..0000000000 --- a/contrib/barbican/barbican/tests/test_clients.py +++ /dev/null @@ -1,44 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock - -from heat.tests.common import HeatTestCase -from heat.tests import utils - -from .. import clients # noqa - - -class TestClient(HeatTestCase): - - def setUp(self): - super(TestClient, self).setUp() - self.ctx = utils.dummy_context() - self.clients = clients.Clients(self.ctx) - - @mock.patch.object(clients.heat_clients, 'Clients') - @mock.patch.object(clients, 'barbican_client') - @mock.patch.object(clients, 'auth') - def test_barbican_passes_in_heat_keystone_client(self, mock_auth, - mock_barbican_client, - mock_heat_clients): - mock_ks = mock.Mock() - self.clients._keystone = mock.Mock() - self.clients._keystone.return_value.client = mock_ks - mock_plugin = mock.Mock() - mock_auth.KeystoneAuthV2.return_value = mock_plugin - - self.clients.client('barbican') - mock_auth.KeystoneAuthV2.assert_called_once_with(keystone=mock_ks) - mock_barbican_client.Client.assert_called_once_with(auth_plugin= - mock_plugin) diff --git a/heat/engine/clients/__init__.py b/heat/engine/clients/__init__.py index b72e898151..1abf528be8 100644 --- a/heat/engine/clients/__init__.py +++ b/heat/engine/clients/__init__.py @@ -15,7 +15,6 @@ from oslo.config import cfg from stevedore import extension import warnings -from heat.common import heat_keystoneclient as hkc from heat.openstack.common.gettextutils import _ from heat.openstack.common import importutils from heat.openstack.common import log as logging @@ -81,9 +80,6 @@ class OpenStackClients(object): 'Replace with calls to client("keystone")') return self.client('keystone') - def _keystone(self): - return hkc.KeystoneClient(self.context) - def url_for(self, **kwargs): return self.client('keystone').url_for(**kwargs) diff --git a/heat/engine/clients/os/keystone.py b/heat/engine/clients/os/keystone.py new file mode 100644 index 0000000000..13f04e2ee4 --- /dev/null +++ b/heat/engine/clients/os/keystone.py @@ -0,0 +1,21 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from heat.common import heat_keystoneclient as hkc +from heat.engine.clients import client_plugin + + +class KeystoneClientPlugin(client_plugin.ClientPlugin): + + def _create(self): + return hkc.KeystoneClient(self.context) diff --git a/heat/tests/common.py b/heat/tests/common.py index ad3f0832cc..d64fc5cae6 100644 --- a/heat/tests/common.py +++ b/heat/tests/common.py @@ -25,7 +25,7 @@ import testscenarios import testtools from heat.common import messaging -from heat.engine import clients +from heat.engine.clients.os import keystone from heat.engine import environment from heat.engine import resources from heat.engine import scheduler @@ -115,7 +115,7 @@ class HeatTestCase(testscenarios.WithScenarios, return mockfixture.mock def stub_keystoneclient(self, **kwargs): - client = self.patchobject(clients.OpenStackClients, "_keystone") + client = self.patchobject(keystone.KeystoneClientPlugin, "_create") fkc = fakes.FakeKeystoneClient(**kwargs) client.return_value = fkc return fkc diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index 35575e6718..c6db9ad4b8 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -32,6 +32,7 @@ from heat.common import template_format from heat.common import urlfetch from heat.db import api as db_api from heat.engine.clients.os import glance +from heat.engine.clients.os import keystone from heat.engine.clients.os import nova from heat.engine import dependencies from heat.engine import environment @@ -197,8 +198,8 @@ def get_stack(stack_name, ctx, template): def setup_keystone_mocks(mocks, stack): fkc = test_fakes.FakeKeystoneClient() - mocks.StubOutWithMock(stack.clients, '_keystone') - stack.clients._keystone().MultipleTimes().AndReturn(fkc) + mocks.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn(fkc) def setup_mock_for_image_constraint(mocks, imageId_input, diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index 76f0d7d59c..25c06832de 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -31,7 +31,7 @@ import heat.db.api as db_api import heat.engine.cfn.functions from heat.engine.cfn import functions as cfn_funcs from heat.engine.cfn import template as cfn_t -from heat.engine import clients +from heat.engine.clients.os import keystone from heat.engine.clients.os import nova from heat.engine import environment from heat.engine import function @@ -956,7 +956,8 @@ class StackTest(HeatTestCase): self.m.ReplayAll() stack = parser.Stack(ctx, 'test_stack', self.tmpl) - self.assertEqual('abcd1234', stack.clients.auth_token) + self.assertEqual('abcd1234', + stack.clients.client('keystone').auth_token) self.m.VerifyAll() @@ -1345,8 +1346,8 @@ class StackTest(HeatTestCase): def delete_trust(self, trust_id): raise Exception("Shouldn't delete") - self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') - clients.OpenStackClients._keystone().MultipleTimes().AndReturn( + self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn( FakeKeystoneClientFail()) self.m.ReplayAll() @@ -1371,8 +1372,8 @@ class StackTest(HeatTestCase): def delete_trust(self, trust_id): raise kc_exceptions.Forbidden("Denied!") - self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') - clients.OpenStackClients._keystone().MultipleTimes().AndReturn( + self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn( FakeKeystoneClientFail()) self.m.ReplayAll() @@ -3030,8 +3031,8 @@ class StackTest(HeatTestCase): """ cfg.CONF.set_override('deferred_auth_method', 'trusts') - self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') - clients.OpenStackClients._keystone().MultipleTimes().AndReturn( + self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn( FakeKeystoneClient()) self.m.ReplayAll() @@ -3189,8 +3190,8 @@ class StackTest(HeatTestCase): def delete_stack_domain_project(self, project_id): raise kc_exceptions.Forbidden("Denied!") - self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') - clients.OpenStackClients._keystone().AndReturn( + self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().AndReturn( FakeKeystoneClientFail()) self.m.ReplayAll() diff --git a/heat/tests/test_signal.py b/heat/tests/test_signal.py index 3ba1fb0a57..7f40c7a4e4 100644 --- a/heat/tests/test_signal.py +++ b/heat/tests/test_signal.py @@ -19,7 +19,7 @@ from oslo.config import cfg from heat.common import exception from heat.common import template_format from heat.db import api as db_api -from heat.engine import clients +from heat.engine.clients.os import keystone from heat.engine import parser from heat.engine import resource from heat.engine import scheduler @@ -214,8 +214,8 @@ class SignalTest(HeatTestCase): def delete_stack_user(self, name): raise kc_exceptions.NotFound() - self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') - clients.OpenStackClients._keystone().AndReturn( + self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().AndReturn( FakeKeystoneClientFail()) self.m.ReplayAll() @@ -309,8 +309,8 @@ class SignalTest(HeatTestCase): # Since we unset the stubs above we must re-stub keystone to keep the # test isolated from keystoneclient. - self.m.StubOutWithMock(self.stack.clients, '_keystone') - self.stack.clients._keystone().AndReturn(self.fc) + self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create') + keystone.KeystoneClientPlugin._create().AndReturn(self.fc) self.m.ReplayAll() diff --git a/setup.cfg b/setup.cfg index bd1d952e91..56019ad3cb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -42,6 +42,7 @@ heat.clients = cinder = heat.engine.clients.os.cinder:CinderClientPlugin glance = heat.engine.clients.os.glance:GlanceClientPlugin heat = heat.engine.clients.os.heat_plugin:HeatClientPlugin + keystone = heat.engine.clients.os.keystone:KeystoneClientPlugin nova = heat.engine.clients.os.nova:NovaClientPlugin neutron = heat.engine.clients.os.neutron:NeutronClientPlugin swift = heat.engine.clients.os.swift:SwiftClientPlugin