blob: bf8d30ef7adec0acda50ab67cec3dc085e8d75d6 [file] [log] [blame]
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +01001# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
Andrea Frittoli (andreaf)848e3482015-10-12 14:17:21 +010014from oslo_concurrency import lockutils
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010015
16from tempest import clients
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010017from tempest.common import dynamic_creds
18from tempest.common import preprov_creds
19from tempest import config
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050020from tempest.lib import auth
Matthew Treinish4217a702016-10-07 17:27:11 -040021from tempest.lib import exceptions
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010022
23CONF = config.CONF
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010024
25
26"""This module provides factories of credential and credential providers
27
Andrea Frittoli (andreaf)1370baf2016-04-29 14:26:22 -050028Credentials providers and clients are (going to be) part of tempest.lib,
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010029and so they may not hold any dependency to tempest configuration.
30
31Methods in this module collect the relevant configuration details and pass
32them to credentials providers and clients, so that test can have easy
33access to these features.
34
35Client managers with hard-coded configured credentials are also moved here,
36to avoid circular dependencies."""
37
38# === Credential Providers
39
40
Andrea Frittoli (andreaf)848e3482015-10-12 14:17:21 +010041# Subset of the parameters of credential providers that depend on configuration
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010042def get_common_provider_params():
Andrea Frittoli (andreaf)848e3482015-10-12 14:17:21 +010043 return {
44 'credentials_domain': CONF.auth.default_credentials_domain_name,
45 'admin_role': CONF.identity.admin_role
46 }
47
48
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010049def get_dynamic_provider_params():
50 return get_common_provider_params()
Andrea Frittoli (andreaf)848e3482015-10-12 14:17:21 +010051
52
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010053def get_preprov_provider_params():
54 _common_params = get_common_provider_params()
Andrea Frittoli (andreaf)848e3482015-10-12 14:17:21 +010055 reseller_admin_role = CONF.object_storage.reseller_admin_role
56 return dict(_common_params, **dict([
57 ('accounts_lock_dir', lockutils.get_lock_path(CONF)),
58 ('test_accounts_file', CONF.auth.test_accounts_file),
59 ('object_storage_operator_role', CONF.object_storage.operator_role),
60 ('object_storage_reseller_admin_role', reseller_admin_role)
61 ]))
62
63
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010064# Return the right implementation of CredentialProvider based on config
65# Dropping interface and password, as they are never used anyways
66# TODO(andreaf) Drop them from the CredentialsProvider interface completely
67def get_credentials_provider(name, network_resources=None,
68 force_tenant_isolation=False,
69 identity_version=None):
70 # If a test requires a new account to work, it can have it via forcing
71 # dynamic credentials. A new account will be produced only for that test.
72 # In case admin credentials are not available for the account creation,
73 # the test should be skipped else it would fail.
74 identity_version = identity_version or CONF.identity.auth_version
75 if CONF.auth.use_dynamic_credentials or force_tenant_isolation:
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +010076 admin_creds = get_configured_admin_credentials(
77 fill_in=True, identity_version=identity_version)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010078 return dynamic_creds.DynamicCredentialProvider(
79 name=name,
80 network_resources=network_resources,
81 identity_version=identity_version,
Andrea Frittoli (andreaf)848e3482015-10-12 14:17:21 +010082 admin_creds=admin_creds,
Matthew Treinish75abbcf2016-10-07 16:19:12 -040083 identity_admin_domain_scope=CONF.identity.admin_domain_scope,
84 identity_admin_role=CONF.identity.admin_role,
85 extra_roles=CONF.auth.tempest_roles,
86 neutron_available=CONF.service_available.neutron,
87 project_network_cidr=CONF.network.project_network_cidr,
88 project_network_mask_bits=CONF.network.project_network_mask_bits,
89 public_network_id=CONF.network.public_network_id,
90 create_networks=(CONF.auth.create_isolated_networks and not
Thiago Paiva66cded22016-08-15 14:55:58 -030091 CONF.network.shared_physical_network),
Matthew Treinish0650aed2016-10-07 16:36:46 -040092 resource_prefix=CONF.resources_prefix,
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010093 **get_dynamic_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010094 else:
Matthew Treinishd89db1b2015-12-16 17:29:14 -050095 if CONF.auth.test_accounts_file:
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010096 # Most params are not relevant for pre-created accounts
97 return preprov_creds.PreProvisionedCredentialProvider(
98 name=name, identity_version=identity_version,
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010099 **get_preprov_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100100 else:
Matthew Treinish40847ac2016-01-04 13:16:03 -0500101 raise exceptions.InvalidConfiguration(
102 'A valid credential provider is needed')
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100103
104
105# We want a helper function here to check and see if admin credentials
106# are available so we can do a single call from skip_checks if admin
107# creds area available.
108# This depends on identity_version as there may be admin credentials
109# available for v2 but not for v3.
110def is_admin_available(identity_version):
111 is_admin = True
112 # If dynamic credentials is enabled admin will be available
113 if CONF.auth.use_dynamic_credentials:
114 return is_admin
115 # Check whether test accounts file has the admin specified or not
Matthew Treinishd89db1b2015-12-16 17:29:14 -0500116 elif CONF.auth.test_accounts_file:
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100117 check_accounts = preprov_creds.PreProvisionedCredentialProvider(
118 identity_version=identity_version, name='check_admin',
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +0100119 **get_preprov_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100120 if not check_accounts.admin_available():
121 is_admin = False
122 else:
123 try:
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100124 get_configured_admin_credentials(fill_in=False,
125 identity_version=identity_version)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100126 except exceptions.InvalidConfiguration:
127 is_admin = False
128 return is_admin
129
130
131# We want a helper function here to check and see if alt credentials
132# are available so we can do a single call from skip_checks if alt
133# creds area available.
134# This depends on identity_version as there may be alt credentials
135# available for v2 but not for v3.
136def is_alt_available(identity_version):
137 # If dynamic credentials is enabled alt will be available
138 if CONF.auth.use_dynamic_credentials:
139 return True
140 # Check whether test accounts file has the admin specified or not
Matthew Treinishd89db1b2015-12-16 17:29:14 -0500141 if CONF.auth.test_accounts_file:
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100142 check_accounts = preprov_creds.PreProvisionedCredentialProvider(
143 identity_version=identity_version, name='check_alt',
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +0100144 **get_preprov_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100145 else:
Matthew Treinish40847ac2016-01-04 13:16:03 -0500146 raise exceptions.InvalidConfiguration(
147 'A valid credential provider is needed')
148
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100149 try:
150 if not check_accounts.is_multi_user():
151 return False
152 else:
153 return True
154 except exceptions.InvalidConfiguration:
155 return False
156
157# === Credentials
158
159# Type of credentials available from configuration
160CREDENTIAL_TYPES = {
161 'identity_admin': ('auth', 'admin'),
162 'user': ('identity', None),
163 'alt_user': ('identity', 'alt')
164}
165
166DEFAULT_PARAMS = {
167 'disable_ssl_certificate_validation':
Daniel Melladocad3f3d2016-08-19 14:17:16 +0000168 CONF.identity.disable_ssl_certificate_validation,
169 'ca_certs': CONF.identity.ca_certificates_file,
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100170 'trace_requests': CONF.debug.trace_requests
171}
172
173
174# Read credentials from configuration, builds a Credentials object
175# based on the specified or configured version
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100176def get_configured_admin_credentials(fill_in=True, identity_version=None):
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100177 identity_version = identity_version or CONF.identity.auth_version
178
179 if identity_version not in ('v2', 'v3'):
180 raise exceptions.InvalidConfiguration(
181 'Unsupported auth version: %s' % identity_version)
182
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100183 conf_attributes = ['username', 'password',
184 'project_name']
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100185
186 if identity_version == 'v3':
187 conf_attributes.append('domain_name')
188 # Read the parts of credentials from config
189 params = DEFAULT_PARAMS.copy()
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100190 for attr in conf_attributes:
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100191 params[attr] = getattr(CONF.auth, 'admin_' + attr)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100192 # Build and validate credentials. We are reading configured credentials,
193 # so validate them even if fill_in is False
194 credentials = get_credentials(fill_in=fill_in,
195 identity_version=identity_version, **params)
196 if not fill_in:
197 if not credentials.is_valid():
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100198 msg = ("The admin credentials are incorrectly set in the config "
199 "file for identity version %s. Double check that all "
200 "required values are assigned.")
201 raise exceptions.InvalidConfiguration(msg % identity_version)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100202 return credentials
203
204
205# Wrapper around auth.get_credentials to use the configured identity version
Andrea Frittoli (andreaf)100d18d2016-05-05 23:34:52 +0100206# if none is specified
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100207def get_credentials(fill_in=True, identity_version=None, **kwargs):
208 params = dict(DEFAULT_PARAMS, **kwargs)
209 identity_version = identity_version or CONF.identity.auth_version
210 # In case of "v3" add the domain from config if not specified
Andrea Frittoli (andreaf)100d18d2016-05-05 23:34:52 +0100211 # To honour the "default_credentials_domain_name", if not domain
212 # field is specified at all, add it the credential dict.
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100213 if identity_version == 'v3':
214 domain_fields = set(x for x in auth.KeystoneV3Credentials.ATTRIBUTES
215 if 'domain' in x)
216 if not domain_fields.intersection(kwargs.keys()):
217 domain_name = CONF.auth.default_credentials_domain_name
Andrea Frittoli (andreaf)100d18d2016-05-05 23:34:52 +0100218 # NOTE(andreaf) Setting domain_name implicitly sets user and
219 # project domain names, if they are None
220 params['domain_name'] = domain_name
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100221
222 auth_url = CONF.identity.uri_v3
223 else:
224 auth_url = CONF.identity.uri
225 return auth.get_credentials(auth_url,
226 fill_in=fill_in,
227 identity_version=identity_version,
228 **params)
229
230# === Credential / client managers
231
232
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100233class AdminManager(clients.Manager):
Ken'ichi Ohmichicb67d2d2015-11-19 08:23:22 +0000234 """Manager that uses admin credentials for its managed client objects"""
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100235
236 def __init__(self, service=None):
237 super(AdminManager, self).__init__(
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100238 credentials=get_configured_admin_credentials(),
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100239 service=service)