diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-03-29 07:46:23 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-03-29 07:46:23 +0000 |
| commit | 3277d38002ceea6ba0a6a09874b1f07ea01ae0b4 (patch) | |
| tree | 1bff8dcceb763d5d3d278b02ff499ba4e9ede545 | |
| parent | dff95d332f399641b2aaad5d4403a372158ca6c3 (diff) | |
| parent | a54dd21fcb6d730bdf53fd8f9d808762f2ff071b (diff) | |
| download | python-neutronclient-2.2.1.tar.gz | |
Merge "Handle auth_token and endpoint_url if passed to the http client constructor"2.2.1
| -rw-r--r-- | quantumclient/client.py | 47 | ||||
| -rw-r--r-- | quantumclient/tests/unit/test_auth.py | 57 |
2 files changed, 74 insertions, 30 deletions
diff --git a/quantumclient/client.py b/quantumclient/client.py index 39e770e..e9d5949 100644 --- a/quantumclient/client.py +++ b/quantumclient/client.py @@ -101,7 +101,6 @@ class HTTPClient(httplib2.Http): self.auth_url = auth_url.rstrip('/') if auth_url else None self.region_name = region_name self.auth_token = token - self.token_retrieved = False self.content_type = 'application/json' self.endpoint_url = endpoint_url self.auth_strategy = auth_strategy @@ -134,30 +133,27 @@ class HTTPClient(httplib2.Http): return resp, body def do_request(self, url, method, **kwargs): - if not self.endpoint_url: + if not self.auth_token: self.authenticate() + elif not self.endpoint_url: + self.endpoint_url = self._get_endpoint_url() # Perform the request once. If we get a 401 back then it # might be because the auth token expired, so try to # re-authenticate and try again. If it still fails, bail. try: - if self.auth_token: - kwargs.setdefault('headers', {}) - kwargs['headers']['X-Auth-Token'] = self.auth_token + kwargs.setdefault('headers', {}) + kwargs['headers']['X-Auth-Token'] = self.auth_token resp, body = self._cs_request(self.endpoint_url + url, method, **kwargs) return resp, body - except exceptions.Unauthorized as ex: - if not self.endpoint_url or self.token_retrieved: - self.authenticate() - if self.auth_token: - kwargs.setdefault('headers', {}) - kwargs['headers']['X-Auth-Token'] = self.auth_token - resp, body = self._cs_request( - self.endpoint_url + url, method, **kwargs) - return resp, body - else: - raise ex + except exceptions.Unauthorized: + self.authenticate() + kwargs.setdefault('headers', {}) + kwargs['headers']['X-Auth-Token'] = self.auth_token + resp, body = self._cs_request( + self.endpoint_url + url, method, **kwargs) + return resp, body def _extract_service_catalog(self, body): """ Set the client's service catalog from the response data. """ @@ -167,7 +163,6 @@ class HTTPClient(httplib2.Http): self.auth_token = sc['id'] self.auth_tenant_id = sc.get('tenant_id') self.auth_user_id = sc.get('user_id') - self.token_retrieved = True except KeyError: raise exceptions.Unauthorized() self.endpoint_url = self.service_catalog.url_for( @@ -205,6 +200,24 @@ class HTTPClient(httplib2.Http): body = None self._extract_service_catalog(body) + def _get_endpoint_url(self): + url = self.auth_url + '/tokens/%s/endpoints' % self.auth_token + try: + resp, body = self._cs_request(url, "GET") + except exceptions.Unauthorized: + # rollback to authenticate() to handle case when quantum client + # is initialized just before the token is expired + self.authenticate() + return self.endpoint_url + + body = json.loads(body) + for endpoint in body.get('endpoints', []): + if (endpoint['type'] == 'network' and + endpoint.get('region') == self.region_name): + return endpoint['adminURL'] + + raise exceptions.EndpointNotFound() + def get_status_code(self, response): """ Returns the integer status code from the response, which diff --git a/quantumclient/tests/unit/test_auth.py b/quantumclient/tests/unit/test_auth.py index ba1aa0b..e8e64b3 100644 --- a/quantumclient/tests/unit/test_auth.py +++ b/quantumclient/tests/unit/test_auth.py @@ -17,7 +17,6 @@ import httplib2 import json -import unittest import uuid import mox @@ -25,7 +24,6 @@ from mox import ContainsKeyValue, IsA, StrContains import testtools from quantumclient.client import HTTPClient -from quantumclient.common import exceptions USERNAME = 'testuser' @@ -54,6 +52,17 @@ KS_TOKEN_RESULT = { } } +ENDPOINTS_RESULT = { + 'endpoints': [{ + 'type': 'network', + 'name': 'Quantum Service', + 'region': REGION, + 'adminURL': ENDPOINT_URL, + 'internalURL': ENDPOINT_URL, + 'publicURL': ENDPOINT_URL + }] +} + class CLITestAuthKeystone(testtools.TestCase): @@ -84,46 +93,68 @@ class CLITestAuthKeystone(testtools.TestCase): self.client.do_request('/resource', 'GET') self.assertEqual(self.client.endpoint_url, ENDPOINT_URL) self.assertEqual(self.client.auth_token, TOKEN) - self.assertEqual(self.client.token_retrieved, True) - def test_already_token_retrieved(self): + def test_refresh_token(self): self.mox.StubOutWithMock(self.client, "request") self.client.auth_token = TOKEN self.client.endpoint_url = ENDPOINT_URL - self.client.token_retrieved = True res200 = self.mox.CreateMock(httplib2.Response) res200.status = 200 + res401 = self.mox.CreateMock(httplib2.Response) + res401.status = 401 + # If a token is expired, quantum server retruns 401 + self.client.request(StrContains(ENDPOINT_URL + '/resource'), 'GET', + headers=ContainsKeyValue('X-Auth-Token', TOKEN)).\ + AndReturn((res401, '')) + self.client.request(AUTH_URL + '/tokens', 'POST', + body=IsA(str), headers=IsA(dict)).\ + AndReturn((res200, json.dumps(KS_TOKEN_RESULT))) self.client.request(StrContains(ENDPOINT_URL + '/resource'), 'GET', headers=ContainsKeyValue('X-Auth-Token', TOKEN)).\ AndReturn((res200, '')) self.mox.ReplayAll() + self.client.do_request('/resource', 'GET') + + def test_get_endpoint_url(self): + self.mox.StubOutWithMock(self.client, "request") + self.client.auth_token = TOKEN + + res200 = self.mox.CreateMock(httplib2.Response) + res200.status = 200 + + self.client.request(StrContains(AUTH_URL + + '/tokens/%s/endpoints' % TOKEN), 'GET', + headers=IsA(dict)). \ + AndReturn((res200, json.dumps(ENDPOINTS_RESULT))) + self.client.request(StrContains(ENDPOINT_URL + '/resource'), 'GET', + headers=ContainsKeyValue('X-Auth-Token', TOKEN)). \ + AndReturn((res200, '')) + self.mox.ReplayAll() self.client.do_request('/resource', 'GET') - def test_refresh_token(self): + def test_get_endpoint_url_failed(self): self.mox.StubOutWithMock(self.client, "request") self.client.auth_token = TOKEN - self.client.endpoint_url = ENDPOINT_URL - self.client.token_retrieved = True res200 = self.mox.CreateMock(httplib2.Response) res200.status = 200 res401 = self.mox.CreateMock(httplib2.Response) res401.status = 401 - # If a token is expired, quantum server retruns 401 - self.client.request(StrContains(ENDPOINT_URL + '/resource'), 'GET', - headers=ContainsKeyValue('X-Auth-Token', TOKEN)).\ + self.client.request(StrContains(AUTH_URL + + '/tokens/%s/endpoints' % TOKEN), 'GET', + headers=IsA(dict)). \ AndReturn((res401, '')) self.client.request(AUTH_URL + '/tokens', 'POST', - body=IsA(str), headers=IsA(dict)).\ + body=IsA(str), headers=IsA(dict)). \ AndReturn((res200, json.dumps(KS_TOKEN_RESULT))) self.client.request(StrContains(ENDPOINT_URL + '/resource'), 'GET', - headers=ContainsKeyValue('X-Auth-Token', TOKEN)).\ + headers=ContainsKeyValue('X-Auth-Token', TOKEN)). \ AndReturn((res200, '')) self.mox.ReplayAll() self.client.do_request('/resource', 'GET') |
