blob: db648dfbec42421fe2f178db82a99b1634937b7d [file] [log] [blame]
DavidPurcellb25f93d2017-01-27 12:46:27 -05001# Copyright 2017 AT&T Corporation.
DavidPurcell029d8c32017-01-06 15:27:41 -05002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Rick Bartra89f498f2017-03-20 15:54:45 -040016import oslo_utils.uuidutils as uuid_utils
DavidPurcell029d8c32017-01-06 15:27:41 -050017import six
18import time
Felipe Monteiro34a138c2017-03-02 17:01:37 -050019
20from tempest.common import credentials_factory
21from tempest import config
22from tempest.test import BaseTestCase
DavidPurcell029d8c32017-01-06 15:27:41 -050023
Rajiv Kumar645dfc92017-01-19 13:48:27 +053024from oslo_log import log as logging
DavidPurcell029d8c32017-01-06 15:27:41 -050025
Felipe Monteiro34a138c2017-03-02 17:01:37 -050026from patrole_tempest_plugin import rbac_exceptions
DavidPurcell029d8c32017-01-06 15:27:41 -050027
DavidPurcell029d8c32017-01-06 15:27:41 -050028CONF = config.CONF
Felipe Monteiro34a138c2017-03-02 17:01:37 -050029LOG = logging.getLogger(__name__)
DavidPurcell029d8c32017-01-06 15:27:41 -050030
31
32class Singleton(type):
33 _instances = {}
34
35 def __call__(cls, *args, **kwargs):
36 if cls not in cls._instances:
37 cls._instances[cls] = super(Singleton, cls).__call__(*args,
38 **kwargs)
39 return cls._instances[cls]
40
41
42@six.add_metaclass(Singleton)
43class RbacUtils(object):
DavidPurcell029d8c32017-01-06 15:27:41 -050044
Felipe Monteiro34a138c2017-03-02 17:01:37 -050045 def __init__(cls):
46 creds_provider = credentials_factory.get_credentials_provider(
47 name=__name__,
48 force_tenant_isolation=True,
49 identity_version=BaseTestCase.get_identity_version())
DavidPurcell029d8c32017-01-06 15:27:41 -050050
Felipe Monteiro34a138c2017-03-02 17:01:37 -050051 cls.creds_client = creds_provider.creds_client
52 cls.available_roles = cls.creds_client.roles_client.list_roles()
53 cls.admin_role_id = cls.rbac_role_id = None
54 for item in cls.available_roles['roles']:
55 if item['name'] == CONF.rbac.rbac_test_role:
56 cls.rbac_role_id = item['id']
57 if item['name'] == 'admin':
58 cls.admin_role_id = item['id']
DavidPurcell029d8c32017-01-06 15:27:41 -050059
Felipe Monteiro34a138c2017-03-02 17:01:37 -050060 def switch_role(cls, test_obj, switchToRbacRole=None):
DavidPurcell029d8c32017-01-06 15:27:41 -050061 LOG.debug('Switching role to: %s', switchToRbacRole)
Felipe Monteirob3b7bc82017-03-03 15:58:15 -050062 # Check if admin and rbac roles exist.
63 if not cls.admin_role_id or not cls.rbac_role_id:
64 msg = ("Defined 'rbac_role' or 'admin' role does not exist"
65 " in the system.")
66 raise rbac_exceptions.RbacResourceSetupFailed(msg)
67
Felipe Monteiro34a138c2017-03-02 17:01:37 -050068 if not isinstance(switchToRbacRole, bool):
69 msg = ("Wrong value for parameter 'switchToRbacRole' is passed."
70 " It should be either 'True' or 'False'.")
Felipe Monteirob3b7bc82017-03-03 15:58:15 -050071 raise rbac_exceptions.RbacResourceSetupFailed(msg)
DavidPurcell029d8c32017-01-06 15:27:41 -050072
73 try:
Felipe Monteiro34a138c2017-03-02 17:01:37 -050074 user_id = test_obj.auth_provider.credentials.user_id
75 project_id = test_obj.auth_provider.credentials.tenant_id
DavidPurcell029d8c32017-01-06 15:27:41 -050076
Felipe Monteirob3b7bc82017-03-03 15:58:15 -050077 cls._clear_user_roles(user_id, project_id)
DavidPurcell029d8c32017-01-06 15:27:41 -050078
79 if switchToRbacRole:
Felipe Monteiro34a138c2017-03-02 17:01:37 -050080 cls.creds_client.roles_client.create_user_role_on_project(
81 project_id, user_id, cls.rbac_role_id)
DavidPurcell029d8c32017-01-06 15:27:41 -050082 else:
Felipe Monteiro34a138c2017-03-02 17:01:37 -050083 cls.creds_client.roles_client.create_user_role_on_project(
84 project_id, user_id, cls.admin_role_id)
DavidPurcell029d8c32017-01-06 15:27:41 -050085
86 except Exception as exp:
87 LOG.error(exp)
88 raise
DavidPurcell029d8c32017-01-06 15:27:41 -050089
Felipe Monteiro34a138c2017-03-02 17:01:37 -050090 finally:
Felipe Monteiro23923f02017-03-17 02:15:07 +000091 # NOTE(felipemonteiro): These two comments below are copied from
92 # tempest.api.identity.v2/v3.test_users.
93 #
94 # Reset auth again to verify the password restore does work.
95 # Clear auth restores the original credentials and deletes
96 # cached auth data.
97 test_obj.auth_provider.clear_auth()
98 # Fernet tokens are not subsecond aware and Keystone should only be
99 # precise to the second. Sleep to ensure we are passing the second
Rick Bartra89f498f2017-03-20 15:54:45 -0400100 # boundary before attempting to authenticate. If token is of type
101 # uuid, then do not sleep.
102 if not uuid_utils.is_uuid_like(cls.creds_client.
103 identity_client.token):
104 time.sleep(1)
Felipe Monteiro23923f02017-03-17 02:15:07 +0000105 test_obj.auth_provider.set_auth()
Felipe Monteiro34a138c2017-03-02 17:01:37 -0500106
Felipe Monteirob3b7bc82017-03-03 15:58:15 -0500107 def _clear_user_roles(cls, user_id, tenant_id):
108 roles = cls.creds_client.roles_client.list_user_roles_on_project(
109 tenant_id, user_id)['roles']
110
111 for role in roles:
112 cls.creds_client.roles_client.delete_role_from_user_on_project(
113 tenant_id, user_id, role['id'])
114
Felipe Monteiro34a138c2017-03-02 17:01:37 -0500115rbac_utils = RbacUtils