Work around a bug in keystoneclient constructor

keystoneclient bug #1513839 means that even when you proerly pass
a Session (like we do) to the discovery constructor (what you'd be
calling if you were passing "pass_version_arg = True") ksc fails
because you didn't send a URL.

We _HAVE_ an appropriate URL that we can pull from the Session. So
until ksc learns how to pull the URL from the Session itself, do it
for them.

Change-Id: I38eb4cfa750fab5196b86989c2cd498d41bf37ac
This commit is contained in:
Monty Taylor 2015-11-06 09:04:12 -05:00
parent 5b993208b9
commit 13b6fbabeb
2 changed files with 47 additions and 1 deletions

View File

@ -258,7 +258,16 @@ class CloudConfig(object):
constructor_args = []
if pass_version_arg:
version = self.get_api_version(service_key)
constructor_args.append(version)
if service_key == 'identity':
# keystoneclient takes version as a tuple.
version = tuple(str(float(version)).split('.'))
constructor_kwargs['version'] = version
# Workaround for bug#1513839
if 'endpoint' not in constructor_kwargs:
endpoint = self.get_session_endpoint('identity')
constructor_kwargs['endpoint'] = endpoint
else:
constructor_args.append(version)
return client_class(*constructor_args, **constructor_kwargs)

View File

@ -278,3 +278,40 @@ class TestCloudConfig(base.TestCase):
service_type='compute',
session=mock.ANY,
service_name=None)
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_identity(self, mock_get_session_endpoint):
mock_client = mock.Mock()
mock_get_session_endpoint.return_value = 'http://example.com/v2'
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
cc = cloud_config.CloudConfig(
"test1", "region-al", config_dict, auth_plugin=mock.Mock())
cc.get_legacy_client('identity', mock_client)
mock_client.assert_called_with(
version=('2', '0'),
endpoint='http://example.com/v2',
endpoint_type='admin',
region_name='region-al',
service_type='identity',
session=mock.ANY,
service_name='locks')
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_identity_v3(self, mock_get_session_endpoint):
mock_client = mock.Mock()
mock_get_session_endpoint.return_value = 'http://example.com'
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
config_dict['identity_api_version'] = '3'
cc = cloud_config.CloudConfig(
"test1", "region-al", config_dict, auth_plugin=mock.Mock())
cc.get_legacy_client('identity', mock_client)
mock_client.assert_called_with(
version=('3', '0'),
endpoint='http://example.com',
endpoint_type='admin',
region_name='region-al',
service_type='identity',
session=mock.ANY,
service_name='locks')