blob: c22afc14fb1f38ba7429786ffe72ba632b530b4c [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
20from tempest import exceptions
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050021from tempest.lib import auth
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,
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010083 **get_dynamic_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010084 else:
Matthew Treinishd89db1b2015-12-16 17:29:14 -050085 if CONF.auth.test_accounts_file:
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010086 # Most params are not relevant for pre-created accounts
87 return preprov_creds.PreProvisionedCredentialProvider(
88 name=name, identity_version=identity_version,
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +010089 **get_preprov_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010090 else:
Matthew Treinish40847ac2016-01-04 13:16:03 -050091 raise exceptions.InvalidConfiguration(
92 'A valid credential provider is needed')
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010093
94
95# We want a helper function here to check and see if admin credentials
96# are available so we can do a single call from skip_checks if admin
97# creds area available.
98# This depends on identity_version as there may be admin credentials
99# available for v2 but not for v3.
100def is_admin_available(identity_version):
101 is_admin = True
102 # If dynamic credentials is enabled admin will be available
103 if CONF.auth.use_dynamic_credentials:
104 return is_admin
105 # Check whether test accounts file has the admin specified or not
Matthew Treinishd89db1b2015-12-16 17:29:14 -0500106 elif CONF.auth.test_accounts_file:
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100107 check_accounts = preprov_creds.PreProvisionedCredentialProvider(
108 identity_version=identity_version, name='check_admin',
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +0100109 **get_preprov_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100110 if not check_accounts.admin_available():
111 is_admin = False
112 else:
113 try:
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100114 get_configured_admin_credentials(fill_in=False,
115 identity_version=identity_version)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100116 except exceptions.InvalidConfiguration:
117 is_admin = False
118 return is_admin
119
120
121# We want a helper function here to check and see if alt credentials
122# are available so we can do a single call from skip_checks if alt
123# creds area available.
124# This depends on identity_version as there may be alt credentials
125# available for v2 but not for v3.
126def is_alt_available(identity_version):
127 # If dynamic credentials is enabled alt will be available
128 if CONF.auth.use_dynamic_credentials:
129 return True
130 # Check whether test accounts file has the admin specified or not
Matthew Treinishd89db1b2015-12-16 17:29:14 -0500131 if CONF.auth.test_accounts_file:
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100132 check_accounts = preprov_creds.PreProvisionedCredentialProvider(
133 identity_version=identity_version, name='check_alt',
Andrea Frittoli (andreaf)bd06f982016-06-02 17:26:51 +0100134 **get_preprov_provider_params())
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100135 else:
Matthew Treinish40847ac2016-01-04 13:16:03 -0500136 raise exceptions.InvalidConfiguration(
137 'A valid credential provider is needed')
138
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100139 try:
140 if not check_accounts.is_multi_user():
141 return False
142 else:
143 return True
144 except exceptions.InvalidConfiguration:
145 return False
146
147# === Credentials
148
149# Type of credentials available from configuration
150CREDENTIAL_TYPES = {
151 'identity_admin': ('auth', 'admin'),
152 'user': ('identity', None),
153 'alt_user': ('identity', 'alt')
154}
155
156DEFAULT_PARAMS = {
157 'disable_ssl_certificate_validation':
Daniel Melladocad3f3d2016-08-19 14:17:16 +0000158 CONF.identity.disable_ssl_certificate_validation,
159 'ca_certs': CONF.identity.ca_certificates_file,
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100160 'trace_requests': CONF.debug.trace_requests
161}
162
163
164# Read credentials from configuration, builds a Credentials object
165# based on the specified or configured version
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100166def get_configured_admin_credentials(fill_in=True, identity_version=None):
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100167 identity_version = identity_version or CONF.identity.auth_version
168
169 if identity_version not in ('v2', 'v3'):
170 raise exceptions.InvalidConfiguration(
171 'Unsupported auth version: %s' % identity_version)
172
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100173 conf_attributes = ['username', 'password',
174 'project_name']
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100175
176 if identity_version == 'v3':
177 conf_attributes.append('domain_name')
178 # Read the parts of credentials from config
179 params = DEFAULT_PARAMS.copy()
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100180 for attr in conf_attributes:
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100181 params[attr] = getattr(CONF.auth, 'admin_' + attr)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100182 # Build and validate credentials. We are reading configured credentials,
183 # so validate them even if fill_in is False
184 credentials = get_credentials(fill_in=fill_in,
185 identity_version=identity_version, **params)
186 if not fill_in:
187 if not credentials.is_valid():
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100188 msg = ("The admin credentials are incorrectly set in the config "
189 "file for identity version %s. Double check that all "
190 "required values are assigned.")
191 raise exceptions.InvalidConfiguration(msg % identity_version)
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100192 return credentials
193
194
195# Wrapper around auth.get_credentials to use the configured identity version
Andrea Frittoli (andreaf)100d18d2016-05-05 23:34:52 +0100196# if none is specified
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100197def get_credentials(fill_in=True, identity_version=None, **kwargs):
198 params = dict(DEFAULT_PARAMS, **kwargs)
199 identity_version = identity_version or CONF.identity.auth_version
200 # In case of "v3" add the domain from config if not specified
Andrea Frittoli (andreaf)100d18d2016-05-05 23:34:52 +0100201 # To honour the "default_credentials_domain_name", if not domain
202 # field is specified at all, add it the credential dict.
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100203 if identity_version == 'v3':
204 domain_fields = set(x for x in auth.KeystoneV3Credentials.ATTRIBUTES
205 if 'domain' in x)
206 if not domain_fields.intersection(kwargs.keys()):
207 domain_name = CONF.auth.default_credentials_domain_name
Andrea Frittoli (andreaf)100d18d2016-05-05 23:34:52 +0100208 # NOTE(andreaf) Setting domain_name implicitly sets user and
209 # project domain names, if they are None
210 params['domain_name'] = domain_name
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100211
212 auth_url = CONF.identity.uri_v3
213 else:
214 auth_url = CONF.identity.uri
215 return auth.get_credentials(auth_url,
216 fill_in=fill_in,
217 identity_version=identity_version,
218 **params)
219
220# === Credential / client managers
221
222
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100223class AdminManager(clients.Manager):
Ken'ichi Ohmichicb67d2d2015-11-19 08:23:22 +0000224 """Manager that uses admin credentials for its managed client objects"""
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100225
226 def __init__(self, service=None):
227 super(AdminManager, self).__init__(
Andrea Frittoli (andreaf)bc0a7a62016-05-26 19:31:49 +0100228 credentials=get_configured_admin_credentials(),
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +0100229 service=service)