Skip to content

Commit

Permalink
Rename isolated creds to dynamic creds
Browse files Browse the repository at this point in the history
Renaming the isolated_creds module to dynamic_creds module, and rename
the IsolatedCreds class to DynamicCredentialProvider in preparation
to migration to tempest-lib.

Partially implements bp tempest-library

Change-Id: I78a4884e980ef7d0103639cb3792a54c69fb7761
  • Loading branch information
afrittoli committed Oct 6, 2015
1 parent fab1370 commit 17209bb
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 177 deletions.
9 changes: 5 additions & 4 deletions HACKING.rst
Expand Up @@ -136,7 +136,7 @@ by test classes. Set-up stages are:
Tear-down is also split in a series of steps (teardown stages), which are
stacked for execution only if the corresponding setup stage had been
reached during the setup phase. Tear-down stages are:
- `clear_isolated_creds` (defined in the base test class)
- `clear_credentials` (defined in the base test class)
- `resource_cleanup`

Skipping Tests
Expand Down Expand Up @@ -206,9 +206,10 @@ Parallel Test Execution
-----------------------
Tempest by default runs its tests in parallel this creates the possibility for
interesting interactions between tests which can cause unexpected failures.
Tenant isolation provides protection from most of the potential race conditions
between tests outside the same class. But there are still a few of things to
watch out for to try to avoid issues when running your tests in parallel.
Dynamic credentials provides protection from most of the potential race
conditions between tests outside the same class. But there are still a few of
things to watch out for to try to avoid issues when running your tests in
parallel.

- Resources outside of a tenant scope still have the potential to conflict. This
is a larger concern for the admin tests since most resources and actions that
Expand Down
54 changes: 28 additions & 26 deletions doc/source/configuration.rst
Expand Up @@ -63,47 +63,49 @@ Credential Provider Mechanisms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Tempest currently also has 3 different internal methods for providing
authentication to tests. Tenant isolation, locking test accounts, and
authentication to tests. Dynamic credentials, locking test accounts, and
non-locking test accounts. Depending on which one is in use the configuration
of tempest is slightly different.

Tenant Isolation
""""""""""""""""
Tenant isolation was originally create to enable running tempest in parallel.
Dynamic Credentials
"""""""""""""""""""
Dynamic Credentials (formerly known as Tenant isolation) was originally created
to enable running tempest in parallel.
For each test class it creates a unique set of user credentials to use for the
tests in the class. It can create up to 3 sets of username, password, and
tenant/project names for a primary user, an admin user, and an alternate user.
To enable and use tenant isolation you only need to configure 2 things:
To enable and use dynamic credentials you only need to configure 2 things:

#. A set of admin credentials with permissions to create users and
tenants/projects. This is specified in the auth section with the
admin_username, admin_tenant_name, admin_domain_name, and admin_password
admin_username, admin_tenant_name, admin_domain_name and admin_password
options
#. To enable tenant_isolation in the auth section with the
allow_tenant_isolation option.
#. To enable dynamic_creds in the auth section with the
use_dynamic_credentials option.

This is also the currently the default credential provider enabled by tempest,
due to it's common use and ease of configuration.

It is worth pointing out that depending on your cloud configuration you might
need to assign a role to each of the users created Tempest's tenant isolation.
need to assign a role to each of the users created by Tempest's dynamic
credentials.
This can be set using the *tempest_roles* option. It takes in a list of role
names each of which will be assigned to each of the users created by tenant
isolation. This option will not have any effect when set and tempest is not
configured to use tenant isolation.
names each of which will be assigned to each of the users created by dynamic
credentials. This option will not have any effect when set and tempest is not
configured to use dynamic credentials.


Locking Test Accounts (aka accounts.yaml or accounts file)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
For a long time using tenant isolation was the only method available if you
For a long time using dynamic credentials was the only method available if you
wanted to enable parallel execution of tempest tests. However this was
insufficient for certain use cases because of the admin credentials requirement
to create the credential sets on demand. To get around that the accounts.yaml
file was introduced and with that a new internal credential provider to enable
using the list of credentials instead of creating them on demand. With locking
test accounts each test class will reserve a set of credentials from the
accounts.yaml before executing any of its tests so that each class is isolated
like in tenant isolation.
like with dynamic credentials.

To enable and use locking test accounts you need do a few things:

Expand All @@ -117,7 +119,7 @@ To enable and use locking test accounts you need do a few things:
#. Provide tempest with the location of your accounts.yaml file with the
test_accounts_file option in the auth section

#. Set allow_tenant_isolation = False in the auth group
#. Set use_dynamic_credentials = False in the auth group

It is worth pointing out that each set of credentials in the accounts.yaml
should have a unique tenant. This is required to provide proper isolation
Expand Down Expand Up @@ -149,7 +151,7 @@ options in the identity section:

And in the auth section:

#. allow_tenant_isolation = False
#. use_dynamic_credentials = False
#. comment out 'test_accounts_file' or keep it as empty

It only makes sense to use it if parallel execution isn't needed, since tempest
Expand Down Expand Up @@ -295,28 +297,28 @@ fixed network name is provided it will serve as a fallback in case of a
misconfiguration or a missing network in the accounts file.


With Tenant Isolation
"""""""""""""""""""""
With tenant isolation enabled and using nova-network then nothing changes. Your
only option for configuration is to either set a fixed network name or not.
With Dynamic Credentials
""""""""""""""""""""""""
With dynamic credentials enabled and using nova-network then nothing changes.
Your only option for configuration is to either set a fixed network name or not.
However, in most cases it shouldn't matter because nova-network should have no
problem booting a server with multiple networks. If this is not the case for
your cloud then using an accounts file is recommended because it provides the
necessary flexibility to describe your configuration. Tenant isolation is not
necessary flexibility to describe your configuration. Dynamic credentials is not
able to dynamically allocate things as necessary if neutron is not enabled.

