diff --git a/cinderclient/client.py b/cinderclient/client.py index b8eaa6263..ee429ffb6 100644 --- a/cinderclient/client.py +++ b/cinderclient/client.py @@ -39,7 +39,7 @@ class HTTPClient(httplib2.Http): USER_AGENT = 'python-cinderclient' def __init__(self, user, password, projectid, auth_url, insecure=False, - timeout=None, proxy_tenant_id=None, + timeout=None, tenant_id=None, proxy_tenant_id=None, proxy_token=None, region_name=None, endpoint_type='publicURL', service_type=None, service_name=None, volume_service_name=None): @@ -47,6 +47,7 @@ class HTTPClient(httplib2.Http): self.user = user self.password = password self.projectid = projectid + self.tenant_id = tenant_id self.auth_url = auth_url.rstrip('/') self.version = 'v1' self.region_name = region_name @@ -282,6 +283,8 @@ class HTTPClient(httplib2.Http): if self.projectid: body['auth']['tenantName'] = self.projectid + elif self.tenant_id: + body['auth']['tenantId'] = self.tenant_id self._authenticate(url, body) diff --git a/cinderclient/v1/client.py b/cinderclient/v1/client.py index a8d405ceb..1412ed864 100644 --- a/cinderclient/v1/client.py +++ b/cinderclient/v1/client.py @@ -21,10 +21,9 @@ class Client(object): """ - # FIXME(jesse): project_id isn't required to authenticate - def __init__(self, username, api_key, project_id, auth_url, - insecure=False, timeout=None, proxy_tenant_id=None, - proxy_token=None, region_name=None, + def __init__(self, username, api_key, project_id=None, auth_url='', + insecure=False, timeout=None, tenant_id=None, + proxy_tenant_id=None, proxy_token=None, region_name=None, endpoint_type='publicURL', extensions=None, service_type='compute', service_name=None, volume_service_name=None): @@ -51,6 +50,7 @@ class Client(object): auth_url, insecure=insecure, timeout=timeout, + tenant_id=tenant_id, proxy_token=proxy_token, proxy_tenant_id=proxy_tenant_id, region_name=region_name, diff --git a/tests/v1/test_auth.py b/tests/v1/test_auth.py index 6cced17da..bdc4b66db 100644 --- a/tests/v1/test_auth.py +++ b/tests/v1/test_auth.py @@ -78,6 +78,76 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase): test_auth_call() + def test_authenticate_tenant_id(self): + cs = client.Client("username", "password", auth_url="auth_url/v2.0", + tenant_id='tenant_id', service_type='compute') + resp = { + "access": { + "token": { + "expires": "12345", + "id": "FAKE_ID", + "tenant": { + "description": None, + "enabled": True, + "id": "tenant_id", + "name": "demo" + } # tenant associated with token + }, + "serviceCatalog": [ + { + "type": "compute", + "endpoints": [ + { + "region": "RegionOne", + "adminURL": "http://localhost:8774/v1", + "internalURL": "http://localhost:8774/v1", + "publicURL": "http://localhost:8774/v1/", + }, + ], + }, + ], + }, + } + auth_response = httplib2.Response({ + "status": 200, + "body": json.dumps(resp), }) + + mock_request = mock.Mock(return_value=(auth_response, + json.dumps(resp))) + + @mock.patch.object(httplib2.Http, "request", mock_request) + def test_auth_call(): + cs.client.authenticate() + headers = { + 'User-Agent': cs.client.USER_AGENT, + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + body = { + 'auth': { + 'passwordCredentials': { + 'username': cs.client.user, + 'password': cs.client.password, + }, + 'tenantId': cs.client.tenant_id, + }, + } + + token_url = cs.client.auth_url + "/tokens" + mock_request.assert_called_with(token_url, "POST", + headers=headers, + body=json.dumps(body)) + + endpoints = resp["access"]["serviceCatalog"][0]['endpoints'] + public_url = endpoints[0]["publicURL"].rstrip('/') + self.assertEqual(cs.client.management_url, public_url) + token_id = resp["access"]["token"]["id"] + self.assertEqual(cs.client.auth_token, token_id) + tenant_id = resp["access"]["token"]["tenant"]["id"] + self.assertEqual(cs.client.tenant_id, tenant_id) + + test_auth_call() + def test_authenticate_failure(self): cs = client.Client("username", "password", "project_id", "auth_url/v2.0")