Merge "Add-in some re-auth logic when using os_cache"
This commit is contained in:
commit
f3bad8acee
novaclient
@ -395,20 +395,38 @@ class HTTPClient(object):
|
||||
|
||||
def _v2_auth(self, url):
|
||||
"""Authenticate against a v2.0 auth service."""
|
||||
body_pass = {"auth": {
|
||||
"passwordCredentials": {"username": self.user,
|
||||
"password": self.password}}}
|
||||
body_token = {"auth": {"token": {"id": self.auth_token}}}
|
||||
|
||||
if self.auth_token:
|
||||
body = {"auth": {
|
||||
"token": {"id": self.auth_token}}}
|
||||
body = body_token
|
||||
else:
|
||||
body = {"auth": {
|
||||
"passwordCredentials": {"username": self.user,
|
||||
"password": self.password}}}
|
||||
body = body_pass
|
||||
|
||||
if self.tenant_id:
|
||||
body['auth']['tenantId'] = self.tenant_id
|
||||
elif self.projectid:
|
||||
body['auth']['tenantName'] = self.projectid
|
||||
|
||||
return self._authenticate(url, body)
|
||||
try:
|
||||
return self._authenticate(url, body)
|
||||
except exceptions.Unauthorized:
|
||||
# NOTE(morganfainberg): there is no actual point in flushing
|
||||
# the cache out because it would result in the same behavior
|
||||
# in either case, a 401 being raised/returned. The expected
|
||||
# recourse in the case of a failure will be the same, reauth
|
||||
# with username and password.
|
||||
|
||||
if (self.os_cache and self.user and self.password and
|
||||
self.keyring_saver is not None):
|
||||
# If we are using a cache, and we failed, try again if we have
|
||||
# the required information to do so.
|
||||
self.auth_token = None
|
||||
body = body_pass
|
||||
return self._authenticate(url, body)
|
||||
raise
|
||||
|
||||
def _authenticate(self, url, body, **kwargs):
|
||||
"""Authenticate and extract the service catalog."""
|
||||
|
@ -9,6 +9,14 @@ from novaclient import exceptions
|
||||
from novaclient.tests import utils
|
||||
|
||||
|
||||
class MockKeyringSaver(object):
|
||||
def __init__(self):
|
||||
self.saved = []
|
||||
|
||||
def save(self, *args):
|
||||
self.saved = args
|
||||
|
||||
|
||||
class AuthenticateAgainstKeystoneTests(utils.TestCase):
|
||||
def test_authenticate_success(self):
|
||||
cs = client.Client("username", "password", "project_id",
|
||||
@ -385,7 +393,8 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
|
||||
self.assertEqual(cs.client.auth_token, token_id)
|
||||
|
||||
def test_authenticate_with_token_failure(self):
|
||||
cs = client.Client("username", None, "project_id", "auth_url/v2.0")
|
||||
cs = client.Client("username", None, "project_id", "auth_url/v2.0",
|
||||
service_type='compute')
|
||||
cs.client.auth_token = "FAKE_ID"
|
||||
resp = {"unauthorized": {"message": "Unauthorized", "code": "401"}}
|
||||
auth_response = utils.TestResponse({
|
||||
@ -398,6 +407,92 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
|
||||
with mock.patch.object(requests.Session, "request", mock_request):
|
||||
self.assertRaises(exceptions.Unauthorized, cs.client.authenticate)
|
||||
|
||||
def test_authenticate_with_os_cache_and_failure(self):
|
||||
cs = client.Client("username", "password", "project_id",
|
||||
"auth_url/v2.0", service_type='compute')
|
||||
cs.client.os_cache = True
|
||||
cs.client.keyring_saver = MockKeyringSaver()
|
||||
cs.client.auth_token = "FAKE_ID"
|
||||
|
||||
catalog_managment_url = u"http://localhost:8774/v1.1"
|
||||
|
||||
headers_get = {
|
||||
'User-Agent': cs.client.USER_AGENT,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-Auth-Token': "FAKE_ID"}
|
||||
headers_post = {
|
||||
'User-Agent': cs.client.USER_AGENT,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'}
|
||||
token_url_get = cs.client.auth_url + "/tokens/FAKE_ID"
|
||||
token_url_post = cs.client.auth_url + "/tokens"
|
||||
resp = {
|
||||
"access": {
|
||||
"token": {
|
||||
"expires": "12345",
|
||||
"id": "FAKE_ID_NEW",
|
||||
"tenant": {
|
||||
"id": "FAKE_TENANT_ID",
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
"type": "compute",
|
||||
"endpoints": [
|
||||
{
|
||||
"region": "RegionOne",
|
||||
"adminURL": catalog_managment_url,
|
||||
"internalURL": catalog_managment_url,
|
||||
"publicURL": catalog_managment_url,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
auth_resp_200 = utils.TestResponse({
|
||||
"status_code": 200,
|
||||
"text": json.dumps(resp),
|
||||
})
|
||||
auth_resp_401 = utils.TestResponse({
|
||||
"status_code": 401,
|
||||
"text": json.dumps({"unauthorized":
|
||||
{"message": "Unauthorized",
|
||||
"code": "401"}}),
|
||||
})
|
||||
|
||||
expected_keyring = (u"FAKE_ID_NEW",
|
||||
catalog_managment_url,
|
||||
u"FAKE_TENANT_ID")
|
||||
|
||||
post_data = {"auth":
|
||||
{"passwordCredentials":
|
||||
{"username": "username",
|
||||
"password": "password"}}}
|
||||
|
||||
mock_request = mock.Mock()
|
||||
mock_request.side_effect = [auth_resp_401, auth_resp_200]
|
||||
|
||||
with mock.patch.object(requests.Session, "request", mock_request):
|
||||
expected = [mock.call("GET",
|
||||
token_url_get,
|
||||
headers=headers_get,
|
||||
data="null",
|
||||
allow_redirects=True,
|
||||
**self.TEST_REQUEST_BASE),
|
||||
mock.call("POST",
|
||||
token_url_post,
|
||||
headers=headers_post,
|
||||
data=json.dumps(post_data),
|
||||
allow_redirects=True,
|
||||
**self.TEST_REQUEST_BASE),
|
||||
]
|
||||
cs.client.authenticate()
|
||||
self.assertEqual(expected, mock_request.call_args_list)
|
||||
self.assertEqual(cs.client.keyring_saver.saved, expected_keyring)
|
||||
|
||||
|
||||
class AuthenticationTests(utils.TestCase):
|
||||
def test_authenticate_success(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user