Fix discovery cache sharing
The intent is that connect_as shares the discovery cache so that users don't pay the double cost. Unfortunately, that's not actually what we were doing. There was also a mistaken thought that we should be sharing a Session, but we can't do that, because the Session has the Auth, and what we're doing is making a new Auth. Attach the discovery_cache to the new Session directly and all is good. Change-Id: I07a362ea710b01d3588b06e9d3e0f1ce7eb101d4
This commit is contained in:
parent
709f215786
commit
57b634b0e0
|
@ -226,21 +226,10 @@ class _OpenStackCloudMixin(object):
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
params['auth'][key] = value
|
params['auth'][key] = value
|
||||||
|
|
||||||
# TODO(mordred) Replace this chunk with the next patch that allows
|
cloud_config = config.get_one(**params)
|
||||||
# passing a Session to CloudRegion.
|
# Attach the discovery cache from the old session so we won't
|
||||||
# Closure to pass to OpenStackConfig to ensure the new cloud shares
|
# double discover.
|
||||||
# the Session with the current cloud. This will ensure that version
|
cloud_config._discovery_cache = self.session._discovery_cache
|
||||||
# discovery cache will be re-used.
|
|
||||||
def session_constructor(*args, **kwargs):
|
|
||||||
# We need to pass our current keystone session to the Session
|
|
||||||
# Constructor, otherwise the new auth plugin doesn't get used.
|
|
||||||
return keystoneauth1.session.Session(
|
|
||||||
session=self.session,
|
|
||||||
discovery_cache=self.config._discovery_cache)
|
|
||||||
|
|
||||||
cloud_config = config.get_one(
|
|
||||||
session_constructor=session_constructor,
|
|
||||||
**params)
|
|
||||||
# Override the cloud name so that logging/location work right
|
# Override the cloud name so that logging/location work right
|
||||||
cloud_config._name = self.name
|
cloud_config._name = self.name
|
||||||
cloud_config.config['profile'] = self.name
|
cloud_config.config['profile'] = self.name
|
||||||
|
|
|
@ -420,24 +420,34 @@ class TestCase(base.TestCase):
|
||||||
self.calls = []
|
self.calls = []
|
||||||
self._uri_registry.clear()
|
self._uri_registry.clear()
|
||||||
|
|
||||||
|
def get_keystone_v3_token(self, catalog='catalog-v3.json'):
|
||||||
|
catalog_file = os.path.join(self.fixtures_directory, catalog)
|
||||||
|
with open(catalog_file, 'r') as tokens_file:
|
||||||
|
return dict(
|
||||||
|
method='POST',
|
||||||
|
uri='https://identity.example.com/v3/auth/tokens',
|
||||||
|
headers={
|
||||||
|
'X-Subject-Token': self.getUniqueString('KeystoneToken')
|
||||||
|
},
|
||||||
|
text=tokens_file.read()
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_keystone_v3_discovery(self):
|
||||||
|
with open(self.discovery_json, 'r') as discovery_file:
|
||||||
|
return dict(
|
||||||
|
method='GET',
|
||||||
|
uri='https://identity.example.com/',
|
||||||
|
text=discovery_file.read(),
|
||||||
|
)
|
||||||
|
|
||||||
def use_keystone_v3(self, catalog='catalog-v3.json'):
|
def use_keystone_v3(self, catalog='catalog-v3.json'):
|
||||||
self.adapter = self.useFixture(rm_fixture.Fixture())
|
self.adapter = self.useFixture(rm_fixture.Fixture())
|
||||||
self.calls = []
|
self.calls = []
|
||||||
self._uri_registry.clear()
|
self._uri_registry.clear()
|
||||||
with open(self.discovery_json, 'r') as discovery_file, \
|
self.__do_register_uris([
|
||||||
open(os.path.join(
|
self.get_keystone_v3_discovery(),
|
||||||
self.fixtures_directory, catalog), 'r') as tokens_file:
|
self.get_keystone_v3_token(catalog),
|
||||||
self.__do_register_uris([
|
])
|
||||||
dict(method='GET', uri='https://identity.example.com/',
|
|
||||||
text=discovery_file.read()),
|
|
||||||
dict(method='POST',
|
|
||||||
uri='https://identity.example.com/v3/auth/tokens',
|
|
||||||
headers={
|
|
||||||
'X-Subject-Token':
|
|
||||||
self.getUniqueString('KeystoneToken')},
|
|
||||||
text=tokens_file.read()
|
|
||||||
),
|
|
||||||
])
|
|
||||||
self._make_test_cloud(identity_api_version='3')
|
self._make_test_cloud(identity_api_version='3')
|
||||||
|
|
||||||
def use_keystone_v2(self):
|
def use_keystone_v2(self):
|
||||||
|
|
|
@ -56,20 +56,41 @@ class TestShade(base.TestCase):
|
||||||
|
|
||||||
def test_connect_as(self):
|
def test_connect_as(self):
|
||||||
# Do initial auth/catalog steps
|
# Do initial auth/catalog steps
|
||||||
# TODO(mordred) This only tests the constructor steps. Discovery
|
# This should authenticate a second time, but should not
|
||||||
# cache sharing is broken. We need to get discovery_cache option
|
# need a second identity discovery
|
||||||
# plumbed through
|
self.register_uris([
|
||||||
# keystoneauth1.loading.base.BaseLoader.load_from_options
|
self.get_keystone_v3_token(),
|
||||||
self.cloud.connect_as(project_name='test_project')
|
self.get_nova_discovery_mock_dict(),
|
||||||
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
'compute', 'public', append=['servers', 'detail']),
|
||||||
|
json={'servers': []},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
c2 = self.cloud.connect_as(project_name='test_project')
|
||||||
|
self.assertEqual(c2.list_servers(), [])
|
||||||
|
self.assert_calls()
|
||||||
|
|
||||||
def test_connect_as_context(self):
|
def test_connect_as_context(self):
|
||||||
# Do initial auth/catalog steps
|
# Do initial auth/catalog steps
|
||||||
# TODO(mordred) This only tests the constructor steps. Discovery
|
# This should authenticate a second time, but should not
|
||||||
# cache sharing is broken. We need to get discovery_cache option
|
# need a second identity discovery
|
||||||
# plumbed through
|
self.register_uris([
|
||||||
# keystoneauth1.loading.base.BaseLoader.load_from_options
|
self.get_keystone_v3_token(),
|
||||||
with self.cloud.connect_as(project_name='test_project'):
|
self.get_nova_discovery_mock_dict(),
|
||||||
pass
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
'compute', 'public', append=['servers', 'detail']),
|
||||||
|
json={'servers': []},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
with self.cloud.connect_as(project_name='test_project') as c2:
|
||||||
|
self.assertEqual(c2.list_servers(), [])
|
||||||
|
self.assert_calls()
|
||||||
|
|
||||||
@mock.patch.object(connection.Connection, 'search_images')
|
@mock.patch.object(connection.Connection, 'search_images')
|
||||||
def test_get_images(self, mock_search):
|
def test_get_images(self, mock_search):
|
||||||
|
|
Loading…
Reference in New Issue