Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 1 | # Copyright 2013 IBM Corp. |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | # not use this file except in compliance with the License. You may obtain |
| 5 | # a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 12 | # License for the specific language governing permissions and limitations |
| 13 | # under the License. |
| 14 | |
zhongjun | 5b68f50 | 2017-07-04 15:28:05 +0800 | [diff] [blame] | 15 | import ipaddress |
| 16 | |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 17 | import netaddr |
Doug Hellmann | 583ce2c | 2015-03-11 14:55:46 +0000 | [diff] [blame] | 18 | from oslo_log import log as logging |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 19 | |
Matthew Treinish | 3787e4c | 2016-10-07 21:25:33 -0400 | [diff] [blame] | 20 | from tempest.lib.common import cred_client |
Matthew Treinish | 00ab6be | 2016-10-07 16:29:18 -0400 | [diff] [blame] | 21 | from tempest.lib.common import cred_provider |
Matthew Treinish | 0650aed | 2016-10-07 16:36:46 -0400 | [diff] [blame] | 22 | from tempest.lib.common.utils import data_utils |
Andrea Frittoli (andreaf) | db9672e | 2016-02-23 14:07:24 -0500 | [diff] [blame] | 23 | from tempest.lib import exceptions as lib_exc |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 24 | from tempest.lib.services import clients |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 25 | |
| 26 | LOG = logging.getLogger(__name__) |
| 27 | |
| 28 | |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 29 | class DynamicCredentialProvider(cred_provider.CredentialProvider): |
Masayuki Igawa | a1c3af3 | 2017-09-07 10:22:37 +0900 | [diff] [blame] | 30 | """Creates credentials dynamically for tests |
| 31 | |
| 32 | A credential provider that, based on an initial set of |
| 33 | admin credentials, creates new credentials on the fly for |
| 34 | tests to use and then discard. |
| 35 | |
| 36 | :param str identity_version: identity API version to use `v2` or `v3` |
| 37 | :param str admin_role: name of the admin role added to admin users |
| 38 | :param str name: names of dynamic resources include this parameter |
| 39 | when specified |
| 40 | :param str credentials_domain: name of the domain where the users |
| 41 | are created. If not defined, the project |
| 42 | domain from admin_credentials is used |
| 43 | :param dict network_resources: network resources to be created for |
| 44 | the created credentials |
| 45 | :param Credentials admin_creds: initial admin credentials |
| 46 | :param bool identity_admin_domain_scope: Set to true if admin should be |
| 47 | scoped to the domain. By |
| 48 | default this is False and the |
| 49 | admin role is scoped to the |
| 50 | project. |
| 51 | :param str identity_admin_role: The role name to use for admin |
| 52 | :param list extra_roles: A list of strings for extra roles that should |
| 53 | be assigned to all created users |
| 54 | :param bool neutron_available: Whether we are running in an environemnt |
| 55 | with neutron |
| 56 | :param bool create_networks: Whether dynamic project networks should be |
| 57 | created or not |
| 58 | :param project_network_cidr: The CIDR to use for created project |
| 59 | networks |
| 60 | :param project_network_mask_bits: The network mask bits to use for |
| 61 | created project networks |
| 62 | :param public_network_id: The id for the public network to use |
| 63 | :param identity_admin_endpoint_type: The endpoint type for identity |
| 64 | admin clients. Defaults to public. |
| 65 | :param identity_uri: Identity URI of the target cloud |
| 66 | """ |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 67 | |
Andrea Frittoli (andreaf) | 1eb0496 | 2015-10-09 14:48:06 +0100 | [diff] [blame] | 68 | def __init__(self, identity_version, name=None, network_resources=None, |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 69 | credentials_domain=None, admin_role=None, admin_creds=None, |
| 70 | identity_admin_domain_scope=False, |
| 71 | identity_admin_role='admin', extra_roles=None, |
| 72 | neutron_available=False, create_networks=True, |
| 73 | project_network_cidr=None, project_network_mask_bits=None, |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 74 | public_network_id=None, resource_prefix=None, |
| 75 | identity_admin_endpoint_type='public', identity_uri=None): |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 76 | super(DynamicCredentialProvider, self).__init__( |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 77 | identity_version=identity_version, identity_uri=identity_uri, |
| 78 | admin_role=admin_role, name=name, |
| 79 | credentials_domain=credentials_domain, |
Andrea Frittoli (andreaf) | 290b3e1 | 2015-10-08 10:25:02 +0100 | [diff] [blame] | 80 | network_resources=network_resources) |
| 81 | self.network_resources = network_resources |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 82 | self._creds = {} |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 83 | self.ports = [] |
Matthew Treinish | 0650aed | 2016-10-07 16:36:46 -0400 | [diff] [blame] | 84 | self.resource_prefix = resource_prefix or '' |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 85 | self.neutron_available = neutron_available |
| 86 | self.create_networks = create_networks |
| 87 | self.project_network_cidr = project_network_cidr |
| 88 | self.project_network_mask_bits = project_network_mask_bits |
| 89 | self.public_network_id = public_network_id |
Andrea Frittoli (andreaf) | 290b3e1 | 2015-10-08 10:25:02 +0100 | [diff] [blame] | 90 | self.default_admin_creds = admin_creds |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 91 | self.identity_admin_domain_scope = identity_admin_domain_scope |
| 92 | self.identity_admin_role = identity_admin_role or 'admin' |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 93 | self.identity_admin_endpoint_type = identity_admin_endpoint_type |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 94 | self.extra_roles = extra_roles or [] |
Yaroslav Lobankov | 47a93ab | 2016-02-07 16:32:49 -0600 | [diff] [blame] | 95 | (self.identity_admin_client, |
| 96 | self.tenants_admin_client, |
Daniel Mellado | 82c83a5 | 2015-12-09 15:16:49 +0000 | [diff] [blame] | 97 | self.users_admin_client, |
Daniel Mellado | 7aea534 | 2016-02-09 09:10:12 +0000 | [diff] [blame] | 98 | self.roles_admin_client, |
Daniel Mellado | 91a26b6 | 2016-02-11 11:13:04 +0000 | [diff] [blame] | 99 | self.domains_admin_client, |
John Warren | 3961acd | 2015-10-02 14:38:53 -0400 | [diff] [blame] | 100 | self.networks_admin_client, |
Ken'ichi Ohmichi | e35f472 | 2015-12-22 04:57:11 +0000 | [diff] [blame] | 101 | self.routers_admin_client, |
John Warren | 49c0fe5 | 2015-10-22 12:35:54 -0400 | [diff] [blame] | 102 | self.subnets_admin_client, |
John Warren | f9606e9 | 2015-12-10 12:12:42 -0500 | [diff] [blame] | 103 | self.ports_admin_client, |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 104 | self.security_groups_admin_client) = self._get_admin_clients( |
| 105 | identity_admin_endpoint_type) |
John Warren | 3961acd | 2015-10-02 14:38:53 -0400 | [diff] [blame] | 106 | # Domain where isolated credentials are provisioned (v3 only). |
Andrea Frittoli | c328015 | 2015-02-26 12:42:34 +0000 | [diff] [blame] | 107 | # Use that of the admin account is None is configured. |
| 108 | self.creds_domain_name = None |
| 109 | if self.identity_version == 'v3': |
| 110 | self.creds_domain_name = ( |
David Kranz | 87fc7e9 | 2015-07-28 14:05:20 -0400 | [diff] [blame] | 111 | self.default_admin_creds.project_domain_name or |
Andrea Frittoli (andreaf) | 1eb0496 | 2015-10-09 14:48:06 +0100 | [diff] [blame] | 112 | self.credentials_domain) |
Jamie Lennox | 1535017 | 2015-08-17 10:54:25 +1000 | [diff] [blame] | 113 | self.creds_client = cred_client.get_creds_client( |
Daniel Mellado | b04da90 | 2015-11-20 17:43:12 +0100 | [diff] [blame] | 114 | self.identity_admin_client, |
| 115 | self.tenants_admin_client, |
Daniel Mellado | 82c83a5 | 2015-12-09 15:16:49 +0000 | [diff] [blame] | 116 | self.users_admin_client, |
Daniel Mellado | 7aea534 | 2016-02-09 09:10:12 +0000 | [diff] [blame] | 117 | self.roles_admin_client, |
Daniel Mellado | 91a26b6 | 2016-02-11 11:13:04 +0000 | [diff] [blame] | 118 | self.domains_admin_client, |
Daniel Mellado | b04da90 | 2015-11-20 17:43:12 +0100 | [diff] [blame] | 119 | self.creds_domain_name) |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 120 | |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 121 | def _get_admin_clients(self, endpoint_type): |
Ken'ichi Ohmichi | cb67d2d | 2015-11-19 08:23:22 +0000 | [diff] [blame] | 122 | """Returns a tuple with instances of the following admin clients |
| 123 | |
| 124 | (in this order): |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 125 | identity |
| 126 | network |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 127 | """ |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 128 | os = clients.ServiceClients(self.default_admin_creds, |
| 129 | self.identity_uri) |
| 130 | params = {'endpoint_type': endpoint_type} |
Andrea Frittoli | c328015 | 2015-02-26 12:42:34 +0000 | [diff] [blame] | 131 | if self.identity_version == 'v2': |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 132 | return (os.identity_v2.IdentityClient(**params), |
| 133 | os.identity_v2.TenantsClient(**params), |
| 134 | os.identity_v2.UsersClient(**params), |
| 135 | os.identity_v2.RolesClient(**params), None, |
| 136 | os.network.NetworksClient(), |
| 137 | os.network.RoutersClient(), |
| 138 | os.network.SubnetsClient(), |
| 139 | os.network.PortsClient(), |
| 140 | os.network.SecurityGroupsClient()) |
Andrea Frittoli | c328015 | 2015-02-26 12:42:34 +0000 | [diff] [blame] | 141 | else: |
Andrea Frittoli (andreaf) | 100d18d | 2016-05-05 23:34:52 +0100 | [diff] [blame] | 142 | # We use a dedicated client manager for identity client in case we |
| 143 | # need a different token scope for them. |
Colleen Murphy | cd0bbbd | 2019-10-01 16:18:36 -0700 | [diff] [blame] | 144 | if self.default_admin_creds.system: |
| 145 | scope = 'system' |
Martin Kopec | a28849f | 2021-01-21 14:06:21 +0000 | [diff] [blame] | 146 | elif (self.identity_admin_domain_scope and |
| 147 | (self.default_admin_creds.domain_id or |
| 148 | self.default_admin_creds.domain_name)): |
Colleen Murphy | cd0bbbd | 2019-10-01 16:18:36 -0700 | [diff] [blame] | 149 | scope = 'domain' |
| 150 | else: |
| 151 | scope = 'project' |
Andrea Frittoli | dcd9100 | 2017-07-18 11:34:13 +0100 | [diff] [blame] | 152 | identity_os = clients.ServiceClients(self.default_admin_creds, |
| 153 | self.identity_uri, |
| 154 | scope=scope) |
| 155 | return (identity_os.identity_v3.IdentityClient(**params), |
| 156 | identity_os.identity_v3.ProjectsClient(**params), |
| 157 | identity_os.identity_v3.UsersClient(**params), |
| 158 | identity_os.identity_v3.RolesClient(**params), |
| 159 | identity_os.identity_v3.DomainsClient(**params), |
| 160 | os.network.NetworksClient(), |
| 161 | os.network.RoutersClient(), |
| 162 | os.network.SubnetsClient(), |
| 163 | os.network.PortsClient(), |
| 164 | os.network.SecurityGroupsClient()) |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 165 | |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 166 | def _create_creds(self, admin=False, roles=None, scope='project', |
| 167 | project_id=None): |
Genadi Chereshnya | 88ea9ab | 2016-05-15 14:47:07 +0300 | [diff] [blame] | 168 | """Create credentials with random name. |
Sean Dague | 6969b90 | 2014-01-28 06:48:37 -0500 | [diff] [blame] | 169 | |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 170 | Creates user and role assignments on a project, domain, or system. When |
| 171 | the admin flag is True, creates user with the admin role on the |
| 172 | resource. If roles are provided, assigns those roles on the resource. |
| 173 | Otherwise, assigns the user the 'member' role on the resource. |
Sean Dague | 6969b90 | 2014-01-28 06:48:37 -0500 | [diff] [blame] | 174 | |
Genadi Chereshnya | 88ea9ab | 2016-05-15 14:47:07 +0300 | [diff] [blame] | 175 | :param admin: Flag if to assign to the user admin role |
| 176 | :type admin: bool |
| 177 | :param roles: Roles to assign for the user |
| 178 | :type roles: list |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 179 | :param str scope: The scope for the role assignment, may be one of |
| 180 | 'project', 'domain', or 'system'. |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 181 | :param str project_id: The project id of already created project |
| 182 | for credentials under same project. |
Genadi Chereshnya | 88ea9ab | 2016-05-15 14:47:07 +0300 | [diff] [blame] | 183 | :return: Readonly Credentials with network resources |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 184 | :raises: Exception if scope is invalid |
Sean Dague | 6969b90 | 2014-01-28 06:48:37 -0500 | [diff] [blame] | 185 | """ |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 186 | if not roles: |
| 187 | roles = [] |
Genadi Chereshnya | 88ea9ab | 2016-05-15 14:47:07 +0300 | [diff] [blame] | 188 | root = self.name |
Sean Dague | 6969b90 | 2014-01-28 06:48:37 -0500 | [diff] [blame] | 189 | |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 190 | cred_params = { |
| 191 | 'project': None, |
| 192 | 'domain': None, |
| 193 | 'system': None |
| 194 | } |
| 195 | if scope == 'project': |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 196 | if not project_id: |
| 197 | project_name = data_utils.rand_name( |
| 198 | root, prefix=self.resource_prefix) |
| 199 | project_desc = project_name + '-desc' |
| 200 | project = self.creds_client.create_project( |
| 201 | name=project_name, description=project_desc) |
| 202 | else: |
| 203 | # NOTE(gmann) This is the case where creds are requested |
| 204 | # from the existing creds within same project. We should |
| 205 | # not create the new project in this case. |
| 206 | project = self.creds_client.show_project(project_id) |
| 207 | project_name = project['name'] |
| 208 | LOG.info("Using the existing project %s for scope %s and " |
| 209 | "roles: %s", project['id'], scope, roles) |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 210 | # NOTE(andreaf) User and project can be distinguished from the |
| 211 | # context, having the same ID in both makes it easier to match them |
| 212 | # and debug. |
| 213 | username = project_name + '-project' |
| 214 | cred_params['project'] = project |
| 215 | elif scope == 'domain': |
| 216 | domain_name = data_utils.rand_name( |
| 217 | root, prefix=self.resource_prefix) |
| 218 | domain_desc = domain_name + '-desc' |
| 219 | domain = self.creds_client.create_domain( |
| 220 | name=domain_name, description=domain_desc) |
| 221 | username = domain_name + '-domain' |
| 222 | cred_params['domain'] = domain |
| 223 | elif scope == 'system': |
| 224 | prefix = data_utils.rand_name(root, prefix=self.resource_prefix) |
| 225 | username = prefix + '-system' |
| 226 | cred_params['system'] = 'all' |
| 227 | else: |
| 228 | raise lib_exc.InvalidScopeType(scope=scope) |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 229 | if admin: |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 230 | username += '-admin' |
| 231 | elif roles and len(roles) == 1: |
| 232 | username += '-' + roles[0] |
| 233 | user_password = data_utils.rand_password() |
| 234 | cred_params['password'] = user_password |
| 235 | user = self.creds_client.create_user( |
| 236 | username, user_password) |
| 237 | cred_params['user'] = user |
| 238 | roles_to_assign = [r for r in roles] |
| 239 | if admin: |
| 240 | roles_to_assign.append(self.admin_role) |
Lance Bragstad | ef13f40 | 2021-03-04 17:12:10 +0000 | [diff] [blame] | 241 | if scope == 'project': |
| 242 | self.creds_client.assign_user_role( |
| 243 | user, project, self.identity_admin_role) |
Andrea Frittoli (andreaf) | 100d18d | 2016-05-05 23:34:52 +0100 | [diff] [blame] | 244 | if (self.identity_version == 'v3' and |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 245 | self.identity_admin_domain_scope): |
Andrea Frittoli (andreaf) | 4bee2e7 | 2015-09-22 13:06:18 +0100 | [diff] [blame] | 246 | self.creds_client.assign_user_role_on_domain( |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 247 | user, self.identity_admin_role) |
Matthew Treinish | 976e8df | 2014-12-19 14:21:54 -0500 | [diff] [blame] | 248 | # Add roles specified in config file |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 249 | roles_to_assign.extend(self.extra_roles) |
| 250 | # If there are still no roles, default to 'member' |
Matthew Treinish | 32f98a4 | 2015-07-14 19:58:46 -0400 | [diff] [blame] | 251 | # NOTE(mtreinish) For a user to have access to a project with v3 auth |
| 252 | # it must beassigned a role on the project. So we need to ensure that |
| 253 | # our newly created user has a role on the newly created project. |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 254 | if not roles_to_assign and self.identity_version == 'v3': |
| 255 | roles_to_assign = ['member'] |
Adam Young | b226f8e | 2016-06-25 21:41:36 -0400 | [diff] [blame] | 256 | try: |
Martin Kopec | 99d4dae | 2020-05-27 10:33:17 +0000 | [diff] [blame] | 257 | self.creds_client.create_user_role('member') |
Adam Young | b226f8e | 2016-06-25 21:41:36 -0400 | [diff] [blame] | 258 | except lib_exc.Conflict: |
Martin Kopec | 99d4dae | 2020-05-27 10:33:17 +0000 | [diff] [blame] | 259 | LOG.warning('member role already exists, ignoring conflict.') |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 260 | for role in roles_to_assign: |
| 261 | if scope == 'project': |
| 262 | self.creds_client.assign_user_role(user, project, role) |
| 263 | elif scope == 'domain': |
| 264 | self.creds_client.assign_user_role_on_domain( |
| 265 | user, role, domain) |
| 266 | elif scope == 'system': |
| 267 | self.creds_client.assign_user_role_on_system(user, role) |
Ghanshyam Mann | c67b026 | 2021-07-16 15:36:27 -0500 | [diff] [blame] | 268 | LOG.info("Dynamic test user %s is created with scope %s and roles: %s", |
| 269 | user['id'], scope, roles_to_assign) |
Matthew Treinish | 32f98a4 | 2015-07-14 19:58:46 -0400 | [diff] [blame] | 270 | |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 271 | creds = self.creds_client.get_credentials(**cred_params) |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 272 | return cred_provider.TestResources(creds) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 273 | |
| 274 | def _create_network_resources(self, tenant_id): |
edannon | 6cc6fbc | 2016-05-03 11:56:12 +0300 | [diff] [blame] | 275 | """The function creates network resources in the given tenant. |
| 276 | |
| 277 | The function checks if network_resources class member is empty, |
| 278 | In case it is, it will create a network, a subnet and a router for |
| 279 | the tenant according to the given tenant id parameter. |
| 280 | Otherwise it will create a network resource according |
| 281 | to the values from network_resources dict. |
| 282 | |
| 283 | :param tenant_id: The tenant id to create resources for. |
| 284 | :type tenant_id: str |
| 285 | :raises: InvalidConfiguration, Exception |
| 286 | :returns: network resources(network,subnet,router) |
| 287 | :rtype: tuple |
| 288 | """ |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 289 | network = None |
| 290 | subnet = None |
| 291 | router = None |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 292 | # Make sure settings |
| 293 | if self.network_resources: |
| 294 | if self.network_resources['router']: |
| 295 | if (not self.network_resources['subnet'] or |
| 296 | not self.network_resources['network']): |
Matthew Treinish | 4217a70 | 2016-10-07 17:27:11 -0400 | [diff] [blame] | 297 | raise lib_exc.InvalidConfiguration( |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 298 | 'A router requires a subnet and network') |
| 299 | elif self.network_resources['subnet']: |
| 300 | if not self.network_resources['network']: |
Matthew Treinish | 4217a70 | 2016-10-07 17:27:11 -0400 | [diff] [blame] | 301 | raise lib_exc.InvalidConfiguration( |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 302 | 'A subnet requires a network') |
| 303 | elif self.network_resources['dhcp']: |
Matthew Treinish | 4217a70 | 2016-10-07 17:27:11 -0400 | [diff] [blame] | 304 | raise lib_exc.InvalidConfiguration('DHCP requires a subnet') |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 305 | |
Matthew Treinish | 0650aed | 2016-10-07 16:36:46 -0400 | [diff] [blame] | 306 | rand_name_root = data_utils.rand_name( |
| 307 | self.name, prefix=self.resource_prefix) |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 308 | if not self.network_resources or self.network_resources['network']: |
Matthew Treinish | 0650aed | 2016-10-07 16:36:46 -0400 | [diff] [blame] | 309 | network_name = rand_name_root + "-network" |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 310 | network = self._create_network(network_name, tenant_id) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 311 | try: |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 312 | if not self.network_resources or self.network_resources['subnet']: |
Matthew Treinish | 0650aed | 2016-10-07 16:36:46 -0400 | [diff] [blame] | 313 | subnet_name = rand_name_root + "-subnet" |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 314 | subnet = self._create_subnet(subnet_name, tenant_id, |
| 315 | network['id']) |
| 316 | if not self.network_resources or self.network_resources['router']: |
Matthew Treinish | 0650aed | 2016-10-07 16:36:46 -0400 | [diff] [blame] | 317 | router_name = rand_name_root + "-router" |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 318 | router = self._create_router(router_name, tenant_id) |
| 319 | self._add_router_interface(router['id'], subnet['id']) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 320 | except Exception: |
Andrea Frittoli (andreaf) | d9a18b0 | 2016-02-29 15:27:34 +0000 | [diff] [blame] | 321 | try: |
| 322 | if router: |
| 323 | self._clear_isolated_router(router['id'], router['name']) |
| 324 | if subnet: |
| 325 | self._clear_isolated_subnet(subnet['id'], subnet['name']) |
| 326 | if network: |
| 327 | self._clear_isolated_network(network['id'], |
| 328 | network['name']) |
| 329 | except Exception as cleanup_exception: |
| 330 | msg = "There was an exception trying to setup network " \ |
| 331 | "resources for tenant %s, and this error happened " \ |
| 332 | "trying to clean them up: %s" |
Jordan Pittier | 525ec71 | 2016-12-07 17:51:26 +0100 | [diff] [blame] | 333 | LOG.warning(msg, tenant_id, cleanup_exception) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 334 | raise |
| 335 | return network, subnet, router |
| 336 | |
| 337 | def _create_network(self, name, tenant_id): |
John Warren | 94d8faf | 2015-09-15 12:22:24 -0400 | [diff] [blame] | 338 | resp_body = self.networks_admin_client.create_network( |
Andrea Frittoli | ae9aca0 | 2014-09-25 11:43:11 +0100 | [diff] [blame] | 339 | name=name, tenant_id=tenant_id) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 340 | return resp_body['network'] |
| 341 | |
| 342 | def _create_subnet(self, subnet_name, tenant_id, network_id): |
Matthew Treinish | 75abbcf | 2016-10-07 16:19:12 -0400 | [diff] [blame] | 343 | base_cidr = netaddr.IPNetwork(self.project_network_cidr) |
| 344 | mask_bits = self.project_network_mask_bits |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 345 | for subnet_cidr in base_cidr.subnet(mask_bits): |
| 346 | try: |
Andrea Frittoli | ae9aca0 | 2014-09-25 11:43:11 +0100 | [diff] [blame] | 347 | if self.network_resources: |
John Warren | 3961acd | 2015-10-02 14:38:53 -0400 | [diff] [blame] | 348 | resp_body = self.subnets_admin_client.\ |
Andrea Frittoli | ae9aca0 | 2014-09-25 11:43:11 +0100 | [diff] [blame] | 349 | create_subnet( |
| 350 | network_id=network_id, cidr=str(subnet_cidr), |
| 351 | name=subnet_name, |
| 352 | tenant_id=tenant_id, |
| 353 | enable_dhcp=self.network_resources['dhcp'], |
zhongjun | 5b68f50 | 2017-07-04 15:28:05 +0800 | [diff] [blame] | 354 | ip_version=(ipaddress.ip_network( |
likui | 19b70a3 | 2020-12-02 13:25:18 +0800 | [diff] [blame] | 355 | str(subnet_cidr)).version)) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 356 | else: |
John Warren | 3961acd | 2015-10-02 14:38:53 -0400 | [diff] [blame] | 357 | resp_body = self.subnets_admin_client.\ |
Andrea Frittoli | ae9aca0 | 2014-09-25 11:43:11 +0100 | [diff] [blame] | 358 | create_subnet(network_id=network_id, |
| 359 | cidr=str(subnet_cidr), |
| 360 | name=subnet_name, |
| 361 | tenant_id=tenant_id, |
zhongjun | 5b68f50 | 2017-07-04 15:28:05 +0800 | [diff] [blame] | 362 | ip_version=(ipaddress.ip_network( |
likui | 19b70a3 | 2020-12-02 13:25:18 +0800 | [diff] [blame] | 363 | str(subnet_cidr)).version)) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 364 | break |
Masayuki Igawa | 4b29e47 | 2015-02-16 10:41:54 +0900 | [diff] [blame] | 365 | except lib_exc.BadRequest as e: |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 366 | if 'overlaps with another subnet' not in str(e): |
| 367 | raise |
| 368 | else: |
David Kranz | d421041 | 2014-11-21 08:37:45 -0500 | [diff] [blame] | 369 | message = 'Available CIDR for subnet creation could not be found' |
| 370 | raise Exception(message) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 371 | return resp_body['subnet'] |
| 372 | |
| 373 | def _create_router(self, router_name, tenant_id): |
zhufl | 6b7040a | 2017-01-18 16:38:34 +0800 | [diff] [blame] | 374 | kwargs = {'name': router_name, |
| 375 | 'tenant_id': tenant_id} |
| 376 | if self.public_network_id: |
| 377 | kwargs['external_gateway_info'] = dict( |
| 378 | network_id=self.public_network_id) |
| 379 | resp_body = self.routers_admin_client.create_router(**kwargs) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 380 | return resp_body['router'] |
| 381 | |
| 382 | def _add_router_interface(self, router_id, subnet_id): |
Ken'ichi Ohmichi | e35f472 | 2015-12-22 04:57:11 +0000 | [diff] [blame] | 383 | self.routers_admin_client.add_router_interface(router_id, |
piyush110786 | 94aca95 | 2015-12-17 12:54:44 +0530 | [diff] [blame] | 384 | subnet_id=subnet_id) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 385 | |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 386 | def _get_project_id(self, credential_type, scope): |
| 387 | same_creds = [['admin'], ['member'], ['reader']] |
| 388 | same_alt_creds = [['alt_admin'], ['alt_member'], ['alt_reader']] |
| 389 | search_in = [] |
| 390 | if credential_type in same_creds: |
| 391 | search_in = same_creds |
| 392 | elif credential_type in same_alt_creds: |
| 393 | search_in = same_alt_creds |
| 394 | for cred in search_in: |
| 395 | found_cred = self._creds.get("%s_%s" % (scope, str(cred))) |
| 396 | if found_cred: |
| 397 | project_id = found_cred.get("%s_%s" % (scope, 'id')) |
| 398 | LOG.debug("Reusing existing project %s from creds: %s ", |
| 399 | project_id, found_cred) |
| 400 | return project_id |
| 401 | return None |
| 402 | |
| 403 | def get_credentials(self, credential_type, scope=None, by_role=False): |
| 404 | cred_prefix = '' |
| 405 | if by_role: |
| 406 | cred_prefix = 'role_' |
| 407 | if not scope and self._creds.get( |
| 408 | "%s%s" % (cred_prefix, str(credential_type))): |
| 409 | credentials = self._creds[ |
| 410 | "%s%s" % (cred_prefix, str(credential_type))] |
| 411 | elif scope and (self._creds.get( |
| 412 | "%s%s_%s" % (cred_prefix, scope, str(credential_type)))): |
| 413 | credentials = self._creds[ |
| 414 | "%s%s_%s" % (cred_prefix, scope, str(credential_type))] |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 415 | else: |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 416 | LOG.debug("Creating new dynamic creds for scope: %s and " |
| 417 | "credential_type: %s", scope, credential_type) |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 418 | project_id = None |
Ghanshyam Mann | 7f39425 | 2021-01-29 13:07:23 -0600 | [diff] [blame] | 419 | if scope: |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 420 | if scope == 'project': |
| 421 | project_id = self._get_project_id( |
| 422 | credential_type, 'project') |
| 423 | if by_role: |
Ghanshyam Mann | 7f39425 | 2021-01-29 13:07:23 -0600 | [diff] [blame] | 424 | credentials = self._create_creds( |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 425 | roles=credential_type, scope=scope) |
| 426 | elif credential_type in [['admin'], ['alt_admin']]: |
| 427 | credentials = self._create_creds( |
| 428 | admin=True, scope=scope, project_id=project_id) |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 429 | elif credential_type in [['alt_member'], ['alt_reader']]: |
| 430 | cred_type = credential_type[0][4:] |
Lance Bragstad | ef13f40 | 2021-03-04 17:12:10 +0000 | [diff] [blame] | 431 | if isinstance(cred_type, str): |
| 432 | cred_type = [cred_type] |
Ghanshyam Mann | 7f39425 | 2021-01-29 13:07:23 -0600 | [diff] [blame] | 433 | credentials = self._create_creds( |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 434 | roles=cred_type, scope=scope, project_id=project_id) |
| 435 | elif credential_type in [['member'], ['reader']]: |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 436 | credentials = self._create_creds( |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 437 | roles=credential_type, scope=scope, |
| 438 | project_id=project_id) |
Ghanshyam Mann | 7f39425 | 2021-01-29 13:07:23 -0600 | [diff] [blame] | 439 | elif credential_type in ['primary', 'alt', 'admin']: |
Matthew Treinish | 976e8df | 2014-12-19 14:21:54 -0500 | [diff] [blame] | 440 | is_admin = (credential_type == 'admin') |
| 441 | credentials = self._create_creds(admin=is_admin) |
| 442 | else: |
Ghanshyam Mann | 7f39425 | 2021-01-29 13:07:23 -0600 | [diff] [blame] | 443 | credentials = self._create_creds(roles=credential_type) |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 444 | if scope: |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 445 | self._creds["%s%s_%s" % ( |
| 446 | cred_prefix, scope, str(credential_type))] = credentials |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 447 | else: |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 448 | self._creds[ |
| 449 | "%s%s" % (cred_prefix, str(credential_type))] = credentials |
Andrea Frittoli | fc31590 | 2014-03-20 09:21:44 +0000 | [diff] [blame] | 450 | # Maintained until tests are ported |
Federico Ressi | 2d6bcaa | 2018-04-11 12:37:36 +0200 | [diff] [blame] | 451 | LOG.info("Acquired dynamic creds:\n" |
| 452 | " credentials: %s", credentials) |
Ghanshyam Mann | 5dcdd41 | 2021-06-25 11:50:03 -0500 | [diff] [blame] | 453 | # NOTE(gmann): For 'domain' and 'system' scoped token, there is no |
| 454 | # project_id so we are skipping the network creation for both |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 455 | # scope. |
| 456 | # We need to create nework resource once per project. |
| 457 | if (not project_id and (not scope or scope == 'project')): |
Ghanshyam Mann | 5dcdd41 | 2021-06-25 11:50:03 -0500 | [diff] [blame] | 458 | if (self.neutron_available and self.create_networks): |
| 459 | network, subnet, router = self._create_network_resources( |
| 460 | credentials.tenant_id) |
| 461 | credentials.set_resources(network=network, subnet=subnet, |
| 462 | router=router) |
| 463 | LOG.info("Created isolated network resources for:\n" |
| 464 | " credentials: %s", credentials) |
| 465 | else: |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 466 | LOG.info("Network resources are not created for requested " |
| 467 | "scope: %s and credentials: %s", scope, credentials) |
Andrea Frittoli | 9612e81 | 2014-03-13 10:57:26 +0000 | [diff] [blame] | 468 | return credentials |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 469 | |
Ghanshyam Mann | 32e0557 | 2021-01-29 11:24:56 -0600 | [diff] [blame] | 470 | # TODO(gmann): Remove this method in favor of get_project_member_creds() |
| 471 | # after the deprecation phase. |
Andrea Frittoli | 9612e81 | 2014-03-13 10:57:26 +0000 | [diff] [blame] | 472 | def get_primary_creds(self): |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 473 | return self.get_project_member_creds() |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 474 | |
Andrea Frittoli | 9612e81 | 2014-03-13 10:57:26 +0000 | [diff] [blame] | 475 | def get_admin_creds(self): |
| 476 | return self.get_credentials('admin') |
Andrea Frittoli | fc31590 | 2014-03-20 09:21:44 +0000 | [diff] [blame] | 477 | |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 478 | # TODO(gmann): Remove this method in favor of |
| 479 | # get_project_alt_member_creds() after the deprecation phase. |
Andrea Frittoli | 9612e81 | 2014-03-13 10:57:26 +0000 | [diff] [blame] | 480 | def get_alt_creds(self): |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 481 | return self.get_project_alt_member_creds() |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 482 | |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 483 | def get_system_admin_creds(self): |
| 484 | return self.get_credentials(['admin'], scope='system') |
| 485 | |
| 486 | def get_system_member_creds(self): |
| 487 | return self.get_credentials(['member'], scope='system') |
| 488 | |
| 489 | def get_system_reader_creds(self): |
| 490 | return self.get_credentials(['reader'], scope='system') |
| 491 | |
| 492 | def get_domain_admin_creds(self): |
| 493 | return self.get_credentials(['admin'], scope='domain') |
| 494 | |
| 495 | def get_domain_member_creds(self): |
| 496 | return self.get_credentials(['member'], scope='domain') |
| 497 | |
| 498 | def get_domain_reader_creds(self): |
| 499 | return self.get_credentials(['reader'], scope='domain') |
| 500 | |
| 501 | def get_project_admin_creds(self): |
| 502 | return self.get_credentials(['admin'], scope='project') |
| 503 | |
Ghanshyam Mann | 420586c | 2021-01-29 13:23:18 -0600 | [diff] [blame] | 504 | def get_project_alt_admin_creds(self): |
| 505 | return self.get_credentials(['alt_admin'], scope='project') |
| 506 | |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 507 | def get_project_member_creds(self): |
| 508 | return self.get_credentials(['member'], scope='project') |
| 509 | |
Ghanshyam Mann | 420586c | 2021-01-29 13:23:18 -0600 | [diff] [blame] | 510 | def get_project_alt_member_creds(self): |
| 511 | return self.get_credentials(['alt_member'], scope='project') |
| 512 | |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 513 | def get_project_reader_creds(self): |
| 514 | return self.get_credentials(['reader'], scope='project') |
| 515 | |
Ghanshyam Mann | 420586c | 2021-01-29 13:23:18 -0600 | [diff] [blame] | 516 | def get_project_alt_reader_creds(self): |
| 517 | return self.get_credentials(['alt_reader'], scope='project') |
| 518 | |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 519 | def get_creds_by_roles(self, roles, force_new=False, scope=None): |
Matthew Treinish | 976e8df | 2014-12-19 14:21:54 -0500 | [diff] [blame] | 520 | roles = list(set(roles)) |
| 521 | # The roles list as a str will become the index as the dict key for |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 522 | # the created credentials set in the dynamic_creds dict. |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 523 | creds_name = "role_%s" % str(roles) |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 524 | if scope: |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 525 | creds_name = "role_%s_%s" % (scope, str(roles)) |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 526 | exist_creds = self._creds.get(creds_name) |
Matthew Treinish | 976e8df | 2014-12-19 14:21:54 -0500 | [diff] [blame] | 527 | # If force_new flag is True 2 cred sets with the same roles are needed |
| 528 | # handle this by creating a separate index for old one to store it |
| 529 | # separately for cleanup |
| 530 | if exist_creds and force_new: |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 531 | new_index = creds_name + '-' + str(len(self._creds)) |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 532 | self._creds[new_index] = exist_creds |
Ghanshyam Mann | 2d0da04 | 2021-03-05 09:09:30 -0600 | [diff] [blame] | 533 | del self._creds[creds_name] |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 534 | return self.get_credentials(roles, scope=scope, by_role=True) |
Matthew Treinish | 976e8df | 2014-12-19 14:21:54 -0500 | [diff] [blame] | 535 | |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 536 | def _clear_isolated_router(self, router_id, router_name): |
Ken'ichi Ohmichi | e35f472 | 2015-12-22 04:57:11 +0000 | [diff] [blame] | 537 | client = self.routers_admin_client |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 538 | try: |
Ken'ichi Ohmichi | e35f472 | 2015-12-22 04:57:11 +0000 | [diff] [blame] | 539 | client.delete_router(router_id) |
Masayuki Igawa | bfa0760 | 2015-01-20 18:47:17 +0900 | [diff] [blame] | 540 | except lib_exc.NotFound: |
Jordan Pittier | 525ec71 | 2016-12-07 17:51:26 +0100 | [diff] [blame] | 541 | LOG.warning('router with name: %s not found for delete', |
zhangguoqing | 6c09664 | 2016-01-04 06:17:21 +0000 | [diff] [blame] | 542 | router_name) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 543 | |
| 544 | def _clear_isolated_subnet(self, subnet_id, subnet_name): |
John Warren | 3961acd | 2015-10-02 14:38:53 -0400 | [diff] [blame] | 545 | client = self.subnets_admin_client |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 546 | try: |
John Warren | 3961acd | 2015-10-02 14:38:53 -0400 | [diff] [blame] | 547 | client.delete_subnet(subnet_id) |
Masayuki Igawa | bfa0760 | 2015-01-20 18:47:17 +0900 | [diff] [blame] | 548 | except lib_exc.NotFound: |
Jordan Pittier | 525ec71 | 2016-12-07 17:51:26 +0100 | [diff] [blame] | 549 | LOG.warning('subnet with name: %s not found for delete', |
zhangguoqing | 6c09664 | 2016-01-04 06:17:21 +0000 | [diff] [blame] | 550 | subnet_name) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 551 | |
| 552 | def _clear_isolated_network(self, network_id, network_name): |
John Warren | 94d8faf | 2015-09-15 12:22:24 -0400 | [diff] [blame] | 553 | net_client = self.networks_admin_client |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 554 | try: |
| 555 | net_client.delete_network(network_id) |
Masayuki Igawa | bfa0760 | 2015-01-20 18:47:17 +0900 | [diff] [blame] | 556 | except lib_exc.NotFound: |
Jordan Pittier | 525ec71 | 2016-12-07 17:51:26 +0100 | [diff] [blame] | 557 | LOG.warning('network with name: %s not found for delete', |
zhangguoqing | 6c09664 | 2016-01-04 06:17:21 +0000 | [diff] [blame] | 558 | network_name) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 559 | |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 560 | def _clear_isolated_net_resources(self): |
Ken'ichi Ohmichi | e35f472 | 2015-12-22 04:57:11 +0000 | [diff] [blame] | 561 | client = self.routers_admin_client |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 562 | for cred in self._creds: |
| 563 | creds = self._creds.get(cred) |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 564 | if (not creds or not any([creds.router, creds.network, |
| 565 | creds.subnet])): |
| 566 | continue |
Salvatore Orlando | cf996c6 | 2014-01-30 09:15:18 -0800 | [diff] [blame] | 567 | LOG.debug("Clearing network: %(network)s, " |
Matthew Treinish | fe094ea | 2014-12-09 01:19:27 +0000 | [diff] [blame] | 568 | "subnet: %(subnet)s, router: %(router)s", |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 569 | {'network': creds.network, 'subnet': creds.subnet, |
| 570 | 'router': creds.router}) |
Salvatore Orlando | cf996c6 | 2014-01-30 09:15:18 -0800 | [diff] [blame] | 571 | if (not self.network_resources or |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 572 | (self.network_resources.get('router') and creds.subnet)): |
Matthew Treinish | 9f756a0 | 2014-01-15 10:26:07 -0500 | [diff] [blame] | 573 | try: |
Ken'ichi Ohmichi | e35f472 | 2015-12-22 04:57:11 +0000 | [diff] [blame] | 574 | client.remove_router_interface( |
piyush110786 | 94aca95 | 2015-12-17 12:54:44 +0530 | [diff] [blame] | 575 | creds.router['id'], |
| 576 | subnet_id=creds.subnet['id']) |
Masayuki Igawa | bfa0760 | 2015-01-20 18:47:17 +0900 | [diff] [blame] | 577 | except lib_exc.NotFound: |
Jordan Pittier | 525ec71 | 2016-12-07 17:51:26 +0100 | [diff] [blame] | 578 | LOG.warning('router with name: %s not found for delete', |
zhangguoqing | 6c09664 | 2016-01-04 06:17:21 +0000 | [diff] [blame] | 579 | creds.router['name']) |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 580 | self._clear_isolated_router(creds.router['id'], |
| 581 | creds.router['name']) |
Salvatore Orlando | cf996c6 | 2014-01-30 09:15:18 -0800 | [diff] [blame] | 582 | if (not self.network_resources or |
Salvatore Orlando | cf996c6 | 2014-01-30 09:15:18 -0800 | [diff] [blame] | 583 | self.network_resources.get('subnet')): |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 584 | self._clear_isolated_subnet(creds.subnet['id'], |
| 585 | creds.subnet['name']) |
Salvatore Orlando | cf996c6 | 2014-01-30 09:15:18 -0800 | [diff] [blame] | 586 | if (not self.network_resources or |
| 587 | self.network_resources.get('network')): |
Andrea Frittoli (andreaf) | 9540dfd | 2015-03-25 17:06:50 -0400 | [diff] [blame] | 588 | self._clear_isolated_network(creds.network['id'], |
| 589 | creds.network['name']) |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 590 | |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 591 | def clear_creds(self): |
| 592 | if not self._creds: |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 593 | return |
Miguel Lavalle | b8fabc5 | 2013-08-23 11:19:57 -0500 | [diff] [blame] | 594 | self._clear_isolated_net_resources() |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 595 | project_ids = set() |
songwenping | e662307 | 2021-02-22 14:47:34 +0800 | [diff] [blame] | 596 | for creds in self._creds.values(): |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 597 | # NOTE(gmann): With new RBAC personas, we can have single project |
| 598 | # and multiple user created under it, to avoid conflict let's |
| 599 | # cleanup the projects at the end. |
| 600 | # Adding project if id is not None, means leaving domain and |
| 601 | # system creds. |
| 602 | if creds.project_id: |
| 603 | project_ids.add(creds.project_id) |
Matthew Treinish | b86cda9 | 2013-07-29 11:22:23 -0400 | [diff] [blame] | 604 | try: |
Andrea Frittoli | c328015 | 2015-02-26 12:42:34 +0000 | [diff] [blame] | 605 | self.creds_client.delete_user(creds.user_id) |
Masayuki Igawa | bfa0760 | 2015-01-20 18:47:17 +0900 | [diff] [blame] | 606 | except lib_exc.NotFound: |
Jordan Pittier | 525ec71 | 2016-12-07 17:51:26 +0100 | [diff] [blame] | 607 | LOG.warning("user with name: %s not found for delete", |
zhangguoqing | 6c09664 | 2016-01-04 06:17:21 +0000 | [diff] [blame] | 608 | creds.username) |
Colleen Murphy | 06374e2 | 2019-10-02 14:28:22 -0700 | [diff] [blame] | 609 | # if cred is domain scoped, delete ephemeral domain |
| 610 | # do not delete default domain |
| 611 | if (hasattr(creds, 'domain_id') and |
| 612 | creds.domain_id != creds.project_domain_id): |
| 613 | try: |
| 614 | self.creds_client.delete_domain(creds.domain_id) |
| 615 | except lib_exc.NotFound: |
| 616 | LOG.warning("domain with name: %s not found for delete", |
| 617 | creds.domain_name) |
Ghanshyam Mann | 35fc95d | 2023-01-18 23:22:29 -0600 | [diff] [blame] | 618 | for project_id in project_ids: |
| 619 | # NOTE(zhufl): Only when neutron's security_group ext is |
| 620 | # enabled, cleanup_default_secgroup will not raise error. But |
| 621 | # here cannot use test_utils.is_extension_enabled for it will |
| 622 | # cause "circular dependency". So here just use try...except to |
| 623 | # ensure tenant deletion without big changes. |
| 624 | LOG.info("Deleting project and security group for project: %s", |
| 625 | project_id) |
| 626 | |
| 627 | try: |
| 628 | if self.neutron_available: |
| 629 | self.cleanup_default_secgroup( |
| 630 | self.security_groups_admin_client, project_id) |
| 631 | except lib_exc.NotFound: |
| 632 | LOG.warning("failed to cleanup tenant %s's secgroup", |
| 633 | project_id) |
| 634 | try: |
| 635 | self.creds_client.delete_project(project_id) |
| 636 | except lib_exc.NotFound: |
| 637 | LOG.warning("tenant with id: %s not found for delete", |
| 638 | project_id) |
| 639 | |
Andrea Frittoli (andreaf) | 17209bb | 2015-05-22 10:16:57 -0700 | [diff] [blame] | 640 | self._creds = {} |
Andrea Frittoli | 8283b4e | 2014-07-17 13:28:58 +0100 | [diff] [blame] | 641 | |
| 642 | def is_multi_user(self): |
| 643 | return True |
Yair Fried | 76488d7 | 2014-10-21 10:13:19 +0300 | [diff] [blame] | 644 | |
| 645 | def is_multi_tenant(self): |
| 646 | return True |
Matthew Treinish | 4a59693 | 2015-03-06 20:37:01 -0500 | [diff] [blame] | 647 | |
| 648 | def is_role_available(self, role): |
| 649 | return True |