blob: 9b591bc4c250559c94bf37c5b45805f1c1031249 [file] [log] [blame]
David Patersone41ebca2015-04-09 05:40:12 -04001# Copyright 2015 Dell Inc.
David Patersonce781492014-09-18 01:07:01 -04002#
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#
David Patersone41ebca2015-04-09 05:40:12 -04007# http://www.apache.org/licenses/LICENSE-2.0
David Patersonce781492014-09-18 01:07:01 -04008#
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.
David Patersonce781492014-09-18 01:07:01 -040014
Doug Hellmann583ce2c2015-03-11 14:55:46 +000015from oslo_log import log as logging
Lukas Piwowarski2c831242020-03-11 12:25:11 +000016from six.moves.urllib import parse as urllib
Doug Hellmann583ce2c2015-03-11 14:55:46 +000017
ghanshyam009a1f62017-08-08 10:22:57 +030018from tempest import clients
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010019from tempest.common import credentials_factory as credentials
Ken'ichi Ohmichi6ea3f982015-11-09 12:41:13 +000020from tempest.common import identity
Andrea Frittolicd368412017-08-14 21:37:56 +010021from tempest.common import utils
Attila Fazekasd7e08a62016-10-07 13:05:05 +020022from tempest.common.utils import net_info
David Patersonce781492014-09-18 01:07:01 -040023from tempest import config
Martin Kopec97857942019-06-12 15:23:21 +000024from tempest.lib import exceptions
David Patersonce781492014-09-18 01:07:01 -040025
26LOG = logging.getLogger(__name__)
27CONF = config.CONF
28
David Patersonce781492014-09-18 01:07:01 -040029CONF_FLAVORS = None
30CONF_IMAGES = None
David Patersond6babc52014-10-14 00:11:56 -040031CONF_NETWORKS = []
32CONF_PRIV_NETWORK_NAME = None
33CONF_PUB_NETWORK = None
34CONF_PUB_ROUTER = None
Arx Cruz05fe4bc2017-10-20 10:48:28 +020035CONF_PROJECTS = None
David Patersond6babc52014-10-14 00:11:56 -040036CONF_USERS = None
David Patersonce781492014-09-18 01:07:01 -040037
David Patersonce781492014-09-18 01:07:01 -040038IS_CINDER = None
39IS_GLANCE = None
David Patersonce781492014-09-18 01:07:01 -040040IS_NEUTRON = None
41IS_NOVA = None
42
43
44def init_conf():
David Patersonce781492014-09-18 01:07:01 -040045 global CONF_FLAVORS
46 global CONF_IMAGES
David Patersond6babc52014-10-14 00:11:56 -040047 global CONF_NETWORKS
48 global CONF_PRIV_NETWORK
49 global CONF_PRIV_NETWORK_NAME
50 global CONF_PUB_NETWORK
51 global CONF_PUB_ROUTER
Arx Cruz05fe4bc2017-10-20 10:48:28 +020052 global CONF_PROJECTS
David Patersond6babc52014-10-14 00:11:56 -040053 global CONF_USERS
David Patersonce781492014-09-18 01:07:01 -040054 global IS_CINDER
55 global IS_GLANCE
56 global IS_HEAT
57 global IS_NEUTRON
58 global IS_NOVA
59
David Patersonce781492014-09-18 01:07:01 -040060 IS_CINDER = CONF.service_available.cinder
61 IS_GLANCE = CONF.service_available.glance
David Patersonce781492014-09-18 01:07:01 -040062 IS_NEUTRON = CONF.service_available.neutron
63 IS_NOVA = CONF.service_available.nova
64
David Patersond6babc52014-10-14 00:11:56 -040065 CONF_FLAVORS = [CONF.compute.flavor_ref, CONF.compute.flavor_ref_alt]
66 CONF_IMAGES = [CONF.compute.image_ref, CONF.compute.image_ref_alt]
67 CONF_PRIV_NETWORK_NAME = CONF.compute.fixed_network_name
68 CONF_PUB_NETWORK = CONF.network.public_network_id
69 CONF_PUB_ROUTER = CONF.network.public_router_id
Arx Cruz05fe4bc2017-10-20 10:48:28 +020070 CONF_PROJECTS = [CONF.auth.admin_project_name]
Jeffrey Zhangb5e23212016-07-06 14:18:53 +080071 CONF_USERS = [CONF.auth.admin_username]
David Patersond6babc52014-10-14 00:11:56 -040072
73 if IS_NEUTRON:
David Paterson82234022015-04-12 14:07:40 -040074 CONF_PRIV_NETWORK = _get_network_id(CONF.compute.fixed_network_name,
Daniel Melladod4d0b932016-04-08 08:57:29 +000075 CONF.auth.admin_project_name)
David Patersond6babc52014-10-14 00:11:56 -040076 CONF_NETWORKS = [CONF_PUB_NETWORK, CONF_PRIV_NETWORK]
77
78
Daniel Melladod4d0b932016-04-08 08:57:29 +000079def _get_network_id(net_name, project_name):
ghanshyam009a1f62017-08-08 10:22:57 +030080 am = clients.Manager(
81 credentials.get_configured_admin_credentials())
John Warren94d8faf2015-09-15 12:22:24 -040082 net_cl = am.networks_client
Arx Cruz05fe4bc2017-10-20 10:48:28 +020083 pr_cl = am.projects_client
David Patersond6babc52014-10-14 00:11:56 -040084
David Kranz34e88122014-12-11 15:24:05 -050085 networks = net_cl.list_networks()
Arx Cruz05fe4bc2017-10-20 10:48:28 +020086 project = identity.get_project_by_name(pr_cl, project_name)
87 p_id = project['id']
David Patersond6babc52014-10-14 00:11:56 -040088 n_id = None
89 for net in networks['networks']:
Arx Cruz05fe4bc2017-10-20 10:48:28 +020090 if (net['project_id'] == p_id and net['name'] == net_name):
David Patersond6babc52014-10-14 00:11:56 -040091 n_id = net['id']
92 break
93 return n_id
94
David Patersonce781492014-09-18 01:07:01 -040095
96class BaseService(object):
97 def __init__(self, kwargs):
98 self.client = None
99 for key, value in kwargs.items():
100 setattr(self, key, value)
101
David Paterson82234022015-04-12 14:07:40 -0400102 self.tenant_filter = {}
103 if hasattr(self, 'tenant_id'):
Martin Kopecb37903c2019-01-20 21:39:58 +0000104 self.tenant_filter['project_id'] = self.tenant_id
David Paterson82234022015-04-12 14:07:40 -0400105
David Patersonce781492014-09-18 01:07:01 -0400106 def _filter_by_tenant_id(self, item_list):
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200107 if (item_list is None or
108 not item_list or
109 not hasattr(self, 'tenant_id') or
110 self.tenant_id is None or
111 'tenant_id' not in item_list[0]):
David Patersonce781492014-09-18 01:07:01 -0400112 return item_list
113
David Patersond6babc52014-10-14 00:11:56 -0400114 return [item for item in item_list
115 if item['tenant_id'] == self.tenant_id]
David Patersonce781492014-09-18 01:07:01 -0400116
117 def list(self):
118 pass
119
120 def delete(self):
121 pass
122
123 def dry_run(self):
124 pass
125
126 def save_state(self):
127 pass
128
129 def run(self):
Martin Kopec97857942019-06-12 15:23:21 +0000130 try:
131 if self.is_dry_run:
132 self.dry_run()
133 elif self.is_save_state:
134 self.save_state()
135 else:
136 self.delete()
137 except exceptions.NotImplemented as exc:
138 # Many OpenStack services use extensions logic to implement the
139 # features or resources. Tempest cleanup tries to clean up the test
140 # resources without having much logic of extensions checks etc.
141 # If any of the extension is missing then, service will return
142 # NotImplemented error.
143 msg = ("Got NotImplemented error in %s, full exception: %s" %
144 (str(self.__class__), str(exc)))
145 LOG.exception(msg)
Martin Kopec219e3222019-08-05 20:02:20 +0000146 self.got_exceptions.append(exc)
David Patersonce781492014-09-18 01:07:01 -0400147
148
149class SnapshotService(BaseService):
150
151 def __init__(self, manager, **kwargs):
152 super(SnapshotService, self).__init__(kwargs)
ghanshyam59928952017-10-26 01:38:45 +0000153 self.client = manager.snapshots_client_latest
David Patersonce781492014-09-18 01:07:01 -0400154
155 def list(self):
156 client = self.client
David Paterson07661de2015-10-29 20:15:04 -0700157 snaps = client.list_snapshots()['snapshots']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000158 if not self.is_save_state:
159 # recreate list removing saved snapshots
160 snaps = [snap for snap in snaps if snap['id']
161 not in self.saved_state_json['snapshots'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100162 LOG.debug("List count, %s Snapshots", len(snaps))
David Patersonce781492014-09-18 01:07:01 -0400163 return snaps
164
165 def delete(self):
166 snaps = self.list()
167 client = self.client
168 for snap in snaps:
169 try:
170 client.delete_snapshot(snap['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400171 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000172 LOG.exception("Delete Snapshot %s exception.", snap['id'])
David Patersonce781492014-09-18 01:07:01 -0400173
174 def dry_run(self):
175 snaps = self.list()
176 self.data['snapshots'] = snaps
177
Martin Kopec5a884bf2019-02-11 18:10:55 +0000178 def save_state(self):
179 snaps = self.list()
180 self.data['snapshots'] = {}
181 for snap in snaps:
182 self.data['snapshots'][snap['id']] = snap['name']
183
David Patersonce781492014-09-18 01:07:01 -0400184
185class ServerService(BaseService):
186 def __init__(self, manager, **kwargs):
187 super(ServerService, self).__init__(kwargs)
188 self.client = manager.servers_client
David Paterson07661de2015-10-29 20:15:04 -0700189 self.server_groups_client = manager.server_groups_client
David Patersonce781492014-09-18 01:07:01 -0400190
191 def list(self):
192 client = self.client
David Kranzae99b9a2015-02-16 13:37:01 -0500193 servers_body = client.list_servers()
David Patersonce781492014-09-18 01:07:01 -0400194 servers = servers_body['servers']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000195 if not self.is_save_state:
196 # recreate list removing saved servers
197 servers = [server for server in servers if server['id']
198 not in self.saved_state_json['servers'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100199 LOG.debug("List count, %s Servers", len(servers))
David Patersonce781492014-09-18 01:07:01 -0400200 return servers
201
202 def delete(self):
203 client = self.client
204 servers = self.list()
205 for server in servers:
206 try:
207 client.delete_server(server['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400208 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000209 LOG.exception("Delete Server %s exception.", server['id'])
David Patersonce781492014-09-18 01:07:01 -0400210
211 def dry_run(self):
212 servers = self.list()
213 self.data['servers'] = servers
214
Martin Kopec5a884bf2019-02-11 18:10:55 +0000215 def save_state(self):
216 servers = self.list()
217 self.data['servers'] = {}
218 for server in servers:
219 self.data['servers'][server['id']] = server['name']
220
David Patersonce781492014-09-18 01:07:01 -0400221
222class ServerGroupService(ServerService):
223
224 def list(self):
David Paterson07661de2015-10-29 20:15:04 -0700225 client = self.server_groups_client
ghanshyam2dc13452015-08-24 17:39:25 +0900226 sgs = client.list_server_groups()['server_groups']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000227 if not self.is_save_state:
228 # recreate list removing saved server_groups
229 sgs = [sg for sg in sgs if sg['id']
230 not in self.saved_state_json['server_groups'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100231 LOG.debug("List count, %s Server Groups", len(sgs))
David Patersonce781492014-09-18 01:07:01 -0400232 return sgs
233
234 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000235 client = self.server_groups_client
David Patersonce781492014-09-18 01:07:01 -0400236 sgs = self.list()
237 for sg in sgs:
238 try:
239 client.delete_server_group(sg['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400240 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000241 LOG.exception("Delete Server Group %s exception.", sg['id'])
David Patersonce781492014-09-18 01:07:01 -0400242
243 def dry_run(self):
244 sgs = self.list()
245 self.data['server_groups'] = sgs
246
Martin Kopec5a884bf2019-02-11 18:10:55 +0000247 def save_state(self):
248 sgs = self.list()
249 self.data['server_groups'] = {}
250 for sg in sgs:
251 self.data['server_groups'][sg['id']] = sg['name']
252
David Patersonce781492014-09-18 01:07:01 -0400253
David Patersonce781492014-09-18 01:07:01 -0400254class KeyPairService(BaseService):
255 def __init__(self, manager, **kwargs):
256 super(KeyPairService, self).__init__(kwargs)
257 self.client = manager.keypairs_client
258
259 def list(self):
260 client = self.client
ghanshyamdee01f22015-08-17 11:41:47 +0900261 keypairs = client.list_keypairs()['keypairs']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000262 if not self.is_save_state:
263 # recreate list removing saved keypairs
264 keypairs = [keypair for keypair in keypairs
265 if keypair['keypair']['name']
266 not in self.saved_state_json['keypairs'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100267 LOG.debug("List count, %s Keypairs", len(keypairs))
David Patersonce781492014-09-18 01:07:01 -0400268 return keypairs
269
270 def delete(self):
271 client = self.client
272 keypairs = self.list()
273 for k in keypairs:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000274 name = k['keypair']['name']
David Patersonce781492014-09-18 01:07:01 -0400275 try:
David Patersonce781492014-09-18 01:07:01 -0400276 client.delete_keypair(name)
David Patersone41ebca2015-04-09 05:40:12 -0400277 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000278 LOG.exception("Delete Keypair %s exception.", name)
David Patersonce781492014-09-18 01:07:01 -0400279
280 def dry_run(self):
281 keypairs = self.list()
282 self.data['keypairs'] = keypairs
283
Martin Kopec5a884bf2019-02-11 18:10:55 +0000284 def save_state(self):
285 keypairs = self.list()
286 self.data['keypairs'] = {}
287 for keypair in keypairs:
288 keypair = keypair['keypair']
289 self.data['keypairs'][keypair['name']] = keypair
290
David Patersonce781492014-09-18 01:07:01 -0400291
David Patersonce781492014-09-18 01:07:01 -0400292class VolumeService(BaseService):
293 def __init__(self, manager, **kwargs):
294 super(VolumeService, self).__init__(kwargs)
ghanshyam59928952017-10-26 01:38:45 +0000295 self.client = manager.volumes_client_latest
David Patersonce781492014-09-18 01:07:01 -0400296
297 def list(self):
298 client = self.client
John Warren6177c9e2015-08-19 20:00:17 +0000299 vols = client.list_volumes()['volumes']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000300 if not self.is_save_state:
301 # recreate list removing saved volumes
302 vols = [vol for vol in vols if vol['id']
303 not in self.saved_state_json['volumes'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100304 LOG.debug("List count, %s Volumes", len(vols))
David Patersonce781492014-09-18 01:07:01 -0400305 return vols
306
307 def delete(self):
308 client = self.client
309 vols = self.list()
310 for v in vols:
311 try:
312 client.delete_volume(v['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400313 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000314 LOG.exception("Delete Volume %s exception.", v['id'])
David Patersonce781492014-09-18 01:07:01 -0400315
316 def dry_run(self):
317 vols = self.list()
318 self.data['volumes'] = vols
319
Martin Kopec5a884bf2019-02-11 18:10:55 +0000320 def save_state(self):
321 vols = self.list()
322 self.data['volumes'] = {}
323 for vol in vols:
324 self.data['volumes'][vol['id']] = vol['name']
325
David Patersonce781492014-09-18 01:07:01 -0400326
David Paterson35c8df02015-04-05 04:35:31 -0400327class VolumeQuotaService(BaseService):
328 def __init__(self, manager, **kwargs):
329 super(VolumeQuotaService, self).__init__(kwargs)
ghanshyam6c682ff2018-08-06 09:54:45 +0000330 self.client = manager.volume_quotas_client_latest
David Paterson35c8df02015-04-05 04:35:31 -0400331
332 def delete(self):
333 client = self.client
334 try:
Martin Kopecb37903c2019-01-20 21:39:58 +0000335 client.delete_quota_set(self.project_id)
David Patersone41ebca2015-04-09 05:40:12 -0400336 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000337 LOG.exception("Delete Volume Quotas exception for 'project %s'.",
338 self.project_id)
David Paterson35c8df02015-04-05 04:35:31 -0400339
340 def dry_run(self):
Ken'ichi Ohmichi3cf9eaf2016-07-29 11:05:21 -0700341 quotas = self.client.show_quota_set(
Martin Kopecb37903c2019-01-20 21:39:58 +0000342 self.project_id, params={'usage': True})['quota_set']
David Paterson35c8df02015-04-05 04:35:31 -0400343 self.data['volume_quotas'] = quotas
344
345
346class NovaQuotaService(BaseService):
347 def __init__(self, manager, **kwargs):
348 super(NovaQuotaService, self).__init__(kwargs)
349 self.client = manager.quotas_client
350 self.limits_client = manager.limits_client
351
352 def delete(self):
353 client = self.client
354 try:
Martin Kopecb37903c2019-01-20 21:39:58 +0000355 client.delete_quota_set(self.project_id)
David Patersone41ebca2015-04-09 05:40:12 -0400356 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000357 LOG.exception("Delete Quotas exception for 'project %s'.",
358 self.project_id)
David Paterson35c8df02015-04-05 04:35:31 -0400359
360 def dry_run(self):
361 client = self.limits_client
ghanshyam8a599492015-08-24 15:55:59 +0900362 quotas = client.show_limits()['limits']
Ken'ichi Ohmichib93e6762015-06-15 07:11:29 +0000363 self.data['compute_quotas'] = quotas['absolute']
David Paterson35c8df02015-04-05 04:35:31 -0400364
365
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000366class NetworkQuotaService(BaseService):
367 def __init__(self, manager, **kwargs):
368 super(NetworkQuotaService, self).__init__(kwargs)
369 self.client = manager.network_quotas_client
370
371 def delete(self):
372 client = self.client
373 try:
374 client.reset_quotas(self.project_id)
375 except Exception:
376 LOG.exception("Delete Network Quotas exception for 'project %s'.",
377 self.project_id)
378
379 def dry_run(self):
380 resp = [quota for quota in self.client.list_quotas()['quotas']
381 if quota['project_id'] == self.project_id]
382 self.data['network_quotas'] = resp
383
384
David Patersonce781492014-09-18 01:07:01 -0400385# Begin network service classes
Martin Kopec5a884bf2019-02-11 18:10:55 +0000386class BaseNetworkService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400387 def __init__(self, manager, **kwargs):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000388 super(BaseNetworkService, self).__init__(kwargs)
John Warren94d8faf2015-09-15 12:22:24 -0400389 self.networks_client = manager.networks_client
John Warren3961acd2015-10-02 14:38:53 -0400390 self.subnets_client = manager.subnets_client
John Warren49c0fe52015-10-22 12:35:54 -0400391 self.ports_client = manager.ports_client
John Warrenfbf2a892015-11-17 12:36:14 -0500392 self.floating_ips_client = manager.floating_ips_client
John Warren6d0083a2015-11-30 18:12:30 -0500393 self.metering_labels_client = manager.metering_labels_client
John Warrendd20b3e2015-12-03 13:11:28 -0500394 self.metering_label_rules_client = manager.metering_label_rules_client
John Warrenf9606e92015-12-10 12:12:42 -0500395 self.security_groups_client = manager.security_groups_client
ghanshyama25c4192016-03-11 18:38:12 +0900396 self.routers_client = manager.routers_client
Martin Kopece6819982019-02-18 12:34:52 +0000397 self.subnetpools_client = manager.subnetpools_client
David Patersonce781492014-09-18 01:07:01 -0400398
David Patersond6babc52014-10-14 00:11:56 -0400399 def _filter_by_conf_networks(self, item_list):
400 if not item_list or not all(('network_id' in i for i in item_list)):
401 return item_list
402
403 return [item for item in item_list if item['network_id']
404 not in CONF_NETWORKS]
405
Martin Kopec5a884bf2019-02-11 18:10:55 +0000406
407class NetworkService(BaseNetworkService):
408
David Patersonce781492014-09-18 01:07:01 -0400409 def list(self):
John Warren94d8faf2015-09-15 12:22:24 -0400410 client = self.networks_client
David Paterson82234022015-04-12 14:07:40 -0400411 networks = client.list_networks(**self.tenant_filter)
412 networks = networks['networks']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000413
414 if not self.is_save_state:
415 # recreate list removing saved networks
416 networks = [network for network in networks if network['id']
417 not in self.saved_state_json['networks'].keys()]
David Patersonce781492014-09-18 01:07:01 -0400418 # filter out networks declared in tempest.conf
419 if self.is_preserve:
420 networks = [network for network in networks
David Patersond6babc52014-10-14 00:11:56 -0400421 if network['id'] not in CONF_NETWORKS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100422 LOG.debug("List count, %s Networks", networks)
David Patersonce781492014-09-18 01:07:01 -0400423 return networks
424
425 def delete(self):
John Warren94d8faf2015-09-15 12:22:24 -0400426 client = self.networks_client
David Patersonce781492014-09-18 01:07:01 -0400427 networks = self.list()
428 for n in networks:
429 try:
430 client.delete_network(n['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400431 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000432 LOG.exception("Delete Network %s exception.", n['id'])
David Patersonce781492014-09-18 01:07:01 -0400433
434 def dry_run(self):
435 networks = self.list()
436 self.data['networks'] = networks
437
Martin Kopec5a884bf2019-02-11 18:10:55 +0000438 def save_state(self):
439 networks = self.list()
440 self.data['networks'] = {}
441 for network in networks:
442 self.data['networks'][network['id']] = network
David Patersonce781492014-09-18 01:07:01 -0400443
Martin Kopec5a884bf2019-02-11 18:10:55 +0000444
445class NetworkFloatingIpService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400446
447 def list(self):
John Warrenfbf2a892015-11-17 12:36:14 -0500448 client = self.floating_ips_client
David Paterson82234022015-04-12 14:07:40 -0400449 flips = client.list_floatingips(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400450 flips = flips['floatingips']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000451
452 if not self.is_save_state:
453 # recreate list removing saved flips
454 flips = [flip for flip in flips if flip['id']
455 not in self.saved_state_json['floatingips'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100456 LOG.debug("List count, %s Network Floating IPs", len(flips))
David Patersonce781492014-09-18 01:07:01 -0400457 return flips
458
459 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000460 client = self.floating_ips_client
David Patersonce781492014-09-18 01:07:01 -0400461 flips = self.list()
462 for flip in flips:
463 try:
464 client.delete_floatingip(flip['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400465 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000466 LOG.exception("Delete Network Floating IP %s exception.",
467 flip['id'])
David Patersonce781492014-09-18 01:07:01 -0400468
469 def dry_run(self):
470 flips = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000471 self.data['floatingips'] = flips
472
473 def save_state(self):
474 flips = self.list()
475 self.data['floatingips'] = {}
476 for flip in flips:
477 self.data['floatingips'][flip['id']] = flip
David Patersonce781492014-09-18 01:07:01 -0400478
479
Martin Kopec5a884bf2019-02-11 18:10:55 +0000480class NetworkRouterService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400481
482 def list(self):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000483 client = self.routers_client
David Paterson82234022015-04-12 14:07:40 -0400484 routers = client.list_routers(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400485 routers = routers['routers']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000486
487 if not self.is_save_state:
488 # recreate list removing saved routers
489 routers = [router for router in routers if router['id']
490 not in self.saved_state_json['routers'].keys()]
David Patersonce781492014-09-18 01:07:01 -0400491 if self.is_preserve:
492 routers = [router for router in routers
493 if router['id'] != CONF_PUB_ROUTER]
494
Jordan Pittier525ec712016-12-07 17:51:26 +0100495 LOG.debug("List count, %s Routers", len(routers))
David Patersonce781492014-09-18 01:07:01 -0400496 return routers
497
498 def delete(self):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000499 client = self.routers_client
Ken'ichi Ohmichif3110f02016-03-21 12:29:03 -0700500 ports_client = self.ports_client
David Patersonce781492014-09-18 01:07:01 -0400501 routers = self.list()
502 for router in routers:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000503 rid = router['id']
Martin Kopec598b1ae2019-04-01 14:41:53 +0000504 ports = [port for port
505 in ports_client.list_ports(device_id=rid)['ports']
506 if net_info.is_router_interface_port(port)]
507 for port in ports:
508 try:
piyush11078694aca952015-12-17 12:54:44 +0530509 client.remove_router_interface(rid, port_id=port['id'])
Martin Kopec598b1ae2019-04-01 14:41:53 +0000510 except Exception:
511 LOG.exception("Delete Router Interface exception for "
512 "'port %s' of 'router %s'.", port['id'], rid)
513 try:
David Patersond6babc52014-10-14 00:11:56 -0400514 client.delete_router(rid)
David Patersone41ebca2015-04-09 05:40:12 -0400515 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000516 LOG.exception("Delete Router %s exception.", rid)
David Patersonce781492014-09-18 01:07:01 -0400517
518 def dry_run(self):
519 routers = self.list()
520 self.data['routers'] = routers
521
Martin Kopec5a884bf2019-02-11 18:10:55 +0000522 def save_state(self):
523 routers = self.list()
524 self.data['routers'] = {}
525 for router in routers:
526 self.data['routers'][router['id']] = router['name']
527
David Patersonce781492014-09-18 01:07:01 -0400528
Alexander Gubanov13379bb2015-05-19 18:57:32 +0300529class NetworkMeteringLabelRuleService(NetworkService):
David Patersonce781492014-09-18 01:07:01 -0400530
531 def list(self):
John Warrendd20b3e2015-12-03 13:11:28 -0500532 client = self.metering_label_rules_client
David Kranz34e88122014-12-11 15:24:05 -0500533 rules = client.list_metering_label_rules()
David Patersonce781492014-09-18 01:07:01 -0400534 rules = rules['metering_label_rules']
535 rules = self._filter_by_tenant_id(rules)
Martin Kopec5a884bf2019-02-11 18:10:55 +0000536
537 if not self.is_save_state:
538 saved_rules = self.saved_state_json['metering_label_rules'].keys()
539 # recreate list removing saved rules
540 rules = [rule for rule in rules if rule['id'] not in saved_rules]
Jordan Pittier525ec712016-12-07 17:51:26 +0100541 LOG.debug("List count, %s Metering Label Rules", len(rules))
David Patersonce781492014-09-18 01:07:01 -0400542 return rules
543
544 def delete(self):
John Warrendd20b3e2015-12-03 13:11:28 -0500545 client = self.metering_label_rules_client
David Patersonce781492014-09-18 01:07:01 -0400546 rules = self.list()
547 for rule in rules:
548 try:
549 client.delete_metering_label_rule(rule['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400550 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000551 LOG.exception("Delete Metering Label Rule %s exception.",
552 rule['id'])
David Patersonce781492014-09-18 01:07:01 -0400553
554 def dry_run(self):
555 rules = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000556 self.data['metering_label_rules'] = rules
557
558 def save_state(self):
559 rules = self.list()
560 self.data['metering_label_rules'] = {}
561 for rule in rules:
562 self.data['metering_label_rules'][rule['id']] = rule
David Patersonce781492014-09-18 01:07:01 -0400563
564
Martin Kopec5a884bf2019-02-11 18:10:55 +0000565class NetworkMeteringLabelService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400566
567 def list(self):
John Warren6d0083a2015-11-30 18:12:30 -0500568 client = self.metering_labels_client
David Kranz34e88122014-12-11 15:24:05 -0500569 labels = client.list_metering_labels()
David Patersonce781492014-09-18 01:07:01 -0400570 labels = labels['metering_labels']
571 labels = self._filter_by_tenant_id(labels)
Martin Kopec5a884bf2019-02-11 18:10:55 +0000572
573 if not self.is_save_state:
574 # recreate list removing saved labels
575 labels = [label for label in labels if label['id']
576 not in self.saved_state_json['metering_labels'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100577 LOG.debug("List count, %s Metering Labels", len(labels))
David Patersonce781492014-09-18 01:07:01 -0400578 return labels
579
580 def delete(self):
John Warren6d0083a2015-11-30 18:12:30 -0500581 client = self.metering_labels_client
David Patersonce781492014-09-18 01:07:01 -0400582 labels = self.list()
583 for label in labels:
584 try:
585 client.delete_metering_label(label['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400586 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000587 LOG.exception("Delete Metering Label %s exception.",
588 label['id'])
David Patersonce781492014-09-18 01:07:01 -0400589
590 def dry_run(self):
591 labels = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000592 self.data['metering_labels'] = labels
593
594 def save_state(self):
595 labels = self.list()
596 self.data['metering_labels'] = {}
597 for label in labels:
598 self.data['metering_labels'][label['id']] = label['name']
David Patersonce781492014-09-18 01:07:01 -0400599
600
Martin Kopec5a884bf2019-02-11 18:10:55 +0000601class NetworkPortService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400602
603 def list(self):
John Warren49c0fe52015-10-22 12:35:54 -0400604 client = self.ports_client
David Paterson82234022015-04-12 14:07:40 -0400605 ports = [port for port in
606 client.list_ports(**self.tenant_filter)['ports']
607 if port["device_owner"] == "" or
608 port["device_owner"].startswith("compute:")]
609
Martin Kopec5a884bf2019-02-11 18:10:55 +0000610 if not self.is_save_state:
611 # recreate list removing saved ports
612 ports = [port for port in ports if port['id']
613 not in self.saved_state_json['ports'].keys()]
David Patersond6babc52014-10-14 00:11:56 -0400614 if self.is_preserve:
615 ports = self._filter_by_conf_networks(ports)
David Paterson82234022015-04-12 14:07:40 -0400616
Jordan Pittier525ec712016-12-07 17:51:26 +0100617 LOG.debug("List count, %s Ports", len(ports))
David Patersonce781492014-09-18 01:07:01 -0400618 return ports
619
620 def delete(self):
John Warren49c0fe52015-10-22 12:35:54 -0400621 client = self.ports_client
David Patersonce781492014-09-18 01:07:01 -0400622 ports = self.list()
623 for port in ports:
624 try:
625 client.delete_port(port['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400626 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000627 LOG.exception("Delete Port %s exception.", port['id'])
David Patersonce781492014-09-18 01:07:01 -0400628
629 def dry_run(self):
630 ports = self.list()
631 self.data['ports'] = ports
632
Martin Kopec5a884bf2019-02-11 18:10:55 +0000633 def save_state(self):
634 ports = self.list()
635 self.data['ports'] = {}
636 for port in ports:
637 self.data['ports'][port['id']] = port['name']
David Patersonce781492014-09-18 01:07:01 -0400638
Martin Kopec5a884bf2019-02-11 18:10:55 +0000639
640class NetworkSecGroupService(BaseNetworkService):
David Paterson82234022015-04-12 14:07:40 -0400641 def list(self):
John Warrenf9606e92015-12-10 12:12:42 -0500642 client = self.security_groups_client
David Paterson82234022015-04-12 14:07:40 -0400643 filter = self.tenant_filter
644 # cannot delete default sec group so never show it.
645 secgroups = [secgroup for secgroup in
646 client.list_security_groups(**filter)['security_groups']
647 if secgroup['name'] != 'default']
648
Martin Kopec5a884bf2019-02-11 18:10:55 +0000649 if not self.is_save_state:
650 # recreate list removing saved security_groups
651 secgroups = [secgroup for secgroup in secgroups if secgroup['id']
652 not in self.saved_state_json['security_groups'].keys()
653 ]
David Paterson82234022015-04-12 14:07:40 -0400654 if self.is_preserve:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000655 secgroups = [secgroup for secgroup in secgroups
656 if secgroup['security_group_rules'][0]['project_id']
657 not in CONF_PROJECTS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100658 LOG.debug("List count, %s security_groups", len(secgroups))
David Paterson82234022015-04-12 14:07:40 -0400659 return secgroups
660
661 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000662 client = self.security_groups_client
David Paterson82234022015-04-12 14:07:40 -0400663 secgroups = self.list()
664 for secgroup in secgroups:
665 try:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000666 client.delete_security_group(secgroup['id'])
David Paterson82234022015-04-12 14:07:40 -0400667 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000668 LOG.exception("Delete security_group %s exception.",
669 secgroup['id'])
David Paterson82234022015-04-12 14:07:40 -0400670
671 def dry_run(self):
672 secgroups = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000673 self.data['security_groups'] = secgroups
674
675 def save_state(self):
676 secgroups = self.list()
677 self.data['security_groups'] = {}
678 for secgroup in secgroups:
679 self.data['security_groups'][secgroup['id']] = secgroup['name']
David Paterson82234022015-04-12 14:07:40 -0400680
681
Martin Kopec5a884bf2019-02-11 18:10:55 +0000682class NetworkSubnetService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400683
684 def list(self):
John Warren3961acd2015-10-02 14:38:53 -0400685 client = self.subnets_client
David Paterson82234022015-04-12 14:07:40 -0400686 subnets = client.list_subnets(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400687 subnets = subnets['subnets']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000688 if not self.is_save_state:
689 # recreate list removing saved subnets
690 subnets = [subnet for subnet in subnets if subnet['id']
691 not in self.saved_state_json['subnets'].keys()]
David Patersond6babc52014-10-14 00:11:56 -0400692 if self.is_preserve:
693 subnets = self._filter_by_conf_networks(subnets)
Jordan Pittier525ec712016-12-07 17:51:26 +0100694 LOG.debug("List count, %s Subnets", len(subnets))
David Patersonce781492014-09-18 01:07:01 -0400695 return subnets
696
697 def delete(self):
John Warren3961acd2015-10-02 14:38:53 -0400698 client = self.subnets_client
David Patersonce781492014-09-18 01:07:01 -0400699 subnets = self.list()
700 for subnet in subnets:
701 try:
702 client.delete_subnet(subnet['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400703 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000704 LOG.exception("Delete Subnet %s exception.", subnet['id'])
David Patersonce781492014-09-18 01:07:01 -0400705
706 def dry_run(self):
707 subnets = self.list()
708 self.data['subnets'] = subnets
709
Martin Kopec5a884bf2019-02-11 18:10:55 +0000710 def save_state(self):
711 subnets = self.list()
712 self.data['subnets'] = {}
713 for subnet in subnets:
714 self.data['subnets'][subnet['id']] = subnet['name']
715
David Patersonce781492014-09-18 01:07:01 -0400716
Martin Kopece6819982019-02-18 12:34:52 +0000717class NetworkSubnetPoolsService(BaseNetworkService):
718
719 def list(self):
720 client = self.subnetpools_client
721 pools = client.list_subnetpools(**self.tenant_filter)['subnetpools']
722 if not self.is_save_state:
723 # recreate list removing saved subnet pools
724 pools = [pool for pool in pools if pool['id']
725 not in self.saved_state_json['subnetpools'].keys()]
726 if self.is_preserve:
727 pools = [pool for pool in pools if pool['project_id']
728 not in CONF_PROJECTS]
729 LOG.debug("List count, %s Subnet Pools", len(pools))
730 return pools
731
732 def delete(self):
733 client = self.subnetpools_client
734 pools = self.list()
735 for pool in pools:
736 try:
737 client.delete_subnetpool(pool['id'])
738 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000739 LOG.exception("Delete Subnet Pool %s exception.", pool['id'])
Martin Kopece6819982019-02-18 12:34:52 +0000740
741 def dry_run(self):
742 pools = self.list()
743 self.data['subnetpools'] = pools
744
745 def save_state(self):
746 pools = self.list()
747 self.data['subnetpools'] = {}
748 for pool in pools:
749 self.data['subnetpools'][pool['id']] = pool['name']
750
751
David Patersonce781492014-09-18 01:07:01 -0400752# begin global services
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000753class RegionService(BaseService):
754
755 def __init__(self, manager, **kwargs):
756 super(RegionService, self).__init__(kwargs)
757 self.client = manager.regions_client
758
759 def list(self):
760 client = self.client
761 regions = client.list_regions()
762 if not self.is_save_state:
763 regions = [region for region in regions['regions'] if region['id']
764 not in self.saved_state_json['regions'].keys()]
765 return regions
766 else:
767 return regions['regions']
768
769 def delete(self):
770 client = self.client
771 regions = self.list()
772 for region in regions:
773 try:
774 client.delete_region(region['id'])
775 except Exception:
776 LOG.exception("Delete Region %s exception.", region['id'])
777
778 def dry_run(self):
779 regions = self.list()
780 self.data['regions'] = {}
781 for region in regions:
782 self.data['regions'][region['id']] = region
783
784 def save_state(self):
785 regions = self.list()
786 self.data['regions'] = {}
787 for region in regions:
788 self.data['regions'][region['id']] = region
789
790
David Patersonce781492014-09-18 01:07:01 -0400791class FlavorService(BaseService):
792 def __init__(self, manager, **kwargs):
793 super(FlavorService, self).__init__(kwargs)
794 self.client = manager.flavors_client
795
796 def list(self):
797 client = self.client
ghanshyam19973be2015-08-18 15:46:42 +0900798 flavors = client.list_flavors({"is_public": None})['flavors']
David Patersonce781492014-09-18 01:07:01 -0400799 if not self.is_save_state:
800 # recreate list removing saved flavors
801 flavors = [flavor for flavor in flavors if flavor['id']
802 not in self.saved_state_json['flavors'].keys()]
803
804 if self.is_preserve:
805 flavors = [flavor for flavor in flavors
806 if flavor['id'] not in CONF_FLAVORS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100807 LOG.debug("List count, %s Flavors after reconcile", len(flavors))
David Patersonce781492014-09-18 01:07:01 -0400808 return flavors
809
810 def delete(self):
811 client = self.client
812 flavors = self.list()
813 for flavor in flavors:
814 try:
815 client.delete_flavor(flavor['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400816 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000817 LOG.exception("Delete Flavor %s exception.", flavor['id'])
David Patersonce781492014-09-18 01:07:01 -0400818
819 def dry_run(self):
820 flavors = self.list()
821 self.data['flavors'] = flavors
822
823 def save_state(self):
824 flavors = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500825 self.data['flavors'] = {}
David Patersonce781492014-09-18 01:07:01 -0400826 for flavor in flavors:
gordon chungc15f1bc2015-02-23 18:00:41 -0500827 self.data['flavors'][flavor['id']] = flavor['name']
David Patersonce781492014-09-18 01:07:01 -0400828
829
830class ImageService(BaseService):
831 def __init__(self, manager, **kwargs):
832 super(ImageService, self).__init__(kwargs)
zhufl66275c22018-03-28 15:32:14 +0800833 self.client = manager.image_client_v2
David Patersonce781492014-09-18 01:07:01 -0400834
835 def list(self):
836 client = self.client
Lukas Piwowarski2c831242020-03-11 12:25:11 +0000837 response = client.list_images()
838 images = []
839 images.extend(response['images'])
840 while 'next' in response:
841 parsed = urllib.urlparse(response['next'])
842 marker = urllib.parse_qs(parsed.query)['marker'][0]
843 response = client.list_images(params={"marker": marker})
844 images.extend(response['images'])
845
David Patersonce781492014-09-18 01:07:01 -0400846 if not self.is_save_state:
847 images = [image for image in images if image['id']
848 not in self.saved_state_json['images'].keys()]
849 if self.is_preserve:
850 images = [image for image in images
851 if image['id'] not in CONF_IMAGES]
Jordan Pittier525ec712016-12-07 17:51:26 +0100852 LOG.debug("List count, %s Images after reconcile", len(images))
David Patersonce781492014-09-18 01:07:01 -0400853 return images
854
855 def delete(self):
856 client = self.client
857 images = self.list()
858 for image in images:
859 try:
860 client.delete_image(image['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400861 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000862 LOG.exception("Delete Image %s exception.", image['id'])
David Patersonce781492014-09-18 01:07:01 -0400863
864 def dry_run(self):
865 images = self.list()
866 self.data['images'] = images
867
868 def save_state(self):
gordon chungc15f1bc2015-02-23 18:00:41 -0500869 self.data['images'] = {}
David Paterson82234022015-04-12 14:07:40 -0400870 images = self.list()
David Patersonce781492014-09-18 01:07:01 -0400871 for image in images:
gordon chungc15f1bc2015-02-23 18:00:41 -0500872 self.data['images'][image['id']] = image['name']
David Patersonce781492014-09-18 01:07:01 -0400873
874
Daniel Mellado82c83a52015-12-09 15:16:49 +0000875class UserService(BaseService):
876
877 def __init__(self, manager, **kwargs):
878 super(UserService, self).__init__(kwargs)
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200879 self.client = manager.users_v3_client
David Patersonce781492014-09-18 01:07:01 -0400880
881 def list(self):
Daniel Mellado82c83a52015-12-09 15:16:49 +0000882 users = self.client.list_users()['users']
David Patersonce781492014-09-18 01:07:01 -0400883
884 if not self.is_save_state:
885 users = [user for user in users if user['id']
886 not in self.saved_state_json['users'].keys()]
887
888 if self.is_preserve:
889 users = [user for user in users if user['name']
890 not in CONF_USERS]
891
892 elif not self.is_save_state: # Never delete admin user
893 users = [user for user in users if user['name'] !=
David Paterson07661de2015-10-29 20:15:04 -0700894 CONF.auth.admin_username]
David Patersonce781492014-09-18 01:07:01 -0400895
Jordan Pittier525ec712016-12-07 17:51:26 +0100896 LOG.debug("List count, %s Users after reconcile", len(users))
David Patersonce781492014-09-18 01:07:01 -0400897 return users
898
899 def delete(self):
David Patersonce781492014-09-18 01:07:01 -0400900 users = self.list()
901 for user in users:
902 try:
Daniel Mellado82c83a52015-12-09 15:16:49 +0000903 self.client.delete_user(user['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400904 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000905 LOG.exception("Delete User %s exception.", user['id'])
David Patersonce781492014-09-18 01:07:01 -0400906
907 def dry_run(self):
908 users = self.list()
909 self.data['users'] = users
910
911 def save_state(self):
912 users = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500913 self.data['users'] = {}
David Patersonce781492014-09-18 01:07:01 -0400914 for user in users:
gordon chungc15f1bc2015-02-23 18:00:41 -0500915 self.data['users'][user['id']] = user['name']
David Patersonce781492014-09-18 01:07:01 -0400916
917
Daniel Melladob83ea562015-12-18 09:12:49 +0000918class RoleService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400919
Daniel Mellado6b16b922015-12-07 12:43:08 +0000920 def __init__(self, manager, **kwargs):
921 super(RoleService, self).__init__(kwargs)
Martin Kopecbd5be762019-07-13 22:42:08 +0000922 self.client = manager.roles_v3_client
Daniel Mellado6b16b922015-12-07 12:43:08 +0000923
David Patersonce781492014-09-18 01:07:01 -0400924 def list(self):
David Patersonce781492014-09-18 01:07:01 -0400925 try:
Daniel Mellado6b16b922015-12-07 12:43:08 +0000926 roles = self.client.list_roles()['roles']
David Patersonce781492014-09-18 01:07:01 -0400927 # reconcile roles with saved state and never list admin role
928 if not self.is_save_state:
929 roles = [role for role in roles if
930 (role['id'] not in
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200931 self.saved_state_json['roles'].keys() and
932 role['name'] != CONF.identity.admin_role)]
Jordan Pittier525ec712016-12-07 17:51:26 +0100933 LOG.debug("List count, %s Roles after reconcile", len(roles))
David Patersonce781492014-09-18 01:07:01 -0400934 return roles
David Patersone41ebca2015-04-09 05:40:12 -0400935 except Exception:
936 LOG.exception("Cannot retrieve Roles.")
David Patersonce781492014-09-18 01:07:01 -0400937 return []
938
939 def delete(self):
David Patersonce781492014-09-18 01:07:01 -0400940 roles = self.list()
941 for role in roles:
942 try:
Daniel Mellado6b16b922015-12-07 12:43:08 +0000943 self.client.delete_role(role['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400944 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000945 LOG.exception("Delete Role %s exception.", role['id'])
David Patersonce781492014-09-18 01:07:01 -0400946
947 def dry_run(self):
948 roles = self.list()
949 self.data['roles'] = roles
950
951 def save_state(self):
952 roles = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500953 self.data['roles'] = {}
David Patersonce781492014-09-18 01:07:01 -0400954 for role in roles:
gordon chungc15f1bc2015-02-23 18:00:41 -0500955 self.data['roles'][role['id']] = role['name']
David Patersonce781492014-09-18 01:07:01 -0400956
957
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200958class ProjectService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400959
Daniel Melladob04da902015-11-20 17:43:12 +0100960 def __init__(self, manager, **kwargs):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200961 super(ProjectService, self).__init__(kwargs)
962 self.client = manager.projects_client
Daniel Melladob04da902015-11-20 17:43:12 +0100963
David Patersonce781492014-09-18 01:07:01 -0400964 def list(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200965 projects = self.client.list_projects()['projects']
David Patersonce781492014-09-18 01:07:01 -0400966 if not self.is_save_state:
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200967 project_ids = self.saved_state_json['projects']
968 projects = [project
969 for project in projects
970 if (project['id'] not in project_ids and
971 project['name'] != CONF.auth.admin_project_name)]
David Patersonce781492014-09-18 01:07:01 -0400972
973 if self.is_preserve:
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200974 projects = [project
975 for project in projects
976 if project['name'] not in CONF_PROJECTS]
David Patersonce781492014-09-18 01:07:01 -0400977
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200978 LOG.debug("List count, %s Projects after reconcile", len(projects))
979 return projects
David Patersonce781492014-09-18 01:07:01 -0400980
981 def delete(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200982 projects = self.list()
983 for project in projects:
David Patersonce781492014-09-18 01:07:01 -0400984 try:
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200985 self.client.delete_project(project['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400986 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000987 LOG.exception("Delete project %s exception.", project['id'])
David Patersonce781492014-09-18 01:07:01 -0400988
989 def dry_run(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200990 projects = self.list()
991 self.data['projects'] = projects
David Patersonce781492014-09-18 01:07:01 -0400992
993 def save_state(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200994 projects = self.list()
995 self.data['projects'] = {}
996 for project in projects:
997 self.data['projects'][project['id']] = project['name']
David Patersonce781492014-09-18 01:07:01 -0400998
999
1000class DomainService(BaseService):
1001
1002 def __init__(self, manager, **kwargs):
1003 super(DomainService, self).__init__(kwargs)
Daniel Mellado91a26b62016-02-11 11:13:04 +00001004 self.client = manager.domains_client
David Patersonce781492014-09-18 01:07:01 -04001005
1006 def list(self):
1007 client = self.client
Thomas Bechtold48268a02015-08-30 19:37:46 +02001008 domains = client.list_domains()['domains']
David Patersonce781492014-09-18 01:07:01 -04001009 if not self.is_save_state:
1010 domains = [domain for domain in domains if domain['id']
1011 not in self.saved_state_json['domains'].keys()]
1012
Jordan Pittier525ec712016-12-07 17:51:26 +01001013 LOG.debug("List count, %s Domains after reconcile", len(domains))
David Patersonce781492014-09-18 01:07:01 -04001014 return domains
1015
1016 def delete(self):
1017 client = self.client
1018 domains = self.list()
1019 for domain in domains:
1020 try:
1021 client.update_domain(domain['id'], enabled=False)
1022 client.delete_domain(domain['id'])
David Patersone41ebca2015-04-09 05:40:12 -04001023 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +00001024 LOG.exception("Delete Domain %s exception.", domain['id'])
David Patersonce781492014-09-18 01:07:01 -04001025
1026 def dry_run(self):
1027 domains = self.list()
1028 self.data['domains'] = domains
1029
1030 def save_state(self):
1031 domains = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -05001032 self.data['domains'] = {}
David Patersonce781492014-09-18 01:07:01 -04001033 for domain in domains:
gordon chungc15f1bc2015-02-23 18:00:41 -05001034 self.data['domains'][domain['id']] = domain['name']
David Patersonce781492014-09-18 01:07:01 -04001035
1036
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001037def get_project_associated_cleanup_services():
1038 """Returns list of project service classes.
1039
1040 The list contains services whose resources need to be deleted prior,
1041 the project they are associated with, deletion. The resources cannot be
1042 most likely deleted after the project is deleted first.
1043 """
1044 project_associated_services = []
ghanshyame4796f82016-04-13 15:49:22 +09001045 # TODO(gmann): Tempest should provide some plugin hook for cleanup
1046 # script extension to plugin tests also.
David Patersonce781492014-09-18 01:07:01 -04001047 if IS_NOVA:
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001048 project_associated_services.append(NovaQuotaService)
David Patersonce781492014-09-18 01:07:01 -04001049 if IS_CINDER:
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001050 project_associated_services.append(VolumeQuotaService)
1051 return project_associated_services
1052
1053
1054def get_resource_cleanup_services():
1055 """Returns list of project related classes.
1056
1057 The list contains services whose resources are associated with a project,
1058 however, their deletion is possible also after the project is deleted
1059 first.
1060 """
1061 resource_cleanup_services = []
1062 # TODO(gmann): Tempest should provide some plugin hook for cleanup
1063 # script extension to plugin tests also.
1064 if IS_NOVA:
1065 resource_cleanup_services.append(ServerService)
1066 resource_cleanup_services.append(KeyPairService)
1067 resource_cleanup_services.append(ServerGroupService)
1068 if IS_NEUTRON:
1069 resource_cleanup_services.append(NetworkFloatingIpService)
1070 if utils.is_extension_enabled('metering', 'network'):
1071 resource_cleanup_services.append(NetworkMeteringLabelRuleService)
1072 resource_cleanup_services.append(NetworkMeteringLabelService)
1073 resource_cleanup_services.append(NetworkRouterService)
1074 resource_cleanup_services.append(NetworkPortService)
1075 resource_cleanup_services.append(NetworkSubnetService)
1076 resource_cleanup_services.append(NetworkService)
1077 resource_cleanup_services.append(NetworkSecGroupService)
1078 resource_cleanup_services.append(NetworkSubnetPoolsService)
Lukas Piwowarskie530f242019-10-29 11:48:00 +00001079 resource_cleanup_services.append(NetworkQuotaService)
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001080 if IS_CINDER:
1081 resource_cleanup_services.append(SnapshotService)
1082 resource_cleanup_services.append(VolumeService)
1083 return resource_cleanup_services
David Patersonce781492014-09-18 01:07:01 -04001084
1085
1086def get_global_cleanup_services():
1087 global_services = []
1088 if IS_NOVA:
1089 global_services.append(FlavorService)
1090 if IS_GLANCE:
1091 global_services.append(ImageService)
1092 global_services.append(UserService)
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001093 global_services.append(ProjectService)
David Patersonce781492014-09-18 01:07:01 -04001094 global_services.append(DomainService)
1095 global_services.append(RoleService)
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +00001096 global_services.append(RegionService)
David Patersonce781492014-09-18 01:07:01 -04001097 return global_services