blob: 8651ab064d3df9aaf16f8a7f6e28725cdfa73281 [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
songwenping99d6e002021-01-05 03:07:46 +000015from urllib import parse as urllib
16
Doug Hellmann583ce2c2015-03-11 14:55:46 +000017from oslo_log import log as logging
18
ghanshyam009a1f62017-08-08 10:22:57 +030019from tempest import clients
Andrea Frittoli (andreaf)290b3e12015-10-08 10:25:02 +010020from tempest.common import credentials_factory as credentials
Ken'ichi Ohmichi6ea3f982015-11-09 12:41:13 +000021from tempest.common import identity
Andrea Frittolicd368412017-08-14 21:37:56 +010022from tempest.common import utils
Attila Fazekasd7e08a62016-10-07 13:05:05 +020023from tempest.common.utils import net_info
David Patersonce781492014-09-18 01:07:01 -040024from tempest import config
Martin Kopec97857942019-06-12 15:23:21 +000025from tempest.lib import exceptions
David Patersonce781492014-09-18 01:07:01 -040026
Martin Kopeca8578802020-04-07 08:19:14 +000027LOG = logging.getLogger('tempest.cmd.cleanup')
David Patersonce781492014-09-18 01:07:01 -040028CONF = config.CONF
29
David Patersonce781492014-09-18 01:07:01 -040030CONF_FLAVORS = None
31CONF_IMAGES = None
David Patersond6babc52014-10-14 00:11:56 -040032CONF_NETWORKS = []
33CONF_PRIV_NETWORK_NAME = None
34CONF_PUB_NETWORK = None
35CONF_PUB_ROUTER = None
Arx Cruz05fe4bc2017-10-20 10:48:28 +020036CONF_PROJECTS = None
David Patersond6babc52014-10-14 00:11:56 -040037CONF_USERS = None
David Patersonce781492014-09-18 01:07:01 -040038
David Patersonce781492014-09-18 01:07:01 -040039IS_CINDER = None
40IS_GLANCE = None
David Patersonce781492014-09-18 01:07:01 -040041IS_NEUTRON = None
42IS_NOVA = None
43
44
45def init_conf():
David Patersonce781492014-09-18 01:07:01 -040046 global CONF_FLAVORS
47 global CONF_IMAGES
David Patersond6babc52014-10-14 00:11:56 -040048 global CONF_NETWORKS
49 global CONF_PRIV_NETWORK
50 global CONF_PRIV_NETWORK_NAME
51 global CONF_PUB_NETWORK
52 global CONF_PUB_ROUTER
Arx Cruz05fe4bc2017-10-20 10:48:28 +020053 global CONF_PROJECTS
David Patersond6babc52014-10-14 00:11:56 -040054 global CONF_USERS
David Patersonce781492014-09-18 01:07:01 -040055 global IS_CINDER
56 global IS_GLANCE
57 global IS_HEAT
58 global IS_NEUTRON
59 global IS_NOVA
60
David Patersonce781492014-09-18 01:07:01 -040061 IS_CINDER = CONF.service_available.cinder
62 IS_GLANCE = CONF.service_available.glance
David Patersonce781492014-09-18 01:07:01 -040063 IS_NEUTRON = CONF.service_available.neutron
64 IS_NOVA = CONF.service_available.nova
65
David Patersond6babc52014-10-14 00:11:56 -040066 CONF_FLAVORS = [CONF.compute.flavor_ref, CONF.compute.flavor_ref_alt]
67 CONF_IMAGES = [CONF.compute.image_ref, CONF.compute.image_ref_alt]
68 CONF_PRIV_NETWORK_NAME = CONF.compute.fixed_network_name
69 CONF_PUB_NETWORK = CONF.network.public_network_id
70 CONF_PUB_ROUTER = CONF.network.public_router_id
Arx Cruz05fe4bc2017-10-20 10:48:28 +020071 CONF_PROJECTS = [CONF.auth.admin_project_name]
Jeffrey Zhangb5e23212016-07-06 14:18:53 +080072 CONF_USERS = [CONF.auth.admin_username]
David Patersond6babc52014-10-14 00:11:56 -040073
74 if IS_NEUTRON:
David Paterson82234022015-04-12 14:07:40 -040075 CONF_PRIV_NETWORK = _get_network_id(CONF.compute.fixed_network_name,
Daniel Melladod4d0b932016-04-08 08:57:29 +000076 CONF.auth.admin_project_name)
David Patersond6babc52014-10-14 00:11:56 -040077 CONF_NETWORKS = [CONF_PUB_NETWORK, CONF_PRIV_NETWORK]
78
79
Daniel Melladod4d0b932016-04-08 08:57:29 +000080def _get_network_id(net_name, project_name):
ghanshyam009a1f62017-08-08 10:22:57 +030081 am = clients.Manager(
82 credentials.get_configured_admin_credentials())
John Warren94d8faf2015-09-15 12:22:24 -040083 net_cl = am.networks_client
Arx Cruz05fe4bc2017-10-20 10:48:28 +020084 pr_cl = am.projects_client
David Patersond6babc52014-10-14 00:11:56 -040085
David Kranz34e88122014-12-11 15:24:05 -050086 networks = net_cl.list_networks()
Arx Cruz05fe4bc2017-10-20 10:48:28 +020087 project = identity.get_project_by_name(pr_cl, project_name)
88 p_id = project['id']
David Patersond6babc52014-10-14 00:11:56 -040089 n_id = None
90 for net in networks['networks']:
Arx Cruz05fe4bc2017-10-20 10:48:28 +020091 if (net['project_id'] == p_id and net['name'] == net_name):
David Patersond6babc52014-10-14 00:11:56 -040092 n_id = net['id']
93 break
94 return n_id
95
David Patersonce781492014-09-18 01:07:01 -040096
97class BaseService(object):
98 def __init__(self, kwargs):
99 self.client = None
100 for key, value in kwargs.items():
101 setattr(self, key, value)
102
David Paterson82234022015-04-12 14:07:40 -0400103 self.tenant_filter = {}
104 if hasattr(self, 'tenant_id'):
Martin Kopecb37903c2019-01-20 21:39:58 +0000105 self.tenant_filter['project_id'] = self.tenant_id
David Paterson82234022015-04-12 14:07:40 -0400106
David Patersonce781492014-09-18 01:07:01 -0400107 def _filter_by_tenant_id(self, item_list):
Federico Ressi2d6bcaa2018-04-11 12:37:36 +0200108 if (item_list is None or
109 not item_list or
110 not hasattr(self, 'tenant_id') or
111 self.tenant_id is None or
112 'tenant_id' not in item_list[0]):
David Patersonce781492014-09-18 01:07:01 -0400113 return item_list
114
David Patersond6babc52014-10-14 00:11:56 -0400115 return [item for item in item_list
116 if item['tenant_id'] == self.tenant_id]
David Patersonce781492014-09-18 01:07:01 -0400117
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000118 def _filter_by_prefix(self, item_list):
119 items = [item for item in item_list
120 if item['name'].startswith(self.prefix)]
121 return items
122
123 def _filter_out_ids_from_saved(self, item_list, attr):
124 items = [item for item in item_list if item['id']
125 not in self.saved_state_json[attr].keys()]
126 return items
127
David Patersonce781492014-09-18 01:07:01 -0400128 def list(self):
129 pass
130
131 def delete(self):
132 pass
133
134 def dry_run(self):
135 pass
136
137 def save_state(self):
138 pass
139
140 def run(self):
Martin Kopec97857942019-06-12 15:23:21 +0000141 try:
142 if self.is_dry_run:
143 self.dry_run()
144 elif self.is_save_state:
145 self.save_state()
146 else:
147 self.delete()
148 except exceptions.NotImplemented as exc:
149 # Many OpenStack services use extensions logic to implement the
150 # features or resources. Tempest cleanup tries to clean up the test
151 # resources without having much logic of extensions checks etc.
152 # If any of the extension is missing then, service will return
153 # NotImplemented error.
154 msg = ("Got NotImplemented error in %s, full exception: %s" %
155 (str(self.__class__), str(exc)))
156 LOG.exception(msg)
Martin Kopec219e3222019-08-05 20:02:20 +0000157 self.got_exceptions.append(exc)
David Patersonce781492014-09-18 01:07:01 -0400158
159
160class SnapshotService(BaseService):
161
162 def __init__(self, manager, **kwargs):
163 super(SnapshotService, self).__init__(kwargs)
ghanshyam59928952017-10-26 01:38:45 +0000164 self.client = manager.snapshots_client_latest
David Patersonce781492014-09-18 01:07:01 -0400165
166 def list(self):
167 client = self.client
David Paterson07661de2015-10-29 20:15:04 -0700168 snaps = client.list_snapshots()['snapshots']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000169 if self.prefix:
170 snaps = self._filter_by_prefix(snaps)
171 elif not self.is_save_state:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000172 # recreate list removing saved snapshots
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000173 snaps = self._filter_out_ids_from_saved(snaps, 'snapshots')
Jordan Pittier525ec712016-12-07 17:51:26 +0100174 LOG.debug("List count, %s Snapshots", len(snaps))
David Patersonce781492014-09-18 01:07:01 -0400175 return snaps
176
177 def delete(self):
178 snaps = self.list()
179 client = self.client
180 for snap in snaps:
181 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000182 LOG.debug("Deleting Snapshot with id %s", snap['id'])
David Patersonce781492014-09-18 01:07:01 -0400183 client.delete_snapshot(snap['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400184 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000185 LOG.exception("Delete Snapshot %s exception.", snap['id'])
David Patersonce781492014-09-18 01:07:01 -0400186
187 def dry_run(self):
188 snaps = self.list()
189 self.data['snapshots'] = snaps
190
Martin Kopec5a884bf2019-02-11 18:10:55 +0000191 def save_state(self):
192 snaps = self.list()
193 self.data['snapshots'] = {}
194 for snap in snaps:
195 self.data['snapshots'][snap['id']] = snap['name']
196
David Patersonce781492014-09-18 01:07:01 -0400197
198class ServerService(BaseService):
199 def __init__(self, manager, **kwargs):
200 super(ServerService, self).__init__(kwargs)
201 self.client = manager.servers_client
David Paterson07661de2015-10-29 20:15:04 -0700202 self.server_groups_client = manager.server_groups_client
David Patersonce781492014-09-18 01:07:01 -0400203
204 def list(self):
205 client = self.client
David Kranzae99b9a2015-02-16 13:37:01 -0500206 servers_body = client.list_servers()
David Patersonce781492014-09-18 01:07:01 -0400207 servers = servers_body['servers']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000208 if self.prefix:
209 servers = self._filter_by_prefix(servers)
210 elif not self.is_save_state:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000211 # recreate list removing saved servers
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000212 servers = self._filter_out_ids_from_saved(servers, 'servers')
Jordan Pittier525ec712016-12-07 17:51:26 +0100213 LOG.debug("List count, %s Servers", len(servers))
David Patersonce781492014-09-18 01:07:01 -0400214 return servers
215
216 def delete(self):
217 client = self.client
218 servers = self.list()
219 for server in servers:
220 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000221 LOG.debug("Deleting Server with id %s", server['id'])
David Patersonce781492014-09-18 01:07:01 -0400222 client.delete_server(server['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400223 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000224 LOG.exception("Delete Server %s exception.", server['id'])
David Patersonce781492014-09-18 01:07:01 -0400225
226 def dry_run(self):
227 servers = self.list()
228 self.data['servers'] = servers
229
Martin Kopec5a884bf2019-02-11 18:10:55 +0000230 def save_state(self):
231 servers = self.list()
232 self.data['servers'] = {}
233 for server in servers:
234 self.data['servers'][server['id']] = server['name']
235
David Patersonce781492014-09-18 01:07:01 -0400236
237class ServerGroupService(ServerService):
238
239 def list(self):
David Paterson07661de2015-10-29 20:15:04 -0700240 client = self.server_groups_client
ghanshyam2dc13452015-08-24 17:39:25 +0900241 sgs = client.list_server_groups()['server_groups']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000242 if self.prefix:
243 sgs = self._filter_by_prefix(sgs)
244 elif not self.is_save_state:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000245 # recreate list removing saved server_groups
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000246 sgs = self._filter_out_ids_from_saved(sgs, 'server_groups')
Jordan Pittier525ec712016-12-07 17:51:26 +0100247 LOG.debug("List count, %s Server Groups", len(sgs))
David Patersonce781492014-09-18 01:07:01 -0400248 return sgs
249
250 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000251 client = self.server_groups_client
David Patersonce781492014-09-18 01:07:01 -0400252 sgs = self.list()
253 for sg in sgs:
254 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000255 LOG.debug("Deleting Server Group with id %s", sg['id'])
David Patersonce781492014-09-18 01:07:01 -0400256 client.delete_server_group(sg['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400257 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000258 LOG.exception("Delete Server Group %s exception.", sg['id'])
David Patersonce781492014-09-18 01:07:01 -0400259
260 def dry_run(self):
261 sgs = self.list()
262 self.data['server_groups'] = sgs
263
Martin Kopec5a884bf2019-02-11 18:10:55 +0000264 def save_state(self):
265 sgs = self.list()
266 self.data['server_groups'] = {}
267 for sg in sgs:
268 self.data['server_groups'][sg['id']] = sg['name']
269
David Patersonce781492014-09-18 01:07:01 -0400270
David Patersonce781492014-09-18 01:07:01 -0400271class KeyPairService(BaseService):
272 def __init__(self, manager, **kwargs):
273 super(KeyPairService, self).__init__(kwargs)
274 self.client = manager.keypairs_client
275
276 def list(self):
277 client = self.client
ghanshyamdee01f22015-08-17 11:41:47 +0900278 keypairs = client.list_keypairs()['keypairs']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000279 if self.prefix:
280 keypairs = self._filter_by_prefix(keypairs)
281 elif not self.is_save_state:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000282 # recreate list removing saved keypairs
283 keypairs = [keypair for keypair in keypairs
284 if keypair['keypair']['name']
285 not in self.saved_state_json['keypairs'].keys()]
Jordan Pittier525ec712016-12-07 17:51:26 +0100286 LOG.debug("List count, %s Keypairs", len(keypairs))
David Patersonce781492014-09-18 01:07:01 -0400287 return keypairs
288
289 def delete(self):
290 client = self.client
291 keypairs = self.list()
292 for k in keypairs:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000293 name = k['keypair']['name']
David Patersonce781492014-09-18 01:07:01 -0400294 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000295 LOG.debug("Deleting keypair %s", name)
David Patersonce781492014-09-18 01:07:01 -0400296 client.delete_keypair(name)
David Patersone41ebca2015-04-09 05:40:12 -0400297 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000298 LOG.exception("Delete Keypair %s exception.", name)
David Patersonce781492014-09-18 01:07:01 -0400299
300 def dry_run(self):
301 keypairs = self.list()
302 self.data['keypairs'] = keypairs
303
Martin Kopec5a884bf2019-02-11 18:10:55 +0000304 def save_state(self):
305 keypairs = self.list()
306 self.data['keypairs'] = {}
307 for keypair in keypairs:
308 keypair = keypair['keypair']
309 self.data['keypairs'][keypair['name']] = keypair
310
David Patersonce781492014-09-18 01:07:01 -0400311
David Patersonce781492014-09-18 01:07:01 -0400312class VolumeService(BaseService):
313 def __init__(self, manager, **kwargs):
314 super(VolumeService, self).__init__(kwargs)
ghanshyam59928952017-10-26 01:38:45 +0000315 self.client = manager.volumes_client_latest
David Patersonce781492014-09-18 01:07:01 -0400316
317 def list(self):
318 client = self.client
John Warren6177c9e2015-08-19 20:00:17 +0000319 vols = client.list_volumes()['volumes']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000320 if self.prefix:
321 vols = self._filter_by_prefix(vols)
322 elif not self.is_save_state:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000323 # recreate list removing saved volumes
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000324 vols = self._filter_out_ids_from_saved(vols, 'volumes')
Jordan Pittier525ec712016-12-07 17:51:26 +0100325 LOG.debug("List count, %s Volumes", len(vols))
David Patersonce781492014-09-18 01:07:01 -0400326 return vols
327
328 def delete(self):
329 client = self.client
330 vols = self.list()
331 for v in vols:
332 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000333 LOG.debug("Deleting volume with id %s", v['id'])
David Patersonce781492014-09-18 01:07:01 -0400334 client.delete_volume(v['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400335 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000336 LOG.exception("Delete Volume %s exception.", v['id'])
David Patersonce781492014-09-18 01:07:01 -0400337
338 def dry_run(self):
339 vols = self.list()
340 self.data['volumes'] = vols
341
Martin Kopec5a884bf2019-02-11 18:10:55 +0000342 def save_state(self):
343 vols = self.list()
344 self.data['volumes'] = {}
345 for vol in vols:
346 self.data['volumes'][vol['id']] = vol['name']
347
David Patersonce781492014-09-18 01:07:01 -0400348
David Paterson35c8df02015-04-05 04:35:31 -0400349class VolumeQuotaService(BaseService):
350 def __init__(self, manager, **kwargs):
351 super(VolumeQuotaService, self).__init__(kwargs)
ghanshyam6c682ff2018-08-06 09:54:45 +0000352 self.client = manager.volume_quotas_client_latest
David Paterson35c8df02015-04-05 04:35:31 -0400353
354 def delete(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000355 if self.prefix:
356 # this means we're cleaning resources based on a certain prefix,
357 # this resource doesn't have a name, therefore do nothing
358 return
David Paterson35c8df02015-04-05 04:35:31 -0400359 client = self.client
360 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000361 LOG.debug("Deleting Volume Quotas for project with id %s",
362 self.project_id)
Martin Kopecb37903c2019-01-20 21:39:58 +0000363 client.delete_quota_set(self.project_id)
David Patersone41ebca2015-04-09 05:40:12 -0400364 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000365 LOG.exception("Delete Volume Quotas exception for 'project %s'.",
366 self.project_id)
David Paterson35c8df02015-04-05 04:35:31 -0400367
368 def dry_run(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000369 if self.prefix:
370 # this means we're cleaning resources based on a certain prefix,
371 # this resource doesn't have a name, therefore do nothing
372 return
Ken'ichi Ohmichi3cf9eaf2016-07-29 11:05:21 -0700373 quotas = self.client.show_quota_set(
Martin Kopecb37903c2019-01-20 21:39:58 +0000374 self.project_id, params={'usage': True})['quota_set']
David Paterson35c8df02015-04-05 04:35:31 -0400375 self.data['volume_quotas'] = quotas
376
377
378class NovaQuotaService(BaseService):
379 def __init__(self, manager, **kwargs):
380 super(NovaQuotaService, self).__init__(kwargs)
381 self.client = manager.quotas_client
382 self.limits_client = manager.limits_client
383
384 def delete(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000385 if self.prefix:
386 # this means we're cleaning resources based on a certain prefix,
387 # this resource doesn't have a name, therefore do nothing
388 return
David Paterson35c8df02015-04-05 04:35:31 -0400389 client = self.client
390 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000391 LOG.debug("Deleting Nova Quotas for project with id %s",
392 self.project_id)
Martin Kopecb37903c2019-01-20 21:39:58 +0000393 client.delete_quota_set(self.project_id)
David Patersone41ebca2015-04-09 05:40:12 -0400394 except Exception:
Martin Kopeca8578802020-04-07 08:19:14 +0000395 LOG.exception("Delete Nova Quotas exception for 'project %s'.",
Martin Kopecfd01fe92019-02-27 08:46:05 +0000396 self.project_id)
David Paterson35c8df02015-04-05 04:35:31 -0400397
398 def dry_run(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000399 if self.prefix:
400 # this means we're cleaning resources based on a certain prefix,
401 # this resource doesn't have a name, therefore do nothing
402 return
David Paterson35c8df02015-04-05 04:35:31 -0400403 client = self.limits_client
ghanshyam8a599492015-08-24 15:55:59 +0900404 quotas = client.show_limits()['limits']
Ken'ichi Ohmichib93e6762015-06-15 07:11:29 +0000405 self.data['compute_quotas'] = quotas['absolute']
David Paterson35c8df02015-04-05 04:35:31 -0400406
407
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000408class NetworkQuotaService(BaseService):
409 def __init__(self, manager, **kwargs):
410 super(NetworkQuotaService, self).__init__(kwargs)
411 self.client = manager.network_quotas_client
412
413 def delete(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000414 if self.prefix:
415 # this means we're cleaning resources based on a certain prefix,
416 # this resource doesn't have a name, therefore do nothing
417 return
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000418 client = self.client
419 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000420 LOG.debug("Deleting Network Quotas for project with id %s",
421 self.project_id)
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000422 client.reset_quotas(self.project_id)
423 except Exception:
424 LOG.exception("Delete Network Quotas exception for 'project %s'.",
425 self.project_id)
426
427 def dry_run(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000428 if self.prefix:
429 # this means we're cleaning resources based on a certain prefix,
430 # this resource doesn't have a name, therefore do nothing
431 return
Lukas Piwowarskie530f242019-10-29 11:48:00 +0000432 resp = [quota for quota in self.client.list_quotas()['quotas']
433 if quota['project_id'] == self.project_id]
434 self.data['network_quotas'] = resp
435
436
David Patersonce781492014-09-18 01:07:01 -0400437# Begin network service classes
Martin Kopec5a884bf2019-02-11 18:10:55 +0000438class BaseNetworkService(BaseService):
David Patersonce781492014-09-18 01:07:01 -0400439 def __init__(self, manager, **kwargs):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000440 super(BaseNetworkService, self).__init__(kwargs)
John Warren94d8faf2015-09-15 12:22:24 -0400441 self.networks_client = manager.networks_client
John Warren3961acd2015-10-02 14:38:53 -0400442 self.subnets_client = manager.subnets_client
John Warren49c0fe52015-10-22 12:35:54 -0400443 self.ports_client = manager.ports_client
John Warrenfbf2a892015-11-17 12:36:14 -0500444 self.floating_ips_client = manager.floating_ips_client
John Warren6d0083a2015-11-30 18:12:30 -0500445 self.metering_labels_client = manager.metering_labels_client
John Warrendd20b3e2015-12-03 13:11:28 -0500446 self.metering_label_rules_client = manager.metering_label_rules_client
John Warrenf9606e92015-12-10 12:12:42 -0500447 self.security_groups_client = manager.security_groups_client
ghanshyama25c4192016-03-11 18:38:12 +0900448 self.routers_client = manager.routers_client
Martin Kopece6819982019-02-18 12:34:52 +0000449 self.subnetpools_client = manager.subnetpools_client
David Patersonce781492014-09-18 01:07:01 -0400450
David Patersond6babc52014-10-14 00:11:56 -0400451 def _filter_by_conf_networks(self, item_list):
452 if not item_list or not all(('network_id' in i for i in item_list)):
453 return item_list
454
455 return [item for item in item_list if item['network_id']
456 not in CONF_NETWORKS]
457
Martin Kopec5a884bf2019-02-11 18:10:55 +0000458
459class NetworkService(BaseNetworkService):
460
David Patersonce781492014-09-18 01:07:01 -0400461 def list(self):
John Warren94d8faf2015-09-15 12:22:24 -0400462 client = self.networks_client
David Paterson82234022015-04-12 14:07:40 -0400463 networks = client.list_networks(**self.tenant_filter)
464 networks = networks['networks']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000465 if self.prefix:
466 networks = self._filter_by_prefix(networks)
467 else:
468 if not self.is_save_state:
469 # recreate list removing saved networks
470 networks = self._filter_out_ids_from_saved(
471 networks, 'networks')
David Patersonce781492014-09-18 01:07:01 -0400472 # filter out networks declared in tempest.conf
473 if self.is_preserve:
474 networks = [network for network in networks
David Patersond6babc52014-10-14 00:11:56 -0400475 if network['id'] not in CONF_NETWORKS]
Martin Kopeca8578802020-04-07 08:19:14 +0000476 LOG.debug("List count, %s Networks", len(networks))
David Patersonce781492014-09-18 01:07:01 -0400477 return networks
478
479 def delete(self):
John Warren94d8faf2015-09-15 12:22:24 -0400480 client = self.networks_client
David Patersonce781492014-09-18 01:07:01 -0400481 networks = self.list()
482 for n in networks:
483 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000484 LOG.debug("Deleting Network with id %s", n['id'])
David Patersonce781492014-09-18 01:07:01 -0400485 client.delete_network(n['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400486 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000487 LOG.exception("Delete Network %s exception.", n['id'])
David Patersonce781492014-09-18 01:07:01 -0400488
489 def dry_run(self):
490 networks = self.list()
491 self.data['networks'] = networks
492
Martin Kopec5a884bf2019-02-11 18:10:55 +0000493 def save_state(self):
494 networks = self.list()
495 self.data['networks'] = {}
496 for network in networks:
497 self.data['networks'][network['id']] = network
David Patersonce781492014-09-18 01:07:01 -0400498
Martin Kopec5a884bf2019-02-11 18:10:55 +0000499
500class NetworkFloatingIpService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400501
502 def list(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000503 if self.prefix:
504 # this means we're cleaning resources based on a certain prefix,
505 # this resource doesn't have a name, therefore return empty list
506 return []
John Warrenfbf2a892015-11-17 12:36:14 -0500507 client = self.floating_ips_client
David Paterson82234022015-04-12 14:07:40 -0400508 flips = client.list_floatingips(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400509 flips = flips['floatingips']
Martin Kopec5a884bf2019-02-11 18:10:55 +0000510
511 if not self.is_save_state:
512 # recreate list removing saved flips
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000513 flips = self._filter_out_ids_from_saved(flips, 'floatingips')
Jordan Pittier525ec712016-12-07 17:51:26 +0100514 LOG.debug("List count, %s Network Floating IPs", len(flips))
David Patersonce781492014-09-18 01:07:01 -0400515 return flips
516
517 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000518 client = self.floating_ips_client
David Patersonce781492014-09-18 01:07:01 -0400519 flips = self.list()
520 for flip in flips:
521 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000522 LOG.debug("Deleting Network Floating IP with id %s",
523 flip['id'])
David Patersonce781492014-09-18 01:07:01 -0400524 client.delete_floatingip(flip['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400525 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000526 LOG.exception("Delete Network Floating IP %s exception.",
527 flip['id'])
David Patersonce781492014-09-18 01:07:01 -0400528
529 def dry_run(self):
530 flips = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000531 self.data['floatingips'] = flips
532
533 def save_state(self):
534 flips = self.list()
535 self.data['floatingips'] = {}
536 for flip in flips:
537 self.data['floatingips'][flip['id']] = flip
David Patersonce781492014-09-18 01:07:01 -0400538
539
Martin Kopec5a884bf2019-02-11 18:10:55 +0000540class NetworkRouterService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400541
542 def list(self):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000543 client = self.routers_client
David Paterson82234022015-04-12 14:07:40 -0400544 routers = client.list_routers(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400545 routers = routers['routers']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000546 if self.prefix:
547 routers = self._filter_by_prefix(routers)
548 else:
549 if not self.is_save_state:
550 # recreate list removing saved routers
551 routers = self._filter_out_ids_from_saved(routers, 'routers')
David Patersonce781492014-09-18 01:07:01 -0400552 if self.is_preserve:
553 routers = [router for router in routers
554 if router['id'] != CONF_PUB_ROUTER]
Jordan Pittier525ec712016-12-07 17:51:26 +0100555 LOG.debug("List count, %s Routers", len(routers))
David Patersonce781492014-09-18 01:07:01 -0400556 return routers
557
558 def delete(self):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000559 client = self.routers_client
Ken'ichi Ohmichif3110f02016-03-21 12:29:03 -0700560 ports_client = self.ports_client
David Patersonce781492014-09-18 01:07:01 -0400561 routers = self.list()
562 for router in routers:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000563 rid = router['id']
Martin Kopec598b1ae2019-04-01 14:41:53 +0000564 ports = [port for port
565 in ports_client.list_ports(device_id=rid)['ports']
566 if net_info.is_router_interface_port(port)]
567 for port in ports:
568 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000569 LOG.debug("Deleting port with id %s of router with id %s",
570 port['id'], rid)
piyush11078694aca952015-12-17 12:54:44 +0530571 client.remove_router_interface(rid, port_id=port['id'])
Martin Kopec598b1ae2019-04-01 14:41:53 +0000572 except Exception:
573 LOG.exception("Delete Router Interface exception for "
574 "'port %s' of 'router %s'.", port['id'], rid)
575 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000576 LOG.debug("Deleting Router with id %s", rid)
David Patersond6babc52014-10-14 00:11:56 -0400577 client.delete_router(rid)
David Patersone41ebca2015-04-09 05:40:12 -0400578 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000579 LOG.exception("Delete Router %s exception.", rid)
David Patersonce781492014-09-18 01:07:01 -0400580
581 def dry_run(self):
582 routers = self.list()
583 self.data['routers'] = routers
584
Martin Kopec5a884bf2019-02-11 18:10:55 +0000585 def save_state(self):
586 routers = self.list()
587 self.data['routers'] = {}
588 for router in routers:
589 self.data['routers'][router['id']] = router['name']
590
David Patersonce781492014-09-18 01:07:01 -0400591
Alexander Gubanov13379bb2015-05-19 18:57:32 +0300592class NetworkMeteringLabelRuleService(NetworkService):
David Patersonce781492014-09-18 01:07:01 -0400593
594 def list(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000595 if self.prefix:
596 # this means we're cleaning resources based on a certain prefix,
597 # this resource doesn't have a name, therefore return empty list
598 return []
John Warrendd20b3e2015-12-03 13:11:28 -0500599 client = self.metering_label_rules_client
David Kranz34e88122014-12-11 15:24:05 -0500600 rules = client.list_metering_label_rules()
David Patersonce781492014-09-18 01:07:01 -0400601 rules = rules['metering_label_rules']
602 rules = self._filter_by_tenant_id(rules)
Martin Kopec5a884bf2019-02-11 18:10:55 +0000603
604 if not self.is_save_state:
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000605 rules = self._filter_out_ids_from_saved(
606 rules, 'metering_label_rules')
Martin Kopec5a884bf2019-02-11 18:10:55 +0000607 # recreate list removing saved rules
Jordan Pittier525ec712016-12-07 17:51:26 +0100608 LOG.debug("List count, %s Metering Label Rules", len(rules))
David Patersonce781492014-09-18 01:07:01 -0400609 return rules
610
611 def delete(self):
John Warrendd20b3e2015-12-03 13:11:28 -0500612 client = self.metering_label_rules_client
David Patersonce781492014-09-18 01:07:01 -0400613 rules = self.list()
614 for rule in rules:
615 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000616 LOG.debug("Deleting Metering Label Rule with id %s",
617 rule['id'])
David Patersonce781492014-09-18 01:07:01 -0400618 client.delete_metering_label_rule(rule['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400619 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000620 LOG.exception("Delete Metering Label Rule %s exception.",
621 rule['id'])
David Patersonce781492014-09-18 01:07:01 -0400622
623 def dry_run(self):
624 rules = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000625 self.data['metering_label_rules'] = rules
626
627 def save_state(self):
628 rules = self.list()
629 self.data['metering_label_rules'] = {}
630 for rule in rules:
631 self.data['metering_label_rules'][rule['id']] = rule
David Patersonce781492014-09-18 01:07:01 -0400632
633
Martin Kopec5a884bf2019-02-11 18:10:55 +0000634class NetworkMeteringLabelService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400635
636 def list(self):
John Warren6d0083a2015-11-30 18:12:30 -0500637 client = self.metering_labels_client
David Kranz34e88122014-12-11 15:24:05 -0500638 labels = client.list_metering_labels()
David Patersonce781492014-09-18 01:07:01 -0400639 labels = labels['metering_labels']
640 labels = self._filter_by_tenant_id(labels)
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000641 if self.prefix:
642 labels = self._filter_by_prefix(labels)
643 elif not self.is_save_state:
Martin Kopec5a884bf2019-02-11 18:10:55 +0000644 # recreate list removing saved labels
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000645 labels = self._filter_out_ids_from_saved(
646 labels, 'metering_labels')
Jordan Pittier525ec712016-12-07 17:51:26 +0100647 LOG.debug("List count, %s Metering Labels", len(labels))
David Patersonce781492014-09-18 01:07:01 -0400648 return labels
649
650 def delete(self):
John Warren6d0083a2015-11-30 18:12:30 -0500651 client = self.metering_labels_client
David Patersonce781492014-09-18 01:07:01 -0400652 labels = self.list()
653 for label in labels:
654 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000655 LOG.debug("Deleting Metering Label with id %s", label['id'])
David Patersonce781492014-09-18 01:07:01 -0400656 client.delete_metering_label(label['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400657 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000658 LOG.exception("Delete Metering Label %s exception.",
659 label['id'])
David Patersonce781492014-09-18 01:07:01 -0400660
661 def dry_run(self):
662 labels = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000663 self.data['metering_labels'] = labels
664
665 def save_state(self):
666 labels = self.list()
667 self.data['metering_labels'] = {}
668 for label in labels:
669 self.data['metering_labels'][label['id']] = label['name']
David Patersonce781492014-09-18 01:07:01 -0400670
671
Martin Kopec5a884bf2019-02-11 18:10:55 +0000672class NetworkPortService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400673
674 def list(self):
John Warren49c0fe52015-10-22 12:35:54 -0400675 client = self.ports_client
David Paterson82234022015-04-12 14:07:40 -0400676 ports = [port for port in
677 client.list_ports(**self.tenant_filter)['ports']
678 if port["device_owner"] == "" or
679 port["device_owner"].startswith("compute:")]
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000680 if self.prefix:
681 ports = self._filter_by_prefix(ports)
682 else:
683 if not self.is_save_state:
684 # recreate list removing saved ports
685 ports = self._filter_out_ids_from_saved(ports, 'ports')
David Patersond6babc52014-10-14 00:11:56 -0400686 if self.is_preserve:
687 ports = self._filter_by_conf_networks(ports)
Jordan Pittier525ec712016-12-07 17:51:26 +0100688 LOG.debug("List count, %s Ports", len(ports))
David Patersonce781492014-09-18 01:07:01 -0400689 return ports
690
691 def delete(self):
John Warren49c0fe52015-10-22 12:35:54 -0400692 client = self.ports_client
David Patersonce781492014-09-18 01:07:01 -0400693 ports = self.list()
694 for port in ports:
695 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000696 LOG.debug("Deleting port with id %s", port['id'])
David Patersonce781492014-09-18 01:07:01 -0400697 client.delete_port(port['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400698 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000699 LOG.exception("Delete Port %s exception.", port['id'])
David Patersonce781492014-09-18 01:07:01 -0400700
701 def dry_run(self):
702 ports = self.list()
703 self.data['ports'] = ports
704
Martin Kopec5a884bf2019-02-11 18:10:55 +0000705 def save_state(self):
706 ports = self.list()
707 self.data['ports'] = {}
708 for port in ports:
709 self.data['ports'][port['id']] = port['name']
David Patersonce781492014-09-18 01:07:01 -0400710
Martin Kopec5a884bf2019-02-11 18:10:55 +0000711
712class NetworkSecGroupService(BaseNetworkService):
David Paterson82234022015-04-12 14:07:40 -0400713 def list(self):
John Warrenf9606e92015-12-10 12:12:42 -0500714 client = self.security_groups_client
David Paterson82234022015-04-12 14:07:40 -0400715 filter = self.tenant_filter
716 # cannot delete default sec group so never show it.
717 secgroups = [secgroup for secgroup in
718 client.list_security_groups(**filter)['security_groups']
719 if secgroup['name'] != 'default']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000720 if self.prefix:
721 secgroups = self._filter_by_prefix(secgroups)
722 else:
723 if not self.is_save_state:
724 # recreate list removing saved security_groups
725 secgroups = self._filter_out_ids_from_saved(
726 secgroups, 'security_groups')
David Paterson82234022015-04-12 14:07:40 -0400727 if self.is_preserve:
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000728 secgroups = [
729 secgroup for secgroup in secgroups
730 if secgroup['security_group_rules'][0]['project_id']
731 not in CONF_PROJECTS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100732 LOG.debug("List count, %s security_groups", len(secgroups))
David Paterson82234022015-04-12 14:07:40 -0400733 return secgroups
734
735 def delete(self):
Martin Kopec5a884bf2019-02-11 18:10:55 +0000736 client = self.security_groups_client
David Paterson82234022015-04-12 14:07:40 -0400737 secgroups = self.list()
738 for secgroup in secgroups:
739 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000740 LOG.debug("Deleting security_group with id %s", secgroup['id'])
Martin Kopec5a884bf2019-02-11 18:10:55 +0000741 client.delete_security_group(secgroup['id'])
David Paterson82234022015-04-12 14:07:40 -0400742 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000743 LOG.exception("Delete security_group %s exception.",
744 secgroup['id'])
David Paterson82234022015-04-12 14:07:40 -0400745
746 def dry_run(self):
747 secgroups = self.list()
Martin Kopec5a884bf2019-02-11 18:10:55 +0000748 self.data['security_groups'] = secgroups
749
750 def save_state(self):
751 secgroups = self.list()
752 self.data['security_groups'] = {}
753 for secgroup in secgroups:
754 self.data['security_groups'][secgroup['id']] = secgroup['name']
David Paterson82234022015-04-12 14:07:40 -0400755
756
Martin Kopec5a884bf2019-02-11 18:10:55 +0000757class NetworkSubnetService(BaseNetworkService):
David Patersonce781492014-09-18 01:07:01 -0400758
759 def list(self):
John Warren3961acd2015-10-02 14:38:53 -0400760 client = self.subnets_client
David Paterson82234022015-04-12 14:07:40 -0400761 subnets = client.list_subnets(**self.tenant_filter)
David Patersonce781492014-09-18 01:07:01 -0400762 subnets = subnets['subnets']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000763 if self.prefix:
764 subnets = self._filter_by_prefix(subnets)
765 else:
766 if not self.is_save_state:
767 # recreate list removing saved subnets
768 subnets = self._filter_out_ids_from_saved(subnets, 'subnets')
David Patersond6babc52014-10-14 00:11:56 -0400769 if self.is_preserve:
770 subnets = self._filter_by_conf_networks(subnets)
Jordan Pittier525ec712016-12-07 17:51:26 +0100771 LOG.debug("List count, %s Subnets", len(subnets))
David Patersonce781492014-09-18 01:07:01 -0400772 return subnets
773
774 def delete(self):
John Warren3961acd2015-10-02 14:38:53 -0400775 client = self.subnets_client
David Patersonce781492014-09-18 01:07:01 -0400776 subnets = self.list()
777 for subnet in subnets:
778 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000779 LOG.debug("Deleting subnet with id %s", subnet['id'])
David Patersonce781492014-09-18 01:07:01 -0400780 client.delete_subnet(subnet['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400781 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000782 LOG.exception("Delete Subnet %s exception.", subnet['id'])
David Patersonce781492014-09-18 01:07:01 -0400783
784 def dry_run(self):
785 subnets = self.list()
786 self.data['subnets'] = subnets
787
Martin Kopec5a884bf2019-02-11 18:10:55 +0000788 def save_state(self):
789 subnets = self.list()
790 self.data['subnets'] = {}
791 for subnet in subnets:
792 self.data['subnets'][subnet['id']] = subnet['name']
793
David Patersonce781492014-09-18 01:07:01 -0400794
Martin Kopece6819982019-02-18 12:34:52 +0000795class NetworkSubnetPoolsService(BaseNetworkService):
796
797 def list(self):
798 client = self.subnetpools_client
799 pools = client.list_subnetpools(**self.tenant_filter)['subnetpools']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000800 if self.prefix:
801 pools = self._filter_by_prefix(pools)
802 else:
803 if not self.is_save_state:
804 # recreate list removing saved subnet pools
805 pools = self._filter_out_ids_from_saved(pools, 'subnetpools')
Martin Kopece6819982019-02-18 12:34:52 +0000806 if self.is_preserve:
807 pools = [pool for pool in pools if pool['project_id']
808 not in CONF_PROJECTS]
809 LOG.debug("List count, %s Subnet Pools", len(pools))
810 return pools
811
812 def delete(self):
813 client = self.subnetpools_client
814 pools = self.list()
815 for pool in pools:
816 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000817 LOG.debug("Deleting Subnet Pool with id %s", pool['id'])
Martin Kopece6819982019-02-18 12:34:52 +0000818 client.delete_subnetpool(pool['id'])
819 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000820 LOG.exception("Delete Subnet Pool %s exception.", pool['id'])
Martin Kopece6819982019-02-18 12:34:52 +0000821
822 def dry_run(self):
823 pools = self.list()
824 self.data['subnetpools'] = pools
825
826 def save_state(self):
827 pools = self.list()
828 self.data['subnetpools'] = {}
829 for pool in pools:
830 self.data['subnetpools'][pool['id']] = pool['name']
831
832
David Patersonce781492014-09-18 01:07:01 -0400833# begin global services
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000834class RegionService(BaseService):
835
836 def __init__(self, manager, **kwargs):
837 super(RegionService, self).__init__(kwargs)
838 self.client = manager.regions_client
839
840 def list(self):
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000841 if self.prefix:
842 # this means we're cleaning resources based on a certain prefix,
843 # this resource doesn't have a name, therefore return empty list
844 return []
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000845 client = self.client
846 regions = client.list_regions()
847 if not self.is_save_state:
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000848 regions = self._filter_out_ids_from_saved(
849 regions['regions'], 'regions')
Martin Kopeca8578802020-04-07 08:19:14 +0000850 LOG.debug("List count, %s Regions", len(regions))
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000851 return regions
852 else:
Martin Kopeca8578802020-04-07 08:19:14 +0000853 LOG.debug("List count, %s Regions", len(regions['regions']))
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000854 return regions['regions']
855
856 def delete(self):
857 client = self.client
858 regions = self.list()
859 for region in regions:
860 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000861 LOG.debug("Deleting region with id %s", region['id'])
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +0000862 client.delete_region(region['id'])
863 except Exception:
864 LOG.exception("Delete Region %s exception.", region['id'])
865
866 def dry_run(self):
867 regions = self.list()
868 self.data['regions'] = {}
869 for region in regions:
870 self.data['regions'][region['id']] = region
871
872 def save_state(self):
873 regions = self.list()
874 self.data['regions'] = {}
875 for region in regions:
876 self.data['regions'][region['id']] = region
877
878
David Patersonce781492014-09-18 01:07:01 -0400879class FlavorService(BaseService):
880 def __init__(self, manager, **kwargs):
881 super(FlavorService, self).__init__(kwargs)
882 self.client = manager.flavors_client
883
884 def list(self):
885 client = self.client
ghanshyam19973be2015-08-18 15:46:42 +0900886 flavors = client.list_flavors({"is_public": None})['flavors']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000887 if self.prefix:
888 flavors = self._filter_by_prefix(flavors)
889 else:
890 if not self.is_save_state:
891 # recreate list removing saved flavors
892 flavors = self._filter_out_ids_from_saved(flavors, 'flavors')
David Patersonce781492014-09-18 01:07:01 -0400893 if self.is_preserve:
894 flavors = [flavor for flavor in flavors
895 if flavor['id'] not in CONF_FLAVORS]
Jordan Pittier525ec712016-12-07 17:51:26 +0100896 LOG.debug("List count, %s Flavors after reconcile", len(flavors))
David Patersonce781492014-09-18 01:07:01 -0400897 return flavors
898
899 def delete(self):
900 client = self.client
901 flavors = self.list()
902 for flavor in flavors:
903 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000904 LOG.debug("Deleting flavor with id %s", flavor['id'])
David Patersonce781492014-09-18 01:07:01 -0400905 client.delete_flavor(flavor['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400906 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000907 LOG.exception("Delete Flavor %s exception.", flavor['id'])
David Patersonce781492014-09-18 01:07:01 -0400908
909 def dry_run(self):
910 flavors = self.list()
911 self.data['flavors'] = flavors
912
913 def save_state(self):
914 flavors = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -0500915 self.data['flavors'] = {}
David Patersonce781492014-09-18 01:07:01 -0400916 for flavor in flavors:
gordon chungc15f1bc2015-02-23 18:00:41 -0500917 self.data['flavors'][flavor['id']] = flavor['name']
David Patersonce781492014-09-18 01:07:01 -0400918
919
920class ImageService(BaseService):
921 def __init__(self, manager, **kwargs):
922 super(ImageService, self).__init__(kwargs)
zhufl66275c22018-03-28 15:32:14 +0800923 self.client = manager.image_client_v2
David Patersonce781492014-09-18 01:07:01 -0400924
925 def list(self):
926 client = self.client
Lukas Piwowarski2c831242020-03-11 12:25:11 +0000927 response = client.list_images()
928 images = []
929 images.extend(response['images'])
930 while 'next' in response:
931 parsed = urllib.urlparse(response['next'])
932 marker = urllib.parse_qs(parsed.query)['marker'][0]
933 response = client.list_images(params={"marker": marker})
934 images.extend(response['images'])
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000935 if self.prefix:
936 images = self._filter_by_prefix(images)
937 else:
938 if not self.is_save_state:
939 images = self._filter_out_ids_from_saved(images, 'images')
David Patersonce781492014-09-18 01:07:01 -0400940 if self.is_preserve:
941 images = [image for image in images
942 if image['id'] not in CONF_IMAGES]
Jordan Pittier525ec712016-12-07 17:51:26 +0100943 LOG.debug("List count, %s Images after reconcile", len(images))
David Patersonce781492014-09-18 01:07:01 -0400944 return images
945
946 def delete(self):
947 client = self.client
948 images = self.list()
949 for image in images:
950 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000951 LOG.debug("Deleting image with id %s", image['id'])
David Patersonce781492014-09-18 01:07:01 -0400952 client.delete_image(image['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400953 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000954 LOG.exception("Delete Image %s exception.", image['id'])
David Patersonce781492014-09-18 01:07:01 -0400955
956 def dry_run(self):
957 images = self.list()
958 self.data['images'] = images
959
960 def save_state(self):
gordon chungc15f1bc2015-02-23 18:00:41 -0500961 self.data['images'] = {}
David Paterson82234022015-04-12 14:07:40 -0400962 images = self.list()
David Patersonce781492014-09-18 01:07:01 -0400963 for image in images:
gordon chungc15f1bc2015-02-23 18:00:41 -0500964 self.data['images'][image['id']] = image['name']
David Patersonce781492014-09-18 01:07:01 -0400965
966
Daniel Mellado82c83a52015-12-09 15:16:49 +0000967class UserService(BaseService):
968
969 def __init__(self, manager, **kwargs):
970 super(UserService, self).__init__(kwargs)
Arx Cruz05fe4bc2017-10-20 10:48:28 +0200971 self.client = manager.users_v3_client
David Patersonce781492014-09-18 01:07:01 -0400972
973 def list(self):
Daniel Mellado82c83a52015-12-09 15:16:49 +0000974 users = self.client.list_users()['users']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +0000975 if self.prefix:
976 users = self._filter_by_prefix(users)
977 else:
978 if not self.is_save_state:
979 users = self._filter_out_ids_from_saved(users, 'users')
David Patersonce781492014-09-18 01:07:01 -0400980 if self.is_preserve:
981 users = [user for user in users if user['name']
982 not in CONF_USERS]
David Patersonce781492014-09-18 01:07:01 -0400983 elif not self.is_save_state: # Never delete admin user
984 users = [user for user in users if user['name'] !=
David Paterson07661de2015-10-29 20:15:04 -0700985 CONF.auth.admin_username]
Jordan Pittier525ec712016-12-07 17:51:26 +0100986 LOG.debug("List count, %s Users after reconcile", len(users))
David Patersonce781492014-09-18 01:07:01 -0400987 return users
988
989 def delete(self):
David Patersonce781492014-09-18 01:07:01 -0400990 users = self.list()
991 for user in users:
992 try:
Martin Kopeca8578802020-04-07 08:19:14 +0000993 LOG.debug("Deleting user with id %s", user['id'])
Daniel Mellado82c83a52015-12-09 15:16:49 +0000994 self.client.delete_user(user['id'])
David Patersone41ebca2015-04-09 05:40:12 -0400995 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +0000996 LOG.exception("Delete User %s exception.", user['id'])
David Patersonce781492014-09-18 01:07:01 -0400997
998 def dry_run(self):
999 users = self.list()
1000 self.data['users'] = users
1001
1002 def save_state(self):
1003 users = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -05001004 self.data['users'] = {}
David Patersonce781492014-09-18 01:07:01 -04001005 for user in users:
gordon chungc15f1bc2015-02-23 18:00:41 -05001006 self.data['users'][user['id']] = user['name']
David Patersonce781492014-09-18 01:07:01 -04001007
1008
Daniel Melladob83ea562015-12-18 09:12:49 +00001009class RoleService(BaseService):
David Patersonce781492014-09-18 01:07:01 -04001010
Daniel Mellado6b16b922015-12-07 12:43:08 +00001011 def __init__(self, manager, **kwargs):
1012 super(RoleService, self).__init__(kwargs)
Martin Kopecbd5be762019-07-13 22:42:08 +00001013 self.client = manager.roles_v3_client
Daniel Mellado6b16b922015-12-07 12:43:08 +00001014
David Patersonce781492014-09-18 01:07:01 -04001015 def list(self):
David Patersonce781492014-09-18 01:07:01 -04001016 try:
Daniel Mellado6b16b922015-12-07 12:43:08 +00001017 roles = self.client.list_roles()['roles']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +00001018 if self.prefix:
1019 roles = self._filter_by_prefix(roles)
1020 elif not self.is_save_state:
1021 # reconcile roles with saved state and never list admin role
1022 roles = self._filter_out_ids_from_saved(roles, 'roles')
1023 roles = [role for role in roles
1024 if role['name'] != CONF.identity.admin_role]
1025 LOG.debug("List count, %s Roles after reconcile", len(roles))
David Patersonce781492014-09-18 01:07:01 -04001026 return roles
David Patersone41ebca2015-04-09 05:40:12 -04001027 except Exception:
1028 LOG.exception("Cannot retrieve Roles.")
David Patersonce781492014-09-18 01:07:01 -04001029 return []
1030
1031 def delete(self):
David Patersonce781492014-09-18 01:07:01 -04001032 roles = self.list()
1033 for role in roles:
1034 try:
Martin Kopeca8578802020-04-07 08:19:14 +00001035 LOG.debug("Deleting role with id %s", role['id'])
Daniel Mellado6b16b922015-12-07 12:43:08 +00001036 self.client.delete_role(role['id'])
David Patersone41ebca2015-04-09 05:40:12 -04001037 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +00001038 LOG.exception("Delete Role %s exception.", role['id'])
David Patersonce781492014-09-18 01:07:01 -04001039
1040 def dry_run(self):
1041 roles = self.list()
1042 self.data['roles'] = roles
1043
1044 def save_state(self):
1045 roles = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -05001046 self.data['roles'] = {}
David Patersonce781492014-09-18 01:07:01 -04001047 for role in roles:
gordon chungc15f1bc2015-02-23 18:00:41 -05001048 self.data['roles'][role['id']] = role['name']
David Patersonce781492014-09-18 01:07:01 -04001049
1050
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001051class ProjectService(BaseService):
David Patersonce781492014-09-18 01:07:01 -04001052
Daniel Melladob04da902015-11-20 17:43:12 +01001053 def __init__(self, manager, **kwargs):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001054 super(ProjectService, self).__init__(kwargs)
1055 self.client = manager.projects_client
Daniel Melladob04da902015-11-20 17:43:12 +01001056
David Patersonce781492014-09-18 01:07:01 -04001057 def list(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001058 projects = self.client.list_projects()['projects']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +00001059 if self.prefix:
1060 projects = self._filter_by_prefix(projects)
1061 else:
1062 if not self.is_save_state:
1063 projects = self._filter_out_ids_from_saved(
1064 projects, 'projects')
1065 projects = [project for project in projects
1066 if project['name'] != CONF.auth.admin_project_name]
David Patersonce781492014-09-18 01:07:01 -04001067 if self.is_preserve:
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +00001068 projects = [project for project in projects
Federico Ressi2d6bcaa2018-04-11 12:37:36 +02001069 if project['name'] not in CONF_PROJECTS]
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001070 LOG.debug("List count, %s Projects after reconcile", len(projects))
1071 return projects
David Patersonce781492014-09-18 01:07:01 -04001072
1073 def delete(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001074 projects = self.list()
1075 for project in projects:
David Patersonce781492014-09-18 01:07:01 -04001076 try:
Martin Kopeca8578802020-04-07 08:19:14 +00001077 LOG.debug("Deleting project with id %s", project['id'])
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001078 self.client.delete_project(project['id'])
David Patersone41ebca2015-04-09 05:40:12 -04001079 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +00001080 LOG.exception("Delete project %s exception.", project['id'])
David Patersonce781492014-09-18 01:07:01 -04001081
1082 def dry_run(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001083 projects = self.list()
1084 self.data['projects'] = projects
David Patersonce781492014-09-18 01:07:01 -04001085
1086 def save_state(self):
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001087 projects = self.list()
1088 self.data['projects'] = {}
1089 for project in projects:
1090 self.data['projects'][project['id']] = project['name']
David Patersonce781492014-09-18 01:07:01 -04001091
1092
1093class DomainService(BaseService):
1094
1095 def __init__(self, manager, **kwargs):
1096 super(DomainService, self).__init__(kwargs)
Daniel Mellado91a26b62016-02-11 11:13:04 +00001097 self.client = manager.domains_client
David Patersonce781492014-09-18 01:07:01 -04001098
1099 def list(self):
1100 client = self.client
Thomas Bechtold48268a02015-08-30 19:37:46 +02001101 domains = client.list_domains()['domains']
Luigi Dino Tamagnone9052dfc2023-04-09 15:24:45 +00001102 if self.prefix:
1103 domains = self._filter_by_prefix(domains)
1104 elif not self.is_save_state:
1105 domains = self._filter_out_ids_from_saved(domains, 'domains')
Jordan Pittier525ec712016-12-07 17:51:26 +01001106 LOG.debug("List count, %s Domains after reconcile", len(domains))
David Patersonce781492014-09-18 01:07:01 -04001107 return domains
1108
1109 def delete(self):
1110 client = self.client
1111 domains = self.list()
1112 for domain in domains:
1113 try:
Martin Kopeca8578802020-04-07 08:19:14 +00001114 LOG.debug("Deleting domain with id %s", domain['id'])
David Patersonce781492014-09-18 01:07:01 -04001115 client.update_domain(domain['id'], enabled=False)
1116 client.delete_domain(domain['id'])
David Patersone41ebca2015-04-09 05:40:12 -04001117 except Exception:
Martin Kopecfd01fe92019-02-27 08:46:05 +00001118 LOG.exception("Delete Domain %s exception.", domain['id'])
David Patersonce781492014-09-18 01:07:01 -04001119
1120 def dry_run(self):
1121 domains = self.list()
1122 self.data['domains'] = domains
1123
1124 def save_state(self):
1125 domains = self.list()
gordon chungc15f1bc2015-02-23 18:00:41 -05001126 self.data['domains'] = {}
David Patersonce781492014-09-18 01:07:01 -04001127 for domain in domains:
gordon chungc15f1bc2015-02-23 18:00:41 -05001128 self.data['domains'][domain['id']] = domain['name']
David Patersonce781492014-09-18 01:07:01 -04001129
1130
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001131def get_project_associated_cleanup_services():
1132 """Returns list of project service classes.
1133
1134 The list contains services whose resources need to be deleted prior,
1135 the project they are associated with, deletion. The resources cannot be
1136 most likely deleted after the project is deleted first.
1137 """
1138 project_associated_services = []
ghanshyame4796f82016-04-13 15:49:22 +09001139 # TODO(gmann): Tempest should provide some plugin hook for cleanup
1140 # script extension to plugin tests also.
David Patersonce781492014-09-18 01:07:01 -04001141 if IS_NOVA:
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001142 project_associated_services.append(NovaQuotaService)
David Patersonce781492014-09-18 01:07:01 -04001143 if IS_CINDER:
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001144 project_associated_services.append(VolumeQuotaService)
Lukas Piwowarski97b84112020-03-25 13:57:30 +00001145 if IS_NEUTRON:
1146 project_associated_services.append(NetworkQuotaService)
Martin Kopec56c0b2b2019-11-13 12:50:07 +00001147 return project_associated_services
1148
1149
1150def get_resource_cleanup_services():
1151 """Returns list of project related classes.
1152
1153 The list contains services whose resources are associated with a project,
1154 however, their deletion is possible also after the project is deleted
1155 first.
1156 """
1157 resource_cleanup_services = []
1158 # TODO(gmann): Tempest should provide some plugin hook for cleanup
1159 # script extension to plugin tests also.
1160 if IS_NOVA:
1161 resource_cleanup_services.append(ServerService)
1162 resource_cleanup_services.append(KeyPairService)
1163 resource_cleanup_services.append(ServerGroupService)
1164 if IS_NEUTRON:
1165 resource_cleanup_services.append(NetworkFloatingIpService)
1166 if utils.is_extension_enabled('metering', 'network'):
1167 resource_cleanup_services.append(NetworkMeteringLabelRuleService)
1168 resource_cleanup_services.append(NetworkMeteringLabelService)
1169 resource_cleanup_services.append(NetworkRouterService)
1170 resource_cleanup_services.append(NetworkPortService)
1171 resource_cleanup_services.append(NetworkSubnetService)
1172 resource_cleanup_services.append(NetworkService)
1173 resource_cleanup_services.append(NetworkSecGroupService)
1174 resource_cleanup_services.append(NetworkSubnetPoolsService)
1175 if IS_CINDER:
1176 resource_cleanup_services.append(SnapshotService)
1177 resource_cleanup_services.append(VolumeService)
1178 return resource_cleanup_services
David Patersonce781492014-09-18 01:07:01 -04001179
1180
1181def get_global_cleanup_services():
1182 global_services = []
1183 if IS_NOVA:
1184 global_services.append(FlavorService)
1185 if IS_GLANCE:
1186 global_services.append(ImageService)
1187 global_services.append(UserService)
Arx Cruz05fe4bc2017-10-20 10:48:28 +02001188 global_services.append(ProjectService)
David Patersonce781492014-09-18 01:07:01 -04001189 global_services.append(DomainService)
1190 global_services.append(RoleService)
Lukas Piwowarski3b1311f2019-11-12 10:43:40 +00001191 global_services.append(RegionService)
David Patersonce781492014-09-18 01:07:01 -04001192 return global_services