From e49819caf95fc6985036231b1e5717f0ff7b6c61 Mon Sep 17 00:00:00 2001 From: Drew Thorstensen Date: Wed, 23 Oct 2013 16:41:45 -0500 Subject: [PATCH] New exception when auth_url is not specified Certain scenarios into the neutron client will not specify the auth_url. This is typically when a token is specified. However, when the token is expired the neutron client will attempt to refresh the token. Users of this may not have passed in all of the required information for this reauthentication to properly occur. This code fixes an error that occurs in this flow where the auth_url (which is None) is appended to another string. This results in a core Python error. The update will provide a more targetted error message specifying to the user that the auth_url needs to be specified. An associated unit test is also included to validate this behavior. Change-Id: I577ce0c009a9a281acdc238d290a22c5e561ff82 Closes-Bug: #1241275 --- neutronclient/client.py | 6 ++++++ neutronclient/common/exceptions.py | 4 ++++ neutronclient/tests/unit/test_auth.py | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/neutronclient/client.py b/neutronclient/client.py index 3a153b018..448a9c564 100644 --- a/neutronclient/client.py +++ b/neutronclient/client.py @@ -228,6 +228,9 @@ class HTTPClient(httplib2.Http): 'password': self.password, }, 'tenantName': self.tenant_name, }, } + if self.auth_url is None: + raise exceptions.NoAuthURLProvided() + token_url = self.auth_url + "/tokens" # Make sure we follow redirects when trying to reach Keystone @@ -252,6 +255,9 @@ class HTTPClient(httplib2.Http): self._extract_service_catalog(resp_body) def _get_endpoint_url(self): + if self.auth_url is None: + raise exceptions.NoAuthURLProvided() + url = self.auth_url + '/tokens/%s/endpoints' % self.auth_token try: resp, body = self._cs_request(url, "GET") diff --git a/neutronclient/common/exceptions.py b/neutronclient/common/exceptions.py index 6e2541ad9..d7e3848be 100644 --- a/neutronclient/common/exceptions.py +++ b/neutronclient/common/exceptions.py @@ -151,6 +151,10 @@ class BadInputError(Exception): pass +class NoAuthURLProvided(BadInputError): + message = _("auth_url was not provided to the Neutron client") + + class Error(Exception): def __init__(self, message=None): super(Error, self).__init__(message) diff --git a/neutronclient/tests/unit/test_auth.py b/neutronclient/tests/unit/test_auth.py index ddbf26813..b81d23614 100644 --- a/neutronclient/tests/unit/test_auth.py +++ b/neutronclient/tests/unit/test_auth.py @@ -148,6 +148,33 @@ class CLITestAuthKeystone(testtools.TestCase): self.mox.ReplayAll() self.client.do_request('/resource', 'GET') + def test_refresh_token_no_auth_url(self): + self.mox.StubOutWithMock(self.client, "request") + self.client.auth_url = None + + self.client.auth_token = TOKEN + self.client.endpoint_url = ENDPOINT_URL + + res401 = self.mox.CreateMock(httplib2.Response) + res401.status = 401 + + # If a token is expired, neutron server returns 401 + self.client.request( + mox.StrContains(ENDPOINT_URL + '/resource'), 'GET', + headers=mox.ContainsKeyValue('X-Auth-Token', TOKEN) + ).AndReturn((res401, '')) + self.mox.ReplayAll() + self.assertRaises(exceptions.NoAuthURLProvided, + self.client.do_request, + '/resource', + 'GET') + + def test_get_endpoint_url_with_invalid_auth_url(self): + # Handle the case when auth_url is not provided + self.client.auth_url = None + self.assertRaises(exceptions.NoAuthURLProvided, + self.client._get_endpoint_url) + def test_get_endpoint_url(self): self.mox.StubOutWithMock(self.client, "request")