From dcd9100d03ddadf931cf18e8701911440a40cf21 Mon Sep 17 00:00:00 2001 From: Andrea Frittoli Date: Tue, 18 Jul 2017 11:34:13 +0100 Subject: [PATCH] Remove creds providers dependency from clients We want to make cred providers a stable interface and move it to lib but to do so it must not depend on modules outside of lib or not generally stable otherwise. The last dependency left is tempest.clients, which can be replaced by its tempest.lib counterpart, tempest.lib.services.clients. While clients does not depend on configuration directly, it uses the client registry singleton. When this class is used as part of tempest, it's populated with configuration values the first time the CONF object is instantiated, so that Tempest configuration values are still honoured. When DynamicCredentialProvider is used by a consumer that does not have a Tempest config file, all the settings defined in __init__ will be honoured. To control more settings, the client registry must be populated before the Credentials Provider is used with the appropriate settings. Change-Id: I7b262607a1fa9f67e6b1d3ec2c4cf1ccffb952a6 --- tempest/common/credentials_factory.py | 12 ++++- tempest/common/dynamic_creds.py | 58 ++++++++++++++-------- tempest/common/preprov_creds.py | 13 +++-- tempest/lib/common/cred_provider.py | 8 ++- tempest/tests/common/test_dynamic_creds.py | 6 ++- tempest/tests/common/test_preprov_creds.py | 5 ++ 6 files changed, 72 insertions(+), 30 deletions(-) diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py index bf7ec99498..449c343896 100644 --- a/tempest/common/credentials_factory.py +++ b/tempest/common/credentials_factory.py @@ -40,8 +40,13 @@ to avoid circular dependencies.""" # Subset of the parameters of credential providers that depend on configuration def _get_common_provider_params(identity_version): + if identity_version == 'v3': + identity_uri = CONF.identity.uri_v3 + elif identity_version == 'v2': + identity_uri = CONF.identity.uri return { 'identity_version': identity_version, + 'identity_uri': identity_uri, 'credentials_domain': CONF.auth.default_credentials_domain_name, 'admin_role': CONF.identity.admin_role } @@ -63,6 +68,10 @@ def get_dynamic_provider_params(identity_version, admin_creds=None): _common_params = _get_common_provider_params(identity_version) admin_creds = admin_creds or get_configured_admin_credentials( fill_in=True, identity_version=identity_version) + if identity_version == 'v3': + endpoint_type = CONF.identity.v3_endpoint_type + elif identity_version == 'v2': + endpoint_type = CONF.identity.v2_admin_endpoint_type return dict(_common_params, **dict([ ('admin_creds', admin_creds), ('identity_admin_domain_scope', CONF.identity.admin_domain_scope), @@ -74,7 +83,8 @@ def get_dynamic_provider_params(identity_version, admin_creds=None): ('public_network_id', CONF.network.public_network_id), ('create_networks', (CONF.auth.create_isolated_networks and not CONF.network.shared_physical_network)), - ('resource_prefix', CONF.resources_prefix) + ('resource_prefix', CONF.resources_prefix), + ('identity_admin_endpoint_type', endpoint_type) ])) diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py index 1e040e68df..90e67b4d49 100644 --- a/tempest/common/dynamic_creds.py +++ b/tempest/common/dynamic_creds.py @@ -18,11 +18,11 @@ import netaddr from oslo_log import log as logging import six -from tempest import clients from tempest.lib.common import cred_client from tempest.lib.common import cred_provider from tempest.lib.common.utils import data_utils from tempest.lib import exceptions as lib_exc +from tempest.lib.services import clients LOG = logging.getLogger(__name__) @@ -35,7 +35,8 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): identity_admin_role='admin', extra_roles=None, neutron_available=False, create_networks=True, project_network_cidr=None, project_network_mask_bits=None, - public_network_id=None, resource_prefix=None): + public_network_id=None, resource_prefix=None, + identity_admin_endpoint_type='public', identity_uri=None): """Creates credentials dynamically for tests A credential provider that, based on an initial set of @@ -69,10 +70,14 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): :param project_network_mask_bits: The network mask bits to use for created project networks :param public_network_id: The id for the public network to use + :param identity_admin_endpoint_type: The endpoint type for identity + admin clients. Defaults to public. + :param identity_uri: Identity URI of the target cloud """ super(DynamicCredentialProvider, self).__init__( - identity_version=identity_version, admin_role=admin_role, - name=name, credentials_domain=credentials_domain, + identity_version=identity_version, identity_uri=identity_uri, + admin_role=admin_role, name=name, + credentials_domain=credentials_domain, network_resources=network_resources) self.network_resources = network_resources self._creds = {} @@ -86,6 +91,7 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): self.default_admin_creds = admin_creds self.identity_admin_domain_scope = identity_admin_domain_scope self.identity_admin_role = identity_admin_role or 'admin' + self.identity_admin_endpoint_type = identity_admin_endpoint_type self.extra_roles = extra_roles or [] (self.identity_admin_client, self.tenants_admin_client, @@ -96,7 +102,8 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): self.routers_admin_client, self.subnets_admin_client, self.ports_admin_client, - self.security_groups_admin_client) = self._get_admin_clients() + self.security_groups_admin_client) = self._get_admin_clients( + identity_admin_endpoint_type) # Domain where isolated credentials are provisioned (v3 only). # Use that of the admin account is None is configured. self.creds_domain_name = None @@ -112,32 +119,43 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): self.domains_admin_client, self.creds_domain_name) - def _get_admin_clients(self): + def _get_admin_clients(self, endpoint_type): """Returns a tuple with instances of the following admin clients (in this order): identity network """ - os = clients.Manager(self.default_admin_creds) + os = clients.ServiceClients(self.default_admin_creds, + self.identity_uri) + params = {'endpoint_type': endpoint_type} if self.identity_version == 'v2': - return (os.identity_client, os.tenants_client, os.users_client, - os.roles_client, None, - os.networks_client, os.routers_client, os.subnets_client, - os.ports_client, os.security_groups_client) + return (os.identity_v2.IdentityClient(**params), + os.identity_v2.TenantsClient(**params), + os.identity_v2.UsersClient(**params), + os.identity_v2.RolesClient(**params), None, + os.network.NetworksClient(), + os.network.RoutersClient(), + os.network.SubnetsClient(), + os.network.PortsClient(), + os.network.SecurityGroupsClient()) else: # We use a dedicated client manager for identity client in case we # need a different token scope for them. scope = 'domain' if self.identity_admin_domain_scope else 'project' - identity_os = clients.Manager(self.default_admin_creds, - scope=scope) - return (identity_os.identity_v3_client, - identity_os.projects_client, - identity_os.users_v3_client, identity_os.roles_v3_client, - identity_os.domains_client, - os.networks_client, os.routers_client, - os.subnets_client, os.ports_client, - os.security_groups_client) + identity_os = clients.ServiceClients(self.default_admin_creds, + self.identity_uri, + scope=scope) + return (identity_os.identity_v3.IdentityClient(**params), + identity_os.identity_v3.ProjectsClient(**params), + identity_os.identity_v3.UsersClient(**params), + identity_os.identity_v3.RolesClient(**params), + identity_os.identity_v3.DomainsClient(**params), + os.network.NetworksClient(), + os.network.RoutersClient(), + os.network.SubnetsClient(), + os.network.PortsClient(), + os.network.SecurityGroupsClient()) def _create_creds(self, admin=False, roles=None): """Create credentials with random name. diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py index 8053cacf30..64cabb766c 100644 --- a/tempest/common/preprov_creds.py +++ b/tempest/common/preprov_creds.py @@ -20,12 +20,12 @@ from oslo_log import log as logging import six import yaml -from tempest import clients from tempest.common import fixed_network from tempest import exceptions from tempest.lib import auth from tempest.lib.common import cred_provider from tempest.lib import exceptions as lib_exc +from tempest.lib.services import clients LOG = logging.getLogger(__name__) @@ -51,7 +51,7 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): 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): + object_storage_reseller_admin_role=None, identity_uri=None): """Credentials provider using pre-provisioned accounts This credentials provider loads the details of pre-provisioned @@ -79,10 +79,12 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): (if no domain is configured) :param object_storage_operator_role: name of the role :param object_storage_reseller_admin_role: name of the role + :param identity_uri: Identity URI of the target cloud """ super(PreProvisionedCredentialProvider, self).__init__( identity_version=identity_version, name=name, - admin_role=admin_role, credentials_domain=credentials_domain) + admin_role=admin_role, credentials_domain=credentials_domain, + identity_uri=identity_uri) self.test_accounts_file = test_accounts_file if test_accounts_file: accounts = read_accounts_yaml(self.test_accounts_file) @@ -341,8 +343,9 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): auth_url=None, fill_in=False, identity_version=self.identity_version, **creds_dict) net_creds = cred_provider.TestResources(credential) - net_clients = clients.Manager(credentials=credential) - compute_network_client = net_clients.compute_networks_client + net_clients = clients.ServiceClients(credentials=credential, + identity_uri=self.identity_uri) + compute_network_client = net_clients.compute.NetworksClient() net_name = self.hash_dict['networks'].get(hash, None) try: network = fixed_network.get_network_from_name( diff --git a/tempest/lib/common/cred_provider.py b/tempest/lib/common/cred_provider.py index 1b450ab9f5..42ed41b395 100644 --- a/tempest/lib/common/cred_provider.py +++ b/tempest/lib/common/cred_provider.py @@ -22,8 +22,9 @@ from tempest.lib import exceptions @six.add_metaclass(abc.ABCMeta) class CredentialProvider(object): - def __init__(self, identity_version, name=None, network_resources=None, - credentials_domain=None, admin_role=None): + def __init__(self, identity_version, name=None, + network_resources=None, credentials_domain=None, + admin_role=None, identity_uri=None): """A CredentialProvider supplies credentials to test classes. :param identity_version: Identity version of the credentials provided @@ -33,8 +34,11 @@ class CredentialProvider(object): credentials :param credentials_domain: Domain credentials belong to :param admin_role: Name of the role of the admin account + :param identity_uri: Identity URI of the target cloud. This *must* be + specified for anything to work. """ self.identity_version = identity_version + self.identity_uri = identity_uri self.name = name or "test_creds" self.network_resources = network_resources self.credentials_domain = credentials_domain or 'Default' diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py index c73961930f..cf131eb79a 100644 --- a/tempest/tests/common/test_dynamic_creds.py +++ b/tempest/tests/common/test_dynamic_creds.py @@ -46,7 +46,8 @@ class TestDynamicCredentialProvider(base.TestCase): fixed_params = {'name': 'test class', 'identity_version': 'v2', - 'admin_role': 'admin'} + 'admin_role': 'admin', + 'identity_uri': 'fake_uri'} token_client = v2_token_client iden_client = v2_iden_client @@ -619,7 +620,8 @@ class TestDynamicCredentialProviderV3(TestDynamicCredentialProvider): fixed_params = {'name': 'test class', 'identity_version': 'v3', - 'admin_role': 'admin'} + 'admin_role': 'admin', + 'identity_uri': 'fake_uri'} token_client = v3_token_client iden_client = v3_iden_client diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py index 414b1064fb..d894c5ed5f 100644 --- a/tempest/tests/common/test_preprov_creds.py +++ b/tempest/tests/common/test_preprov_creds.py @@ -38,6 +38,7 @@ class TestPreProvisionedCredentials(base.TestCase): fixed_params = {'name': 'test class', 'identity_version': 'v2', + 'identity_uri': 'fake_uri', 'test_accounts_file': 'fake_accounts_file', 'accounts_lock_dir': 'fake_locks_dir', 'admin_role': 'admin', @@ -91,6 +92,9 @@ class TestPreProvisionedCredentials(base.TestCase): return_value=self.test_accounts)) self.useFixture(fixtures.MockPatch( 'os.path.isfile', return_value=True)) + # NOTE(andreaf) Ensure config is loaded so service clients are + # registered in the registry before tests + config.service_client_config() def tearDown(self): super(TestPreProvisionedCredentials, self).tearDown() @@ -436,6 +440,7 @@ class TestPreProvisionedCredentialsV3(TestPreProvisionedCredentials): fixed_params = {'name': 'test class', 'identity_version': 'v3', + 'identity_uri': 'fake_uri', 'test_accounts_file': 'fake_accounts_file', 'accounts_lock_dir': 'fake_locks_dir_v3', 'admin_role': 'admin',