Merge "Move default creds to cred_provider"
diff --git a/tempest/auth.py b/tempest/auth.py
index 6a92b5f..5820893 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -440,31 +440,23 @@
datetime.datetime.utcnow()
-def get_default_credentials(credential_type, fill_in=True):
- """
- Returns configured credentials of the specified type
- based on the configured auth_version
- """
- return get_credentials(fill_in=fill_in, credential_type=credential_type)
-
-
-def get_credentials(credential_type=None, fill_in=True, **kwargs):
+def get_credentials(fill_in=True, **kwargs):
"""
Builds a credentials object based on the configured auth_version
- :param credential_type (string): requests credentials from tempest
- configuration file. Valid values are defined in
- Credentials.TYPE.
- :param kwargs (dict): take into account only if credential_type is
- not specified or None. Dict of credential key/value pairs
+ :param fill_in (boolean): obtain a token and fill in all credential
+ details provided by the identity service. When fill_in is not
+ specified, credentials are not validated. Validation can be invoked
+ by invoking ``is_valid()``
+ :param kwargs (dict): Dict of credential key/value pairs
Examples:
Returns credentials from the provided parameters:
>>> get_credentials(username='foo', password='bar')
- Returns credentials from tempest configuration:
- >>> get_credentials(credential_type='user')
+ Returns credentials including IDs:
+ >>> get_credentials(username='foo', password='bar', fill_in=True)
"""
if CONF.identity.auth_version == 'v2':
credential_class = KeystoneV2Credentials
@@ -474,10 +466,7 @@
auth_provider_class = KeystoneV3AuthProvider
else:
raise exceptions.InvalidConfiguration('Unsupported auth version')
- if credential_type is not None:
- creds = credential_class.get_default(credential_type)
- else:
- creds = credential_class(**kwargs)
+ creds = credential_class(**kwargs)
# Fill in the credentials fields that were not specified
if fill_in:
auth_provider = auth_provider_class(creds)
@@ -490,18 +479,9 @@
Set of credentials for accessing OpenStack services
ATTRIBUTES: list of valid class attributes representing credentials.
-
- TYPES: types of credentials available in the configuration file.
- For each key there's a tuple (section, prefix) to match the
- configuration options.
"""
ATTRIBUTES = []
- TYPES = {
- 'identity_admin': ('identity', 'admin'),
- 'user': ('identity', None),
- 'alt_user': ('identity', 'alt')
- }
def __init__(self, **kwargs):
"""
@@ -554,21 +534,8 @@
except AttributeError:
return default
- @classmethod
- def get_default(cls, credentials_type):
- if credentials_type not in cls.TYPES:
- raise exceptions.InvalidCredentials()
- creds = cls._get_default(credentials_type)
- if not creds.is_valid():
- msg = ("The %s credentials are incorrectly set in the config file."
- " Double check that all required values are assigned" %
- credentials_type)
- raise exceptions.InvalidConfiguration(msg)
- return creds
-
- @classmethod
- def _get_default(cls, credentials_type):
- raise NotImplementedError
+ def get_init_attributes(self):
+ return self._initial.keys()
def is_valid(self):
raise NotImplementedError
@@ -584,21 +551,8 @@
class KeystoneV2Credentials(Credentials):
- CONF_ATTRIBUTES = ['username', 'password', 'tenant_name']
- ATTRIBUTES = ['user_id', 'tenant_id']
- ATTRIBUTES.extend(CONF_ATTRIBUTES)
-
- @classmethod
- def _get_default(cls, credentials_type='user'):
- params = {}
- section, prefix = cls.TYPES[credentials_type]
- for attr in cls.CONF_ATTRIBUTES:
- _section = getattr(CONF, section)
- if prefix is None:
- params[attr] = getattr(_section, attr)
- else:
- params[attr] = getattr(_section, prefix + "_" + attr)
- return cls(**params)
+ ATTRIBUTES = ['username', 'password', 'tenant_name', 'user_id',
+ 'tenant_id']
def is_valid(self):
"""
@@ -608,16 +562,15 @@
return None not in (self.username, self.password)
-class KeystoneV3Credentials(KeystoneV2Credentials):
+class KeystoneV3Credentials(Credentials):
"""
Credentials suitable for the Keystone Identity V3 API
"""
- CONF_ATTRIBUTES = ['domain_name', 'password', 'tenant_name', 'username']
- ATTRIBUTES = ['project_domain_id', 'project_domain_name', 'project_id',
+ ATTRIBUTES = ['domain_name', 'password', 'tenant_name', 'username',
+ 'project_domain_id', 'project_domain_name', 'project_id',
'project_name', 'tenant_id', 'tenant_name', 'user_domain_id',
'user_domain_name', 'user_id']
- ATTRIBUTES.extend(CONF_ATTRIBUTES)
def __init__(self, **kwargs):
"""
diff --git a/tempest/clients.py b/tempest/clients.py
index 03928ba..cbc6571 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -15,7 +15,7 @@
import copy
-from tempest import auth
+from tempest.common import cred_provider
from tempest.common import negative_rest_client
from tempest import config
from tempest import manager
@@ -378,6 +378,7 @@
def __init__(self, interface='json', service=None):
super(AdminManager, self).__init__(
- credentials=auth.get_default_credentials('identity_admin'),
+ credentials=cred_provider.get_configured_credentials(
+ 'identity_admin'),
interface=interface,
service=service)
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 66285e4..35a1f86 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -109,9 +109,9 @@
def get_hash(self, creds):
for _hash in self.hash_dict:
- # Comparing on the attributes that are expected in the YAML
+ # Comparing on the attributes that were read from the YAML
if all([getattr(creds, k) == self.hash_dict[_hash][k] for k in
- creds.CONF_ATTRIBUTES]):
+ creds.get_init_attributes()]):
return _hash
raise AttributeError('Invalid credentials %s' % creds)
@@ -191,7 +191,8 @@
creds = self.get_creds(0)
primary_credential = auth.get_credentials(**creds)
else:
- primary_credential = auth.get_default_credentials('user')
+ primary_credential = cred_provider.get_configured_credentials(
+ 'user')
self.isolated_creds['primary'] = primary_credential
return primary_credential
@@ -202,7 +203,8 @@
creds = self.get_creds(1)
alt_credential = auth.get_credentials(**creds)
else:
- alt_credential = auth.get_default_credentials('alt_user')
+ alt_credential = cred_provider.get_configured_credentials(
+ 'alt_user')
self.isolated_creds['alt'] = alt_credential
return alt_credential
@@ -210,4 +212,5 @@
self.isolated_creds = {}
def get_admin_creds(self):
- return auth.get_default_credentials("identity_admin", fill_in=False)
+ return cred_provider.get_configured_credentials(
+ "identity_admin", fill_in=False)
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index c5be0c0..07fd03f 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -16,12 +16,55 @@
import six
+from tempest import auth
from tempest import config
+from tempest import exceptions
from tempest.openstack.common import log as logging
CONF = config.CONF
LOG = logging.getLogger(__name__)
+# Type of credentials available from configuration
+CREDENTIAL_TYPES = {
+ 'identity_admin': ('identity', 'admin'),
+ 'user': ('identity', None),
+ 'alt_user': ('identity', 'alt')
+}
+
+
+# Read credentials from configuration, builds a Credentials object
+# based on the specified or configured version
+def get_configured_credentials(credential_type, fill_in=True,
+ identity_version=None):
+ identity_version = identity_version or CONF.identity.auth_version
+ if identity_version not in ('v2', 'v3'):
+ raise exceptions.InvalidConfiguration(
+ 'Unsupported auth version: %s' % identity_version)
+ if credential_type not in CREDENTIAL_TYPES:
+ raise exceptions.InvalidCredentials()
+ conf_attributes = ['username', 'password', 'tenant_name']
+ if identity_version == 'v3':
+ conf_attributes.append('domain_name')
+ # Read the parts of credentials from config
+ params = {}
+ section, prefix = CREDENTIAL_TYPES[credential_type]
+ for attr in conf_attributes:
+ _section = getattr(CONF, section)
+ if prefix is None:
+ params[attr] = getattr(_section, attr)
+ else:
+ params[attr] = getattr(_section, prefix + "_" + attr)
+ # Build and validate credentials. We are reading configured credentials,
+ # so validate them even if fill_in is False
+ credentials = auth.get_credentials(fill_in=fill_in, **params)
+ if not fill_in:
+ if not credentials.is_valid():
+ msg = ("The %s credentials are incorrectly set in the config file."
+ " Double check that all required values are assigned" %
+ credential_type)
+ raise exceptions.InvalidConfiguration(msg)
+ return credentials
+
@six.add_metaclass(abc.ABCMeta)
class CredentialProvider(object):
diff --git a/tempest/manager.py b/tempest/manager.py
index 538b619..2b00e89 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -14,6 +14,7 @@
# under the License.
from tempest import auth
+from tempest.common import cred_provider
from tempest import config
from tempest import exceptions
@@ -39,7 +40,7 @@
"""
self.auth_version = CONF.identity.auth_version
if credentials is None:
- self.credentials = auth.get_default_credentials('user')
+ self.credentials = cred_provider.get_configured_credentials('user')
else:
self.credentials = credentials
# Check if passed or default credentials are valid
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 6b44f64..7da7b12 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -21,8 +21,8 @@
import six
from tempest_lib import exceptions as lib_exc
-from tempest import auth
from tempest import clients
+from tempest.common import cred_provider
from tempest.common import credentials
from tempest.common.utils import data_utils
from tempest.common.utils.linux import remote_client
@@ -1321,8 +1321,9 @@
@classmethod
def credentials(cls):
- admin_creds = auth.get_default_credentials('identity_admin')
- creds = auth.get_default_credentials('user')
+ admin_creds = cred_provider.get_configured_credentials(
+ 'identity_admin')
+ creds = cred_provider.get_configured_credentials('user')
admin_creds.tenant_name = creds.tenant_name
return admin_creds
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index f997a65..061f5c8 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -21,8 +21,8 @@
import testscenarios
import testtools
-from tempest import auth
from tempest import clients
+from tempest.common import cred_provider
from tempest.common.utils import misc
from tempest import config
from tempest import exceptions
@@ -101,7 +101,7 @@
def __init__(self):
os = clients.Manager(
- auth.get_default_credentials('user', fill_in=False))
+ cred_provider.get_configured_credentials('user', fill_in=False))
self.images_client = os.images_client
self.flavors_client = os.flavors_client
self.image_pattern = CONF.input_scenario.image_regex
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
new file mode 100644
index 0000000..160ecaa
--- /dev/null
+++ b/tempest/tests/common/test_cred_provider.py
@@ -0,0 +1,97 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+#
+# 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 oslo.config import cfg
+
+from tempest import auth
+from tempest.common import cred_provider
+from tempest.common import tempest_fixtures as fixtures
+from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v3.json import token_client as v3_client
+from tempest.tests import fake_identity
+# Note: eventually the auth module will move to tempest-lib, and so wil its
+# unit tests. *CredentialsTests will be imported from tempest-lib then.
+from tempest.tests import test_credentials as test_creds
+
+
+class ConfiguredV2CredentialsTests(test_creds.CredentialsTests):
+ attributes = {
+ 'username': 'fake_username',
+ 'password': 'fake_password',
+ 'tenant_name': 'fake_tenant_name'
+ }
+
+ identity_response = fake_identity._fake_v2_response
+ credentials_class = auth.KeystoneV2Credentials
+ tokenclient_class = v2_client.TokenClientJSON
+ identity_version = 'v2'
+
+ def setUp(self):
+ super(ConfiguredV2CredentialsTests, self).setUp()
+ self.stubs.Set(self.tokenclient_class, 'raw_request',
+ self.identity_response)
+
+ def _verify_credentials(self, credentials_class, filled=True,
+ identity_version=None):
+ for ctype in cred_provider.CREDENTIAL_TYPES:
+ if identity_version is None:
+ creds = cred_provider.get_configured_credentials(
+ credential_type=ctype, fill_in=filled)
+ else:
+ creds = cred_provider.get_configured_credentials(
+ credential_type=ctype, fill_in=filled,
+ identity_version=identity_version)
+ self._check(creds, credentials_class, filled)
+
+ def test_get_configured_credentials(self):
+ self.useFixture(fixtures.LockFixture('auth_version'))
+ self._verify_credentials(credentials_class=self.credentials_class)
+
+ def test_get_configured_credentials_unfilled(self):
+ self.useFixture(fixtures.LockFixture('auth_version'))
+ self._verify_credentials(credentials_class=self.credentials_class,
+ filled=False)
+
+ def test_get_configured_credentials_version(self):
+ # version specified and not loaded from config
+ self.useFixture(fixtures.LockFixture('auth_version'))
+ self._verify_credentials(credentials_class=self.credentials_class,
+ identity_version=self.identity_version)
+
+ def test_is_valid(self):
+ creds = self._get_credentials()
+ self.assertTrue(creds.is_valid())
+
+
+class ConfiguredV3CredentialsTests(ConfiguredV2CredentialsTests):
+ attributes = {
+ 'username': 'fake_username',
+ 'password': 'fake_password',
+ 'project_name': 'fake_project_name',
+ 'user_domain_name': 'fake_domain_name'
+ }
+
+ credentials_class = auth.KeystoneV3Credentials
+ identity_response = fake_identity._fake_v3_response
+ tokenclient_class = v3_client.V3TokenClientJSON
+ identity_version = 'v3'
+
+ def setUp(self):
+ super(ConfiguredV3CredentialsTests, self).setUp()
+ # Additional config items reset by cfg fixture after each test
+ cfg.CONF.set_default('auth_version', 'v3', group='identity')
+ # Identity group items
+ for prefix in ['', 'alt_', 'admin_']:
+ cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
+ group='identity')
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index 90bb8a7..785880d 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -30,11 +30,7 @@
from tempest.tests import fake_identity
-def fake_get_default_credentials(credential_type, fill_in=True):
- return fake_credentials.FakeCredentials()
-
-
-def fake_get_credentials(credential_type=None, fill_in=True, **kwargs):
+def fake_get_credentials(fill_in=True, **kwargs):
return fake_credentials.FakeCredentials()
@@ -54,8 +50,6 @@
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
self.fake_http = fake_http.fake_httplib2(return_type=200)
self.stubs.Set(auth, 'get_credentials', fake_get_credentials)
- self.stubs.Set(auth, 'get_default_credentials',
- fake_get_default_credentials)
self.auth_provider = self._auth(self.credentials)
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index 6e447d6..3d0e171 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -37,6 +37,18 @@
attributes = self.attributes
return self.credentials_class(**attributes)
+ def _check(self, credentials, credentials_class, filled):
+ # Check the right version of credentials has been returned
+ self.assertIsInstance(credentials, credentials_class)
+ # Check the id attributes are filled in
+ attributes = [x for x in credentials.ATTRIBUTES if (
+ '_id' in x and x != 'domain_id')]
+ for attr in attributes:
+ if filled:
+ self.assertIsNotNone(getattr(credentials, attr))
+ else:
+ self.assertIsNone(getattr(credentials, attr))
+
def setUp(self):
super(CredentialsTests, self).setUp()
self.useFixture(fake_config.ConfigFixture())
@@ -51,18 +63,6 @@
self._get_credentials,
attributes=dict(invalid='fake'))
- def test_default(self):
- self.useFixture(fixtures.LockFixture('auth_version'))
- for ctype in self.credentials_class.TYPES:
- self.assertRaises(NotImplementedError,
- self.credentials_class.get_default,
- credentials_type=ctype)
-
- def test_invalid_default(self):
- self.assertRaises(exceptions.InvalidCredentials,
- auth.Credentials.get_default,
- credentials_type='invalid_type')
-
def test_is_valid(self):
creds = self._get_credentials()
self.assertRaises(NotImplementedError, creds.is_valid)
@@ -84,33 +84,9 @@
self.stubs.Set(self.tokenclient_class, 'raw_request',
self.identity_response)
- def _verify_credentials(self, credentials_class, filled=True,
- creds_dict=None):
-
- def _check(credentials):
- # Check the right version of credentials has been returned
- self.assertIsInstance(credentials, credentials_class)
- # Check the id attributes are filled in
- attributes = [x for x in credentials.ATTRIBUTES if (
- '_id' in x and x != 'domain_id')]
- for attr in attributes:
- if filled:
- self.assertIsNotNone(getattr(credentials, attr))
- else:
- self.assertIsNone(getattr(credentials, attr))
-
- if creds_dict is None:
- for ctype in auth.Credentials.TYPES:
- creds = auth.get_default_credentials(credential_type=ctype,
- fill_in=filled)
- _check(creds)
- else:
- creds = auth.get_credentials(fill_in=filled, **creds_dict)
- _check(creds)
-
- def test_get_default_credentials(self):
- self.useFixture(fixtures.LockFixture('auth_version'))
- self._verify_credentials(credentials_class=self.credentials_class)
+ def _verify_credentials(self, credentials_class, creds_dict, filled=True):
+ creds = auth.get_credentials(fill_in=filled, **creds_dict)
+ self._check(creds, credentials_class, filled)
def test_get_credentials(self):
self.useFixture(fixtures.LockFixture('auth_version'))
@@ -120,8 +96,8 @@
def test_get_credentials_not_filled(self):
self.useFixture(fixtures.LockFixture('auth_version'))
self._verify_credentials(credentials_class=self.credentials_class,
- filled=False,
- creds_dict=self.attributes)
+ creds_dict=self.attributes,
+ filled=False)
def test_is_valid(self):
creds = self._get_credentials()
@@ -144,15 +120,6 @@
# credential requirements
self._test_is_not_valid('tenant_name')
- def test_default(self):
- self.useFixture(fixtures.LockFixture('auth_version'))
- for ctype in self.credentials_class.TYPES:
- creds = self.credentials_class.get_default(credentials_type=ctype)
- for attr in self.attributes.keys():
- # Default configuration values related to credentials
- # are defined as fake_* in fake_config.py
- self.assertEqual(getattr(creds, attr), 'fake_' + attr)
-
def test_reset_all_attributes(self):
creds = self._get_credentials()
initial_creds = copy.deepcopy(creds)
@@ -199,19 +166,6 @@
cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
group='identity')
- def test_default(self):
- self.useFixture(fixtures.LockFixture('auth_version'))
- for ctype in self.credentials_class.TYPES:
- creds = self.credentials_class.get_default(credentials_type=ctype)
- for attr in self.attributes.keys():
- if attr == 'project_name':
- config_value = 'fake_tenant_name'
- elif attr == 'user_domain_name':
- config_value = 'fake_domain_name'
- else:
- config_value = 'fake_' + attr
- self.assertEqual(getattr(creds, attr), config_value)
-
def test_is_not_valid(self):
# NOTE(mtreinish) For a Keystone V3 credential object a project name
# is not required to be valid, so we skip that check. See tempest.auth