With neutron and tenant isolation enabled there should not be any additional
With neutron and dynamic credentials enabled there should not be any additional
configuration necessary to enable Tempest to create servers with working
networking, assuming you have properly configured the network section to work
for your cloud. Tempest will dynamically create the neutron resources necessary
to enable using servers with that network. Also, just as with the accounts
file, if you specify a fixed network name while using neutron and tenant
isolation it will enable running tests which require a static network and it
file, if you specify a fixed network name while using neutron and dynamic
credentials it will enable running tests which require a static network and it
will additionally be used as a fallback for server creation. However, unlike
accounts.yaml this should never be triggered.

However, there is an option *create_isolated_networks* to disable tenant
isolation's automatic provisioning of network resources. If this option is
However, there is an option *create_isolated_networks* to disable dynamic
credentials's automatic provisioning of network resources. If this option is
used you will have to either rely on there only being a single/default network
available for the server creation, or use *fixed_network_name* to inform
Tempest which network to use.
Expand Down
2 changes: 1 addition & 1 deletion tempest/api/volume/admin/test_volume_quotas_negative.py
Expand Up @@ -35,7 +35,7 @@ def resource_setup(cls):
'volumes': 1, 'snapshots': 1}

# NOTE(gfidente): no need to restore original quota set
# after the tests as they only work with tenant isolation.
# after the tests as they only work with dynamic credentials.
cls.quotas_client.update_quota_set(
cls.demo_tenant_id,
**cls.shared_quota_set)
Expand Down
4 changes: 2 additions & 2 deletions tempest/cmd/verify_tempest_config.py
Expand Up @@ -348,7 +348,7 @@ def main():
CONF_PARSER = moves.configparser.SafeConfigParser()
CONF_PARSER.optionxform = str
CONF_PARSER.readfp(conf_file)
icreds = credentials.get_isolated_credentials('verify_tempest_config')
icreds = credentials.get_credentials_provider('verify_tempest_config')
try:
os = clients.Manager(icreds.get_primary_creds())
services = check_service_availability(os, update)
Expand All @@ -370,7 +370,7 @@ def main():
CONF_PARSER.write(outfile)
outfile.close()
finally:
icreds.clear_isolated_creds()
icreds.clear_creds()


if __name__ == "__main__":
Expand Down
54 changes: 27 additions & 27 deletions tempest/common/accounts.py
Expand Up @@ -51,7 +51,7 @@ def __init__(self, identity_version=None, name=None):
self.hash_dict = self.get_hash_dict(accounts)
self.accounts_dir = os.path.join(lockutils.get_lock_path(CONF),
'test_accounts')
self.isolated_creds = {}
self._creds = {}

@classmethod
def _append_role(cls, role, account_hash, hash_dict):
Expand Down Expand Up @@ -230,38 +230,38 @@ def remove_credentials(self, creds):
LOG.info("%s returned allocated creds:\n%s" % (self.name, clean_creds))

def get_primary_creds(self):
if self.isolated_creds.get('primary'):
return self.isolated_creds.get('primary')
if self._creds.get('primary'):
return self._creds.get('primary')
net_creds = self._get_creds()
self.isolated_creds['primary'] = net_creds
self._creds['primary'] = net_creds
return net_creds

def get_alt_creds(self):
if self.isolated_creds.get('alt'):
return self.isolated_creds.get('alt')
if self._creds.get('alt'):
return self._creds.get('alt')
net_creds = self._get_creds()
self.isolated_creds['alt'] = net_creds
self._creds['alt'] = net_creds
return net_creds

