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
This commit is contained in:
Steve Baker 2014-06-09 11:42:16 +12:00
parent cc1ffff771
commit bd4317e7b9
8 changed files with 43 additions and 67 deletions

View File

@ -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)

View File

@ -15,7 +15,6 @@ from oslo.config import cfg
from stevedore import extension from stevedore import extension
import warnings import warnings
from heat.common import heat_keystoneclient as hkc
from heat.openstack.common.gettextutils import _ from heat.openstack.common.gettextutils import _
from heat.openstack.common import importutils from heat.openstack.common import importutils
from heat.openstack.common import log as logging from heat.openstack.common import log as logging
@ -81,9 +80,6 @@ class OpenStackClients(object):
'Replace with calls to client("keystone")') 'Replace with calls to client("keystone")')
return self.client('keystone') return self.client('keystone')
def _keystone(self):
return hkc.KeystoneClient(self.context)
def url_for(self, **kwargs): def url_for(self, **kwargs):
return self.client('keystone').url_for(**kwargs) return self.client('keystone').url_for(**kwargs)

View File

@ -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)

View File

@ -25,7 +25,7 @@ import testscenarios
import testtools import testtools
from heat.common import messaging 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 environment
from heat.engine import resources from heat.engine import resources
from heat.engine import scheduler from heat.engine import scheduler
@ -115,7 +115,7 @@ class HeatTestCase(testscenarios.WithScenarios,
return mockfixture.mock return mockfixture.mock
def stub_keystoneclient(self, **kwargs): def stub_keystoneclient(self, **kwargs):
client = self.patchobject(clients.OpenStackClients, "_keystone") client = self.patchobject(keystone.KeystoneClientPlugin, "_create")
fkc = fakes.FakeKeystoneClient(**kwargs) fkc = fakes.FakeKeystoneClient(**kwargs)
client.return_value = fkc client.return_value = fkc
return fkc return fkc

View File

@ -32,6 +32,7 @@ from heat.common import template_format
from heat.common import urlfetch from heat.common import urlfetch
from heat.db import api as db_api from heat.db import api as db_api
from heat.engine.clients.os import glance from heat.engine.clients.os import glance
from heat.engine.clients.os import keystone
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import dependencies from heat.engine import dependencies
from heat.engine import environment from heat.engine import environment
@ -197,8 +198,8 @@ def get_stack(stack_name, ctx, template):
def setup_keystone_mocks(mocks, stack): def setup_keystone_mocks(mocks, stack):
fkc = test_fakes.FakeKeystoneClient() fkc = test_fakes.FakeKeystoneClient()
mocks.StubOutWithMock(stack.clients, '_keystone') mocks.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
stack.clients._keystone().MultipleTimes().AndReturn(fkc) keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn(fkc)
def setup_mock_for_image_constraint(mocks, imageId_input, def setup_mock_for_image_constraint(mocks, imageId_input,

View File

@ -31,7 +31,7 @@ import heat.db.api as db_api
import heat.engine.cfn.functions import heat.engine.cfn.functions
from heat.engine.cfn import functions as cfn_funcs from heat.engine.cfn import functions as cfn_funcs
from heat.engine.cfn import template as cfn_t 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.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import function from heat.engine import function
@ -956,7 +956,8 @@ class StackTest(HeatTestCase):
self.m.ReplayAll() self.m.ReplayAll()
stack = parser.Stack(ctx, 'test_stack', self.tmpl) 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() self.m.VerifyAll()
@ -1345,8 +1346,8 @@ class StackTest(HeatTestCase):
def delete_trust(self, trust_id): def delete_trust(self, trust_id):
raise Exception("Shouldn't delete") raise Exception("Shouldn't delete")
self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
clients.OpenStackClients._keystone().MultipleTimes().AndReturn( keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn(
FakeKeystoneClientFail()) FakeKeystoneClientFail())
self.m.ReplayAll() self.m.ReplayAll()
@ -1371,8 +1372,8 @@ class StackTest(HeatTestCase):
def delete_trust(self, trust_id): def delete_trust(self, trust_id):
raise kc_exceptions.Forbidden("Denied!") raise kc_exceptions.Forbidden("Denied!")
self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
clients.OpenStackClients._keystone().MultipleTimes().AndReturn( keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn(
FakeKeystoneClientFail()) FakeKeystoneClientFail())
self.m.ReplayAll() self.m.ReplayAll()
@ -3030,8 +3031,8 @@ class StackTest(HeatTestCase):
""" """
cfg.CONF.set_override('deferred_auth_method', 'trusts') cfg.CONF.set_override('deferred_auth_method', 'trusts')
self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
clients.OpenStackClients._keystone().MultipleTimes().AndReturn( keystone.KeystoneClientPlugin._create().MultipleTimes().AndReturn(
FakeKeystoneClient()) FakeKeystoneClient())
self.m.ReplayAll() self.m.ReplayAll()
@ -3189,8 +3190,8 @@ class StackTest(HeatTestCase):
def delete_stack_domain_project(self, project_id): def delete_stack_domain_project(self, project_id):
raise kc_exceptions.Forbidden("Denied!") raise kc_exceptions.Forbidden("Denied!")
self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
clients.OpenStackClients._keystone().AndReturn( keystone.KeystoneClientPlugin._create().AndReturn(
FakeKeystoneClientFail()) FakeKeystoneClientFail())
self.m.ReplayAll() self.m.ReplayAll()

View File

@ -19,7 +19,7 @@ from oslo.config import cfg
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.db import api as db_api 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 parser
from heat.engine import resource from heat.engine import resource
from heat.engine import scheduler from heat.engine import scheduler
@ -214,8 +214,8 @@ class SignalTest(HeatTestCase):
def delete_stack_user(self, name): def delete_stack_user(self, name):
raise kc_exceptions.NotFound() raise kc_exceptions.NotFound()
self.m.StubOutWithMock(clients.OpenStackClients, '_keystone') self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
clients.OpenStackClients._keystone().AndReturn( keystone.KeystoneClientPlugin._create().AndReturn(
FakeKeystoneClientFail()) FakeKeystoneClientFail())
self.m.ReplayAll() self.m.ReplayAll()
@ -309,8 +309,8 @@ class SignalTest(HeatTestCase):
# Since we unset the stubs above we must re-stub keystone to keep the # Since we unset the stubs above we must re-stub keystone to keep the
# test isolated from keystoneclient. # test isolated from keystoneclient.
self.m.StubOutWithMock(self.stack.clients, '_keystone') self.m.StubOutWithMock(keystone.KeystoneClientPlugin, '_create')
self.stack.clients._keystone().AndReturn(self.fc) keystone.KeystoneClientPlugin._create().AndReturn(self.fc)
self.m.ReplayAll() self.m.ReplayAll()

View File

@ -42,6 +42,7 @@ heat.clients =
cinder = heat.engine.clients.os.cinder:CinderClientPlugin cinder = heat.engine.clients.os.cinder:CinderClientPlugin
glance = heat.engine.clients.os.glance:GlanceClientPlugin glance = heat.engine.clients.os.glance:GlanceClientPlugin
heat = heat.engine.clients.os.heat_plugin:HeatClientPlugin heat = heat.engine.clients.os.heat_plugin:HeatClientPlugin
keystone = heat.engine.clients.os.keystone:KeystoneClientPlugin
nova = heat.engine.clients.os.nova:NovaClientPlugin nova = heat.engine.clients.os.nova:NovaClientPlugin
neutron = heat.engine.clients.os.neutron:NeutronClientPlugin neutron = heat.engine.clients.os.neutron:NeutronClientPlugin
swift = heat.engine.clients.os.swift:SwiftClientPlugin swift = heat.engine.clients.os.swift:SwiftClientPlugin