Remove preprov provider dependencies from CONF
This commit removes the last dependencie of the preprov
provider from CONF. The required configuration is passed
now as parameters at init time.
As the number of parameter grows, and many of them are taken from
configuration, adding dicts with parameters that can be used
when instantiating the credentials providers.
Depends-on: I0ca0b96fc618ffe60851984a9c6d46b0507878d4
Partially-implements: bp tempest-library
Change-Id: I945994580ce9a29f6fbf67183e5da4b100542386
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 486b7fd..3d330db 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -13,6 +13,7 @@
import os
+from oslo_concurrency import lockutils
from oslo_log import log as logging
from tempest_lib import auth
@@ -42,6 +43,29 @@
# === Credential Providers
+# Subset of the parameters of credential providers that depend on configuration
+def _get_common_provider_params():
+ return {
+ 'credentials_domain': CONF.auth.default_credentials_domain_name,
+ 'admin_role': CONF.identity.admin_role
+ }
+
+
+def _get_dynamic_provider_params():
+ return _get_common_provider_params()
+
+
+def _get_preprov_provider_params():
+ _common_params = _get_common_provider_params()
+ reseller_admin_role = CONF.object_storage.reseller_admin_role
+ return dict(_common_params, **dict([
+ ('accounts_lock_dir', lockutils.get_lock_path(CONF)),
+ ('test_accounts_file', CONF.auth.test_accounts_file),
+ ('object_storage_operator_role', CONF.object_storage.operator_role),
+ ('object_storage_reseller_admin_role', reseller_admin_role)
+ ]))
+
+
class LegacyCredentialProvider(cred_provider.CredentialProvider):
def __init__(self, identity_version):
@@ -143,17 +167,15 @@
name=name,
network_resources=network_resources,
identity_version=identity_version,
- credentials_domain=CONF.auth.default_credentials_domain_name,
- admin_role=CONF.identity.admin_role,
- admin_creds=admin_creds)
+ admin_creds=admin_creds,
+ **_get_dynamic_provider_params())
else:
if (CONF.auth.test_accounts_file and
os.path.isfile(CONF.auth.test_accounts_file)):
# Most params are not relevant for pre-created accounts
return preprov_creds.PreProvisionedCredentialProvider(
name=name, identity_version=identity_version,
- credentials_domain=CONF.auth.default_credentials_domain_name,
- admin_role=CONF.identity.admin_role)
+ **_get_preprov_provider_params())
else:
# Dynamic credentials are disabled, and the account file is not
# defined - we fall back on credentials configured in tempest.conf
@@ -175,7 +197,7 @@
os.path.isfile(CONF.auth.test_accounts_file)):
check_accounts = preprov_creds.PreProvisionedCredentialProvider(
identity_version=identity_version, name='check_admin',
- admin_role=CONF.identity.admin_role)
+ **_get_preprov_provider_params())
if not check_accounts.admin_available():
is_admin = False
else:
@@ -201,7 +223,7 @@
os.path.isfile(CONF.auth.test_accounts_file)):
check_accounts = preprov_creds.PreProvisionedCredentialProvider(
identity_version=identity_version, name='check_alt',
- admin_role=CONF.identity.admin_role)
+ **_get_preprov_provider_params())
else:
check_accounts = LegacyCredentialProvider(identity_version)
try:
diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py
index f711302..5b81148 100644
--- a/tempest/common/preprov_creds.py
+++ b/tempest/common/preprov_creds.py
@@ -19,15 +19,14 @@
from oslo_log import log as logging
import six
from tempest_lib import auth
+from tempest_lib import exceptions as lib_exc
import yaml
from tempest import clients
from tempest.common import cred_provider
from tempest.common import fixed_network
-from tempest import config
from tempest import exceptions
-CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -39,21 +38,52 @@
class PreProvisionedCredentialProvider(cred_provider.CredentialProvider):
- def __init__(self, identity_version, name=None, credentials_domain=None,
- admin_role=None):
+ def __init__(self, identity_version, test_accounts_file,
+ accounts_lock_dir, name=None, credentials_domain=None,
+ admin_role=None, object_storage_operator_role=None,
+ object_storage_reseller_admin_role=None):
+ """Credentials provider using pre-provisioned accounts
+
+ This credentials provider loads the details of pre-provisioned
+ accounts from a YAML file, in the format specified by
+ `etc/accounts.yaml.sample`. It locks accounts while in use, using the
+ external locking mechanism, allowing for multiple python processes
+ to share a single account file, and thus running tests in parallel.
+
+ The accounts_lock_dir must be generated using `lockutils.get_lock_path`
+ from the oslo.concurrency library. For instance:
+
+ accounts_lock_dir = os.path.join(lockutils.get_lock_path(CONF),
+ 'test_accounts')
+
+ Role names for object storage are optional as long as the
+ `operator` and `reseller_admin` credential types are not used in the
+ accounts file.
+
+ :param identity_version: identity version of the credentials
+ :param admin_role: name of the admin role
+ :param test_accounts_file: path to the accounts YAML file
+ :param accounts_lock_dir: the directory for external locking
+ :param name: name of the hash file (optional)
+ :param credentials_domain: name of the domain credentials belong to
+ (if no domain is configured)
+ :param object_storage_operator_role: name of the role
+ :param object_storage_reseller_admin_role: name of the role
+ """
super(PreProvisionedCredentialProvider, self).__init__(
identity_version=identity_version, name=name,
- credentials_domain=credentials_domain, admin_role=admin_role)
- if (CONF.auth.test_accounts_file and
- os.path.isfile(CONF.auth.test_accounts_file)):
- accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
+ admin_role=admin_role, credentials_domain=credentials_domain)
+ self.test_accounts_file = test_accounts_file
+ if test_accounts_file and os.path.isfile(test_accounts_file):
+ accounts = read_accounts_yaml(self.test_accounts_file)
self.use_default_creds = False
else:
accounts = {}
self.use_default_creds = True
- self.hash_dict = self.get_hash_dict(accounts, admin_role)
- self.accounts_dir = os.path.join(lockutils.get_lock_path(CONF),
- 'test_accounts')
+ self.hash_dict = self.get_hash_dict(
+ accounts, admin_role, object_storage_operator_role,
+ object_storage_reseller_admin_role)
+ self.accounts_dir = accounts_lock_dir
self._creds = {}
@classmethod
@@ -65,7 +95,9 @@
return hash_dict
@classmethod
- def get_hash_dict(cls, accounts, admin_role):
+ def get_hash_dict(cls, accounts, admin_role,
+ object_storage_operator_role=None,
+ object_storage_reseller_admin_role=None):
hash_dict = {'roles': {}, 'creds': {}, 'networks': {}}
# Loop over the accounts read from the yaml file
for account in accounts:
@@ -92,14 +124,24 @@
hash_dict = cls._append_role(admin_role, temp_hash_key,
hash_dict)
elif type == 'operator':
- hash_dict = cls._append_role(
- CONF.object_storage.operator_role, temp_hash_key,
- hash_dict)
+ if object_storage_operator_role:
+ hash_dict = cls._append_role(
+ object_storage_operator_role, temp_hash_key,
+ hash_dict)
+ else:
+ msg = ("Type 'operator' configured, but no "
+ "object_storage_operator_role specified")
+ raise lib_exc.InvalidCredentials(msg)
elif type == 'reseller_admin':
- hash_dict = cls._append_role(
- CONF.object_storage.reseller_admin_role,
- temp_hash_key,
- hash_dict)
+ if object_storage_reseller_admin_role:
+ hash_dict = cls._append_role(
+ object_storage_reseller_admin_role,
+ temp_hash_key,
+ hash_dict)
+ else:
+ msg = ("Type 'reseller_admin' configured, but no "
+ "object_storage_reseller_admin_role specified")
+ raise lib_exc.InvalidCredentials(msg)
# Populate the network subdict
for resource in resources:
if resource == 'network':
@@ -112,8 +154,8 @@
def is_multi_user(self):
# Default credentials is not a valid option with locking Account
if self.use_default_creds:
- raise exceptions.InvalidConfiguration(
- "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
+ raise lib_exc.InvalidCredentials(
+ "Account file %s doesn't exist" % self.test_accounts_file)
else:
return len(self.hash_dict['creds']) > 1
@@ -149,7 +191,7 @@
names.append(fd.read())
msg = ('Insufficient number of users provided. %s have allocated all '
'the credentials for this allocation request' % ','.join(names))
- raise exceptions.InvalidConfiguration(msg)
+ raise lib_exc.InvalidCredentials(msg)
def _get_match_hash_list(self, roles=None):
hashes = []
@@ -159,7 +201,7 @@
for role in roles:
temp_hashes = self.hash_dict['roles'].get(role, None)
if not temp_hashes:
- raise exceptions.InvalidConfiguration(
+ raise lib_exc.InvalidCredentials(
"No credentials with role: %s specified in the "
"accounts ""file" % role)
hashes.append(temp_hashes)
@@ -191,8 +233,8 @@
def _get_creds(self, roles=None):
if self.use_default_creds:
- raise exceptions.InvalidConfiguration(
- "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
+ raise lib_exc.InvalidCredentials(
+ "Account file %s doesn't exist" % self.test_accounts_file)
useable_hashes = self._get_match_hash_list(roles)
free_hash = self._get_free_hash(useable_hashes)
clean_creds = self._sanitize_creds(
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index 36dd976..2e0f82a 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -17,17 +17,17 @@
import mock
from oslo_concurrency.fixture import lockutils as lockutils_fixtures
-from oslo_concurrency import lockutils
from oslo_config import cfg
from oslotest import mockpatch
+import shutil
import six
from tempest_lib import auth
+from tempest_lib import exceptions as lib_exc
from tempest_lib.services.identity.v2 import token_client
from tempest.common import cred_provider
from tempest.common import preprov_creds
from tempest import config
-from tempest import exceptions
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests import fake_http
@@ -38,7 +38,11 @@
fixed_params = {'name': 'test class',
'identity_version': 'v2',
- 'admin_role': 'admin'}
+ 'test_accounts_file': 'fake_accounts_file',
+ 'accounts_lock_dir': 'fake_locks_dir',
+ 'admin_role': 'admin',
+ 'object_storage_operator_role': 'operator',
+ 'object_storage_reseller_admin_role': 'reseller'}
def setUp(self):
super(TestPreProvisionedCredentials, self).setUp()
@@ -77,9 +81,13 @@
self.accounts_mock = self.useFixture(mockpatch.Patch(
'tempest.common.preprov_creds.read_accounts_yaml',
return_value=self.test_accounts))
- cfg.CONF.set_default('test_accounts_file', 'fake_path', group='auth')
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
+ def tearDown(self):
+ super(TestPreProvisionedCredentials, self).tearDown()
+ shutil.rmtree(self.fixed_params['accounts_lock_dir'],
+ ignore_errors=True)
+
def _get_hash_list(self, accounts_list):
hash_list = []
for account in accounts_list:
@@ -147,11 +155,10 @@
with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
- lock_path = os.path.join(lockutils.get_lock_path(
- preprov_creds.CONF), 'test_accounts', hash_list[0])
+ lock_path = os.path.join(self.fixed_params['accounts_lock_dir'],
+ hash_list[0])
open_mock.assert_called_once_with(lock_path, 'w')
- mkdir_path = os.path.join(
- preprov_creds.CONF.oslo_concurrency.lock_path, 'test_accounts')
+ mkdir_path = os.path.join(self.fixed_params['accounts_lock_dir'])
mkdir_mock.mock.assert_called_once_with(mkdir_path)
@mock.patch('oslo_concurrency.lockutils.lock')
@@ -165,7 +172,7 @@
**self.fixed_params)
with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True):
- self.assertRaises(exceptions.InvalidConfiguration,
+ self.assertRaises(lib_exc.InvalidCredentials,
test_account_class._get_free_hash, hash_list)
@mock.patch('oslo_concurrency.lockutils.lock')
@@ -187,9 +194,8 @@
with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
- lock_path = os.path.join(
- lockutils.get_lock_path(preprov_creds.CONF),
- 'test_accounts', hash_list[3])
+ lock_path = os.path.join(self.fixed_params['accounts_lock_dir'],
+ hash_list[3])
open_mock.assert_has_calls([mock.call(lock_path, 'w')])
@mock.patch('oslo_concurrency.lockutils.lock')
@@ -204,11 +210,9 @@
remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
test_account_class.remove_hash(hash_list[2])
- hash_path = os.path.join(lockutils.get_lock_path(preprov_creds.CONF),
- 'test_accounts',
+ hash_path = os.path.join(self.fixed_params['accounts_lock_dir'],
hash_list[2])
- lock_path = os.path.join(preprov_creds.CONF.oslo_concurrency.lock_path,
- 'test_accounts')
+ lock_path = self.fixed_params['accounts_lock_dir']
remove_mock.mock.assert_called_once_with(hash_path)
rmdir_mock.mock.assert_called_once_with(lock_path)
@@ -225,8 +229,7 @@
remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
test_account_class.remove_hash(hash_list[2])
- hash_path = os.path.join(lockutils.get_lock_path(preprov_creds.CONF),
- 'test_accounts',
+ hash_path = os.path.join(self.fixed_params['accounts_lock_dir'],
hash_list[2])
remove_mock.mock.assert_called_once_with(hash_path)
rmdir_mock.mock.assert_not_called()