From 71cb6b3d0ee1f393c2bafee13aa2f013cc82f77d Mon Sep 17 00:00:00 2001 From: Mehdi Abaakouk Date: Wed, 6 Jan 2016 09:44:09 +0100 Subject: Don't copy the auth_plugin for aodh We must not copy a keystone session object or auth_plugin object. This change simplifies the aodh redirection code by: * sharing the keystone session object between aodh and ceilometer client * creating a new AuthPlugin() for the aodh client instead of copying the ceilometer one and then change its content. Closes-bug: #1531452 Change-Id: I2b2195e32c5dd74136237f7166c9c0d325434611 --- ceilometerclient/client.py | 76 +------------- ceilometerclient/tests/unit/test_client.py | 148 ++++++++++----------------- ceilometerclient/tests/unit/test_shell.py | 40 +++++--- ceilometerclient/tests/unit/v2/test_shell.py | 12 +-- ceilometerclient/v2/client.py | 78 +++++++------- 5 files changed, 127 insertions(+), 227 deletions(-) diff --git a/ceilometerclient/client.py b/ceilometerclient/client.py index f0fc469..cc65f8d 100644 --- a/ceilometerclient/client.py +++ b/ceilometerclient/client.py @@ -134,66 +134,6 @@ def _get_keystone_session(**kwargs): return ks_session -def _get_token_auth_ks_session(**kwargs): - - cacert = kwargs.pop('cacert', None) - cert = kwargs.pop('cert', None) - key = kwargs.pop('key', None) - insecure = kwargs.pop('insecure', False) - auth_url = kwargs.pop('auth_url', None) - project_id = kwargs.pop('project_id', None) - project_name = kwargs.pop('project_name', None) - timeout = kwargs.get('timeout') - token = kwargs['token'] - - if insecure: - verify = False - else: - verify = cacert or True - - if cert and key: - # passing cert and key together is deprecated in favour of the - # requests lib form of having the cert and key as a tuple - cert = (cert, key) - - # create the keystone client session - ks_session = session.Session(verify=verify, cert=cert, timeout=timeout) - v2_auth_url, v3_auth_url = _discover_auth_versions(ks_session, auth_url) - - user_domain_name = kwargs.pop('user_domain_name', None) - user_domain_id = kwargs.pop('user_domain_id', None) - project_domain_name = kwargs.pop('project_domain_name', None) - project_domain_id = kwargs.pop('project_domain_id', None) - auth = None - - use_domain = (user_domain_id or user_domain_name or - project_domain_id or project_domain_name) - use_v3 = v3_auth_url and (use_domain or (not v2_auth_url)) - use_v2 = v2_auth_url and not use_domain - - if use_v3: - auth = v3_auth.Token( - v3_auth_url, - token=token, - project_name=project_name, - project_id=project_id, - project_domain_name=project_domain_name, - project_domain_id=project_domain_id) - elif use_v2: - auth = v2_auth.Token( - v2_auth_url, - token=token, - tenant_id=project_id, - tenant_name=project_name) - else: - raise exc.CommandError('Unable to determine the Keystone version ' - 'to authenticate with using the given ' - 'auth_url.') - - ks_session.auth = auth - return ks_session - - def _get_endpoint(ks_session, **kwargs): """Get an endpoint using the provided keystone session.""" @@ -255,26 +195,12 @@ class AuthPlugin(auth.BaseAuthPlugin): 'insecure': strutils.bool_from_string( self.opts.get('insecure')), 'endpoint_type': self.opts.get('endpoint_type'), + 'service_type': self.opts.get('service_type'), 'region_name': self.opts.get('region_name'), 'timeout': http_timeout, } return ks_kwargs - def redirect_to_aodh_endpoint(self, http_timeout): - ks_kwargs = self._get_ks_kwargs(http_timeout) - token = self.opts.get('token') or self.opts.get('auth_token') - # NOTE(liusheng): if token provided, we try to get keystone session - # with token, else, we get keystone session with user info and - # password. And then use the keystone session to get aodh's endpoint. - if token: - token = token() if callable(token) else token - ks_kwargs.update(token=token) - ks_session = _get_token_auth_ks_session(**ks_kwargs) - else: - ks_session = _get_keystone_session(**ks_kwargs) - ks_kwargs.update(service_type='alarming') - self.opts['endpoint'] = _get_endpoint(ks_session, **ks_kwargs) - def token_and_endpoint(self, endpoint_type, service_type): token = self.opts.get('token') if callable(token): diff --git a/ceilometerclient/tests/unit/test_client.py b/ceilometerclient/tests/unit/test_client.py index 90f0c3d..18335ba 100644 --- a/ceilometerclient/tests/unit/test_client.py +++ b/ceilometerclient/tests/unit/test_client.py @@ -12,7 +12,6 @@ import types -from keystoneauth1 import exceptions as ka_exc from keystoneclient.auth.identity import v2 as v2_auth from keystoneclient.auth.identity import v3 as v3_auth from keystoneclient import exceptions as ks_exc @@ -44,14 +43,8 @@ class ClientTest(utils.BaseTestCase): def create_client(env, api_version=2, endpoint=None, exclude=[]): env = dict((k, v) for k, v in env.items() if k not in exclude) - if not env.get('auth_plugin'): - with mock.patch('ceilometerclient.client.AuthPlugin.' - 'redirect_to_aodh_endpoint') as redirect_aodh: - redirect_aodh.side_effect = ka_exc.EndpointNotFound - return client.get_client(api_version, **env) - else: - env['auth_plugin'].redirect_to_aodh_endpoint.side_effect = \ - ks_exc.EndpointNotFound + with mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None): return client.get_client(api_version, **env) def test_client_v2_with_session(self): @@ -113,7 +106,8 @@ class ClientTest(utils.BaseTestCase): } with mock.patch('ceilometerclient.client.AuthPlugin') as auth_plugin: self.create_client(env, api_version=2, endpoint='http://no.where') - auth_plugin.assert_called_with(**expected) + self.assertEqual(mock.call(**expected), + auth_plugin.mock_calls[0]) def test_v2_client_timeout_invalid_value(self): env = FAKE_ENV.copy() @@ -191,14 +185,8 @@ class ClientTest2(ClientTest): def create_client(env, api_version=2, endpoint=None, exclude=[]): env = dict((k, v) for k, v in env.items() if k not in exclude) - if not env.get('auth_plugin'): - with mock.patch('ceilometerclient.client.AuthPlugin.' - 'redirect_to_aodh_endpoint') as redirect_aodh: - redirect_aodh.side_effect = ks_exc.EndpointNotFound - return client.Client(api_version, endpoint, **env) - else: - env['auth_plugin'].redirect_to_aodh_endpoint.side_effect = \ - ks_exc.EndpointNotFound + with mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None): return client.Client(api_version, endpoint, **env) @@ -207,12 +195,9 @@ class ClientTestWithAodh(ClientTest): def create_client(env, api_version=2, endpoint=None, exclude=[]): env = dict((k, v) for k, v in env.items() if k not in exclude) - if not env.get('auth_plugin'): - with mock.patch('ceilometerclient.client.AuthPlugin.' - 'redirect_to_aodh_endpoint'): - return client.get_client(api_version, **env) - else: - env['auth_plugin'].redirect_to_aodh_endpoint = mock.MagicMock() + with mock.patch('ceilometerclient.openstack.common.apiclient.client.' + 'HTTPClient.client_request', + return_value=mock.MagicMock()): return client.get_client(api_version, **env) @mock.patch('keystoneclient.v2_0.client', fakes.FakeKeystone) @@ -220,15 +205,18 @@ class ClientTestWithAodh(ClientTest): env = FAKE_ENV.copy() del env['auth_plugin'] c = self.create_client(env, api_version=2, endpoint='fake_endpoint') - self.assertIsInstance(c.alarm_auth_plugin, client.AuthPlugin) + self.assertIsInstance(c.alarm_client.http_client.auth_plugin, + client.AuthPlugin) def test_v2_client_insecure(self): env = FAKE_ENV.copy() env.pop('auth_plugin') env['insecure'] = 'True' client = self.create_client(env) - self.assertIn('insecure', client.alarm_auth_plugin.opts) - self.assertEqual('True', client.alarm_auth_plugin.opts['insecure']) + self.assertIn('insecure', + client.alarm_client.http_client.auth_plugin.opts) + self.assertEqual('True', (client.alarm_client.http_client. + auth_plugin.opts['insecure'])) class ClientAuthTest(utils.BaseTestCase): @@ -237,8 +225,10 @@ class ClientAuthTest(utils.BaseTestCase): def create_client(env, api_version=2, endpoint=None, exclude=[]): env = dict((k, v) for k, v in env.items() if k not in exclude) - - return client.get_client(api_version, **env) + with mock.patch('ceilometerclient.openstack.common.apiclient.client.' + 'HTTPClient.client_request', + return_value=mock.MagicMock()): + return client.get_client(api_version, **env) @mock.patch('keystoneclient.discover.Discover') @mock.patch('keystoneclient.session.Session') @@ -254,8 +244,6 @@ class ClientAuthTest(utils.BaseTestCase): client.auth_plugin._do_authenticate(mock.MagicMock()) self.assertEqual([mock.call(auth_url='http://no.where', - session=mock_session_instance), - mock.call(auth_url='http://no.where', session=mock_session_instance)], discover_mock.call_args_list) self.assertIsInstance(mock_session_instance.auth, v3_auth.Password) @@ -282,8 +270,6 @@ class ClientAuthTest(utils.BaseTestCase): client.auth_plugin.opts.pop('token', None) client.auth_plugin._do_authenticate(mock.MagicMock()) self.assertEqual([mock.call(auth_url='http://no.where', - session=session_instance_mock), - mock.call(auth_url='http://no.where', session=session_instance_mock)], discover.call_args_list) @@ -296,6 +282,7 @@ class ClientAuthTest(utils.BaseTestCase): discover): env = FAKE_ENV.copy() env.pop('auth_plugin', None) + env.pop('token', None) session_instance_mock = mock.MagicMock() session.return_value = session_instance_mock @@ -304,7 +291,10 @@ class ClientAuthTest(utils.BaseTestCase): discover_instance_mock.url_for.side_effect = (lambda v: v if v == '2.0' else None) discover.side_effect = ks_exc.DiscoveryFailure - self.assertRaises(ks_exc.DiscoveryFailure, self.create_client, env) + client = self.create_client(env) + self.assertRaises(ks_exc.DiscoveryFailure, + client.auth_plugin._do_authenticate, + mock.Mock()) discover.side_effect = mock.MagicMock() client = self.create_client(env) discover.side_effect = ks_exc.DiscoveryFailure @@ -315,69 +305,37 @@ class ClientAuthTest(utils.BaseTestCase): mock.Mock()) self.assertEqual([mock.call(auth_url='http://no.where', session=session_instance_mock), - mock.call(auth_url='http://no.where', - session=session_instance_mock), mock.call(auth_url='http://no.where', session=session_instance_mock)], discover.call_args_list) - @mock.patch('keystoneclient.discover.Discover') - @mock.patch('keystoneclient.session.Session') - def test_discover_auth_versions_raise_command_err(self, session, discover): - env = FAKE_ENV.copy() - env.pop('auth_plugin', None) - - session_instance_mock = mock.MagicMock() - session.return_value = session_instance_mock - - discover.side_effect = exceptions.ClientException - - # the redirect_to_aodh_endpoint method will raise CommandError if - # didn't specify keystone api version - self.assertRaises(exc.CommandError, self.create_client, env) - with mock.patch('ceilomet' - 'erclient.client.AuthPlugin.' - 'redirect_to_aodh_endpoint'): - client = self.create_client(env) - client.auth_plugin.opts.pop('token', None) - - self.assertRaises(exc.CommandError, - client.auth_plugin._do_authenticate, - mock.Mock()) - @mock.patch('ceilometerclient.client._get_keystone_session') - @mock.patch('ceilometerclient.client._get_token_auth_ks_session') - def test_get_endpoint(self, token_session, session): + def test_get_endpoint(self, session): env = FAKE_ENV.copy() env.pop('auth_plugin', None) env.pop('endpoint', None) session_instance_mock = mock.MagicMock() session.return_value = session_instance_mock - token_ks_session_mock = mock.MagicMock() - token_session.return_value = token_ks_session_mock client = self.create_client(env) - token_ks_session_mock.get_endpoint.assert_called_with( - interface='publicURL', region_name=None, service_type='alarming') - client.auth_plugin.opts.pop('token', None) client.auth_plugin.opts.pop('endpoint') - client.auth_plugin._do_authenticate(mock.MagicMock()) - session_instance_mock.get_endpoint.assert_called_with( - region_name=None, interface='publicURL', service_type='metering') + client.auth_plugin.opts.pop('token', None) + alarm_auth_plugin = client.alarm_client.http_client.auth_plugin + alarm_auth_plugin.opts.pop('endpoint') + alarm_auth_plugin.opts.pop('token', None) - @mock.patch('ceilometerclient.client._get_token_auth_ks_session') - def test_get_aodh_endpoint(self, session): - env = FAKE_ENV.copy() - env.pop('auth_plugin', None) - env.pop('endpoint', None) + self.assertNotEqual(client.auth_plugin, alarm_auth_plugin) - session_instance_mock = mock.MagicMock() - session.return_value = session_instance_mock + client.auth_plugin._do_authenticate(mock.MagicMock()) + alarm_auth_plugin._do_authenticate(mock.MagicMock()) - self.create_client(env) - session_instance_mock.get_endpoint.assert_called_with( - region_name=None, interface='publicURL', service_type='alarming') + self.assertEqual([ + mock.call(interface='publicURL', region_name=None, + service_type='metering'), + mock.call(interface='publicURL', region_name=None, + service_type='alarming'), + ], session_instance_mock.get_endpoint.mock_calls) def test_http_client_with_session(self): session = mock.Mock() @@ -396,12 +354,11 @@ class ClientAuthTest(utils.BaseTestCase): env.pop('endpoint', None) env.pop('auth_url', None) client = self.create_client(env, endpoint='fake_endpoint') - self.assertEqual(client.alarm_auth_plugin.opts, + self.assertEqual(client.alarm_client.http_client.auth_plugin.opts, client.auth_plugin.opts) @mock.patch('ceilometerclient.client._get_keystone_session') - @mock.patch('ceilometerclient.client._get_token_auth_ks_session') - def test_get_different_endpoint_type(self, token_session, session): + def test_get_different_endpoint_type(self, session): env = FAKE_ENV.copy() env.pop('auth_plugin', None) env.pop('endpoint', None) @@ -409,21 +366,28 @@ class ClientAuthTest(utils.BaseTestCase): session_instance_mock = mock.MagicMock() session.return_value = session_instance_mock - token_ks_session_mock = mock.MagicMock() - token_session.return_value = token_ks_session_mock client = self.create_client(env) - token_ks_session_mock.get_endpoint.assert_called_with( - interface='internal', region_name=None, service_type='alarming') - client.auth_plugin.opts.pop('token', None) client.auth_plugin.opts.pop('endpoint') + client.auth_plugin.opts.pop('token', None) + alarm_auth_plugin = client.alarm_client.http_client.auth_plugin + alarm_auth_plugin.opts.pop('endpoint') + alarm_auth_plugin.opts.pop('token', None) + + self.assertNotEqual(client.auth_plugin, alarm_auth_plugin) + client.auth_plugin._do_authenticate(mock.MagicMock()) - session_instance_mock.get_endpoint.assert_called_with( - region_name=None, interface='internal', service_type='metering') + alarm_auth_plugin._do_authenticate(mock.MagicMock()) + + self.assertEqual([ + mock.call(interface='internal', region_name=None, + service_type='metering'), + mock.call(interface='internal', region_name=None, + service_type='alarming'), + ], session_instance_mock.get_endpoint.mock_calls) @mock.patch('ceilometerclient.client._get_keystone_session') - @mock.patch('ceilometerclient.client._get_token_auth_ks_session') - def test_get_sufficient_options_missing(self, token_session, session): + def test_get_sufficient_options_missing(self, session): env = FAKE_ENV.copy() env.pop('auth_plugin', None) env.pop('password', None) diff --git a/ceilometerclient/tests/unit/test_shell.py b/ceilometerclient/tests/unit/test_shell.py index e40835b..75b04ac 100644 --- a/ceilometerclient/tests/unit/test_shell.py +++ b/ceilometerclient/tests/unit/test_shell.py @@ -112,16 +112,18 @@ class ShellBashCompletionTest(ShellTestBase): class ShellKeystoneV2Test(ShellTestBase): @mock.patch.object(ks_session, 'Session') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_debug_switch_raises_error(self, aodh_redirect, mock_ksclient): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_debug_switch_raises_error(self, get_alarm_client, mock_ksclient): mock_ksclient.side_effect = exc.HTTPUnauthorized self.make_env(FAKE_V2_ENV) args = ['--debug', 'event-list'] self.assertRaises(exc.CommandError, ceilometer_shell.main, args) @mock.patch.object(ks_session, 'Session') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_dash_d_switch_raises_error(self, aodh_redirect, mock_ksclient): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_dash_d_switch_raises_error(self, get_alarm_client, mock_ksclient): mock_ksclient.side_effect = exc.CommandError("FAIL") self.make_env(FAKE_V2_ENV) args = ['-d', 'event-list'] @@ -139,8 +141,9 @@ class ShellKeystoneV2Test(ShellTestBase): class ShellKeystoneV3Test(ShellTestBase): @mock.patch.object(ks_session, 'Session') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_debug_switch_raises_error(self, aodh_redirect, mock_ksclient): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_debug_switch_raises_error(self, get_alarm_client, mock_ksclient): mock_ksclient.side_effect = exc.HTTPUnauthorized self.make_env(FAKE_V3_ENV) args = ['--debug', 'event-list'] @@ -191,8 +194,9 @@ class ShellTimeoutTest(ShellTestBase): self._test_timeout('0', expected_msg) @mock.patch.object(ks_session, 'Session') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_timeout_keystone_session(self, aodh_redirect, mocked_session): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_timeout_keystone_session(self, get_alarm_client, mocked_session): mocked_session.side_effect = exc.HTTPUnauthorized("FAIL") self.make_env(FAKE_V2_ENV) args = ['--debug', '--timeout', '5', 'alarm-list'] @@ -204,8 +208,9 @@ class ShellTimeoutTest(ShellTestBase): class ShellInsecureTest(ShellTestBase): @mock.patch.object(api_client, 'HTTPClient') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_insecure_true_ceilometer(self, aodh_redirect, mocked_client): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_insecure_true_ceilometer(self, get_alarm_client, mocked_client): self.make_env(FAKE_V2_ENV) args = ['--debug', '--os-insecure', 'true', 'alarm-list'] self.assertIsNone(ceilometer_shell.main(args)) @@ -213,8 +218,9 @@ class ShellInsecureTest(ShellTestBase): self.assertEqual(False, kwargs.get('verify')) @mock.patch.object(ks_session, 'Session') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_insecure_true_keystone(self, aodh_redirect, mocked_session): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_insecure_true_keystone(self, get_alarm_client, mocked_session): mocked_session.side_effect = exc.HTTPUnauthorized("FAIL") self.make_env(FAKE_V2_ENV) args = ['--debug', '--os-insecure', 'true', 'alarm-list'] @@ -223,8 +229,9 @@ class ShellInsecureTest(ShellTestBase): self.assertEqual(False, kwargs.get('verify')) @mock.patch.object(api_client, 'HTTPClient') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_insecure_false_ceilometer(self, aodh_redirect, mocked_client): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_insecure_false_ceilometer(self, get_alarm_client, mocked_client): self.make_env(FAKE_V2_ENV) args = ['--debug', '--os-insecure', 'false', 'alarm-list'] self.assertIsNone(ceilometer_shell.main(args)) @@ -232,8 +239,9 @@ class ShellInsecureTest(ShellTestBase): self.assertEqual(True, kwargs.get('verify')) @mock.patch.object(ks_session, 'Session') - @mock.patch('ceilometerclient.client.AuthPlugin.redirect_to_aodh_endpoint') - def test_insecure_false_keystone(self, aodh_redirect, mocked_session): + @mock.patch('ceilometerclient.v2.client.Client._get_alarm_client', + return_value=None) + def test_insecure_false_keystone(self, get_alarm_client, mocked_session): mocked_session.side_effect = exc.HTTPUnauthorized("FAIL") self.make_env(FAKE_V2_ENV) args = ['--debug', '--os-insecure', 'false', 'alarm-list'] diff --git a/ceilometerclient/tests/unit/v2/test_shell.py b/ceilometerclient/tests/unit/v2/test_shell.py index a4209f7..bdcabee 100644 --- a/ceilometerclient/tests/unit/v2/test_shell.py +++ b/ceilometerclient/tests/unit/v2/test_shell.py @@ -1235,9 +1235,9 @@ class ShellShadowedArgsTest(test_shell.ShellTestBase): '--user-id', 'the-user-id-i-want-to-set', '--name', 'project-id-test'] + args with mock.patch.object(alarms.AlarmManager, method) as mocked: - with mock.patch('ceilometerclient.client.AuthPlugin.' - 'redirect_to_aodh_endpoint') as redirect_aodh: - redirect_aodh.site_effect = exceptions.EndpointNotFound + with mock.patch('ceilometerclient.openstack.common.apiclient.' + 'client.HTTPClient.client_request') as request: + request.site_effect = exceptions.EndpointNotFound base_shell.main(cli_args) args, kwargs = mocked.call_args self.assertEqual('the-project-id-i-want-to-set', @@ -1279,9 +1279,9 @@ class ShellShadowedArgsTest(test_shell.ShellTestBase): '--meter-unit', 'ns', '--sample-volume', '10086', ] - with mock.patch('ceilometerclient.client.AuthPlugin.' - 'redirect_to_aodh_endpoint') as redirect_aodh: - redirect_aodh.site_effect = exceptions.EndpointNotFound + with mock.patch('ceilometerclient.openstack.common.apiclient.client.' + 'HTTPClient.client_request') as client_request: + client_request.site_effect = exceptions.EndpointNotFound base_shell.main(cli_args) args, kwargs = mocked.call_args self.assertEqual('the-project-id-i-want-to-set', diff --git a/ceilometerclient/v2/client.py b/ceilometerclient/v2/client.py index e6a6075..f613cec 100644 --- a/ceilometerclient/v2/client.py +++ b/ceilometerclient/v2/client.py @@ -57,13 +57,17 @@ class Client(object): def __init__(self, *args, **kwargs): """Initialize a new client for the Ceilometer v2 API.""" - if not kwargs.get('auth_plugin'): + if not kwargs.get('auth_plugin') and not kwargs.get('session'): kwargs['auth_plugin'] = ceiloclient.get_auth_plugin(*args, **kwargs) + self.auth_plugin = kwargs.get('auth_plugin') self.http_client = ceiloclient._construct_http_client(**kwargs) - self.alarm_client, aodh_enabled = self._get_alarm_client(**kwargs) + self.alarm_client = self._get_alarm_client(**kwargs) + aodh_enabled = self.alarm_client is not None + if not aodh_enabled: + self.alarm_client = self.http_client self.meters = meters.MeterManager(self.http_client) self.samples = samples.OldSampleManager(self.http_client) self.new_samples = samples.SampleManager(self.http_client) @@ -83,43 +87,41 @@ class Client(object): self.alarm_client) self.capabilities = capabilities.CapabilitiesManager(self.http_client) - def _get_alarm_client(self, **kwargs): + @staticmethod + def _get_alarm_client(**ceilo_kwargs): """Get client for alarm manager that redirect to aodh.""" - kwargs = copy.deepcopy(kwargs) - self.alarm_auth_plugin = kwargs.get('auth_plugin') - aodh_endpoint = kwargs.get('aodh_endpoint') - if kwargs.get('session') is not None: + # NOTE(sileht): the auth_plugin/keystone session cannot be copied + # because they rely on threading module. + auth_plugin = ceilo_kwargs.pop('auth_plugin', None) + session = ceilo_kwargs.pop('session', None) + + kwargs = copy.deepcopy(ceilo_kwargs) + kwargs["service_type"] = "alarming" + aodh_endpoint = ceilo_kwargs.get('aodh_endpoint') + + if session: + # keystone session can be shared between client + ceilo_kwargs['session'] = kwargs['session'] = session if aodh_endpoint: kwargs['endpoint_override'] = aodh_endpoint - else: - kwargs["service_type"] = "alarming" - try: - c = ceiloclient._construct_http_client(**kwargs) - # NOTE(sileht): when a keystoneauth1 session object is used - # endpoint looking is done on first request, so do it. - c.get("/") - return c, True - except ka_exc.EndpointNotFound: - return self.http_client, False - except kc_exc.EndpointNotFound: - return self.http_client, False + elif auth_plugin and kwargs.get('auth_url'): + ceilo_kwargs['auth_plugin'] = auth_plugin + kwargs.pop('endpoint', None) + kwargs['auth_plugin'] = ceiloclient.get_auth_plugin( + aodh_endpoint, **kwargs) else: - if aodh_endpoint: - kwargs["auth_plugin"].opts['endpoint'] = aodh_endpoint - elif not kwargs.get('auth_url'): - # Users may just provided ceilometer endpoint and token, and no - # auth_url, in this case, we need 'aodh_endpoint' also - # provided, otherwise we cannot get aodh endpoint from - # keystone, and assume aodh is unavailable. - return self.http_client, False - else: - try: - # NOTE(liusheng): Getting the aodh's endpoint to rewrite - # the endpoint of alarm auth_plugin. - kwargs["auth_plugin"].redirect_to_aodh_endpoint( - kwargs.get('timeout')) - except ka_exc.EndpointNotFound: - return self.http_client, False - except kc_exc.EndpointNotFound: - return self.http_client, False - return ceiloclient._construct_http_client(**kwargs), True + # Users may just provided ceilometer endpoint and token, and no + # auth_url, in this case, we need 'aodh_endpoint' also + # provided, otherwise we cannot get aodh endpoint from + # keystone, and assume aodh is unavailable. + return None + + try: + # NOTE(sileht): try to use aodh + c = ceiloclient._construct_http_client(**kwargs) + c.get("/") + return c + except ka_exc.EndpointNotFound: + return None + except kc_exc.EndpointNotFound: + return None -- cgit v1.2.1