Implement tempest client for keystone v2 token APIs

Implement Tempest client for Keystone v2 token API - v2.0/tokens/

Although some of the APIs have been implemented, many of the token
related APIs are yet to be implemented such as
list_endpoints_for_token, check_token_existence

Here are the OpenStack docs link
https://developer.openstack.org/api-ref/identity/v2-admin/index.html
https://developer.openstack.org/api-ref/identity/v2/

Change-Id: Idc351fdcce420bb42c00bab23460f32e3c66e9ce
Co-Authored-By: Pramod Kumar Singh <pk110e@att.com>
Co-Authored-By: Nishant Kumar E <nk613n@att.com>
This commit is contained in:
Pradeep Kumar 2017-04-27 16:48:36 +05:30 committed by Pramod Kumar Singh
parent 7203f58c97
commit 1c79628760
5 changed files with 152 additions and 1 deletions

View File

@ -0,0 +1,6 @@
---
features:
- |
Add additional API endpoints to the identity v2 client token API:
- list_endpoints_for_token
- check_token_existence

View File

@ -14,14 +14,18 @@
# under the License.
from tempest.api.identity import base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
CONF = config.CONF
class TokensTestJSON(base.BaseIdentityV2AdminTest):
@decorators.idempotent_id('453ad4d5-e486-4b2f-be72-cffc8149e586')
def test_create_get_delete_token(self):
def test_create_check_get_delete_token(self):
# get a token by username and password
user_name = data_utils.rand_name(name='user')
user_password = data_utils.rand_password()
@ -40,6 +44,7 @@ class TokensTestJSON(base.BaseIdentityV2AdminTest):
tenant['name'])
# Perform GET Token
token_id = body['token']['id']
self.client.check_token_existence(token_id)
token_details = self.client.show_token(token_id)['access']
self.assertEqual(token_id, token_details['token']['id'])
self.assertEqual(user['id'], token_details['user']['id'])
@ -48,6 +53,9 @@ class TokensTestJSON(base.BaseIdentityV2AdminTest):
token_details['token']['tenant']['name'])
# then delete the token
self.client.delete_token(token_id)
self.assertRaises(lib_exc.NotFound,
self.client.check_token_existence,
token_id)
@decorators.idempotent_id('25ba82ee-8a32-4ceb-8f50-8b8c71e8765e')
def test_rescope_token(self):
@ -101,3 +109,25 @@ class TokensTestJSON(base.BaseIdentityV2AdminTest):
# Use the unscoped token to get a token scoped to tenant2
body = self.token_client.auth_token(token_id,
tenant=tenant2_name)
@decorators.idempotent_id('ca3ea6f7-ed08-4a61-adbd-96906456ad31')
def test_list_endpoints_for_token(self):
# get a token for the user
creds = self.os_primary.credentials
username = creds.username
password = creds.password
tenant_name = creds.tenant_name
token = self.token_client.auth(username,
password,
tenant_name)['token']
endpoints = self.client.list_endpoints_for_token(
token['id'])['endpoints']
self.assertIsInstance(endpoints, list)
# Store list of service names
service_names = [e['name'] for e in endpoints]
# Get the list of available services.
available_services = [s[0] for s in list(
CONF.service_available.items()) if s[1] is True]
# Verify that all available services are present.
for service in available_services:
self.assertIn(service, service_names)

View File

@ -0,0 +1,38 @@
# Copyright 2017 AT&T 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.
from tempest.api.identity import base
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
class TokensAdminTestNegative(base.BaseIdentityV2AdminTest):
credentials = ['primary', 'admin', 'alt']
@decorators.attr(type=['negative'])
@decorators.idempotent_id('a0a0a600-4292-4364-99c5-922c834fdf05')
def test_check_token_existence_negative(self):
creds = self.os_primary.credentials
creds_alt = self.os_alt.credentials
username = creds.username
password = creds.password
tenant_name = creds.tenant_name
alt_tenant_name = creds_alt.tenant_name
body = self.token_client.auth(username, password, tenant_name)
self.assertRaises(lib_exc.Unauthorized,
self.client.check_token_existence,
body['token']['id'],
belongsTo=alt_tenant_name)

View File

@ -11,6 +11,7 @@
# under the License.
from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.lib.common import rest_client
@ -45,3 +46,24 @@ class IdentityClient(rest_client.RestClient):
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def list_endpoints_for_token(self, token_id):
"""List endpoints for a token """
resp, body = self.get("tokens/%s/endpoints" % token_id)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
def check_token_existence(self, token_id, **params):
"""Validates a token and confirms that it belongs to a tenant.
For a full list of available parameters, please refer to the
official API reference:
https://developer.openstack.org/api-ref/identity/v2-admin/#validate-token
"""
url = "tokens/%s" % token_id
if params:
url += '?%s' % urllib.urlencode(params)
resp, body = self.head(url)
self.expected_success(200, resp.status)
return rest_client.ResponseBody(resp, body)

View File

@ -26,6 +26,33 @@ class TestIdentityClient(base.BaseServiceTest):
}
}
FAKE_ENDPOINTS_FOR_TOKEN = {
"endpoints_links": [],
"endpoints": [
{
"name": "nova",
"adminURL": "https://nova.region-one.internal.com/" +
"v2/be1319401cfa4a0aa590b97cc7b64d8d",
"region": "RegionOne",
"internalURL": "https://nova.region-one.internal.com/" +
"v2/be1319401cfa4a0aa590b97cc7b64d8d",
"type": "compute",
"id": "11b41ee1b00841128b7333d4bf1a6140",
"publicURL": "https://nova.region-one.public.com/v2/" +
"be1319401cfa4a0aa590b97cc7b64d8d"
},
{
"name": "neutron",
"adminURL": "https://neutron.region-one.internal.com/",
"region": "RegionOne",
"internalURL": "https://neutron.region-one.internal.com/",
"type": "network",
"id": "cdbfa3c416d741a9b5c968f2dc628acb",
"publicURL": "https://neutron.region-one.public.com/"
}
]
}
FAKE_API_INFO = {
"name": "API_info",
"type": "API",
@ -148,6 +175,22 @@ class TestIdentityClient(base.BaseServiceTest):
bytes_body,
token_id="cbc36478b0bd8e67e89")
def _test_list_endpoints_for_token(self, bytes_body=False):
self.check_service_client_function(
self.client.list_endpoints_for_token,
'tempest.lib.common.rest_client.RestClient.get',
self.FAKE_ENDPOINTS_FOR_TOKEN,
bytes_body,
token_id="cbc36478b0bd8e67e89")
def _test_check_token_existence(self, bytes_body=False):
self.check_service_client_function(
self.client.check_token_existence,
'tempest.lib.common.rest_client.RestClient.head',
{},
bytes_body,
token_id="cbc36478b0bd8e67e89")
def test_show_api_description_with_str_body(self):
self._test_show_api_description()
@ -166,6 +209,18 @@ class TestIdentityClient(base.BaseServiceTest):
def test_show_token_with_bytes_body(self):
self._test_show_token(bytes_body=True)
def test_list_endpoints_for_token_with_str_body(self):
self._test_list_endpoints_for_token()
def test_list_endpoints_for_token_with_bytes_body(self):
self._test_list_endpoints_for_token(bytes_body=True)
def test_check_token_existence_with_bytes_body(self):
self._test_check_token_existence(bytes_body=True)
def test_check_token_existence_with_str_body(self):
self._test_check_token_existence()
def test_delete_token(self):
self.check_service_client_function(
self.client.delete_token,