def get_creds_by_roles(self, roles, force_new=False):
roles = list(set(roles))
exist_creds = self.isolated_creds.get(six.text_type(roles).encode(
exist_creds = self._creds.get(six.text_type(roles).encode(
'utf-8'), None)
# The force kwarg is used to allocate an additional set of creds with
# the same role list. The index used for the previously allocation
# in the isolated_creds dict will be moved.
# in the preprov_creds dict will be moved.
if exist_creds and not force_new:
return exist_creds
elif exist_creds and force_new:
new_index = six.text_type(roles).encode('utf-8') + '-' + \
six.text_type(len(self.isolated_creds)).encode('utf-8')
self.isolated_creds[new_index] = exist_creds
six.text_type(len(self._creds)).encode('utf-8')
self._creds[new_index] = exist_creds
net_creds = self._get_creds(roles=roles)
self.isolated_creds[six.text_type(roles).encode('utf-8')] = net_creds
self._creds[six.text_type(roles).encode('utf-8')] = net_creds
return net_creds

def clear_isolated_creds(self):
for creds in self.isolated_creds.values():
def clear_creds(self):
for creds in self._creds.values():
self.remove_credentials(creds)

def get_admin_creds(self):
Expand Down Expand Up @@ -320,36 +320,36 @@ def is_multi_tenant(self):
return self._unique_creds('tenant_id')

def get_primary_creds(self):
if self.isolated_creds.get('primary'):
return self.isolated_creds.get('primary')
if self._creds.get('primary'):
return self._creds.get('primary')
primary_credential = cred_provider.get_configured_credentials(
credential_type='user', identity_version=self.identity_version)
self.isolated_creds['primary'] = cred_provider.TestResources(
self._creds['primary'] = cred_provider.TestResources(
primary_credential)
return self.isolated_creds['primary']
return self._creds['primary']

def get_alt_creds(self):
if self.isolated_creds.get('alt'):
return self.isolated_creds.get('alt')
if self._creds.get('alt'):
return self._creds.get('alt')
alt_credential = cred_provider.get_configured_credentials(
credential_type='alt_user',
identity_version=self.identity_version)
self.isolated_creds['alt'] = cred_provider.TestResources(
self._creds['alt'] = cred_provider.TestResources(
alt_credential)
return self.isolated_creds['alt']
return self._creds['alt']

def clear_isolated_creds(self):
self.isolated_creds = {}
def clear_creds(self):
self._creds = {}

def get_admin_creds(self):
creds = cred_provider.get_configured_credentials(
"identity_admin", fill_in=False)
self.isolated_creds['admin'] = cred_provider.TestResources(creds)
return self.isolated_creds['admin']
self._creds['admin'] = cred_provider.TestResources(creds)
return self._creds['admin']

def get_creds_by_roles(self, roles, force_new=False):
msg = "Credentials being specified through the config file can not be"\
" used with tests that specify using credentials by roles. "\
"Either exclude/skip the tests doing this or use either an "\
"test_accounts_file or tenant isolation."
"test_accounts_file or dynamic credentials."
raise exceptions.InvalidConfiguration(msg)
2 changes: 1 addition & 1 deletion tempest/common/cred_provider.py
Expand Up @@ -128,7 +128,7 @@ def get_alt_creds(self):
return

@abc.abstractmethod
def clear_isolated_creds(self):
def clear_creds(self):
return

@abc.abstractmethod
Expand Down
18 changes: 9 additions & 9 deletions tempest/common/credentials.py
Expand Up @@ -15,7 +15,7 @@

from tempest.common import accounts
from tempest.common import cred_provider
from tempest.common import isolated_creds
from tempest.common import dynamic_creds
from tempest import config
from tempest import exceptions

Expand All @@ -25,15 +25,15 @@
# Return the right implementation of CredentialProvider based on config
# Dropping interface and password, as they are never used anyways
# TODO(andreaf) Drop them from the CredentialsProvider interface completely
def get_isolated_credentials(name, network_resources=None,
def get_credentials_provider(name, network_resources=None,
force_tenant_isolation=False,
identity_version=None):
# If a test requires a new account to work, it can have it via forcing
# tenant isolation. A new account will be produced only for that test.
# dynamic credentials. A new account will be produced only for that test.
# In case admin credentials are not available for the account creation,
# the test should be skipped else it would fail.
if CONF.auth.allow_tenant_isolation or force_tenant_isolation:
return isolated_creds.IsolatedCreds(
if CONF.auth.use_dynamic_credentials or force_tenant_isolation:
return dynamic_creds.DynamicCredentialProvider(
name=name,
network_resources=network_resources,
identity_version=identity_version)
Expand All @@ -53,8 +53,8 @@ def get_isolated_credentials(name, network_resources=None,
# creds area vailable.
def is_admin_available():
is_admin = True
# If tenant isolation is enabled admin will be available
if CONF.auth.allow_tenant_isolation:
# If dynamic credentials is enabled admin will be available
if CONF.auth.use_dynamic_credentials:
return is_admin
# Check whether test accounts file has the admin specified or not
elif (CONF.auth.test_accounts_file and
Expand All @@ -75,8 +75,8 @@ def is_admin_available():
# are available so we can do a single call from skip_checks if alt
# creds area vailable.
def is_alt_available():
# If tenant isolation is enabled admin will be available
if CONF.auth.allow_tenant_isolation:
# If dynamic credentials is enabled admin will be available
if CONF.auth.use_dynamic_credentials:
return True
# Check whether test accounts file has the admin specified or not
if (CONF.auth.test_accounts_file and
Expand Down

0 comments on commit 17209bb

Please sign in to comment.