Merge "Handle auth_token and endpoint_url if passed to the http client constructor"
This commit is contained in:
commit
3277d38002
|
@ -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
|
||||
|
|
|
@ -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,31 +93,12 @@ 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):
|
||||
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
|
||||
|
||||
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):
|
||||
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
|
||||
|
@ -127,3 +117,44 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||
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_get_endpoint_url_failed(self):
|
||||
self.mox.StubOutWithMock(self.client, "request")
|
||||
|
||||
self.client.auth_token = TOKEN
|
||||
|
||||
res200 = self.mox.CreateMock(httplib2.Response)
|
||||
res200.status = 200
|
||||
res401 = self.mox.CreateMock(httplib2.Response)
|
||||
res401.status = 401
|
||||
|
||||
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)). \
|
||||
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')
|
||||
|
|
Loading…
Reference in New Issue