Merge "Make _get_router() non-private"
diff --git a/releasenotes/notes/intermediate-wallaby-release-55a0b31b1dee7b23.yaml b/releasenotes/notes/intermediate-wallaby-release-55a0b31b1dee7b23.yaml
new file mode 100644
index 0000000..cda3b89
--- /dev/null
+++ b/releasenotes/notes/intermediate-wallaby-release-55a0b31b1dee7b23.yaml
@@ -0,0 +1,4 @@
+---
+prelude: >
+ This is an intermediate release during the Wallaby development cycle to
+ make new functionality available to plugins and other consumers.
diff --git a/releasenotes/notes/support-scope-in-get-roles-dynamic-creds-90bfab163c1c289a.yaml b/releasenotes/notes/support-scope-in-get-roles-dynamic-creds-90bfab163c1c289a.yaml
new file mode 100644
index 0000000..26282f0
--- /dev/null
+++ b/releasenotes/notes/support-scope-in-get-roles-dynamic-creds-90bfab163c1c289a.yaml
@@ -0,0 +1,36 @@
+---
+features:
+ - |
+ Dynamic credentials now support the scope type for specific roles
+ too along with ``admin``, ``member``, ``reader`` role.
+ Test can specify the scope in the prefix of ``cls.credentials`` name.
+ If ``system`` is prefix in ``cls.credentials`` name then creds will
+ be created with scope as ``system``. If ``domain`` is prefix in
+ ``cls.credentials`` name then creds will be created with scope as
+ ``domain`` otherwise default ``project`` scope will be used.
+ For Example::
+
+ credentials = [['my_role', 'role1'], # this will be old style and project scoped
+ ['project_my_role', 'role1'], # this will be project scoped
+ ['domain_my_role', 'role1'], # this will be domain scoped
+ ['system_my_role', 'role1']] # this will be system scoped
+
+ And below is how test can access the credential manager of respective
+ credentials type::
+
+ cls.os_my_role.any_client
+ cls.os_project_my_role.any_client
+ cls.os_domain_my_role.any_client
+ cls.os_system_my_role.any_client
+
+
+ For backward compatibility, we set the credentials manager class attribute
+ in old style form too which is prefix with ``os_roles_*``, example
+ ``cls.os_roles_my_role`` but we recommend to use the new style attribute
+ as shown above.
+issues:
+ - |
+ Scope support for specific role is not yet added for pre-provisioned credentials.
+fixes:
+ - |
+ Fixes the `bug# 1917168 <https://bugs.launchpad.net/tempest/+bug/1917168>`_
diff --git a/tempest/cmd/subunit_describe_calls.py b/tempest/cmd/subunit_describe_calls.py
index 172fbaa..6c36d82 100644
--- a/tempest/cmd/subunit_describe_calls.py
+++ b/tempest/cmd/subunit_describe_calls.py
@@ -40,12 +40,14 @@
subunit-describe-calls will take in either stdin subunit v1 or v2 stream or a
file path which contains either a subunit v1 or v2 stream passed via the
---subunit parameter. This is then parsed checking for details contained in the
-file_bytes of the --non-subunit-name parameter (the default is pythonlogging
-which is what Tempest uses to store logs). By default the OpenStack Kilo
-release port defaults (http://bit.ly/22jpF5P) are used unless a file is
-provided via the --ports option. The resulting output is dumped in JSON output
-to the path provided in the --output-file option.
+``--subunit`` parameter. This is then parsed checking for details contained in
+the file_bytes of the ``--non-subunit-name`` parameter (the default is
+pythonlogging which is what Tempest uses to store logs). By default `the
+OpenStack default ports
+<https://docs.openstack.org/install-guide/firewalls-default-ports.html>`_
+are used unless a file is provided via the ``--ports`` option. The resulting
+output is dumped in JSON output to the path provided in the ``--output-file``
+option.
Ports file JSON structure
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,9 +112,8 @@
response_re = re.compile(r'.* Response - Headers: (?P<headers>.*)')
body_re = re.compile(r'.*Body: (?P<body>.*)')
- # Based on newton defaults:
- # http://docs.openstack.org/newton/config-reference/
- # firewalls-default-ports.html
+ # Based on OpenStack default ports:
+ # https://docs.openstack.org/install-guide/firewalls-default-ports.html
services = {
"8776": "Block Storage",
"8774": "Nova",
@@ -131,7 +132,10 @@
"3260": "iSCSI",
"3306": "MySQL",
"5672": "AMQP",
- "8082": "murano"}
+ "8082": "murano",
+ "8778": "Clustering",
+ "8999": "Vitrage",
+ "8989": "Mistral"}
def __init__(self, services=None):
super(UrlParser, self).__init__()
diff --git a/tempest/lib/common/cred_provider.py b/tempest/lib/common/cred_provider.py
index 5af5a5e..069172a 100644
--- a/tempest/lib/common/cred_provider.py
+++ b/tempest/lib/common/cred_provider.py
@@ -118,7 +118,7 @@
return
@abc.abstractmethod
- def get_creds_by_roles(self, roles, force_new=False):
+ def get_creds_by_roles(self, roles, force_new=False, scope=None):
return
@abc.abstractmethod
diff --git a/tempest/lib/common/dynamic_creds.py b/tempest/lib/common/dynamic_creds.py
index 5e2308e..f334c36 100644
--- a/tempest/lib/common/dynamic_creds.py
+++ b/tempest/lib/common/dynamic_creds.py
@@ -228,8 +228,9 @@
roles_to_assign = [r for r in roles]
if admin:
roles_to_assign.append(self.admin_role)
- self.creds_client.assign_user_role(
- user, project, self.identity_admin_role)
+ if scope == 'project':
+ self.creds_client.assign_user_role(
+ user, project, self.identity_admin_role)
if (self.identity_version == 'v3' and
self.identity_admin_domain_scope):
self.creds_client.assign_user_role_on_domain(
@@ -375,19 +376,25 @@
def get_credentials(self, credential_type, scope=None):
if not scope and self._creds.get(str(credential_type)):
credentials = self._creds[str(credential_type)]
- elif scope and self._creds.get("%s_%s" % (scope, credential_type[0])):
- credentials = self._creds["%s_%s" % (scope, credential_type[0])]
+ elif scope and (
+ self._creds.get("%s_%s" % (scope, str(credential_type)))):
+ credentials = self._creds["%s_%s" % (scope, str(credential_type))]
else:
+ LOG.debug("Creating new dynamic creds for scope: %s and "
+ "credential_type: %s", scope, credential_type)
if scope:
if credential_type in [['admin'], ['alt_admin']]:
credentials = self._create_creds(
admin=True, scope=scope)
- else:
- cred_type = credential_type
- if credential_type in [['alt_member'], ['alt_reader']]:
- cred_type = credential_type[0][4:]
+ elif credential_type in [['alt_member'], ['alt_reader']]:
+ cred_type = credential_type[0][4:]
+ if isinstance(cred_type, str):
+ cred_type = [cred_type]
credentials = self._create_creds(
- roles=[cred_type], scope=scope)
+ roles=cred_type, scope=scope)
+ else:
+ credentials = self._create_creds(
+ roles=credential_type, scope=scope)
elif credential_type in ['primary', 'alt', 'admin']:
is_admin = (credential_type == 'admin')
credentials = self._create_creds(admin=is_admin)
@@ -395,7 +402,7 @@
credentials = self._create_creds(roles=credential_type)
if scope:
self._creds["%s_%s" %
- (scope, credential_type[0])] = credentials
+ (scope, str(credential_type))] = credentials
else:
self._creds[str(credential_type)] = credentials
# Maintained until tests are ported
@@ -461,19 +468,22 @@
def get_project_alt_reader_creds(self):
return self.get_credentials(['alt_reader'], scope='project')
- def get_creds_by_roles(self, roles, force_new=False):
+ def get_creds_by_roles(self, roles, force_new=False, scope=None):
roles = list(set(roles))
# The roles list as a str will become the index as the dict key for
# the created credentials set in the dynamic_creds dict.
- exist_creds = self._creds.get(str(roles))
+ creds_name = str(roles)
+ if scope:
+ creds_name = "%s_%s" % (scope, str(roles))
+ exist_creds = self._creds.get(creds_name)
# If force_new flag is True 2 cred sets with the same roles are needed
# handle this by creating a separate index for old one to store it
# separately for cleanup
if exist_creds and force_new:
- new_index = str(roles) + '-' + str(len(self._creds))
+ new_index = creds_name + '-' + str(len(self._creds))
self._creds[new_index] = exist_creds
- del self._creds[str(roles)]
- return self.get_credentials(roles)
+ del self._creds[creds_name]
+ return self.get_credentials(roles, scope=scope)
def _clear_isolated_router(self, router_id, router_name):
client = self.routers_admin_client
diff --git a/tempest/lib/common/preprov_creds.py b/tempest/lib/common/preprov_creds.py
index a41f0bb..df0f4d6 100644
--- a/tempest/lib/common/preprov_creds.py
+++ b/tempest/lib/common/preprov_creds.py
@@ -400,7 +400,7 @@
# TODO(gmann): Implement alt reader hash.
return
- def get_creds_by_roles(self, roles, force_new=False):
+ def get_creds_by_roles(self, roles, force_new=False, scope=None):
roles = list(set(roles))
exist_creds = self._creds.get(str(roles).encode(
'utf-8'), None)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 69488a1..67d134e 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -590,7 +590,7 @@
rules.append(sg_rule)
return rules
- def _create_security_group(self, **kwargs):
+ def create_security_group(self, **kwargs):
"""Create security group and add rules to security group"""
if not kwargs.get('name'):
kwargs['name'] = data_utils.rand_name(self.__class__.__name__)
@@ -1386,10 +1386,10 @@
self.log_console_output()
self.fail(msg)
- def _create_security_group(self, security_group_rules_client=None,
- project_id=None,
- namestart='secgroup-smoke',
- security_groups_client=None):
+ def create_security_group(self, security_group_rules_client=None,
+ project_id=None,
+ namestart='secgroup-smoke',
+ security_groups_client=None):
if security_group_rules_client is None:
security_group_rules_client = self.security_group_rules_client
if security_groups_client is None:
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index fe42583..5201315 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -78,7 +78,7 @@
self.assertEqual(1, disks.count(CONF.compute.volume_device_name))
def create_and_add_security_group_to_server(self, server):
- secgroup = self._create_security_group()
+ secgroup = self.create_security_group()
self.servers_client.add_security_group(server['id'],
name=secgroup['name'])
self.addCleanup(self.servers_client.remove_security_group,
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index dbab212..20d2e80 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -60,7 +60,7 @@
def _setup_server(self, keypair):
security_groups = []
if utils.is_extension_enabled('security-group', 'network'):
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
security_groups = [{'name': security_group['name']}]
network, _, _ = self.create_networks()
server = self.create_server(
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index da1e794..d6f5a4b 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -159,7 +159,7 @@
keypair = self.create_keypair()
self.keypairs[keypair['name']] = keypair
security_groups = [
- {'name': self._create_security_group()['name']}
+ {'name': self.create_security_group()['name']}
]
network = {'uuid': network['id']}
if port_id is not None:
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index a8fe20f..4f5118b 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -66,7 +66,7 @@
def setUp(self):
super(TestGettingAddress, self).setUp()
self.keypair = self.create_keypair()
- self.sec_grp = self._create_security_group()
+ self.sec_grp = self.create_security_group()
def prepare_network(self, address6_mode, n_subnets6=1, dualnet=False):
"""Prepare network
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 60242d5..4c82d84 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -128,7 +128,7 @@
@utils.services('compute', 'network')
def test_server_basic_ops(self):
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
self.instance = self.create_server(
key_name=keypair['name'],
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index ed06898..29612ec 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -76,7 +76,7 @@
cold_migrate=False):
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
security_groups = [{'name': security_group['name']}]
server = self.create_server(
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index a062d40..d04cb9a 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -50,7 +50,7 @@
def test_snapshot_pattern(self):
# prepare for booting an instance
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# boot an instance and create a timestamp file in it
server = self.create_server(
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index a8e4c30..4b81b9e 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -81,7 +81,7 @@
def test_stamp_pattern(self):
# prepare for booting an instance
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# boot an instance and create a timestamp file in it
volume = self.create_volume()
diff --git a/tempest/scenario/test_volume_backup_restore.py b/tempest/scenario/test_volume_backup_restore.py
index 8a8c54e..71e6b53 100644
--- a/tempest/scenario/test_volume_backup_restore.py
+++ b/tempest/scenario/test_volume_backup_restore.py
@@ -70,7 +70,7 @@
# Create keypair and security group
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# Boot a server from the restored backup
bd_map_v2 = [{
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 3b4bbda..5a5cc27 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -64,7 +64,7 @@
LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# create an instance from volume
LOG.info("Booting instance 1 from volume")
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index 106500e..57d2a1a 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -100,7 +100,7 @@
def test_volume_retype_attached(self):
LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
# create volume types
LOG.info("Creating Volume types")
@@ -156,7 +156,7 @@
def test_volume_migrate_attached(self):
LOG.info("Creating keypair and security group")
keypair = self.create_keypair()
- security_group = self._create_security_group()
+ security_group = self.create_security_group()
LOG.info("Creating volume")
# Create a unique volume type to avoid using the backend default
diff --git a/tempest/test.py b/tempest/test.py
index 2dfedeb..655b9a4 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -415,8 +415,18 @@
'alt_manager', 'os_alt', version='Pike',
removal_version='Queens')
elif isinstance(credentials_type, list):
+ scope = 'project'
+ if credentials_type[0].startswith('system'):
+ scope = 'system'
+ elif credentials_type[0].startswith('domain'):
+ scope = 'domain'
manager = cls.get_client_manager(roles=credentials_type[1:],
- force_new=True)
+ force_new=True,
+ scope=scope)
+ setattr(cls, 'os_%s' % credentials_type[0], manager)
+ # TODO(gmann): Setting the old style attribute too for
+ # backward compatibility but at some point we should
+ # remove this.
setattr(cls, 'os_roles_%s' % credentials_type[0], manager)
@classmethod
@@ -658,7 +668,7 @@
@classmethod
def get_client_manager(cls, credential_type=None, roles=None,
- force_new=None):
+ force_new=None, scope=None):
"""Returns an OpenStack client manager
Returns an OpenStack client manager based on either credential_type
@@ -666,6 +676,7 @@
credential_type 'primary'
:param credential_type: string - primary, alt or admin
:param roles: list of roles
+ :param scope: scope for the test user
:returns: the created client manager
:raises skipException: if the requested credentials are not available
@@ -684,7 +695,7 @@
" is not able to provide credentials with the %s role "
"assigned." % (cls.__name__, role))
raise cls.skipException(skip_msg)
- params = dict(roles=roles)
+ params = dict(roles=roles, scope=scope)
if force_new is not None:
params.update(force_new=force_new)
creds = cred_provider.get_creds_by_roles(**params)
@@ -851,7 +862,13 @@
if isinstance(credentials_type, six.string_types):
manager = cls.get_client_manager(credential_type=credentials_type)
elif isinstance(credentials_type, list):
- manager = cls.get_client_manager(roles=credentials_type[1:])
+ scope = 'project'
+ if credentials_type[0].startswith('system'):
+ scope = 'system'
+ elif credentials_type[0].startswith('domain'):
+ scope = 'domain'
+ manager = cls.get_client_manager(roles=credentials_type[1:],
+ scope=scope)
else:
manager = cls.get_client_manager()
diff --git a/tempest/tests/lib/common/test_dynamic_creds.py b/tempest/tests/lib/common/test_dynamic_creds.py
index 4bb6440..b4b1b91 100644
--- a/tempest/tests/lib/common/test_dynamic_creds.py
+++ b/tempest/tests/lib/common/test_dynamic_creds.py
@@ -292,6 +292,100 @@
self.assertEqual(role_creds.user_id, '1234')
@mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_role_creds_with_project_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+
+ user_mock = mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project')
+ user_mock.start()
+ self.addCleanup(user_mock.stop)
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='project')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ args = map(lambda x: x[1], calls)
+ args = list(args)
+ self.assertIn(('1234', '1234', '1234'), args)
+ self.assertIn(('1234', '1234', '12345'), args)
+ self.assertEqual(role_creds.username, 'fake_role_user')
+ self.assertEqual(role_creds.project_name, 'fake_role_project')
+ # Verify IDs
+ self.assertEqual(role_creds.project_id, '1234')
+ self.assertEqual(role_creds.user_id, '1234')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def _test_get_same_role_creds_with_project_scope(self, MockRestClient,
+ scope=None):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope=scope)
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope=scope)
+ calls = user_mock1.mock_calls
+ # Assert that previously created creds are return and no call to
+ # role creation.
+ self.assertEqual(len(calls), 0)
+ # Check if previously created creds are returned.
+ self.assertEqual(role_creds, role_creds_new)
+
+ def test_get_same_role_creds_with_project_scope(self):
+ self._test_get_same_role_creds_with_project_scope(scope='project')
+
+ def test_get_same_role_creds_with_default_scope(self):
+ self._test_get_same_role_creds_with_project_scope()
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def _test_get_different_role_creds_with_project_scope(
+ self, MockRestClient, scope=None):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope=scope)
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Fetch the creds with one role different
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1'], scope=scope)
+ calls = user_mock1.mock_calls
+ # Because one role is different, assert that the role creation
+ # is called with the 1 specified roles
+ self.assertEqual(len(calls), 1)
+ # Check new creds is created for new roles.
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ def test_get_different_role_creds_with_project_scope(self):
+ self._test_get_different_role_creds_with_project_scope(
+ scope='project')
+
+ def test_get_different_role_creds_with_default_scope(self):
+ self._test_get_different_role_creds_with_project_scope()
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
def test_all_cred_cleanup(self, MockRestClient):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
self._mock_assign_user_role()
@@ -708,6 +802,232 @@
return project_fix
@mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_role_creds_with_system_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ args = map(lambda x: x[1], calls)
+ args = list(args)
+ self.assertIn(('1234', '1234'), args)
+ self.assertIn(('1234', '12345'), args)
+ self.assertEqual(role_creds.username, 'fake_role_user')
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify system scope
+ self.assertEqual(role_creds.system, 'all')
+ # Verify domain is default
+ self.assertEqual(role_creds.domain_id, 'default')
+ self.assertEqual(role_creds.domain_name, 'Default')
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_same_role_creds_with_system_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock1.mock_calls
+ # Assert that previously created creds are return and no call to
+ # role creation.
+ self.assertEqual(len(calls), 0)
+ # Verify system scope
+ self.assertEqual(role_creds_new.system, 'all')
+ # Check if previously created creds are returned.
+ self.assertEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_different_role_creds_with_system_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Verify system scope
+ self.assertEqual(role_creds.system, 'all')
+ # Fetch the creds with one role different
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1'], scope='system')
+ calls = user_mock1.mock_calls
+ # Because one role is different, assert that the role creation
+ # is called with the 1 specified roles
+ self.assertEqual(len(calls), 1)
+ # Verify Scope
+ self.assertEqual(role_creds_new.system, 'all')
+ # Check new creds is created for new roles.
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_role_creds_with_domain_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ domain = {
+ "id": '12',
+ "enabled": True,
+ "name": "TestDomain"
+ }
+
+ self.useFixture(fixtures.MockPatch(
+ 'tempest.lib.common.cred_client.V3CredsClient.create_domain',
+ return_value=domain))
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ args = map(lambda x: x[1], calls)
+ args = list(args)
+ self.assertIn((domain['id'], '1234', '1234'), args)
+ self.assertIn((domain['id'], '1234', '12345'), args)
+ self.assertEqual(role_creds.username, 'fake_role_user')
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify creds are under new created domain
+ self.assertEqual(role_creds.domain_id, domain['id'])
+ self.assertEqual(role_creds.domain_name, domain['name'])
+ # Verify that Scope is None
+ self.assertIsNone(role_creds.system)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_same_role_creds_with_domain_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ domain = {
+ "id": '12',
+ "enabled": True,
+ "name": "TestDomain"
+ }
+
+ self.useFixture(fixtures.MockPatch(
+ 'tempest.lib.common.cred_client.V3CredsClient.create_domain',
+ return_value=domain))
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify Scope
+ self.assertIsNone(role_creds.system)
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock1.mock_calls
+ # Assert that previously created creds are return and no call to
+ # role creation.
+ self.assertEqual(len(calls), 0)
+ # Verify Scope
+ self.assertIsNone(role_creds_new.system)
+ # Check if previously created creds are returned.
+ self.assertEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_different_role_creds_with_domain_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+
+ domain = {
+ "id": '12',
+ "enabled": True,
+ "name": "TestDomain"
+ }
+
+ self.useFixture(fixtures.MockPatch(
+ 'tempest.lib.common.cred_client.V3CredsClient.create_domain',
+ return_value=domain))
+
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='domain')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ self.assertEqual(role_creds.user_id, '1234')
+ # Verify Scope
+ self.assertIsNone(role_creds.system)
+ # Fetch the same creds again
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_domain') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1'], scope='domain')
+ calls = user_mock1.mock_calls
+ # Because one role is different, assert that the role creation
+ # is called with the 1 specified roles
+ self.assertEqual(len(calls), 1)
+ # Verify Scope
+ self.assertIsNone(role_creds_new.system)
+ # Check new creds is created for new roles.
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
+ def test_get_role_creds_with_different_scope(self, MockRestClient):
+ creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
+ self._mock_list_2_roles()
+ self._mock_user_create('1234', 'fake_role_user')
+ self._mock_tenant_create('1234', 'fake_role_project')
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_system') as user_mock:
+ role_creds = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='system')
+ calls = user_mock.mock_calls
+ # Assert that the role creation is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Verify Scope
+ self.assertEqual(role_creds.system, 'all')
+
+ # Fetch the same role creds but with different scope
+ with mock.patch.object(self.roles_client.RolesClient,
+ 'create_user_role_on_project') as user_mock1:
+ role_creds_new = creds.get_creds_by_roles(
+ roles=['role1', 'role2'], scope='project')
+ calls = user_mock1.mock_calls
+ # Because scope is different, assert that the role creation
+ # is called with the 2 specified roles
+ self.assertEqual(len(calls), 2)
+ # Verify Scope
+ self.assertIsNone(role_creds_new.system)
+ # Check that created creds are different
+ self.assertNotEqual(role_creds, role_creds_new)
+
+ @mock.patch('tempest.lib.common.rest_client.RestClient')
def test_member_role_creation_with_duplicate(self, rest_client_mock):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
creds.creds_client = mock.MagicMock()
diff --git a/tempest/tests/test_base_test.py b/tempest/tests/test_base_test.py
index b154cd5..88c28bf 100644
--- a/tempest/tests/test_base_test.py
+++ b/tempest/tests/test_base_test.py
@@ -109,7 +109,7 @@
test.BaseTestCase.get_tenant_network(credentials_type=creds)
- mock_gcm.assert_called_once_with(roles=['role1'])
+ mock_gcm.assert_called_once_with(roles=['role1'], scope='project')
mock_gprov.assert_called_once_with()
mock_gtn.assert_called_once_with(mock_prov, net_client,
self.fixed_network_name)
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index 72e8b6d..9aeedb3 100644
--- a/tempest/tests/test_test.py
+++ b/tempest/tests/test_test.py
@@ -453,6 +453,130 @@
expected_creds[1][1:],
mock_get_client_manager.mock_calls[1][2]['roles'])
+ def test_setup_credentials_with_role_and_system_scope(self):
+ expected_creds = [['system_my_role', 'role1', 'role2']]
+
+ class SystemRoleCredentials(self.parent_test):
+ credentials = expected_creds
+
+ expected_clients = 'clients'
+ with mock.patch.object(
+ SystemRoleCredentials,
+ 'get_client_manager') as mock_get_client_manager:
+ mock_get_client_manager.return_value = expected_clients
+ sys_creds = SystemRoleCredentials()
+ sys_creds.setup_credentials()
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
+ self.assertEqual(1, mock_get_client_manager.call_count)
+ self.assertEqual(
+ expected_creds[0][1:],
+ mock_get_client_manager.mock_calls[0][2]['roles'])
+ self.assertEqual(
+ 'system',
+ mock_get_client_manager.mock_calls[0][2]['scope'])
+
+ def test_setup_credentials_with_multiple_role_and_system_scope(self):
+ expected_creds = [['system_my_role', 'role1', 'role2'],
+ ['system_my_role2', 'role1', 'role2'],
+ ['system_my_role3', 'role3']]
+
+ class SystemRoleCredentials(self.parent_test):
+ credentials = expected_creds
+
+ expected_clients = 'clients'
+ with mock.patch.object(
+ SystemRoleCredentials,
+ 'get_client_manager') as mock_get_client_manager:
+ mock_get_client_manager.return_value = expected_clients
+ sys_creds = SystemRoleCredentials()
+ sys_creds.setup_credentials()
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role2'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role2)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role2'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role2)
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role3'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role3)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role3'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role3)
+ self.assertEqual(3, mock_get_client_manager.call_count)
+ self.assertEqual(
+ expected_creds[0][1:],
+ mock_get_client_manager.mock_calls[0][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[0][2]['scope'])
+ self.assertEqual(
+ expected_creds[1][1:],
+ mock_get_client_manager.mock_calls[1][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[1][2]['scope'])
+ self.assertEqual(
+ expected_creds[2][1:],
+ mock_get_client_manager.mock_calls[2][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[2][2]['scope'])
+
+ def test_setup_credentials_with_role_and_multiple_scope(self):
+ expected_creds = [['my_role', 'role1', 'role2'],
+ ['project_my_role', 'role1', 'role2'],
+ ['domain_my_role', 'role1', 'role2'],
+ ['system_my_role', 'role1', 'role2']]
+
+ class SystemRoleCredentials(self.parent_test):
+ credentials = expected_creds
+
+ expected_clients = 'clients'
+ with mock.patch.object(
+ SystemRoleCredentials,
+ 'get_client_manager') as mock_get_client_manager:
+ mock_get_client_manager.return_value = expected_clients
+ sys_creds = SystemRoleCredentials()
+ sys_creds.setup_credentials()
+ self.assertTrue(hasattr(sys_creds, 'os_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_project_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_project_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_project_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_project_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_domain_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_domain_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_domain_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_domain_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_system_my_role)
+ self.assertTrue(hasattr(sys_creds, 'os_roles_system_my_role'))
+ self.assertEqual(expected_clients, sys_creds.os_roles_system_my_role)
+
+ self.assertEqual(4, mock_get_client_manager.call_count)
+ self.assertEqual(
+ expected_creds[0][1:],
+ mock_get_client_manager.mock_calls[0][2]['roles'])
+ self.assertEqual(
+ 'project', mock_get_client_manager.mock_calls[0][2]['scope'])
+ self.assertEqual(
+ expected_creds[1][1:],
+ mock_get_client_manager.mock_calls[1][2]['roles'])
+ self.assertEqual(
+ 'project', mock_get_client_manager.mock_calls[1][2]['scope'])
+ self.assertEqual(
+ expected_creds[2][1:],
+ mock_get_client_manager.mock_calls[2][2]['roles'])
+ self.assertEqual(
+ 'domain', mock_get_client_manager.mock_calls[2][2]['scope'])
+ self.assertEqual(
+ expected_creds[3][1:],
+ mock_get_client_manager.mock_calls[3][2]['roles'])
+ self.assertEqual(
+ 'system', mock_get_client_manager.mock_calls[3][2]['scope'])
+
def test_setup_class_overwritten(self):
class OverridesSetup(self.parent_test):
diff --git a/zuul.d/integrated-gate.yaml b/zuul.d/integrated-gate.yaml
index 0a9fb71..4e62d67 100644
--- a/zuul.d/integrated-gate.yaml
+++ b/zuul.d/integrated-gate.yaml
@@ -306,6 +306,12 @@
subnode:
devstack_localrc:
USE_PYTHON3: true
+ devstack_local_conf:
+ post-config:
+ "/$NEUTRON_CORE_PLUGIN_CONF":
+ ovs:
+ bridge_mappings: public:br-ex
+ resource_provider_bandwidths: br-ex:1000000:1000000
- job:
name: tempest-slow