Separate token client from identity client
Identity 'TokenClientJSON' is being derived from 'IdentityClientJSON'
which is not needed. 'TokenClientJSON' class can be directly derived from
ServiceClient.
This patch makes the above inheritance changes and separate token
clients (V2 & v3) in separate file.
This will helpful in moving services client to tempest-lib.
Change-Id: I25186dc1fde57cd7fd16784aa6baf2f8d2f0a46d
diff --git a/tempest/auth.py b/tempest/auth.py
index 9687905..6a92b5f 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -24,8 +24,8 @@
from tempest import config
from tempest.openstack.common import log as logging
-from tempest.services.identity.json import identity_client as json_id
-from tempest.services.identity.v3.json import identity_client as json_v3id
+from tempest.services.identity.json import token_client as json_id
+from tempest.services.identity.v3.json import token_client as json_v3id
CONF = config.CONF
diff --git a/tempest/clients.py b/tempest/clients.py
index 36d3e53..0c03ec8 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -70,18 +70,18 @@
from tempest.services.database.json.versions_client import \
DatabaseVersionsClientJSON
from tempest.services.identity.json.identity_client import IdentityClientJSON
-from tempest.services.identity.json.identity_client import TokenClientJSON
+from tempest.services.identity.json.token_client import TokenClientJSON
from tempest.services.identity.v3.json.credentials_client import \
CredentialsClientJSON
from tempest.services.identity.v3.json.endpoints_client import \
EndPointClientJSON
from tempest.services.identity.v3.json.identity_client import \
IdentityV3ClientJSON
-from tempest.services.identity.v3.json.identity_client import V3TokenClientJSON
from tempest.services.identity.v3.json.policy_client import PolicyClientJSON
from tempest.services.identity.v3.json.region_client import RegionClientJSON
from tempest.services.identity.v3.json.service_client import \
ServiceClientJSON
+from tempest.services.identity.v3.json.token_client import V3TokenClientJSON
from tempest.services.image.v1.json.image_client import ImageClientJSON
from tempest.services.image.v2.json.image_client import ImageClientV2JSON
from tempest.services.messaging.json.messaging_client import \
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index a6c5049..d4f57e0 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -279,90 +279,3 @@
body = json.loads(body)
return service_client.ResponseBodyList(resp,
body['extensions']['values'])
-
-
-class TokenClientJSON(IdentityClientJSON):
-
- def __init__(self):
- super(TokenClientJSON, self).__init__(None)
- auth_url = CONF.identity.uri
-
- # Normalize URI to ensure /tokens is in it.
- if 'tokens' not in auth_url:
- auth_url = auth_url.rstrip('/') + '/tokens'
-
- self.auth_url = auth_url
-
- def auth(self, user, password, tenant=None):
- creds = {
- 'auth': {
- 'passwordCredentials': {
- 'username': user,
- 'password': password,
- },
- }
- }
-
- if tenant:
- creds['auth']['tenantName'] = tenant
-
- body = json.dumps(creds)
- resp, body = self.post(self.auth_url, body=body)
- self.expected_success(200, resp.status)
-
- return service_client.ResponseBody(resp, body['access'])
-
- def auth_token(self, token_id, tenant=None):
- creds = {
- 'auth': {
- 'token': {
- 'id': token_id,
- },
- }
- }
-
- if tenant:
- creds['auth']['tenantName'] = tenant
-
- body = json.dumps(creds)
- resp, body = self.post(self.auth_url, body=body)
- self.expected_success(200, resp.status)
-
- return service_client.ResponseBody(resp, body['access'])
-
- def request(self, method, url, extra_headers=False, headers=None,
- body=None):
- """A simple HTTP request interface."""
- if headers is None:
- headers = self.get_headers(accept_type="json")
- elif extra_headers:
- try:
- headers.update(self.get_headers(accept_type="json"))
- except (ValueError, TypeError):
- headers = self.get_headers(accept_type="json")
-
- resp, resp_body = self.raw_request(url, method,
- headers=headers, body=body)
- self._log_request(method, url, resp)
-
- if resp.status in [401, 403]:
- resp_body = json.loads(resp_body)
- raise exceptions.Unauthorized(resp_body['error']['message'])
- elif resp.status not in [200, 201]:
- raise exceptions.IdentityError(
- 'Unexpected status code {0}'.format(resp.status))
-
- if isinstance(resp_body, str):
- resp_body = json.loads(resp_body)
- return resp, resp_body
-
- def get_token(self, user, password, tenant, auth_data=False):
- """
- Returns (token id, token data) for supplied credentials
- """
- body = self.auth(user, password, tenant)
-
- if auth_data:
- return body['token']['id'], body
- else:
- return body['token']['id']
diff --git a/tempest/services/identity/json/token_client.py b/tempest/services/identity/json/token_client.py
new file mode 100644
index 0000000..93936bc
--- /dev/null
+++ b/tempest/services/identity/json/token_client.py
@@ -0,0 +1,108 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+
+from tempest.common import service_client
+from tempest import config
+from tempest import exceptions
+
+CONF = config.CONF
+
+
+class TokenClientJSON(service_client.ServiceClient):
+
+ def __init__(self):
+ super(TokenClientJSON, self).__init__(None, None, None)
+ auth_url = CONF.identity.uri
+
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
+ self.auth_url = auth_url
+
+ def auth(self, user, password, tenant=None):
+ creds = {
+ 'auth': {
+ 'passwordCredentials': {
+ 'username': user,
+ 'password': password,
+ },
+ }
+ }
+
+ if tenant:
+ creds['auth']['tenantName'] = tenant
+
+ body = json.dumps(creds)
+ resp, body = self.post(self.auth_url, body=body)
+ self.expected_success(200, resp.status)
+
+ return service_client.ResponseBody(resp, body['access'])
+
+ def auth_token(self, token_id, tenant=None):
+ creds = {
+ 'auth': {
+ 'token': {
+ 'id': token_id,
+ },
+ }
+ }
+
+ if tenant:
+ creds['auth']['tenantName'] = tenant
+
+ body = json.dumps(creds)
+ resp, body = self.post(self.auth_url, body=body)
+ self.expected_success(200, resp.status)
+
+ return service_client.ResponseBody(resp, body['access'])
+
+ def request(self, method, url, extra_headers=False, headers=None,
+ body=None):
+ """A simple HTTP request interface."""
+ if headers is None:
+ headers = self.get_headers(accept_type="json")
+ elif extra_headers:
+ try:
+ headers.update(self.get_headers(accept_type="json"))
+ except (ValueError, TypeError):
+ headers = self.get_headers(accept_type="json")
+
+ resp, resp_body = self.raw_request(url, method,
+ headers=headers, body=body)
+ self._log_request(method, url, resp)
+
+ if resp.status in [401, 403]:
+ resp_body = json.loads(resp_body)
+ raise exceptions.Unauthorized(resp_body['error']['message'])
+ elif resp.status not in [200, 201]:
+ raise exceptions.IdentityError(
+ 'Unexpected status code {0}'.format(resp.status))
+
+ if isinstance(resp_body, str):
+ resp_body = json.loads(resp_body)
+ return resp, resp_body
+
+ def get_token(self, user, password, tenant, auth_data=False):
+ """
+ Returns (token id, token data) for supplied credentials
+ """
+ body = self.auth(user, password, tenant)
+
+ if auth_data:
+ return body['token']['id'], body
+ else:
+ return body['token']['id']
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 6010249..f3d9d2d 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -18,7 +18,6 @@
from tempest.common import service_client
from tempest import config
-from tempest import exceptions
from tempest.services.identity.v3.json import base
CONF = config.CONF
@@ -525,117 +524,3 @@
% (trust_id, role_id))
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
-
-
-class V3TokenClientJSON(service_client.ServiceClient):
-
- def __init__(self):
- super(V3TokenClientJSON, self).__init__(None, None, None)
- auth_url = CONF.identity.uri_v3
- if not auth_url:
- raise exceptions.InvalidConfiguration('you must specify a v3 uri '
- 'if using the v3 identity '
- 'api')
- if 'auth/tokens' not in auth_url:
- auth_url = auth_url.rstrip('/') + '/auth/tokens'
-
- self.auth_url = auth_url
-
- def auth(self, user=None, password=None, tenant=None, user_type='id',
- domain=None, token=None):
- """
- :param user: user id or name, as specified in user_type
- :param domain: the user and tenant domain
- :param token: a token to re-scope.
-
- Accepts different combinations of credentials. Restrictions:
- - tenant and domain are only name (no id)
- - user domain and tenant domain are assumed identical
- - domain scope is not supported here
- Sample sample valid combinations:
- - token
- - token, tenant, domain
- - user_id, password
- - username, password, domain
- - username, password, tenant, domain
- Validation is left to the server side.
- """
- creds = {
- 'auth': {
- 'identity': {
- 'methods': [],
- }
- }
- }
- id_obj = creds['auth']['identity']
- if token:
- id_obj['methods'].append('token')
- id_obj['token'] = {
- 'id': token
- }
- if user and password:
- id_obj['methods'].append('password')
- id_obj['password'] = {
- 'user': {
- 'password': password,
- }
- }
- if user_type == 'id':
- id_obj['password']['user']['id'] = user
- else:
- id_obj['password']['user']['name'] = user
- if domain is not None:
- _domain = dict(name=domain)
- id_obj['password']['user']['domain'] = _domain
- if tenant is not None:
- _domain = dict(name=domain)
- project = dict(name=tenant, domain=_domain)
- scope = dict(project=project)
- creds['auth']['scope'] = scope
-
- body = json.dumps(creds)
- resp, body = self.post(self.auth_url, body=body)
- self.expected_success(201, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def request(self, method, url, extra_headers=False, headers=None,
- body=None):
- """A simple HTTP request interface."""
- if headers is None:
- # Always accept 'json', for xml token client too.
- # Because XML response is not easily
- # converted to the corresponding JSON one
- headers = self.get_headers(accept_type="json")
- elif extra_headers:
- try:
- headers.update(self.get_headers(accept_type="json"))
- except (ValueError, TypeError):
- headers = self.get_headers(accept_type="json")
-
- resp, resp_body = self.raw_request(url, method,
- headers=headers, body=body)
- self._log_request(method, url, resp)
-
- if resp.status in [401, 403]:
- resp_body = json.loads(resp_body)
- raise exceptions.Unauthorized(resp_body['error']['message'])
- elif resp.status not in [200, 201, 204]:
- raise exceptions.IdentityError(
- 'Unexpected status code {0}'.format(resp.status))
-
- return resp, json.loads(resp_body)
-
- def get_token(self, user, password, tenant, domain='Default',
- auth_data=False):
- """
- :param user: username
- Returns (token id, token data) for supplied credentials
- """
- body = self.auth(user, password, tenant, user_type='name',
- domain=domain)
-
- token = body.response.get('x-subject-token')
- if auth_data:
- return token, body['token']
- else:
- return token
diff --git a/tempest/services/identity/v3/json/token_client.py b/tempest/services/identity/v3/json/token_client.py
new file mode 100644
index 0000000..14c4a0a
--- /dev/null
+++ b/tempest/services/identity/v3/json/token_client.py
@@ -0,0 +1,135 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+
+from tempest.common import service_client
+from tempest import config
+from tempest import exceptions
+
+CONF = config.CONF
+
+
+class V3TokenClientJSON(service_client.ServiceClient):
+
+ def __init__(self):
+ super(V3TokenClientJSON, self).__init__(None, None, None)
+ auth_url = CONF.identity.uri_v3
+ if not auth_url:
+ raise exceptions.InvalidConfiguration('you must specify a v3 uri '
+ 'if using the v3 identity '
+ 'api')
+ if 'auth/tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/auth/tokens'
+
+ self.auth_url = auth_url
+
+ def auth(self, user=None, password=None, tenant=None, user_type='id',
+ domain=None, token=None):
+ """
+ :param user: user id or name, as specified in user_type
+ :param domain: the user and tenant domain
+ :param token: a token to re-scope.
+
+ Accepts different combinations of credentials. Restrictions:
+ - tenant and domain are only name (no id)
+ - user domain and tenant domain are assumed identical
+ - domain scope is not supported here
+ Sample sample valid combinations:
+ - token
+ - token, tenant, domain
+ - user_id, password
+ - username, password, domain
+ - username, password, tenant, domain
+ Validation is left to the server side.
+ """
+ creds = {
+ 'auth': {
+ 'identity': {
+ 'methods': [],
+ }
+ }
+ }
+ id_obj = creds['auth']['identity']
+ if token:
+ id_obj['methods'].append('token')
+ id_obj['token'] = {
+ 'id': token
+ }
+ if user and password:
+ id_obj['methods'].append('password')
+ id_obj['password'] = {
+ 'user': {
+ 'password': password,
+ }
+ }
+ if user_type == 'id':
+ id_obj['password']['user']['id'] = user
+ else:
+ id_obj['password']['user']['name'] = user
+ if domain is not None:
+ _domain = dict(name=domain)
+ id_obj['password']['user']['domain'] = _domain
+ if tenant is not None:
+ _domain = dict(name=domain)
+ project = dict(name=tenant, domain=_domain)
+ scope = dict(project=project)
+ creds['auth']['scope'] = scope
+
+ body = json.dumps(creds)
+ resp, body = self.post(self.auth_url, body=body)
+ self.expected_success(201, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def request(self, method, url, extra_headers=False, headers=None,
+ body=None):
+ """A simple HTTP request interface."""
+ if headers is None:
+ # Always accept 'json', for xml token client too.
+ # Because XML response is not easily
+ # converted to the corresponding JSON one
+ headers = self.get_headers(accept_type="json")
+ elif extra_headers:
+ try:
+ headers.update(self.get_headers(accept_type="json"))
+ except (ValueError, TypeError):
+ headers = self.get_headers(accept_type="json")
+
+ resp, resp_body = self.raw_request(url, method,
+ headers=headers, body=body)
+ self._log_request(method, url, resp)
+
+ if resp.status in [401, 403]:
+ resp_body = json.loads(resp_body)
+ raise exceptions.Unauthorized(resp_body['error']['message'])
+ elif resp.status not in [200, 201, 204]:
+ raise exceptions.IdentityError(
+ 'Unexpected status code {0}'.format(resp.status))
+
+ return resp, json.loads(resp_body)
+
+ def get_token(self, user, password, tenant, domain='Default',
+ auth_data=False):
+ """
+ :param user: username
+ Returns (token id, token data) for supplied credentials
+ """
+ body = self.auth(user, password, tenant, user_type='name',
+ domain=domain)
+
+ token = body.response.get('x-subject-token')
+ if auth_data:
+ return token, body['token']
+ else:
+ return token
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index 0800b47..f45f2cf 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -24,7 +24,7 @@
from tempest.common import accounts
from tempest import config
from tempest import exceptions
-from tempest.services.identity.json import identity_client
+from tempest.services.identity.json import token_client
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests import fake_identity
@@ -68,7 +68,7 @@
return hash_list
def test_get_hash(self):
- self.stubs.Set(identity_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
fake_identity._fake_v2_response)
test_account_class = accounts.Accounts('test_name')
hash_list = self._get_hash_list(self.test_accounts)
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index a191781..90bb8a7 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -21,8 +21,8 @@
from tempest import auth
from tempest import config
from tempest import exceptions
-from tempest.services.identity.json import identity_client as v2_client
-from tempest.services.identity.v3.json import identity_client as v3_client
+from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v3.json import token_client as v3_client
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests import fake_credentials
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index 1abb941..6e447d6 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -21,8 +21,8 @@
from tempest.common import tempest_fixtures as fixtures
from tempest import config
from tempest import exceptions
-from tempest.services.identity.json import identity_client as v2_client
-from tempest.services.identity.v3.json import identity_client as v3_client
+from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v3.json import token_client as v3_client
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests import fake_identity
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index 58a8060..6c80496 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -21,6 +21,7 @@
from tempest import exceptions
from tempest.openstack.common.fixture import mockpatch
from tempest.services.identity.json import identity_client as json_iden_client
+from tempest.services.identity.json import token_client as json_token_client
from tempest.services.network.json import network_client as json_network_client
from tempest.tests import base
from tempest.tests import fake_config
@@ -35,7 +36,7 @@
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(json_iden_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(json_token_client.TokenClientJSON, 'raw_request',
fake_identity._fake_v2_response)
cfg.CONF.set_default('operator_role', 'FakeRole',
group='object-storage')