blob: 84d2492e64ccfec8ff599aa325628cba1869b747 [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
Martin Kopeca8578802020-04-07 08:19:14 +000026LOG = logging.getLogger('tempest.cmd.cleanup')
David Patersonce781492014-09-18 01:07:01 -040027CONF = 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:
Martin Kopeca8578802020-04-07 08:19:14 +0000170 LOG.debug("Deleting Snapshot with id %s", snap['id'])
David Patersonce781492014-09-18 01:07:01 -0400171 client.delete_snapshot(snap['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400172 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000173 LOG.exception("Delete Snapshot %s exception.", snap['id'])
David Patersonce781492014-09-18 01:07:01 -0400174
175 def dry_run(self):
176 snaps = self.list()
177 self.data['snapshots'] = snaps
178
Martin Kopec5a884bf2019-02-11 18:10:55 +0000179 def save_state(self):
180 snaps = self.list()
181 self.data['snapshots'] = {}
182 for snap in snaps:
183 self.data['snapshots'][snap['id']] = snap['name']
184
David Patersonce781492014-09-18 01:07:01 -0400185
186class ServerService(BaseService):
187 def __init__(self, manager, **kwargs):
188 super(ServerService, self).__init__(kwargs)
189 self.client = manager.servers_client
David Paterson07661de2015-10-29 20:15:04 -0700190 self.server_groups_client = manager.server_groups_client
David Patersonce781492014-09-18 01:07:01 -0400191
192 def list(self):
193 client = self.client
David Kranzae99b9a2015-02-16 13:37:01 -0500194 servers_body = client.list_servers()
David Patersonce781492014-09-18 01:07:01 -0400195 servers = servers_body['servers']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000196 if not self.is_save_state:
197 # recreate list removing saved servers
198 servers = [server for server in servers if server['id']
199 not in self.saved_state_json['servers'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100200 LOG.debug("List count, %s Servers", len(servers))
David Patersonce781492014-09-18 01:07:01 -0400201 return servers
202
203 def delete(self):
204 client = self.client
205 servers = self.list()
206 for server in servers:
207 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000208 LOG.debug("Deleting Server with id %s", server['id'])
David Patersonce781492014-09-18 01:07:01 -0400209 client.delete_server(server['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400210 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000211 LOG.exception("Delete Server %s exception.", server['id'])
David Patersonce781492014-09-18 01:07:01 -0400212
213 def dry_run(self):
214 servers = self.list()
215 self.data['servers'] = servers
216
Martin Kopec5a884bf2019-02-11 18:10:55 +0000217 def save_state(self):
218 servers = self.list()
219 self.data['servers'] = {}
220 for server in servers:
221 self.data['servers'][server['id']] = server['name']
222
David Patersonce781492014-09-18 01:07:01 -0400223
224class ServerGroupService(ServerService):
225
226 def list(self):
David Paterson07661de2015-10-29 20:15:04 -0700227 client = self.server_groups_client
ghanshyam2dc13452015-08-24 17:39:25 +0900228 sgs = client.list_server_groups()['server_groups']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000229 if not self.is_save_state:
230 # recreate list removing saved server_groups
231 sgs = [sg for sg in sgs if sg['id']
232 not in self.saved_state_json['server_groups'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100233 LOG.debug("List count, %s Server Groups", len(sgs))
David Patersonce781492014-09-18 01:07:01 -0400234 return sgs
235
236 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000237 client = self.server_groups_client
David Patersonce781492014-09-18 01:07:01 -0400238 sgs = self.list()
239 for sg in sgs:
240 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000241 LOG.debug("Deleting Server Group with id %s", sg['id'])
David Patersonce781492014-09-18 01:07:01 -0400242 client.delete_server_group(sg['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400243 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000244 LOG.exception("Delete Server Group %s exception.", sg['id'])
David Patersonce781492014-09-18 01:07:01 -0400245
246 def dry_run(self):
247 sgs = self.list()
248 self.data['server_groups'] = sgs
249
Martin Kopec5a884bf2019-02-11 18:10:55 +0000250 def save_state(self):
251 sgs = self.list()
252 self.data['server_groups'] = {}
253 for sg in sgs:
254 self.data['server_groups'][sg['id']] = sg['name']
255
David Patersonce781492014-09-18 01:07:01 -0400256
David Patersonce781492014-09-18 01:07:01 -0400257class KeyPairService(BaseService):
258 def __init__(self, manager, **kwargs):
259 super(KeyPairService, self).__init__(kwargs)
260 self.client = manager.keypairs_client
261
262 def list(self):
263 client = self.client
ghanshyamdee01f22015-08-17 11:41:47 +0900264 keypairs = client.list_keypairs()['keypairs']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000265 if not self.is_save_state:
266 # recreate list removing saved keypairs
267 keypairs = [keypair for keypair in keypairs
268 if keypair['keypair']['name']
269 not in self.saved_state_json['keypairs'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100270 LOG.debug("List count, %s Keypairs", len(keypairs))
David Patersonce781492014-09-18 01:07:01 -0400271 return keypairs
272
273 def delete(self):
274 client = self.client
275 keypairs = self.list()
276 for k in keypairs:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000277 name = k['keypair']['name']
David Patersonce781492014-09-18 01:07:01 -0400278 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000279 LOG.debug("Deleting keypair %s", name)
David Patersonce781492014-09-18 01:07:01 -0400280 client.delete_keypair(name)
David Patersone41ebca2015-04-09 05:40:12 -0400281 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000282 LOG.exception("Delete Keypair %s exception.", name)
David Patersonce781492014-09-18 01:07:01 -0400283
284 def dry_run(self):
285 keypairs = self.list()
286 self.data['keypairs'] = keypairs
287
Martin Kopec5a884bf2019-02-11 18:10:55 +0000288 def save_state(self):
289 keypairs = self.list()
290 self.data['keypairs'] = {}
291 for keypair in keypairs:
292 keypair = keypair['keypair']
293 self.data['keypairs'][keypair['name']] = keypair
294
David Patersonce781492014-09-18 01:07:01 -0400295
David Patersonce781492014-09-18 01:07:01 -0400296class VolumeService(BaseService):
297 def __init__(self, manager, **kwargs):
298 super(VolumeService, self).__init__(kwargs)
ghanshyam59928952017-10-26 01:38:45 +0000299 self.client = manager.volumes_client_latest
David Patersonce781492014-09-18 01:07:01 -0400300
301 def list(self):
302 client = self.client
John Warren6177c9e2015-08-19 20:00:17 +0000303 vols = client.list_volumes()['volumes']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000304 if not self.is_save_state:
305 # recreate list removing saved volumes
306 vols = [vol for vol in vols if vol['id']
307 not in self.saved_state_json['volumes'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100308 LOG.debug("List count, %s Volumes", len(vols))
David Patersonce781492014-09-18 01:07:01 -0400309 return vols
310
311 def delete(self):
312 client = self.client
313 vols = self.list()
314 for v in vols:
315 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000316 LOG.debug("Deleting volume with id %s", v['id'])
David Patersonce781492014-09-18 01:07:01 -0400317 client.delete_volume(v['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400318 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000319 LOG.exception("Delete Volume %s exception.", v['id'])
David Patersonce781492014-09-18 01:07:01 -0400320
321 def dry_run(self):
322 vols = self.list()
323 self.data['volumes'] = vols
324
Martin Kopec5a884bf2019-02-11 18:10:55 +0000325 def save_state(self):
326 vols = self.list()
327 self.data['volumes'] = {}
328 for vol in vols:
329 self.data['volumes'][vol['id']] = vol['name']
330
David Patersonce781492014-09-18 01:07:01 -0400331
David Paterson35c8df02015-04-05 04:35:31 -0400332class VolumeQuotaService(BaseService):
333 def __init__(self, manager, **kwargs):
334 super(VolumeQuotaService, self).__init__(kwargs)
ghanshyam6c682ff2018-08-06 09:54:45 +0000335 self.client = manager.volume_quotas_client_latest
David Paterson35c8df02015-04-05 04:35:31 -0400336
337 def delete(self):
338 client = self.client
339 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000340 LOG.debug("Deleting Volume Quotas for project with id %s",
341 self.project_id)
Martin Kopecb37903c2019-01-20 21:39:58 +0000342 client.delete_quota_set(self.project_id)
David Patersone41ebca2015-04-09 05:40:12 -0400343 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000344 LOG.exception("Delete Volume Quotas exception for 'project %s'.",
345 self.project_id)
David Paterson35c8df02015-04-05 04:35:31 -0400346
347 def dry_run(self):
Ken'ichi Ohmichi3cf9eaf2016-07-29 11:05:21 -0700348 quotas = self.client.show_quota_set(
Martin Kopecb37903c2019-01-20 21:39:58 +0000349 self.project_id, params={'usage': True})['quota_set']
David Paterson35c8df02015-04-05 04:35:31 -0400350 self.data['volume_quotas'] = quotas
351
352
353class NovaQuotaService(BaseService):
354 def __init__(self, manager, **kwargs):
355 super(NovaQuotaService, self).__init__(kwargs)
356 self.client = manager.quotas_client
357 self.limits_client = manager.limits_client
358
359 def delete(self):
360 client = self.client
361 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000362 LOG.debug("Deleting Nova Quotas for project with id %s",
363 self.project_id)
Martin Kopecb37903c2019-01-20 21:39:58 +0000364 client.delete_quota_set(self.project_id)
David Patersone41ebca2015-04-09 05:40:12 -0400365 except Exception:
Martin Kopeca8578802020-04-07 08:19:14 +0000366 LOG.exception("Delete Nova Quotas exception for 'project %s'.",
Martin Kopecfd01fe92019-02-27 08:46:05 +0000367 self.project_id)
David Paterson35c8df02015-04-05 04:35:31 -0400368
369 def dry_run(self):
370 client = self.limits_client
ghanshyam8a599492015-08-24 15:55:59 +0900371 quotas = client.show_limits()['limits']
Ken'ichi Ohmichib93e6762015-06-15 07:11:29 +0000372 self.data['compute_quotas'] = quotas['absolute']
David Paterson35c8df02015-04-05 04:35:31 -0400373
374
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000375class NetworkQuotaService(BaseService):
376 def __init__(self, manager, **kwargs):
377 super(NetworkQuotaService, self).__init__(kwargs)
378 self.client = manager.network_quotas_client
379
380 def delete(self):
381 client = self.client
382 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000383 LOG.debug("Deleting Network Quotas for project with id %s",
384 self.project_id)
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000385 client.reset_quotas(self.project_id)
386 except Exception:
387 LOG.exception("Delete Network Quotas exception for 'project %s'.",
388 self.project_id)
389
390 def dry_run(self):
391 resp = [quota for quota in self.client.list_quotas()['quotas']
392 if quota['project_id'] == self.project_id]
393 self.data['network_quotas'] = resp
394
395
David Patersonce781492014-09-18 01:07:01 -0400396# Begin network service classes
Martin Kopec5a884bf2019-02-11 18:10:55 +0000397class BaseNetworkService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400398 def __init__(self, manager, **kwargs):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000399 super(BaseNetworkService, self).__init__(kwargs)
John Warren94d8faf2015-09-15 12:22:24 -0400400 self.networks_client = manager.networks_client
John Warren3961acd2015-10-02 14:38:53 -0400401 self.subnets_client = manager.subnets_client
John Warren49c0fe52015-10-22 12:35:54 -0400402 self.ports_client = manager.ports_client
John Warrenfbf2a892015-11-17 12:36:14 -0500403 self.floating_ips_client = manager.floating_ips_client
John Warren6d0083a2015-11-30 18:12:30 -0500404 self.metering_labels_client = manager.metering_labels_client
John Warrendd20b3e2015-12-03 13:11:28 -0500405 self.metering_label_rules_client = manager.metering_label_rules_client
John Warrenf9606e92015-12-10 12:12:42 -0500406 self.security_groups_client = manager.security_groups_client
ghanshyama25c4192016-03-11 18:38:12 +0900407 self.routers_client = manager.routers_client
Martin Kopece6819982019-02-18 12:34:52 +0000408 self.subnetpools_client = manager.subnetpools_client
David Patersonce781492014-09-18 01:07:01 -0400409
David Patersond6babc52014-10-14 00:11:56 -0400410 def _filter_by_conf_networks(self, item_list):
411 if not item_list or not all(('network_id' in i for i in item_list)):
412 return item_list
413
414 return [item for item in item_list if item['network_id']
415 not in CONF_NETWORKS]
416
Martin Kopec5a884bf2019-02-11 18:10:55 +0000417
418class NetworkService(BaseNetworkService):
419
David Patersonce781492014-09-18 01:07:01 -0400420 def list(self):
John Warren94d8faf2015-09-15 12:22:24 -0400421 client = self.networks_client
David Paterson82234022015-04-12 14:07:40 -0400422 networks = client.list_networks(**self.tenant_filter)
423 networks = networks['networks']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000424
425 if not self.is_save_state:
426 # recreate list removing saved networks
427 networks = [network for network in networks if network['id']
428 not in self.saved_state_json['networks'].keys()]
David Patersonce781492014-09-18 01:07:01 -0400429 # filter out networks declared in tempest.conf
430 if self.is_preserve:
431 networks = [network for network in networks
David Patersond6babc52014-10-14 00:11:56 -0400432 if network['id'] not in CONF_NETWORKS]
Martin Kopeca8578802020-04-07 08:19:14 +0000433 LOG.debug("List count, %s Networks", len(networks))
David Patersonce781492014-09-18 01:07:01 -0400434 return networks
435
436 def delete(self):
John Warren94d8faf2015-09-15 12:22:24 -0400437 client = self.networks_client
David Patersonce781492014-09-18 01:07:01 -0400438 networks = self.list()
439 for n in networks:
440 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000441 LOG.debug("Deleting Network with id %s", n['id'])
David Patersonce781492014-09-18 01:07:01 -0400442 client.delete_network(n['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400443 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000444 LOG.exception("Delete Network %s exception.", n['id'])
David Patersonce781492014-09-18 01:07:01 -0400445
446 def dry_run(self):
447 networks = self.list()
448 self.data['networks'] = networks
449
Martin Kopec5a884bf2019-02-11 18:10:55 +0000450 def save_state(self):
451 networks = self.list()
452 self.data['networks'] = {}
453 for network in networks:
454 self.data['networks'][network['id']] = network
David Patersonce781492014-09-18 01:07:01 -0400455
Martin Kopec5a884bf2019-02-11 18:10:55 +0000456
457class NetworkFloatingIpService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400458
459 def list(self):
John Warrenfbf2a892015-11-17 12:36:14 -0500460 client = self.floating_ips_client
David Paterson82234022015-04-12 14:07:40 -0400461 flips = client.list_floatingips(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400462 flips = flips['floatingips']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000463
464 if not self.is_save_state:
465 # recreate list removing saved flips
466 flips = [flip for flip in flips if flip['id']
467 not in self.saved_state_json['floatingips'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100468 LOG.debug("List count, %s Network Floating IPs", len(flips))
David Patersonce781492014-09-18 01:07:01 -0400469 return flips
470
471 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000472 client = self.floating_ips_client
David Patersonce781492014-09-18 01:07:01 -0400473 flips = self.list()
474 for flip in flips:
475 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000476 LOG.debug("Deleting Network Floating IP with id %s",
477 flip['id'])
David Patersonce781492014-09-18 01:07:01 -0400478 client.delete_floatingip(flip['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400479 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000480 LOG.exception("Delete Network Floating IP %s exception.",
481 flip['id'])
David Patersonce781492014-09-18 01:07:01 -0400482
483 def dry_run(self):
484 flips = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000485 self.data['floatingips'] = flips
486
487 def save_state(self):
488 flips = self.list()
489 self.data['floatingips'] = {}
490 for flip in flips:
491 self.data['floatingips'][flip['id']] = flip
David Patersonce781492014-09-18 01:07:01 -0400492
493
Martin Kopec5a884bf2019-02-11 18:10:55 +0000494class NetworkRouterService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400495
496 def list(self):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000497 client = self.routers_client
David Paterson82234022015-04-12 14:07:40 -0400498 routers = client.list_routers(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400499 routers = routers['routers']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000500
501 if not self.is_save_state:
502 # recreate list removing saved routers
503 routers = [router for router in routers if router['id']
504 not in self.saved_state_json['routers'].keys()]
David Patersonce781492014-09-18 01:07:01 -0400505 if self.is_preserve:
506 routers = [router for router in routers
507 if router['id'] != CONF_PUB_ROUTER]
508
Jordan Pittier525ec712016-12-07 17:51:26 +0100509 LOG.debug("List count, %s Routers", len(routers))
David Patersonce781492014-09-18 01:07:01 -0400510 return routers
511
512 def delete(self):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000513 client = self.routers_client
Ken'ichi Ohmichif3110f02016-03-21 12:29:03 -0700514 ports_client = self.ports_client
David Patersonce781492014-09-18 01:07:01 -0400515 routers = self.list()
516 for router in routers:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000517 rid = router['id']
Martin Kopec598b1ae2019-04-01 14:41:53 +0000518 ports = [port for port
519 in ports_client.list_ports(device_id=rid)['ports']
520 if net_info.is_router_interface_port(port)]
521 for port in ports:
522 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000523 LOG.debug("Deleting port with id %s of router with id %s",
524 port['id'], rid)
piyush11078694aca952015-12-17 12:54:44 +0530525 client.remove_router_interface(rid, port_id=port['id'])
Martin Kopec598b1ae2019-04-01 14:41:53 +0000526 except Exception:
527 LOG.exception("Delete Router Interface exception for "
528 "'port %s' of 'router %s'.", port['id'], rid)
529 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000530 LOG.debug("Deleting Router with id %s", rid)
David Patersond6babc52014-10-14 00:11:56 -0400531 client.delete_router(rid)
David Patersone41ebca2015-04-09 05:40:12 -0400532 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000533 LOG.exception("Delete Router %s exception.", rid)
David Patersonce781492014-09-18 01:07:01 -0400534
535 def dry_run(self):
536 routers = self.list()
537 self.data['routers'] = routers
538
Martin Kopec5a884bf2019-02-11 18:10:55 +0000539 def save_state(self):
540 routers = self.list()
541 self.data['routers'] = {}
542 for router in routers:
543 self.data['routers'][router['id']] = router['name']
544
David Patersonce781492014-09-18 01:07:01 -0400545
Alexander Gubanov13379bb2015-05-19 18:57:32 +0300546class NetworkMeteringLabelRuleService(NetworkService):
David Patersonce781492014-09-18 01:07:01 -0400547
548 def list(self):
John Warrendd20b3e2015-12-03 13:11:28 -0500549 client = self.metering_label_rules_client
David Kranz34e88122014-12-11 15:24:05 -0500550 rules = client.list_metering_label_rules()
David Patersonce781492014-09-18 01:07:01 -0400551 rules = rules['metering_label_rules']
552 rules = self._filter_by_tenant_id(rules)
Martin Kopec5a884bf2019-02-11 18:10:55 +0000553
554 if not self.is_save_state:
555 saved_rules = self.saved_state_json['metering_label_rules'].keys()
556 # recreate list removing saved rules
557 rules = [rule for rule in rules if rule['id'] not in saved_rules]
Jordan Pittier525ec712016-12-07 17:51:26 +0100558 LOG.debug("List count, %s Metering Label Rules", len(rules))
David Patersonce781492014-09-18 01:07:01 -0400559 return rules
560
561 def delete(self):
John Warrendd20b3e2015-12-03 13:11:28 -0500562 client = self.metering_label_rules_client
David Patersonce781492014-09-18 01:07:01 -0400563 rules = self.list()
564 for rule in rules:
565 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000566 LOG.debug("Deleting Metering Label Rule with id %s",
567 rule['id'])
David Patersonce781492014-09-18 01:07:01 -0400568 client.delete_metering_label_rule(rule['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400569 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000570 LOG.exception("Delete Metering Label Rule %s exception.",
571 rule['id'])
David Patersonce781492014-09-18 01:07:01 -0400572
573 def dry_run(self):
574 rules = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000575 self.data['metering_label_rules'] = rules
576
577 def save_state(self):
578 rules = self.list()
579 self.data['metering_label_rules'] = {}
580 for rule in rules:
581 self.data['metering_label_rules'][rule['id']] = rule
David Patersonce781492014-09-18 01:07:01 -0400582
583
Martin Kopec5a884bf2019-02-11 18:10:55 +0000584class NetworkMeteringLabelService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400585
586 def list(self):
John Warren6d0083a2015-11-30 18:12:30 -0500587 client = self.metering_labels_client
David Kranz34e88122014-12-11 15:24:05 -0500588 labels = client.list_metering_labels()
David Patersonce781492014-09-18 01:07:01 -0400589 labels = labels['metering_labels']
590 labels = self._filter_by_tenant_id(labels)
Martin Kopec5a884bf2019-02-11 18:10:55 +0000591
592 if not self.is_save_state:
593 # recreate list removing saved labels
594 labels = [label for label in labels if label['id']
595 not in self.saved_state_json['metering_labels'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100596 LOG.debug("List count, %s Metering Labels", len(labels))
David Patersonce781492014-09-18 01:07:01 -0400597 return labels
598
599 def delete(self):
John Warren6d0083a2015-11-30 18:12:30 -0500600 client = self.metering_labels_client
David Patersonce781492014-09-18 01:07:01 -0400601 labels = self.list()
602 for label in labels:
603 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000604 LOG.debug("Deleting Metering Label with id %s", label['id'])
David Patersonce781492014-09-18 01:07:01 -0400605 client.delete_metering_label(label['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400606 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000607 LOG.exception("Delete Metering Label %s exception.",
608 label['id'])
David Patersonce781492014-09-18 01:07:01 -0400609
610 def dry_run(self):
611 labels = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000612 self.data['metering_labels'] = labels
613
614 def save_state(self):
615 labels = self.list()
616 self.data['metering_labels'] = {}
617 for label in labels:
618 self.data['metering_labels'][label['id']] = label['name']
David Patersonce781492014-09-18 01:07:01 -0400619
620
Martin Kopec5a884bf2019-02-11 18:10:55 +0000621class NetworkPortService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400622
623 def list(self):
John Warren49c0fe52015-10-22 12:35:54 -0400624 client = self.ports_client
David Paterson82234022015-04-12 14:07:40 -0400625 ports = [port for port in
626 client.list_ports(**self.tenant_filter)['ports']
627 if port["device_owner"] == "" or
628 port["device_owner"].startswith("compute:")]
629
Martin Kopec5a884bf2019-02-11 18:10:55 +0000630 if not self.is_save_state:
631 # recreate list removing saved ports
632 ports = [port for port in ports if port['id']
633 not in self.saved_state_json['ports'].keys()]
David Patersond6babc52014-10-14 00:11:56 -0400634 if self.is_preserve:
635 ports = self._filter_by_conf_networks(ports)
David Paterson82234022015-04-12 14:07:40 -0400636
Jordan Pittier525ec712016-12-07 17:51:26 +0100637 LOG.debug("List count, %s Ports", len(ports))
David Patersonce781492014-09-18 01:07:01 -0400638 return ports
639
640 def delete(self):
John Warren49c0fe52015-10-22 12:35:54 -0400641 client = self.ports_client
David Patersonce781492014-09-18 01:07:01 -0400642 ports = self.list()
643 for port in ports:
644 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000645 LOG.debug("Deleting port with id %s", port['id'])
David Patersonce781492014-09-18 01:07:01 -0400646 client.delete_port(port['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400647 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000648 LOG.exception("Delete Port %s exception.", port['id'])
David Patersonce781492014-09-18 01:07:01 -0400649
650 def dry_run(self):
651 ports = self.list()
652 self.data['ports'] = ports
653
Martin Kopec5a884bf2019-02-11 18:10:55 +0000654 def save_state(self):
655 ports = self.list()
656 self.data['ports'] = {}
657 for port in ports:
658 self.data['ports'][port['id']] = port['name']
David Patersonce781492014-09-18 01:07:01 -0400659
Martin Kopec5a884bf2019-02-11 18:10:55 +0000660
661class NetworkSecGroupService(BaseNetworkService):
David Paterson82234022015-04-12 14:07:40 -0400662 def list(self):
John Warrenf9606e92015-12-10 12:12:42 -0500663 client = self.security_groups_client
David Paterson82234022015-04-12 14:07:40 -0400664 filter = self.tenant_filter
665 # cannot delete default sec group so never show it.
666 secgroups = [secgroup for secgroup in
667 client.list_security_groups(**filter)['security_groups']
668 if secgroup['name'] != 'default']
669
Martin Kopec5a884bf2019-02-11 18:10:55 +0000670 if not self.is_save_state:
671 # recreate list removing saved security_groups
672 secgroups = [secgroup for secgroup in secgroups if secgroup['id']
673 not in self.saved_state_json['security_groups'].keys()
674 ]
David Paterson82234022015-04-12 14:07:40 -0400675 if self.is_preserve:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000676 secgroups = [secgroup for secgroup in secgroups
677 if secgroup['security_group_rules'][0]['project_id']
678 not in CONF_PROJECTS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100679 LOG.debug("List count, %s security_groups", len(secgroups))
David Paterson82234022015-04-12 14:07:40 -0400680 return secgroups
681
682 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000683 client = self.security_groups_client
David Paterson82234022015-04-12 14:07:40 -0400684 secgroups = self.list()
685 for secgroup in secgroups:
686 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000687 LOG.debug("Deleting security_group with id %s", secgroup['id'])
Martin Kopec5a884bf2019-02-11 18:10:55 +0000688 client.delete_security_group(secgroup['id'])
David Paterson82234022015-04-12 14:07:40 -0400689 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000690 LOG.exception("Delete security_group %s exception.",
691 secgroup['id'])
David Paterson82234022015-04-12 14:07:40 -0400692
693 def dry_run(self):
694 secgroups = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000695 self.data['security_groups'] = secgroups
696
697 def save_state(self):
698 secgroups = self.list()
699 self.data['security_groups'] = {}
700 for secgroup in secgroups:
701 self.data['security_groups'][secgroup['id']] = secgroup['name']
David Paterson82234022015-04-12 14:07:40 -0400702
703
Martin Kopec5a884bf2019-02-11 18:10:55 +0000704class NetworkSubnetService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400705
706 def list(self):
John Warren3961acd2015-10-02 14:38:53 -0400707 client = self.subnets_client
David Paterson82234022015-04-12 14:07:40 -0400708 subnets = client.list_subnets(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400709 subnets = subnets['subnets']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000710 if not self.is_save_state:
711 # recreate list removing saved subnets
712 subnets = [subnet for subnet in subnets if subnet['id']
713 not in self.saved_state_json['subnets'].keys()]
David Patersond6babc52014-10-14 00:11:56 -0400714 if self.is_preserve:
715 subnets = self._filter_by_conf_networks(subnets)
Jordan Pittier525ec712016-12-07 17:51:26 +0100716 LOG.debug("List count, %s Subnets", len(subnets))
David Patersonce781492014-09-18 01:07:01 -0400717 return subnets
718
719 def delete(self):
John Warren3961acd2015-10-02 14:38:53 -0400720 client = self.subnets_client
David Patersonce781492014-09-18 01:07:01 -0400721 subnets = self.list()
722 for subnet in subnets:
723 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000724 LOG.debug("Deleting subnet with id %s", subnet['id'])
David Patersonce781492014-09-18 01:07:01 -0400725 client.delete_subnet(subnet['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400726 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000727 LOG.exception("Delete Subnet %s exception.", subnet['id'])
David Patersonce781492014-09-18 01:07:01 -0400728
729 def dry_run(self):
730 subnets = self.list()
731 self.data['subnets'] = subnets
732
Martin Kopec5a884bf2019-02-11 18:10:55 +0000733 def save_state(self):
734 subnets = self.list()
735 self.data['subnets'] = {}
736 for subnet in subnets:
737 self.data['subnets'][subnet['id']] = subnet['name']
738
David Patersonce781492014-09-18 01:07:01 -0400739
Martin Kopece6819982019-02-18 12:34:52 +0000740class NetworkSubnetPoolsService(BaseNetworkService):
741
742 def list(self):
743 client = self.subnetpools_client
744 pools = client.list_subnetpools(**self.tenant_filter)['subnetpools']
745 if not self.is_save_state:
746 # recreate list removing saved subnet pools
747 pools = [pool for pool in pools if pool['id']
748 not in self.saved_state_json['subnetpools'].keys()]
749 if self.is_preserve:
750 pools = [pool for pool in pools if pool['project_id']
751 not in CONF_PROJECTS]
752 LOG.debug("List count, %s Subnet Pools", len(pools))
753 return pools
754
755 def delete(self):
756 client = self.subnetpools_client
757 pools = self.list()
758 for pool in pools:
759 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000760 LOG.debug("Deleting Subnet Pool with id %s", pool['id'])
Martin Kopece6819982019-02-18 12:34:52 +0000761 client.delete_subnetpool(pool['id'])
762 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000763 LOG.exception("Delete Subnet Pool %s exception.", pool['id'])
Martin Kopece6819982019-02-18 12:34:52 +0000764
765 def dry_run(self):
766 pools = self.list()
767 self.data['subnetpools'] = pools
768
769 def save_state(self):
770 pools = self.list()
771 self.data['subnetpools'] = {}
772 for pool in pools:
773 self.data['subnetpools'][pool['id']] = pool['name']
774
775
David Patersonce781492014-09-18 01:07:01 -0400776# begin global services
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000777class RegionService(BaseService):
778
779 def __init__(self, manager, **kwargs):
780 super(RegionService, self).__init__(kwargs)
781 self.client = manager.regions_client
782
783 def list(self):
784 client = self.client
785 regions = client.list_regions()
786 if not self.is_save_state:
787 regions = [region for region in regions['regions'] if region['id']
788 not in self.saved_state_json['regions'].keys()]
Martin Kopeca8578802020-04-07 08:19:14 +0000789 LOG.debug("List count, %s Regions", len(regions))
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000790 return regions
791 else:
Martin Kopeca8578802020-04-07 08:19:14 +0000792 LOG.debug("List count, %s Regions", len(regions['regions']))
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000793 return regions['regions']
794
795 def delete(self):
796 client = self.client
797 regions = self.list()
798 for region in regions:
799 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000800 LOG.debug("Deleting region with id %s", region['id'])
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000801 client.delete_region(region['id'])
802 except Exception:
803 LOG.exception("Delete Region %s exception.", region['id'])
804
805 def dry_run(self):
806 regions = self.list()
807 self.data['regions'] = {}
808 for region in regions:
809 self.data['regions'][region['id']] = region
810
811 def save_state(self):
812 regions = self.list()
813 self.data['regions'] = {}
814 for region in regions:
815 self.data['regions'][region['id']] = region
816
817
David Patersonce781492014-09-18 01:07:01 -0400818class FlavorService(BaseService):
819 def __init__(self, manager, **kwargs):
820 super(FlavorService, self).__init__(kwargs)
821 self.client = manager.flavors_client
822
823 def list(self):
824 client = self.client
ghanshyam19973be2015-08-18 15:46:42 +0900825 flavors = client.list_flavors({"is_public": None})['flavors']
David Patersonce781492014-09-18 01:07:01 -0400826 if not self.is_save_state:
827 # recreate list removing saved flavors
828 flavors = [flavor for flavor in flavors if flavor['id']
829 not in self.saved_state_json['flavors'].keys()]
830
831 if self.is_preserve:
832 flavors = [flavor for flavor in flavors
833 if flavor['id'] not in CONF_FLAVORS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100834 LOG.debug("List count, %s Flavors after reconcile", len(flavors))
David Patersonce781492014-09-18 01:07:01 -0400835 return flavors
836
837 def delete(self):
838 client = self.client
839 flavors = self.list()
840 for flavor in flavors:
841 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000842 LOG.debug("Deleting flavor with id %s", flavor['id'])
David Patersonce781492014-09-18 01:07:01 -0400843 client.delete_flavor(flavor['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400844 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000845 LOG.exception("Delete Flavor %s exception.", flavor['id'])
David Patersonce781492014-09-18 01:07:01 -0400846
847 def dry_run(self):
848 flavors = self.list()
849 self.data['flavors'] = flavors
850
851 def save_state(self):
852 flavors = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500853 self.data['flavors'] = {}
David Patersonce781492014-09-18 01:07:01 -0400854 for flavor in flavors:
gordon chungc15f1bc2015-02-23 18:00:41 -0500855 self.data['flavors'][flavor['id']] = flavor['name']
David Patersonce781492014-09-18 01:07:01 -0400856
857
858class ImageService(BaseService):
859 def __init__(self, manager, **kwargs):
860 super(ImageService, self).__init__(kwargs)
zhufl66275c22018-03-28 15:32:14 +0800861 self.client = manager.image_client_v2
David Patersonce781492014-09-18 01:07:01 -0400862
863 def list(self):
864 client = self.client
Lukas Piwowarski2c831242020-03-11 12:25:11 +0000865 response = client.list_images()
866 images = []
867 images.extend(response['images'])
868 while 'next' in response:
869 parsed = urllib.urlparse(response['next'])
870 marker = urllib.parse_qs(parsed.query)['marker'][0]
871 response = client.list_images(params={"marker": marker})
872 images.extend(response['images'])
873
David Patersonce781492014-09-18 01:07:01 -0400874 if not self.is_save_state:
875 images = [image for image in images if image['id']
876 not in self.saved_state_json['images'].keys()]
877 if self.is_preserve:
878 images = [image for image in images
879 if image['id'] not in CONF_IMAGES]
Jordan Pittier525ec712016-12-07 17:51:26 +0100880 LOG.debug("List count, %s Images after reconcile", len(images))
David Patersonce781492014-09-18 01:07:01 -0400881 return images
882
883 def delete(self):
884 client = self.client
885 images = self.list()
886 for image in images:
887 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000888 LOG.debug("Deleting image with id %s", image['id'])
David Patersonce781492014-09-18 01:07:01 -0400889 client.delete_image(image['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400890 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000891 LOG.exception("Delete Image %s exception.", image['id'])
David Patersonce781492014-09-18 01:07:01 -0400892
893 def dry_run(self):
894 images = self.list()
895 self.data['images'] = images
896
897 def save_state(self):
gordon chungc15f1bc2015-02-23 18:00:41 -0500898 self.data['images'] = {}
David Paterson82234022015-04-12 14:07:40 -0400899 images = self.list()
David Patersonce781492014-09-18 01:07:01 -0400900 for image in images:
gordon chungc15f1bc2015-02-23 18:00:41 -0500901 self.data['images'][image['id']] = image['name']
David Patersonce781492014-09-18 01:07:01 -0400902
903
Daniel Mellado82c83a52015-12-09 15:16:49 +0000904class UserService(BaseService):
905
906 def __init__(self, manager, **kwargs):
907 super(UserService, self).__init__(kwargs)
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200908 self.client = manager.users_v3_client
David Patersonce781492014-09-18 01:07:01 -0400909
910 def list(self):
Daniel Mellado82c83a52015-12-09 15:16:49 +0000911 users = self.client.list_users()['users']
David Patersonce781492014-09-18 01:07:01 -0400912
913 if not self.is_save_state:
914 users = [user for user in users if user['id']
915 not in self.saved_state_json['users'].keys()]
916
917 if self.is_preserve:
918 users = [user for user in users if user['name']
919 not in CONF_USERS]
920
921 elif not self.is_save_state: # Never delete admin user
922 users = [user for user in users if user['name'] !=
David Paterson07661de2015-10-29 20:15:04 -0700923 CONF.auth.admin_username]
David Patersonce781492014-09-18 01:07:01 -0400924
Jordan Pittier525ec712016-12-07 17:51:26 +0100925 LOG.debug("List count, %s Users after reconcile", len(users))
David Patersonce781492014-09-18 01:07:01 -0400926 return users
927
928 def delete(self):
David Patersonce781492014-09-18 01:07:01 -0400929 users = self.list()
930 for user in users:
931 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000932 LOG.debug("Deleting user with id %s", user['id'])
Daniel Mellado82c83a52015-12-09 15:16:49 +0000933 self.client.delete_user(user['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400934 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000935 LOG.exception("Delete User %s exception.", user['id'])
David Patersonce781492014-09-18 01:07:01 -0400936
937 def dry_run(self):
938 users = self.list()
939 self.data['users'] = users
940
941 def save_state(self):
942 users = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500943 self.data['users'] = {}
David Patersonce781492014-09-18 01:07:01 -0400944 for user in users:
gordon chungc15f1bc2015-02-23 18:00:41 -0500945 self.data['users'][user['id']] = user['name']
David Patersonce781492014-09-18 01:07:01 -0400946
947
Daniel Melladob83ea562015-12-18 09:12:49 +0000948class RoleService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400949
Daniel Mellado6b16b922015-12-07 12:43:08 +0000950 def __init__(self, manager, **kwargs):
951 super(RoleService, self).__init__(kwargs)
Martin Kopecbd5be762019-07-13 22:42:08 +0000952 self.client = manager.roles_v3_client
Daniel Mellado6b16b922015-12-07 12:43:08 +0000953
David Patersonce781492014-09-18 01:07:01 -0400954 def list(self):
David Patersonce781492014-09-18 01:07:01 -0400955 try:
Daniel Mellado6b16b922015-12-07 12:43:08 +0000956 roles = self.client.list_roles()['roles']
David Patersonce781492014-09-18 01:07:01 -0400957 # reconcile roles with saved state and never list admin role
958 if not self.is_save_state:
959 roles = [role for role in roles if
960 (role['id'] not in
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200961 self.saved_state_json['roles'].keys() and
962 role['name'] != CONF.identity.admin_role)]
Jordan Pittier525ec712016-12-07 17:51:26 +0100963 LOG.debug("List count, %s Roles after reconcile", len(roles))
David Patersonce781492014-09-18 01:07:01 -0400964 return roles
David Patersone41ebca2015-04-09 05:40:12 -0400965 except Exception:
966 LOG.exception("Cannot retrieve Roles.")
David Patersonce781492014-09-18 01:07:01 -0400967 return []
968
969 def delete(self):
David Patersonce781492014-09-18 01:07:01 -0400970 roles = self.list()
971 for role in roles:
972 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000973 LOG.debug("Deleting role with id %s", role['id'])
Daniel Mellado6b16b922015-12-07 12:43:08 +0000974 self.client.delete_role(role['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400975 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000976 LOG.exception("Delete Role %s exception.", role['id'])
David Patersonce781492014-09-18 01:07:01 -0400977
978 def dry_run(self):
979 roles = self.list()
980 self.data['roles'] = roles
981
982 def save_state(self):
983 roles = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500984 self.data['roles'] = {}
David Patersonce781492014-09-18 01:07:01 -0400985 for role in roles:
gordon chungc15f1bc2015-02-23 18:00:41 -0500986 self.data['roles'][role['id']] = role['name']
David Patersonce781492014-09-18 01:07:01 -0400987
988
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200989class ProjectService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400990
Daniel Melladob04da902015-11-20 17:43:12 +0100991 def __init__(self, manager, **kwargs):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200992 super(ProjectService, self).__init__(kwargs)
993 self.client = manager.projects_client
Daniel Melladob04da902015-11-20 17:43:12 +0100994
David Patersonce781492014-09-18 01:07:01 -0400995 def list(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200996 projects = self.client.list_projects()['projects']
David Patersonce781492014-09-18 01:07:01 -0400997 if not self.is_save_state:
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200998 project_ids = self.saved_state_json['projects']
999 projects = [project
1000 for project in projects
1001 if (project['id'] not in project_ids and
1002 project['name'] != CONF.auth.admin_project_name)]
David Patersonce781492014-09-18 01:07:01 -04001003
1004 if self.is_preserve:
Federico Ressi2d6bcaa2018-04-11 12:37:36 +02001005 projects = [project
1006 for project in projects
1007 if project['name'] not in CONF_PROJECTS]
David Patersonce781492014-09-18 01:07:01 -04001008
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001009 LOG.debug("List count, %s Projects after reconcile", len(projects))
1010 return projects
David Patersonce781492014-09-18 01:07:01 -04001011
1012 def delete(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001013 projects = self.list()
1014 for project in projects:
David Patersonce781492014-09-18 01:07:01 -04001015 try:
Martin Kopeca8578802020-04-07 08:19:14 +00001016 LOG.debug("Deleting project with id %s", project['id'])
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001017 self.client.delete_project(project['id'])
David Patersone41ebca2015-04-09 05:40:12 -04001018 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +00001019 LOG.exception("Delete project %s exception.", project['id'])
David Patersonce781492014-09-18 01:07:01 -04001020
1021 def dry_run(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001022 projects = self.list()
1023 self.data['projects'] = projects
David Patersonce781492014-09-18 01:07:01 -04001024
1025 def save_state(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001026 projects = self.list()
1027 self.data['projects'] = {}
1028 for project in projects:
1029 self.data['projects'][project['id']] = project['name']
David Patersonce781492014-09-18 01:07:01 -04001030
1031
1032class DomainService(BaseService):
1033
1034 def __init__(self, manager, **kwargs):
1035 super(DomainService, self).__init__(kwargs)
Daniel Mellado91a26b62016-02-11 11:13:04 +00001036 self.client = manager.domains_client
David Patersonce781492014-09-18 01:07:01 -04001037
1038 def list(self):
1039 client = self.client
Thomas Bechtold48268a02015-08-30 19:37:46 +02001040 domains = client.list_domains()['domains']
David Patersonce781492014-09-18 01:07:01 -04001041 if not self.is_save_state:
1042 domains = [domain for domain in domains if domain['id']
1043 not in self.saved_state_json['domains'].keys()]
1044
Jordan Pittier525ec712016-12-07 17:51:26 +01001045 LOG.debug("List count, %s Domains after reconcile", len(domains))
David Patersonce781492014-09-18 01:07:01 -04001046 return domains
1047
1048 def delete(self):
1049 client = self.client
1050 domains = self.list()
1051 for domain in domains:
1052 try:
Martin Kopeca8578802020-04-07 08:19:14 +00001053 LOG.debug("Deleting domain with id %s", domain['id'])
David Patersonce781492014-09-18 01:07:01 -04001054 client.update_domain(domain['id'], enabled=False)
1055 client.delete_domain(domain['id'])
David Patersone41ebca2015-04-09 05:40:12 -04001056 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +00001057 LOG.exception("Delete Domain %s exception.", domain['id'])
David Patersonce781492014-09-18 01:07:01 -04001058
1059 def dry_run(self):
1060 domains = self.list()
1061 self.data['domains'] = domains
1062
1063 def save_state(self):
1064 domains = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -05001065 self.data['domains'] = {}
David Patersonce781492014-09-18 01:07:01 -04001066 for domain in domains:
gordon chungc15f1bc2015-02-23 18:00:41 -05001067 self.data['domains'][domain['id']] = domain['name']
David Patersonce781492014-09-18 01:07:01 -04001068
1069
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001070def get_project_associated_cleanup_services():
1071 """Returns list of project service classes.
1072
1073 The list contains services whose resources need to be deleted prior,
1074 the project they are associated with, deletion. The resources cannot be
1075 most likely deleted after the project is deleted first.
1076 """
1077 project_associated_services = []
ghanshyame4796f82016-04-13 15:49:22 +09001078 # TODO(gmann): Tempest should provide some plugin hook for cleanup
1079 # script extension to plugin tests also.
David Patersonce781492014-09-18 01:07:01 -04001080 if IS_NOVA:
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001081 project_associated_services.append(NovaQuotaService)
David Patersonce781492014-09-18 01:07:01 -04001082 if IS_CINDER:
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001083 project_associated_services.append(VolumeQuotaService)
Lukas Piwowarski97b84112020-03-25 13:57:30 +00001084 if IS_NEUTRON:
1085 project_associated_services.append(NetworkQuotaService)
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001086 return project_associated_services
1087
1088
1089def get_resource_cleanup_services():
1090 """Returns list of project related classes.
1091
1092 The list contains services whose resources are associated with a project,
1093 however, their deletion is possible also after the project is deleted
1094 first.
1095 """
1096 resource_cleanup_services = []
1097 # TODO(gmann): Tempest should provide some plugin hook for cleanup
1098 # script extension to plugin tests also.
1099 if IS_NOVA:
1100 resource_cleanup_services.append(ServerService)
1101 resource_cleanup_services.append(KeyPairService)
1102 resource_cleanup_services.append(ServerGroupService)
1103 if IS_NEUTRON:
1104 resource_cleanup_services.append(NetworkFloatingIpService)
1105 if utils.is_extension_enabled('metering', 'network'):
1106 resource_cleanup_services.append(NetworkMeteringLabelRuleService)
1107 resource_cleanup_services.append(NetworkMeteringLabelService)
1108 resource_cleanup_services.append(NetworkRouterService)
1109 resource_cleanup_services.append(NetworkPortService)
1110 resource_cleanup_services.append(NetworkSubnetService)
1111 resource_cleanup_services.append(NetworkService)
1112 resource_cleanup_services.append(NetworkSecGroupService)
1113 resource_cleanup_services.append(NetworkSubnetPoolsService)
1114 if IS_CINDER:
1115 resource_cleanup_services.append(SnapshotService)
1116 resource_cleanup_services.append(VolumeService)
1117 return resource_cleanup_services
David Patersonce781492014-09-18 01:07:01 -04001118
1119
1120def get_global_cleanup_services():
1121 global_services = []
1122 if IS_NOVA:
1123 global_services.append(FlavorService)
1124 if IS_GLANCE:
1125 global_services.append(ImageService)
1126 global_services.append(UserService)
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001127 global_services.append(ProjectService)
David Patersonce781492014-09-18 01:07:01 -04001128 global_services.append(DomainService)
1129 global_services.append(RoleService)
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +00001130 global_services.append(RegionService)
David Patersonce781492014-09-18 01:07:01 -04001131 return global_services