From e8274fa57df3a833f8e46be2e9a6feff366e4b5c Mon Sep 17 00:00:00 2001 From: "Derrick J. Wippler" <thrawn01@gmail.com> Date: Wed, 19 Aug 2015 15:48:27 -0500 Subject: [PATCH] No longer ignores CINDER_SERVICE_NAME Cinderclient now utilizes the CINDER_SERVICE_NAME when deciding what endpoint to choose. Closes-Bug: #1486256 Change-Id: I494a34afe5799e7832b1359b9c24c31ead68b6d1 UpgradeImpact: Existing configurations may select a different endpoint after this patch. --- cinderclient/client.py | 3 +- .../unit/fixture_data/keystone_client.py | 66 +++++++++++++------ cinderclient/tests/unit/test_shell.py | 19 ++++++ 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/cinderclient/client.py b/cinderclient/client.py index 2a6b9775f..6393c1b26 100644 --- a/cinderclient/client.py +++ b/cinderclient/client.py @@ -332,7 +332,8 @@ class HTTPClient(object): management_url = self.service_catalog.url_for( region_name=self.region_name, endpoint_type=self.endpoint_type, - service_type=self.service_type) + service_type=self.service_type, + service_name=self.service_name) self.management_url = management_url.rstrip('/') return None except exceptions.AmbiguousEndpoints: diff --git a/cinderclient/tests/unit/fixture_data/keystone_client.py b/cinderclient/tests/unit/fixture_data/keystone_client.py index dc4c6c6d1..c94977ef8 100644 --- a/cinderclient/tests/unit/fixture_data/keystone_client.py +++ b/cinderclient/tests/unit/fixture_data/keystone_client.py @@ -115,28 +115,49 @@ def generate_v2_project_scoped_token(**kwargs): } }} - # we only care about Neutron and Keystone endpoints + # Add endpoint Keystone o['access']['serviceCatalog'] = [ - {'endpoints': [ - {'publicURL': 'public_' + ref.get('cinder_url'), - 'internalURL': 'internal_' + ref.get('cinder_url'), - 'adminURL': 'admin_' + (ref.get('auth_url') or ""), - 'id': uuid.uuid4().hex, - 'region': 'RegionOne' - }], - 'endpoints_links': [], - 'name': 'Neutron', - 'type': 'network'}, - {'endpoints': [ - {'publicURL': ref.get('auth_url'), - 'adminURL': ref.get('auth_url'), - 'internalURL': ref.get('auth_url'), - 'id': uuid.uuid4().hex, - 'region': 'RegionOne' - }], - 'endpoint_links': [], - 'name': 'keystone', - 'type': 'identity'}] + { + 'endpoints': [ + { + 'publicURL': ref.get('auth_url'), + 'adminURL': ref.get('auth_url'), + 'internalURL': ref.get('auth_url'), + 'id': uuid.uuid4().hex, + 'region': 'RegionOne' + }], + 'endpoint_links': [], + 'name': 'keystone', + 'type': 'identity' + } + ] + + cinder_endpoint = { + 'endpoints': [ + { + 'publicURL': 'public_' + ref.get('cinder_url'), + 'internalURL': 'internal_' + ref.get('cinder_url'), + 'adminURL': 'admin_' + (ref.get('auth_url') or ""), + 'id': uuid.uuid4().hex, + 'region': 'RegionOne' + } + ], + 'endpoints_links': [], + 'name': None, + 'type': 'volumev2' + } + + # Add multiple Cinder endpoints + for count in range(1, 4): + # Copy the endpoint and create a service name + endpoint_copy = copy.deepcopy(cinder_endpoint) + name = "cinder%i" % count + # Assign the service name and a unique endpoint + endpoint_copy['endpoints'][0]['publicURL'] = \ + 'http://%s.api.com/v2' % name + endpoint_copy['name'] = name + + o['access']['serviceCatalog'].append(endpoint_copy) return token, o @@ -218,6 +239,9 @@ def keystone_request_callback(request, context): elif request.url == BASE_URL + "/v2.0": token_id, token_data = generate_v2_project_scoped_token() return token_data + elif request.url.startswith("http://multiple.service.names"): + token_id, token_data = generate_v2_project_scoped_token() + return json.dumps(token_data) elif request.url == BASE_URL + "/v3": token_id, token_data = generate_v3_project_scoped_token() context.headers["X-Subject-Token"] = token_id diff --git a/cinderclient/tests/unit/test_shell.py b/cinderclient/tests/unit/test_shell.py index 3407a267f..af6d1fa0a 100644 --- a/cinderclient/tests/unit/test_shell.py +++ b/cinderclient/tests/unit/test_shell.py @@ -122,6 +122,25 @@ class ShellTest(utils.TestCase): self.assertEqual(v3_url, os_auth_url, "Expected v3 url") self.assertIsNone(v2_url, "Expected no v2 url") + @requests_mock.Mocker() + def list_volumes_on_service(self, count, mocker): + os_auth_url = "http://multiple.service.names/v2.0" + mocker.register_uri('POST', os_auth_url + "/tokens", + text=keystone_client.keystone_request_callback) + mocker.register_uri('GET', + "http://cinder%i.api.com/v2/volumes/detail" + % count, text='{"volumes": []}') + self.make_env(include={'OS_AUTH_URL': os_auth_url, + 'CINDER_SERVICE_NAME': 'cinder%i' % count}) + _shell = shell.OpenStackCinderShell() + _shell.main(['list']) + + def test_cinder_service_name(self): + # Failing with 'No mock address' means we are not + # choosing the correct endpoint + for count in range(1, 4): + self.list_volumes_on_service(count) + @mock.patch('keystoneclient.adapter.Adapter.get_token', side_effect=ks_exc.ConnectionRefused()) @mock.patch('keystoneclient.discover.Discover',