Merge "Add-in some re-auth logic when using os_cache"

This commit is contained in:
Jenkins 2013-10-02 21:17:21 +00:00 committed by Gerrit Code Review
commit f3bad8acee
2 changed files with 120 additions and 7 deletions
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):