From 0bc97917872a8be88265c1d9805a82994541a31a Mon Sep 17 00:00:00 2001 From: Md Nadeem Date: Wed, 18 Nov 2015 18:21:51 +0900 Subject: [PATCH] Fix client UnauthorizedError Zaqar server threw UnauthorizedError when client try to execute any cli command. This patch fixes the issue and changes the default authorization backend from noauth to keystone. Change-Id: I88c2f5aa914b5fb40b6dc16a256d3e385d9aaa23 Closes-Bug: #1491738 --- tests/unit/auth/test_keystone.py | 8 ++++---- tests/unit/queues/v1/test_client.py | 6 +++--- tests/unit/queues/v2/test_client.py | 6 +++--- tests/unit/transport/test_request.py | 1 + zaqarclient/auth/__init__.py | 4 ++-- zaqarclient/auth/keystone.py | 25 +++++++++++++++---------- zaqarclient/queues/cli.py | 25 +++++++++++++++++++++++-- zaqarclient/tests/base.py | 1 + 8 files changed, 52 insertions(+), 24 deletions(-) diff --git a/tests/unit/auth/test_keystone.py b/tests/unit/auth/test_keystone.py index cf51728c..a49a0504 100644 --- a/tests/unit/auth/test_keystone.py +++ b/tests/unit/auth/test_keystone.py @@ -27,7 +27,7 @@ from zaqarclient.transport import request class _FakeKeystoneClient(object): - auth_token = 'test-token' + auth_token = 'fake-token' def __init__(self, *args, **kwargs): pass @@ -41,8 +41,7 @@ class TestKeystoneAuth(base.TestBase): if not ksclient: self.skipTest('Keystone client is not installed') - self.auth = auth.get_backend(backend='keystone', - options=self.conf) + self.auth = auth.get_backend(options=self.conf) def test_no_token(self): test_endpoint = 'http://example.org:8888' @@ -56,9 +55,10 @@ class TestKeystoneAuth(base.TestBase): req = self.auth.authenticate(1, request.Request()) self.assertEqual(test_endpoint, req.endpoint) self.assertIn('X-Auth-Token', req.headers) + self.assertIn(req.headers['X-Auth-Token'], 'fake-token') def test_with_token(self): - self.config(os_auth_token='test-token') + self.auth.conf.update({"auth_token": "test-token"}) req = request.Request(endpoint='http://example.org:8888') req = self.auth.authenticate(1, req) self.assertIn('X-Auth-Token', req.headers) diff --git a/tests/unit/queues/v1/test_client.py b/tests/unit/queues/v1/test_client.py index 51a3f4b8..3bcb5f7f 100644 --- a/tests/unit/queues/v1/test_client.py +++ b/tests/unit/queues/v1/test_client.py @@ -31,13 +31,13 @@ class TestClient(base.TestBase): @ddt.data(*VERSIONS) def test_transport(self, version): cli = client.Client('http://example.com', - version, {}) + version, {"auth_opts": {'backend': 'noauth'}}) self.assertIsNotNone(cli.transport()) @ddt.data(*VERSIONS) def test_health_ok(self, version): cli = client.Client('http://example.com', - version, {}) + version, {"auth_opts": {'backend': 'noauth'}}) with mock.patch.object(core, 'health', autospec=True) as core_health: core_health.return_value = None self.assertTrue(cli.health()) @@ -45,7 +45,7 @@ class TestClient(base.TestBase): @ddt.data(*VERSIONS) def test_health_bad(self, version): cli = client.Client('http://example.com', - version, {}) + version, {"auth_opts": {'backend': 'noauth'}}) def raise_error(*args, **kwargs): raise errors.ServiceUnavailableError() diff --git a/tests/unit/queues/v2/test_client.py b/tests/unit/queues/v2/test_client.py index 4433c87a..9335a8f9 100644 --- a/tests/unit/queues/v2/test_client.py +++ b/tests/unit/queues/v2/test_client.py @@ -31,13 +31,13 @@ class TestClient(base.TestBase): @ddt.data(*VERSIONS) def test_transport(self, version): cli = client.Client('http://example.com', - version, {}) + version, {"auth_opts": {'backend': 'noauth'}}) self.assertIsNotNone(cli.transport()) @ddt.data(*VERSIONS) def test_health_ok(self, version): cli = client.Client('http://example.com', - version, {}) + version, {"auth_opts": {'backend': 'noauth'}}) with mock.patch.object(core, 'health', autospec=True) as core_health: core_health.return_value = None self.assertTrue(cli.health()) @@ -45,7 +45,7 @@ class TestClient(base.TestBase): @ddt.data(*VERSIONS) def test_health_bad(self, version): cli = client.Client('http://example.com', - version, {}) + version, {"auth_opts": {'backend': 'noauth'}}) def raise_error(*args, **kwargs): raise errors.ServiceUnavailableError() diff --git a/tests/unit/transport/test_request.py b/tests/unit/transport/test_request.py index 5646a9fa..d8235a1a 100644 --- a/tests/unit/transport/test_request.py +++ b/tests/unit/transport/test_request.py @@ -28,6 +28,7 @@ class TestRequest(base.TestBase): 'os_project_id': 'my-project' } } + auth_opts.update({'backend': 'noauth'}) req = request.prepare_request(auth_opts) self.assertEqual('my-project', req.headers['X-Project-Id']) diff --git a/zaqarclient/auth/__init__.py b/zaqarclient/auth/__init__.py index ac9e2712..34a3beba 100644 --- a/zaqarclient/auth/__init__.py +++ b/zaqarclient/auth/__init__.py @@ -23,11 +23,11 @@ _BACKENDS = { } -def get_backend(backend='noauth', options=None): +def get_backend(backend='keystone', options=None): """Loads backend `auth_backend` :params backend: The backend name to load. - Default: `noauth` + Default: `keystone` :type backend: `six.string_types` :param options: Options to pass to the Auth backend. Refer to the backend for more info. diff --git a/zaqarclient/auth/keystone.py b/zaqarclient/auth/keystone.py index 030e8d5e..cf12fa36 100644 --- a/zaqarclient/auth/keystone.py +++ b/zaqarclient/auth/keystone.py @@ -47,6 +47,9 @@ class KeystoneAuth(base.AuthBackend): * auth_url: endpoint to authenticate against * insecure: allow insecure SSL (no cert verification) * project_{name|id}: name or ID of project + * region_name: Name of a region + * cacert:CA certificate + """ return ksclient.Client(**kwargs) @@ -62,23 +65,25 @@ class KeystoneAuth(base.AuthBackend): the auth information. """ - token = self.conf.get('os_auth_token') + token = self.conf.get('auth_token') if not token or not request.endpoint: # NOTE(flaper87): Lets assume all the # required information was provided # either through env variables or CLI # params. Let keystoneclient fail otherwise. - ks_kwargs = { - 'username': self.conf.get('os_username'), - 'password': self.conf.get('os_password'), - 'tenant_id': self.conf.get('os_project_id'), - 'tenant_name': self.conf.get('os_project_name'), - 'auth_url': self.conf.get('os_auth_url'), - 'insecure': self.conf.get('insecure'), - } + + def get_options(k): + k = k if k in self.conf else "os_"+k + return self.conf.get(k, None) + + ks_kwargs = {} + keys = ("username", "password", "project_id", + "project_name", "auth_url", "insecure", + "cacert", "region_name") + for k in keys: + ks_kwargs.update({k: get_options(k)}) _ksclient = self._get_ksclient(**ks_kwargs) - if not token: token = _ksclient.auth_token diff --git a/zaqarclient/queues/cli.py b/zaqarclient/queues/cli.py index 426a5d71..75deefcf 100644 --- a/zaqarclient/queues/cli.py +++ b/zaqarclient/queues/cli.py @@ -37,9 +37,30 @@ def make_client(instance): API_VERSIONS) if not instance._url: - instance._url = instance.get_endpoint_for_service_type(API_NAME) + instance._url = instance.get_endpoint_for_service_type( + API_NAME, + region_name=instance._region_name, + interface=instance._interface + ) - return queues_client(url=instance._url, version=version) + auth_params = instance._auth_params + auth_params.update({ + "auth_token": instance.auth.get_token(instance.session), + "insecure": instance._insecure, + "cacert": instance._cacert, + "region_name": instance._region_name + }) + + conf = { + "auth_opts": {'options': auth_params} + } + + LOG.debug('Instantiating queues service client: %s', queues_client) + return queues_client( + instance._url, + version, + conf + ) def build_option_parser(parser): diff --git a/zaqarclient/tests/base.py b/zaqarclient/tests/base.py index 0d4467ae..8edac189 100644 --- a/zaqarclient/tests/base.py +++ b/zaqarclient/tests/base.py @@ -33,6 +33,7 @@ class TestBase(testtools.TestCase): self.conf = { 'auth_opts': { + 'backend': 'noauth', 'options': { 'os_project_id': 'my-project' }