OpenStack Testing (Tempest) of an existing cloud
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cleanup_service.py 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  1. # Copyright 2015 Dell Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. from oslo_log import log as logging
  15. from tempest import clients
  16. from tempest.common import credentials_factory as credentials
  17. from tempest.common import identity
  18. from tempest.common import utils
  19. from tempest.common.utils import net_info
  20. from tempest import config
  21. from tempest.lib import exceptions
  22. LOG = logging.getLogger(__name__)
  23. CONF = config.CONF
  24. CONF_FLAVORS = None
  25. CONF_IMAGES = None
  26. CONF_NETWORKS = []
  27. CONF_PRIV_NETWORK_NAME = None
  28. CONF_PUB_NETWORK = None
  29. CONF_PUB_ROUTER = None
  30. CONF_PROJECTS = None
  31. CONF_USERS = None
  32. IS_CINDER = None
  33. IS_GLANCE = None
  34. IS_NEUTRON = None
  35. IS_NOVA = None
  36. def init_conf():
  37. global CONF_FLAVORS
  38. global CONF_IMAGES
  39. global CONF_NETWORKS
  40. global CONF_PRIV_NETWORK
  41. global CONF_PRIV_NETWORK_NAME
  42. global CONF_PUB_NETWORK
  43. global CONF_PUB_ROUTER
  44. global CONF_PROJECTS
  45. global CONF_USERS
  46. global IS_CINDER
  47. global IS_GLANCE
  48. global IS_HEAT
  49. global IS_NEUTRON
  50. global IS_NOVA
  51. IS_CINDER = CONF.service_available.cinder
  52. IS_GLANCE = CONF.service_available.glance
  53. IS_NEUTRON = CONF.service_available.neutron
  54. IS_NOVA = CONF.service_available.nova
  55. CONF_FLAVORS = [CONF.compute.flavor_ref, CONF.compute.flavor_ref_alt]
  56. CONF_IMAGES = [CONF.compute.image_ref, CONF.compute.image_ref_alt]
  57. CONF_PRIV_NETWORK_NAME = CONF.compute.fixed_network_name
  58. CONF_PUB_NETWORK = CONF.network.public_network_id
  59. CONF_PUB_ROUTER = CONF.network.public_router_id
  60. CONF_PROJECTS = [CONF.auth.admin_project_name]
  61. CONF_USERS = [CONF.auth.admin_username]
  62. if IS_NEUTRON:
  63. CONF_PRIV_NETWORK = _get_network_id(CONF.compute.fixed_network_name,
  64. CONF.auth.admin_project_name)
  65. CONF_NETWORKS = [CONF_PUB_NETWORK, CONF_PRIV_NETWORK]
  66. def _get_network_id(net_name, project_name):
  67. am = clients.Manager(
  68. credentials.get_configured_admin_credentials())
  69. net_cl = am.networks_client
  70. pr_cl = am.projects_client
  71. networks = net_cl.list_networks()
  72. project = identity.get_project_by_name(pr_cl, project_name)
  73. p_id = project['id']
  74. n_id = None
  75. for net in networks['networks']:
  76. if (net['project_id'] == p_id and net['name'] == net_name):
  77. n_id = net['id']
  78. break
  79. return n_id
  80. class BaseService(object):
  81. def __init__(self, kwargs):
  82. self.client = None
  83. for key, value in kwargs.items():
  84. setattr(self, key, value)
  85. self.tenant_filter = {}
  86. if hasattr(self, 'tenant_id'):
  87. self.tenant_filter['project_id'] = self.tenant_id
  88. def _filter_by_tenant_id(self, item_list):
  89. if (item_list is None or
  90. not item_list or
  91. not hasattr(self, 'tenant_id') or
  92. self.tenant_id is None or
  93. 'tenant_id' not in item_list[0]):
  94. return item_list
  95. return [item for item in item_list
  96. if item['tenant_id'] == self.tenant_id]
  97. def list(self):
  98. pass
  99. def delete(self):
  100. pass
  101. def dry_run(self):
  102. pass
  103. def save_state(self):
  104. pass
  105. def run(self):
  106. try:
  107. if self.is_dry_run:
  108. self.dry_run()
  109. elif self.is_save_state:
  110. self.save_state()
  111. else:
  112. self.delete()
  113. except exceptions.NotImplemented as exc:
  114. # Many OpenStack services use extensions logic to implement the
  115. # features or resources. Tempest cleanup tries to clean up the test
  116. # resources without having much logic of extensions checks etc.
  117. # If any of the extension is missing then, service will return
  118. # NotImplemented error.
  119. msg = ("Got NotImplemented error in %s, full exception: %s" %
  120. (str(self.__class__), str(exc)))
  121. LOG.exception(msg)
  122. self.got_exceptions.append(exc)
  123. class SnapshotService(BaseService):
  124. def __init__(self, manager, **kwargs):
  125. super(SnapshotService, self).__init__(kwargs)
  126. self.client = manager.snapshots_client_latest
  127. def list(self):
  128. client = self.client
  129. snaps = client.list_snapshots()['snapshots']
  130. if not self.is_save_state:
  131. # recreate list removing saved snapshots
  132. snaps = [snap for snap in snaps if snap['id']
  133. not in self.saved_state_json['snapshots'].keys()]
  134. LOG.debug("List count, %s Snapshots", len(snaps))
  135. return snaps
  136. def delete(self):
  137. snaps = self.list()
  138. client = self.client
  139. for snap in snaps:
  140. try:
  141. client.delete_snapshot(snap['id'])
  142. except Exception:
  143. LOG.exception("Delete Snapshot %s exception.", snap['id'])
  144. def dry_run(self):
  145. snaps = self.list()
  146. self.data['snapshots'] = snaps
  147. def save_state(self):
  148. snaps = self.list()
  149. self.data['snapshots'] = {}
  150. for snap in snaps:
  151. self.data['snapshots'][snap['id']] = snap['name']
  152. class ServerService(BaseService):
  153. def __init__(self, manager, **kwargs):
  154. super(ServerService, self).__init__(kwargs)
  155. self.client = manager.servers_client
  156. self.server_groups_client = manager.server_groups_client
  157. def list(self):
  158. client = self.client
  159. servers_body = client.list_servers()
  160. servers = servers_body['servers']
  161. if not self.is_save_state:
  162. # recreate list removing saved servers
  163. servers = [server for server in servers if server['id']
  164. not in self.saved_state_json['servers'].keys()]
  165. LOG.debug("List count, %s Servers", len(servers))
  166. return servers
  167. def delete(self):
  168. client = self.client
  169. servers = self.list()
  170. for server in servers:
  171. try:
  172. client.delete_server(server['id'])
  173. except Exception:
  174. LOG.exception("Delete Server %s exception.", server['id'])
  175. def dry_run(self):
  176. servers = self.list()
  177. self.data['servers'] = servers
  178. def save_state(self):
  179. servers = self.list()
  180. self.data['servers'] = {}
  181. for server in servers:
  182. self.data['servers'][server['id']] = server['name']
  183. class ServerGroupService(ServerService):
  184. def list(self):
  185. client = self.server_groups_client
  186. sgs = client.list_server_groups()['server_groups']
  187. if not self.is_save_state:
  188. # recreate list removing saved server_groups
  189. sgs = [sg for sg in sgs if sg['id']
  190. not in self.saved_state_json['server_groups'].keys()]
  191. LOG.debug("List count, %s Server Groups", len(sgs))
  192. return sgs
  193. def delete(self):
  194. client = self.server_groups_client
  195. sgs = self.list()
  196. for sg in sgs:
  197. try:
  198. client.delete_server_group(sg['id'])
  199. except Exception:
  200. LOG.exception("Delete Server Group %s exception.", sg['id'])
  201. def dry_run(self):
  202. sgs = self.list()
  203. self.data['server_groups'] = sgs
  204. def save_state(self):
  205. sgs = self.list()
  206. self.data['server_groups'] = {}
  207. for sg in sgs:
  208. self.data['server_groups'][sg['id']] = sg['name']
  209. class KeyPairService(BaseService):
  210. def __init__(self, manager, **kwargs):
  211. super(KeyPairService, self).__init__(kwargs)
  212. self.client = manager.keypairs_client
  213. def list(self):
  214. client = self.client
  215. keypairs = client.list_keypairs()['keypairs']
  216. if not self.is_save_state:
  217. # recreate list removing saved keypairs
  218. keypairs = [keypair for keypair in keypairs
  219. if keypair['keypair']['name']
  220. not in self.saved_state_json['keypairs'].keys()]
  221. LOG.debug("List count, %s Keypairs", len(keypairs))
  222. return keypairs
  223. def delete(self):
  224. client = self.client
  225. keypairs = self.list()
  226. for k in keypairs:
  227. name = k['keypair']['name']
  228. try:
  229. client.delete_keypair(name)
  230. except Exception:
  231. LOG.exception("Delete Keypair %s exception.", name)
  232. def dry_run(self):
  233. keypairs = self.list()
  234. self.data['keypairs'] = keypairs
  235. def save_state(self):
  236. keypairs = self.list()
  237. self.data['keypairs'] = {}
  238. for keypair in keypairs:
  239. keypair = keypair['keypair']
  240. self.data['keypairs'][keypair['name']] = keypair
  241. class VolumeService(BaseService):
  242. def __init__(self, manager, **kwargs):
  243. super(VolumeService, self).__init__(kwargs)
  244. self.client = manager.volumes_client_latest
  245. def list(self):
  246. client = self.client
  247. vols = client.list_volumes()['volumes']
  248. if not self.is_save_state:
  249. # recreate list removing saved volumes
  250. vols = [vol for vol in vols if vol['id']
  251. not in self.saved_state_json['volumes'].keys()]
  252. LOG.debug("List count, %s Volumes", len(vols))
  253. return vols
  254. def delete(self):
  255. client = self.client
  256. vols = self.list()
  257. for v in vols:
  258. try:
  259. client.delete_volume(v['id'])
  260. except Exception:
  261. LOG.exception("Delete Volume %s exception.", v['id'])
  262. def dry_run(self):
  263. vols = self.list()
  264. self.data['volumes'] = vols
  265. def save_state(self):
  266. vols = self.list()
  267. self.data['volumes'] = {}
  268. for vol in vols:
  269. self.data['volumes'][vol['id']] = vol['name']
  270. class VolumeQuotaService(BaseService):
  271. def __init__(self, manager, **kwargs):
  272. super(VolumeQuotaService, self).__init__(kwargs)
  273. self.client = manager.volume_quotas_client_latest
  274. def delete(self):
  275. client = self.client
  276. try:
  277. client.delete_quota_set(self.project_id)
  278. except Exception:
  279. LOG.exception("Delete Volume Quotas exception for 'project %s'.",
  280. self.project_id)
  281. def dry_run(self):
  282. quotas = self.client.show_quota_set(
  283. self.project_id, params={'usage': True})['quota_set']
  284. self.data['volume_quotas'] = quotas
  285. class NovaQuotaService(BaseService):
  286. def __init__(self, manager, **kwargs):
  287. super(NovaQuotaService, self).__init__(kwargs)
  288. self.client = manager.quotas_client
  289. self.limits_client = manager.limits_client
  290. def delete(self):
  291. client = self.client
  292. try:
  293. client.delete_quota_set(self.project_id)
  294. except Exception:
  295. LOG.exception("Delete Quotas exception for 'project %s'.",
  296. self.project_id)
  297. def dry_run(self):
  298. client = self.limits_client
  299. quotas = client.show_limits()['limits']
  300. self.data['compute_quotas'] = quotas['absolute']
  301. # Begin network service classes
  302. class BaseNetworkService(BaseService):
  303. def __init__(self, manager, **kwargs):
  304. super(BaseNetworkService, self).__init__(kwargs)
  305. self.networks_client = manager.networks_client
  306. self.subnets_client = manager.subnets_client
  307. self.ports_client = manager.ports_client
  308. self.floating_ips_client = manager.floating_ips_client
  309. self.metering_labels_client = manager.metering_labels_client
  310. self.metering_label_rules_client = manager.metering_label_rules_client
  311. self.security_groups_client = manager.security_groups_client
  312. self.routers_client = manager.routers_client
  313. self.subnetpools_client = manager.subnetpools_client
  314. def _filter_by_conf_networks(self, item_list):
  315. if not item_list or not all(('network_id' in i for i in item_list)):
  316. return item_list
  317. return [item for item in item_list if item['network_id']
  318. not in CONF_NETWORKS]
  319. class NetworkService(BaseNetworkService):
  320. def list(self):
  321. client = self.networks_client
  322. networks = client.list_networks(**self.tenant_filter)
  323. networks = networks['networks']
  324. if not self.is_save_state:
  325. # recreate list removing saved networks
  326. networks = [network for network in networks if network['id']
  327. not in self.saved_state_json['networks'].keys()]
  328. # filter out networks declared in tempest.conf
  329. if self.is_preserve:
  330. networks = [network for network in networks
  331. if network['id'] not in CONF_NETWORKS]
  332. LOG.debug("List count, %s Networks", networks)
  333. return networks
  334. def delete(self):
  335. client = self.networks_client
  336. networks = self.list()
  337. for n in networks:
  338. try:
  339. client.delete_network(n['id'])
  340. except Exception:
  341. LOG.exception("Delete Network %s exception.", n['id'])
  342. def dry_run(self):
  343. networks = self.list()
  344. self.data['networks'] = networks
  345. def save_state(self):
  346. networks = self.list()
  347. self.data['networks'] = {}
  348. for network in networks:
  349. self.data['networks'][network['id']] = network
  350. class NetworkFloatingIpService(BaseNetworkService):
  351. def list(self):
  352. client = self.floating_ips_client
  353. flips = client.list_floatingips(**self.tenant_filter)
  354. flips = flips['floatingips']
  355. if not self.is_save_state:
  356. # recreate list removing saved flips
  357. flips = [flip for flip in flips if flip['id']
  358. not in self.saved_state_json['floatingips'].keys()]
  359. LOG.debug("List count, %s Network Floating IPs", len(flips))
  360. return flips
  361. def delete(self):
  362. client = self.floating_ips_client
  363. flips = self.list()
  364. for flip in flips:
  365. try:
  366. client.delete_floatingip(flip['id'])
  367. except Exception:
  368. LOG.exception("Delete Network Floating IP %s exception.",
  369. flip['id'])
  370. def dry_run(self):
  371. flips = self.list()
  372. self.data['floatingips'] = flips
  373. def save_state(self):
  374. flips = self.list()
  375. self.data['floatingips'] = {}
  376. for flip in flips:
  377. self.data['floatingips'][flip['id']] = flip
  378. class NetworkRouterService(BaseNetworkService):
  379. def list(self):
  380. client = self.routers_client
  381. routers = client.list_routers(**self.tenant_filter)
  382. routers = routers['routers']
  383. if not self.is_save_state:
  384. # recreate list removing saved routers
  385. routers = [router for router in routers if router['id']
  386. not in self.saved_state_json['routers'].keys()]
  387. if self.is_preserve:
  388. routers = [router for router in routers
  389. if router['id'] != CONF_PUB_ROUTER]
  390. LOG.debug("List count, %s Routers", len(routers))
  391. return routers
  392. def delete(self):
  393. client = self.routers_client
  394. ports_client = self.ports_client
  395. routers = self.list()
  396. for router in routers:
  397. rid = router['id']
  398. ports = [port for port
  399. in ports_client.list_ports(device_id=rid)['ports']
  400. if net_info.is_router_interface_port(port)]
  401. for port in ports:
  402. try:
  403. client.remove_router_interface(rid, port_id=port['id'])
  404. except Exception:
  405. LOG.exception("Delete Router Interface exception for "
  406. "'port %s' of 'router %s'.", port['id'], rid)
  407. try:
  408. client.delete_router(rid)
  409. except Exception:
  410. LOG.exception("Delete Router %s exception.", rid)
  411. def dry_run(self):
  412. routers = self.list()
  413. self.data['routers'] = routers
  414. def save_state(self):
  415. routers = self.list()
  416. self.data['routers'] = {}
  417. for router in routers:
  418. self.data['routers'][router['id']] = router['name']
  419. class NetworkMeteringLabelRuleService(NetworkService):
  420. def list(self):
  421. client = self.metering_label_rules_client
  422. rules = client.list_metering_label_rules()
  423. rules = rules['metering_label_rules']
  424. rules = self._filter_by_tenant_id(rules)
  425. if not self.is_save_state:
  426. saved_rules = self.saved_state_json['metering_label_rules'].keys()
  427. # recreate list removing saved rules
  428. rules = [rule for rule in rules if rule['id'] not in saved_rules]
  429. LOG.debug("List count, %s Metering Label Rules", len(rules))
  430. return rules
  431. def delete(self):
  432. client = self.metering_label_rules_client
  433. rules = self.list()
  434. for rule in rules:
  435. try:
  436. client.delete_metering_label_rule(rule['id'])
  437. except Exception:
  438. LOG.exception("Delete Metering Label Rule %s exception.",
  439. rule['id'])
  440. def dry_run(self):
  441. rules = self.list()
  442. self.data['metering_label_rules'] = rules
  443. def save_state(self):
  444. rules = self.list()
  445. self.data['metering_label_rules'] = {}
  446. for rule in rules:
  447. self.data['metering_label_rules'][rule['id']] = rule
  448. class NetworkMeteringLabelService(BaseNetworkService):
  449. def list(self):
  450. client = self.metering_labels_client
  451. labels = client.list_metering_labels()
  452. labels = labels['metering_labels']
  453. labels = self._filter_by_tenant_id(labels)
  454. if not self.is_save_state:
  455. # recreate list removing saved labels
  456. labels = [label for label in labels if label['id']
  457. not in self.saved_state_json['metering_labels'].keys()]
  458. LOG.debug("List count, %s Metering Labels", len(labels))
  459. return labels
  460. def delete(self):
  461. client = self.metering_labels_client
  462. labels = self.list()
  463. for label in labels:
  464. try:
  465. client.delete_metering_label(label['id'])
  466. except Exception:
  467. LOG.exception("Delete Metering Label %s exception.",
  468. label['id'])
  469. def dry_run(self):
  470. labels = self.list()
  471. self.data['metering_labels'] = labels
  472. def save_state(self):
  473. labels = self.list()
  474. self.data['metering_labels'] = {}
  475. for label in labels:
  476. self.data['metering_labels'][label['id']] = label['name']
  477. class NetworkPortService(BaseNetworkService):
  478. def list(self):
  479. client = self.ports_client
  480. ports = [port for port in
  481. client.list_ports(**self.tenant_filter)['ports']
  482. if port["device_owner"] == "" or
  483. port["device_owner"].startswith("compute:")]
  484. if not self.is_save_state:
  485. # recreate list removing saved ports
  486. ports = [port for port in ports if port['id']
  487. not in self.saved_state_json['ports'].keys()]
  488. if self.is_preserve:
  489. ports = self._filter_by_conf_networks(ports)
  490. LOG.debug("List count, %s Ports", len(ports))
  491. return ports
  492. def delete(self):
  493. client = self.ports_client
  494. ports = self.list()
  495. for port in ports:
  496. try:
  497. client.delete_port(port['id'])
  498. except Exception:
  499. LOG.exception("Delete Port %s exception.", port['id'])
  500. def dry_run(self):
  501. ports = self.list()
  502. self.data['ports'] = ports
  503. def save_state(self):
  504. ports = self.list()
  505. self.data['ports'] = {}
  506. for port in ports:
  507. self.data['ports'][port['id']] = port['name']
  508. class NetworkSecGroupService(BaseNetworkService):
  509. def list(self):
  510. client = self.security_groups_client
  511. filter = self.tenant_filter
  512. # cannot delete default sec group so never show it.
  513. secgroups = [secgroup for secgroup in
  514. client.list_security_groups(**filter)['security_groups']
  515. if secgroup['name'] != 'default']
  516. if not self.is_save_state:
  517. # recreate list removing saved security_groups
  518. secgroups = [secgroup for secgroup in secgroups if secgroup['id']
  519. not in self.saved_state_json['security_groups'].keys()
  520. ]
  521. if self.is_preserve:
  522. secgroups = [secgroup for secgroup in secgroups
  523. if secgroup['security_group_rules'][0]['project_id']
  524. not in CONF_PROJECTS]
  525. LOG.debug("List count, %s security_groups", len(secgroups))
  526. return secgroups
  527. def delete(self):
  528. client = self.security_groups_client
  529. secgroups = self.list()
  530. for secgroup in secgroups:
  531. try:
  532. client.delete_security_group(secgroup['id'])
  533. except Exception:
  534. LOG.exception("Delete security_group %s exception.",
  535. secgroup['id'])
  536. def dry_run(self):
  537. secgroups = self.list()
  538. self.data['security_groups'] = secgroups
  539. def save_state(self):
  540. secgroups = self.list()
  541. self.data['security_groups'] = {}
  542. for secgroup in secgroups:
  543. self.data['security_groups'][secgroup['id']] = secgroup['name']
  544. class NetworkSubnetService(BaseNetworkService):
  545. def list(self):
  546. client = self.subnets_client
  547. subnets = client.list_subnets(**self.tenant_filter)
  548. subnets = subnets['subnets']
  549. if not self.is_save_state:
  550. # recreate list removing saved subnets
  551. subnets = [subnet for subnet in subnets if subnet['id']
  552. not in self.saved_state_json['subnets'].keys()]
  553. if self.is_preserve:
  554. subnets = self._filter_by_conf_networks(subnets)
  555. LOG.debug("List count, %s Subnets", len(subnets))
  556. return subnets
  557. def delete(self):
  558. client = self.subnets_client
  559. subnets = self.list()
  560. for subnet in subnets:
  561. try:
  562. client.delete_subnet(subnet['id'])
  563. except Exception:
  564. LOG.exception("Delete Subnet %s exception.", subnet['id'])
  565. def dry_run(self):
  566. subnets = self.list()
  567. self.data['subnets'] = subnets
  568. def save_state(self):
  569. subnets = self.list()
  570. self.data['subnets'] = {}
  571. for subnet in subnets:
  572. self.data['subnets'][subnet['id']] = subnet['name']
  573. class NetworkSubnetPoolsService(BaseNetworkService):
  574. def list(self):
  575. client = self.subnetpools_client
  576. pools = client.list_subnetpools(**self.tenant_filter)['subnetpools']
  577. if not self.is_save_state:
  578. # recreate list removing saved subnet pools
  579. pools = [pool for pool in pools if pool['id']
  580. not in self.saved_state_json['subnetpools'].keys()]
  581. if self.is_preserve:
  582. pools = [pool for pool in pools if pool['project_id']
  583. not in CONF_PROJECTS]
  584. LOG.debug("List count, %s Subnet Pools", len(pools))
  585. return pools
  586. def delete(self):
  587. client = self.subnetpools_client
  588. pools = self.list()
  589. for pool in pools:
  590. try:
  591. client.delete_subnetpool(pool['id'])
  592. except Exception:
  593. LOG.exception("Delete Subnet Pool %s exception.", pool['id'])
  594. def dry_run(self):
  595. pools = self.list()
  596. self.data['subnetpools'] = pools
  597. def save_state(self):
  598. pools = self.list()
  599. self.data['subnetpools'] = {}
  600. for pool in pools:
  601. self.data['subnetpools'][pool['id']] = pool['name']
  602. # begin global services
  603. class FlavorService(BaseService):
  604. def __init__(self, manager, **kwargs):
  605. super(FlavorService, self).__init__(kwargs)
  606. self.client = manager.flavors_client
  607. def list(self):
  608. client = self.client
  609. flavors = client.list_flavors({"is_public": None})['flavors']
  610. if not self.is_save_state:
  611. # recreate list removing saved flavors
  612. flavors = [flavor for flavor in flavors if flavor['id']
  613. not in self.saved_state_json['flavors'].keys()]
  614. if self.is_preserve:
  615. flavors = [flavor for flavor in flavors
  616. if flavor['id'] not in CONF_FLAVORS]
  617. LOG.debug("List count, %s Flavors after reconcile", len(flavors))
  618. return flavors
  619. def delete(self):
  620. client = self.client
  621. flavors = self.list()
  622. for flavor in flavors:
  623. try:
  624. client.delete_flavor(flavor['id'])
  625. except Exception:
  626. LOG.exception("Delete Flavor %s exception.", flavor['id'])
  627. def dry_run(self):
  628. flavors = self.list()
  629. self.data['flavors'] = flavors
  630. def save_state(self):
  631. flavors = self.list()
  632. self.data['flavors'] = {}
  633. for flavor in flavors:
  634. self.data['flavors'][flavor['id']] = flavor['name']
  635. class ImageService(BaseService):
  636. def __init__(self, manager, **kwargs):
  637. super(ImageService, self).__init__(kwargs)
  638. self.client = manager.image_client_v2
  639. def list(self):
  640. client = self.client
  641. images = client.list_images(params={"all_tenants": True})['images']
  642. if not self.is_save_state:
  643. images = [image for image in images if image['id']
  644. not in self.saved_state_json['images'].keys()]
  645. if self.is_preserve:
  646. images = [image for image in images
  647. if image['id'] not in CONF_IMAGES]
  648. LOG.debug("List count, %s Images after reconcile", len(images))
  649. return images
  650. def delete(self):
  651. client = self.client
  652. images = self.list()
  653. for image in images:
  654. try:
  655. client.delete_image(image['id'])
  656. except Exception:
  657. LOG.exception("Delete Image %s exception.", image['id'])
  658. def dry_run(self):
  659. images = self.list()
  660. self.data['images'] = images
  661. def save_state(self):
  662. self.data['images'] = {}
  663. images = self.list()
  664. for image in images:
  665. self.data['images'][image['id']] = image['name']
  666. class UserService(BaseService):
  667. def __init__(self, manager, **kwargs):
  668. super(UserService, self).__init__(kwargs)
  669. self.client = manager.users_v3_client
  670. def list(self):
  671. users = self.client.list_users()['users']
  672. if not self.is_save_state:
  673. users = [user for user in users if user['id']
  674. not in self.saved_state_json['users'].keys()]
  675. if self.is_preserve:
  676. users = [user for user in users if user['name']
  677. not in CONF_USERS]
  678. elif not self.is_save_state: # Never delete admin user
  679. users = [user for user in users if user['name'] !=
  680. CONF.auth.admin_username]
  681. LOG.debug("List count, %s Users after reconcile", len(users))
  682. return users
  683. def delete(self):
  684. users = self.list()
  685. for user in users:
  686. try:
  687. self.client.delete_user(user['id'])
  688. except Exception:
  689. LOG.exception("Delete User %s exception.", user['id'])
  690. def dry_run(self):
  691. users = self.list()
  692. self.data['users'] = users
  693. def save_state(self):
  694. users = self.list()
  695. self.data['users'] = {}
  696. for user in users:
  697. self.data['users'][user['id']] = user['name']
  698. class RoleService(BaseService):
  699. def __init__(self, manager, **kwargs):
  700. super(RoleService, self).__init__(kwargs)
  701. self.client = manager.roles_v3_client
  702. def list(self):
  703. try:
  704. roles = self.client.list_roles()['roles']
  705. # reconcile roles with saved state and never list admin role
  706. if not self.is_save_state:
  707. roles = [role for role in roles if
  708. (role['id'] not in
  709. self.saved_state_json['roles'].keys() and
  710. role['name'] != CONF.identity.admin_role)]
  711. LOG.debug("List count, %s Roles after reconcile", len(roles))
  712. return roles
  713. except Exception:
  714. LOG.exception("Cannot retrieve Roles.")
  715. return []
  716. def delete(self):
  717. roles = self.list()
  718. for role in roles:
  719. try:
  720. self.client.delete_role(role['id'])
  721. except Exception:
  722. LOG.exception("Delete Role %s exception.", role['id'])
  723. def dry_run(self):
  724. roles = self.list()
  725. self.data['roles'] = roles
  726. def save_state(self):
  727. roles = self.list()
  728. self.data['roles'] = {}
  729. for role in roles:
  730. self.data['roles'][role['id']] = role['name']
  731. class ProjectService(BaseService):
  732. def __init__(self, manager, **kwargs):
  733. super(ProjectService, self).__init__(kwargs)
  734. self.client = manager.projects_client
  735. def list(self):
  736. projects = self.client.list_projects()['projects']
  737. if not self.is_save_state:
  738. project_ids = self.saved_state_json['projects']
  739. projects = [project
  740. for project in projects
  741. if (project['id'] not in project_ids and
  742. project['name'] != CONF.auth.admin_project_name)]
  743. if self.is_preserve:
  744. projects = [project
  745. for project in projects
  746. if project['name'] not in CONF_PROJECTS]
  747. LOG.debug("List count, %s Projects after reconcile", len(projects))
  748. return projects
  749. def delete(self):
  750. projects = self.list()
  751. for project in projects:
  752. try:
  753. self.client.delete_project(project['id'])
  754. except Exception:
  755. LOG.exception("Delete project %s exception.", project['id'])
  756. def dry_run(self):
  757. projects = self.list()
  758. self.data['projects'] = projects
  759. def save_state(self):
  760. projects = self.list()
  761. self.data['projects'] = {}
  762. for project in projects:
  763. self.data['projects'][project['id']] = project['name']
  764. class DomainService(BaseService):
  765. def __init__(self, manager, **kwargs):
  766. super(DomainService, self).__init__(kwargs)
  767. self.client = manager.domains_client
  768. def list(self):
  769. client = self.client
  770. domains = client.list_domains()['domains']
  771. if not self.is_save_state:
  772. domains = [domain for domain in domains if domain['id']
  773. not in self.saved_state_json['domains'].keys()]
  774. LOG.debug("List count, %s Domains after reconcile", len(domains))
  775. return domains
  776. def delete(self):
  777. client = self.client
  778. domains = self.list()
  779. for domain in domains:
  780. try:
  781. client.update_domain(domain['id'], enabled=False)
  782. client.delete_domain(domain['id'])
  783. except Exception:
  784. LOG.exception("Delete Domain %s exception.", domain['id'])
  785. def dry_run(self):
  786. domains = self.list()
  787. self.data['domains'] = domains
  788. def save_state(self):
  789. domains = self.list()
  790. self.data['domains'] = {}
  791. for domain in domains:
  792. self.data['domains'][domain['id']] = domain['name']
  793. def get_project_cleanup_services():
  794. project_services = []
  795. # TODO(gmann): Tempest should provide some plugin hook for cleanup
  796. # script extension to plugin tests also.
  797. if IS_NOVA:
  798. project_services.append(ServerService)
  799. project_services.append(KeyPairService)
  800. project_services.append(ServerGroupService)
  801. project_services.append(NovaQuotaService)
  802. if IS_NEUTRON:
  803. project_services.append(NetworkFloatingIpService)
  804. if utils.is_extension_enabled('metering', 'network'):
  805. project_services.append(NetworkMeteringLabelRuleService)
  806. project_services.append(NetworkMeteringLabelService)
  807. project_services.append(NetworkRouterService)
  808. project_services.append(NetworkPortService)
  809. project_services.append(NetworkSubnetService)
  810. project_services.append(NetworkService)
  811. project_services.append(NetworkSecGroupService)
  812. project_services.append(NetworkSubnetPoolsService)
  813. if IS_CINDER:
  814. project_services.append(SnapshotService)
  815. project_services.append(VolumeService)
  816. project_services.append(VolumeQuotaService)
  817. return project_services
  818. def get_global_cleanup_services():
  819. global_services = []
  820. if IS_NOVA:
  821. global_services.append(FlavorService)
  822. if IS_GLANCE:
  823. global_services.append(ImageService)
  824. global_services.append(UserService)
  825. global_services.append(ProjectService)
  826. global_services.append(DomainService)
  827. global_services.append(RoleService)
  828. return global_services