From f9644702ad2561becd9ab70fd647ef83db4c923e Mon Sep 17 00:00:00 2001 From: tsv Date: Tue, 5 Aug 2014 15:19:29 -0600 Subject: [PATCH] remove tenant-id from uri Barbican server will be dropping project-id (a.k.a tenant-id) from its resource API (https://review.openstack.org/#/c/105562/). Once that happens, the client will be broken. This commit fixes that by removing all references of tenant-id from the secret/order resource URIs. Also, for the unauthenticated use case, the tenant-id is now passed to the server in the request header as X-Project-Id Patch Set 7: Rebased and fixed merge issue Change-Id: I9961e13194485b7945060b18130b4b5265022367 Implements: https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id CR: #1353101 --- barbicanclient/client.py | 13 ++++- barbicanclient/test/test_barbican.py | 72 +++++++++++++--------------- barbicanclient/test/test_client.py | 60 ++++++++++++----------- 3 files changed, 77 insertions(+), 68 deletions(-) diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 1115ed4b..8427f150 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -98,7 +98,7 @@ class Client(object): self._barbican_url = self._get_normalized_endpoint(endpoint) self._tenant_id = tenant_id - self.base_url = '{0}/{1}'.format(self._barbican_url, self._tenant_id) + self.base_url = '{0}'.format(self._barbican_url) self.secrets = secrets.SecretManager(self) self.orders = orders.OrderManager(self) self.verifications = verifications.VerificationManager(self) @@ -158,24 +158,33 @@ class Client(object): # this is a Barbican auth plugin return auth_plugin.tenant_id + def _prepare_auth(self, headers): + if headers and not self._session.auth: + headers['X-Project-Id'] = self._tenant_id + def get(self, href, params=None): headers = {'Accept': 'application/json'} + self._prepare_auth(headers) resp = self._session.get(href, params=params, headers=headers) self._check_status_code(resp) return resp.json() def get_raw(self, href, headers): + self._prepare_auth(headers) resp = self._session.get(href, headers=headers) self._check_status_code(resp) return resp.content def delete(self, href): - resp = self._session.delete(href) + headers = {} + self._prepare_auth(headers) + resp = self._session.delete(href, headers=headers) self._check_status_code(resp) def post(self, path, data): url = '{0}/{1}/'.format(self.base_url, path) headers = {'content-type': 'application/json'} + self._prepare_auth(headers) resp = self._session.post(url, data=json.dumps(data), headers=headers) self._check_status_code(resp) return resp.json() diff --git a/barbicanclient/test/test_barbican.py b/barbicanclient/test/test_barbican.py index 336448b1..21edda36 100644 --- a/barbicanclient/test/test_barbican.py +++ b/barbicanclient/test/test_barbican.py @@ -102,14 +102,13 @@ class WhenTestingBarbicanCLI(test_client.BaseEntityResource): @httpretty.activate def test_should_succeed_if_noauth_with_valid_args_specified(self): list_secrets_content = '{"secrets": [], "total": 0}' - list_secrets_url = '%s%s/secrets' % ( - self.endpoint, self.tenant_id) + list_secrets_url = '{0}secrets'.format(self.endpoint) httpretty.register_uri( httpretty.GET, list_secrets_url, body=list_secrets_content) self._expect_success_code( - "--no-auth --endpoint %s --os-tenant-id %s secret list" - % (self.endpoint, self.tenant_id)) + "--no-auth --endpoint {0} --os-tenant-id {1} secret list". + format(self.endpoint, self.tenant_id)) def test_should_error_if_required_keystone_auth_arguments_are_missing( self): @@ -142,56 +141,53 @@ class TestBarbicanWithKeystoneClient(testtools.TestCase): argv.append(v) return argv + def _delete_secret(self, auth_url): + self.kwargs['auth_url'] = auth_url + argv = self._to_argv(**self.kwargs) + barbican_url = keystone_client_fixtures.BARBICAN_ENDPOINT + argv.append('--endpoint') + argv.append(barbican_url) + argv.append('secret') + argv.append('delete') + mySecretRef = '{0}/secrets/mysecretid'.format(barbican_url) + argv.append(mySecretRef) + # emulate delete secret + httpretty.register_uri( + httpretty.DELETE, + mySecretRef, + status=204) + + try: + self.barbican.run(argv=argv) + except: + self.fail('failed to delete secret') + @httpretty.activate def test_v2_auth(self): - self.kwargs['auth_url'] = keystone_client_fixtures.V2_URL - argv = self._to_argv(**self.kwargs) - argv.append('secret') - argv.append('list') - argv.append('-h') - argv.append('mysecretid') # emulate Keystone version discovery httpretty.register_uri(httpretty.GET, - self.kwargs['auth_url'], + keystone_client_fixtures.V2_URL, body=keystone_client_fixtures.V2_VERSION_ENTRY) # emulate Keystone v2 token request v2_token = keystone_client_fixtures.generate_v2_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/tokens' % (self.kwargs['auth_url']), + '{0}/tokens'.format( + keystone_client_fixtures.V2_URL), body=json.dumps(v2_token)) - # emulate get secrets - barbican_url = keystone_client_fixtures.BARBICAN_ENDPOINT - httpretty.register_uri( - httpretty.DELETE, - '%s/%s/secrets/mysecretid' % ( - barbican_url, - v2_token['access']['token']['tenant']['id']), - status=200) - self.barbican.run(argv=argv) + self._delete_secret(keystone_client_fixtures.V2_URL) @httpretty.activate def test_v3_auth(self): - argv = self._to_argv(**self.kwargs) - argv.append('secret') - argv.append('list') - argv.append('-h') - argv.append('mysecretid') # emulate Keystone version discovery httpretty.register_uri(httpretty.GET, - self.kwargs['auth_url'], + keystone_client_fixtures.V3_URL, body=keystone_client_fixtures.V3_VERSION_ENTRY) # emulate Keystone v3 token request id, v3_token = \ keystone_client_fixtures.generate_v3_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/auth/tokens' % (self.kwargs['auth_url']), - body=json.dumps(v3_token)) - # emulate delete secret - barbican_url = keystone_client_fixtures.BARBICAN_ENDPOINT - httpretty.register_uri( - httpretty.DELETE, - '%s/%s/secrets/mysecretid' % ( - barbican_url, - v3_token['token']['project']['id']), - status=200) - self.barbican.run(argv=argv) + '{0}/auth/tokens'.format( + keystone_client_fixtures.V3_URL), + body=json.dumps(v3_token), + adding_headers={'x-subject-token': '1234'}) + self._delete_secret(keystone_client_fixtures.V3_URL) diff --git a/barbicanclient/test/test_client.py b/barbicanclient/test/test_client.py index 74fc1501..f1e7d6d9 100644 --- a/barbicanclient/test/test_client.py +++ b/barbicanclient/test/test_client.py @@ -108,7 +108,7 @@ class WhenTestingClientInit(testtools.TestCase): def test_can_be_used_without_auth_plugin(self): c = client.Client(auth_plugin=None, endpoint=self.endpoint, tenant_id=self.tenant_id) - expected = '%s%s' % (self.endpoint, self.tenant_id) + expected = self.endpoint.rstrip('/') self.assertEqual(expected, c.base_url) def test_auth_token_header_is_set_when_using_auth_plugin(self): @@ -132,9 +132,9 @@ class WhenTestingClientInit(testtools.TestCase): c = client.Client(auth_plugin=self.fake_auth) self.assertTrue(c.base_url.startswith(self.endpoint)) - def test_base_url_ends_with_tenant_id(self): + def test_base_url_has_no_tenant_id(self): c = client.Client(auth_plugin=self.fake_auth) - self.assertTrue(c.base_url.endswith(self.tenant_id)) + self.assertNotIn(self.tenant_id, c.base_url) def test_should_raise_for_unauthorized_response(self): resp = self._mock_response(status_code=401) @@ -160,7 +160,7 @@ class WhenTestingClientWithSession(testtools.TestCase): self.tenant_id = '1234567' self.entity = 'dummy-entity' - base = self.endpoint + self.tenant_id + "/" + base = self.endpoint self.entity_base = base + self.entity + "/" self.entity_href = self.entity_base + \ 'abcd1234-eabc-5678-9abc-abcdef012345' @@ -252,18 +252,19 @@ class WhenTestingClientWithKeystoneV2(WhenTestingClientWithSession): # emulate Keystone v2 token request v2_token = keystone_client_fixtures.generate_v2_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/tokens' % (keystone_client_fixtures.V2_URL), + '{0}/tokens'.format( + keystone_client_fixtures.V2_URL), body=json.dumps(v2_token)) auth_plugin = KeystonePasswordPlugins.get_v2_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - list_secrets_url = '%s/secrets' % (c.base_url) + list_secrets_url = '{0}/secrets'.format(c.base_url) httpretty.register_uri( httpretty.GET, list_secrets_url, status=200, - body='{"name": "%s", "secret_ref": "%s"}' % - (self.entity_name, self.entity_href)) + body='{{"name": "{0}", "secret_ref": "{1}"}}'.format( + self.entity_name, self.entity_href)) resp = c.get(list_secrets_url) self.assertEqual(self.entity_name, resp['name']) self.assertEqual(self.entity_href, resp['secret_ref']) @@ -277,18 +278,19 @@ class WhenTestingClientWithKeystoneV2(WhenTestingClientWithSession): # emulate Keystone v2 token request v2_token = keystone_client_fixtures.generate_v2_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/tokens' % (keystone_client_fixtures.V2_URL), + '{0}/tokens'.format( + keystone_client_fixtures.V2_URL), body=json.dumps(v2_token)) auth_plugin = KeystonePasswordPlugins.get_v2_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - post_secret_url = '%s/secrets/' % (c.base_url) + post_secret_url = '{0}/secrets/'.format(c.base_url) httpretty.register_uri( httpretty.POST, post_secret_url, status=200, - body='{"name": "%s", "secret_ref": "%s"}' - % (self.entity_name, self.entity_href)) + body='{{"name": "{0}", "secret_ref": "{1}"}}'.format( + self.entity_name, self.entity_href)) resp = c.post('secrets', '{"name":"test"}') self.assertEqual(self.entity_name, resp['name']) self.assertEqual(self.entity_href, resp['secret_ref']) @@ -302,12 +304,13 @@ class WhenTestingClientWithKeystoneV2(WhenTestingClientWithSession): # emulate Keystone v2 token request v2_token = keystone_client_fixtures.generate_v2_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/tokens' % (keystone_client_fixtures.V2_URL), + '{0}/tokens'.format( + keystone_client_fixtures.V2_URL), body=json.dumps(v2_token)) auth_plugin = KeystonePasswordPlugins.get_v2_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - get_secret_url = '%s/secrets/s1' % (c.base_url) + get_secret_url = '{0}/secrets/s1'.format(c.base_url) httpretty.register_uri( httpretty.GET, get_secret_url, @@ -325,12 +328,13 @@ class WhenTestingClientWithKeystoneV2(WhenTestingClientWithSession): # emulate Keystone v2 token request v2_token = keystone_client_fixtures.generate_v2_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/tokens' % (keystone_client_fixtures.V2_URL), + '{0}/tokens'.format( + keystone_client_fixtures.V2_URL), body=json.dumps(v2_token)) auth_plugin = KeystonePasswordPlugins.get_v2_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - delete_secret_url = '%s/secrets/s1' % (c.base_url) + delete_secret_url = '{0}/secrets/s1'.format(c.base_url) httpretty.register_uri( httpretty.DELETE, delete_secret_url, @@ -353,19 +357,19 @@ class WhenTestingClientWithKeystoneV3(WhenTestingClientWithSession): id, v3_token = keystone_client_fixtures.\ generate_v3_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/auth/tokens' % ( + '{0}/auth/tokens'.format( keystone_client_fixtures.V3_URL), body=json.dumps(v3_token), x_subject_token=id) auth_plugin = KeystonePasswordPlugins.get_v3_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - list_secrets_url = '%s/secrets' % (c.base_url) + list_secrets_url = '{0}/secrets'.format(c.base_url) httpretty.register_uri( httpretty.GET, list_secrets_url, status=200, - body='{"name": "%s", "secret_ref": "%s"}' - % (self.entity_name, self.entity_href)) + body='{{"name": "{0}", "secret_ref": "{1}"}}'.format( + self.entity_name, self.entity_href)) resp = c.get(list_secrets_url) self.assertEqual(self.entity_name, resp['name']) self.assertEqual(self.entity_href, resp['secret_ref']) @@ -380,21 +384,21 @@ class WhenTestingClientWithKeystoneV3(WhenTestingClientWithSession): id, v3_token = keystone_client_fixtures.\ generate_v3_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/auth/tokens' % ( + '{0}/auth/tokens'.format( keystone_client_fixtures.V3_URL), body=json.dumps(v3_token), x_subject_token=id) auth_plugin = KeystonePasswordPlugins.get_v3_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - post_secret_url = '%s/secrets/' % (c.base_url) + post_secret_url = '{0}/secrets/'.format(c.base_url) httpretty.register_uri( httpretty.POST, post_secret_url, status=200, x_subject_token=id, - body='{"name": "%s", "secret_ref": "%s"}' - % (self.entity_name, self.entity_href)) + body='{{"name": "{0}", "secret_ref": "{1}"}}'.format( + self.entity_name, self.entity_href)) resp = c.post('secrets', '{"name":"test"}') self.assertEqual(self.entity_name, resp['name']) self.assertEqual(self.entity_href, resp['secret_ref']) @@ -409,14 +413,14 @@ class WhenTestingClientWithKeystoneV3(WhenTestingClientWithSession): id, v3_token = keystone_client_fixtures.\ generate_v3_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/auth/tokens' % ( + '{0}/auth/tokens'.format( keystone_client_fixtures.V3_URL), body=json.dumps(v3_token), x_subject_token=id) auth_plugin = KeystonePasswordPlugins.get_v3_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - get_secret_url = '%s/secrets/s1' % (c.base_url) + get_secret_url = '{0}/secrets/s1'.format(c.base_url) httpretty.register_uri( httpretty.GET, get_secret_url, @@ -435,14 +439,14 @@ class WhenTestingClientWithKeystoneV3(WhenTestingClientWithSession): id, v3_token = keystone_client_fixtures.\ generate_v3_project_scoped_token() httpretty.register_uri(httpretty.POST, - '%s/auth/tokens' % ( + '{0}/auth/tokens'.format( keystone_client_fixtures.V3_URL), body=json.dumps(v3_token), x_subject_token=id) auth_plugin = KeystonePasswordPlugins.get_v3_plugin() c = client.Client(auth_plugin=auth_plugin) # emulate list secrets - delete_secret_url = '%s/secrets/s1' % (c.base_url) + delete_secret_url = '{0}/secrets/s1'.format(c.base_url) httpretty.register_uri( httpretty.DELETE, delete_secret_url,