diff --git a/devstack/tools/nsxp_cleanup.py b/devstack/tools/nsxp_cleanup.py index a5946a360f..30e83f13eb 100755 --- a/devstack/tools/nsxp_cleanup.py +++ b/devstack/tools/nsxp_cleanup.py @@ -17,6 +17,11 @@ import optparse import sqlalchemy as sa +from neutron.db.models import l3 +from neutron.db.models import securitygroup +from neutron.db.models import segment # noqa +from neutron.db import models_v2 + from vmware_nsxlib import v3 from vmware_nsxlib.v3 import config @@ -30,6 +35,21 @@ class NeutronNsxDB(object): def query_all(self, column, model): return list(set([r[column] for r in self.session.query(model).all()])) + def get_security_groups(self): + return self.query_all('id', securitygroup.SecurityGroup) + + def get_security_groups_rules(self): + return self.query_all('id', securitygroup.SecurityGroupRule) + + def get_routers(self): + return self.query_all('id', l3.Router) + + def get_networks(self): + return self.query_all('id', models_v2.Network) + + def get_ports(self): + return self.query_all('id', models_v2.Port) + class NSXClient(object): """Base NSX REST client""" @@ -52,20 +72,143 @@ class NSXClient(object): allow_overwrite_header=True) self.nsxlib = v3.NsxPolicyLib(nsxlib_config) + def get_nsx_os_domains(self): + domains = self.get_os_resources(self.nsxlib.domain.list()) + return [d['id'] for d in domains] + + def cleanup_domains(self, domains): + """Delete all OS created NSX Policy segments ports per segment""" + for domain_id in domains: + self.nsxlib.domain.delete(domain_id) + + def get_os_resources(self, resources): + """ + Get all logical resources created by OpenStack + """ + os_resources = [r for r in resources if 'tags' in r + for tag in r['tags'] + if 'os-api-version' in tag.values()] + return os_resources + + def get_os_nsx_groups_and_maps(self, domain_id): + """ + Retrieve all NSX policy groups & maps created from OpenStack (by tags) + If the DB is available - use only objects in the neutron DB + """ + groups = self.get_os_resources(self.nsxlib.group.list(domain_id)) + maps = self.get_os_resources(self.nsxlib.comm_map.list(domain_id)) + + if self.neutron_db: + db_sgs = self.neutron_db.get_security_groups() + groups = [g for g in groups if g['id'] in db_sgs] + maps = [m for m in maps if m['id'] in db_sgs] + return groups, maps + + def cleanup_security_groups(self, domain_id): + """Delete all OS created NSX Policy security group resources""" + groups, maps = self.get_os_nsx_groups_and_maps(domain_id) + print("Number of OS Communication maps of domain %s to be deleted: " + "%s" % (domain_id, len(maps))) + for m in maps: + self.nsxlib.comm_map.delete(domain_id, m['id']) + print("Number of OS Groups of domain %s to be deleted: " + "%s" % (domain_id, len(groups))) + for grp in groups: + self.nsxlib.group.delete(domain_id, grp['id']) + + def get_os_nsx_tier1_routers(self): + """ + Retrieve all NSX policy routers created from OpenStack (by tags) + If the DB is available - use only objects in the neutron DB + """ + routers = self.get_os_resources(self.nsxlib.tier1.list()) + if routers and self.neutron_db: + db_routers = self.neutron_db.get_routers() + routers = [r for r in routers if r['id'] in db_routers] + return routers + + def cleanup_tier1_routers(self): + """Delete all OS created NSX Policy routers""" + routers = self.get_os_nsx_tier1_routers() + print("Number of OS Tier1 routers to be deleted: %s" % len(routers)) + for rtr in routers: + self.nsxlib.tier1.delete(rtr['id']) + + def get_os_nsx_segments(self): + """ + Retrieve all NSX policy segments created from OpenStack (by tags) + If the DB is available - use only objects in the neutron DB + """ + segments = self.get_os_resources(self.nsxlib.segment.list()) + if segments and self.neutron_db: + db_networks = self.neutron_db.get_networks() + segments = [s for s in segments if s['id'] in db_networks] + return segments + + def cleanup_segments(self): + """Delete all OS created NSX Policy segments & ports""" + segments = self.get_os_nsx_segments() + print("Number of OS segments to be deleted: %s" % len(segments)) + for s in segments: + self.cleanup_segment_ports(s['id']) + self.nsxlib.segment.delete(s['id']) + + def get_os_nsx_segment_ports(self, segment_id): + """ + Retrieve all NSX policy segment ports created from OpenStack (by tags) + If the DB is available - use only objects in the neutron DB + """ + segment_ports = self.get_os_resources( + self.nsxlib.segment_port.list(segment_id)) + if segment_ports and self.neutron_db: + db_ports = self.neutron_db.get_ports() + segment_ports = [s for s in segment_ports if s['id'] in db_ports] + return segment_ports + + def cleanup_segment_ports(self, segment_id): + """Delete all OS created NSX Policy segments ports per segment""" + segment_ports = self.get_os_nsx_segment_ports(segment_id) + for p in segment_ports: + self.nsxlib.segment_port.delete(segment_id, p['id']) + + def get_os_nsx_services(self): + """ + Retrieve all NSX policy services created from OpenStack SG rules + (by tags) + If the DB is available - use only objects in the neutron DB + """ + services = self.get_os_resources(self.nsxlib.service.list()) + if services and self.neutron_db: + db_rules = self.neutron_db.get_security_groups_rules() + services = [s for s in services if s['id'] in db_rules] + return services + + def cleanup_rules_services(self): + """Delete all OS created NSX services""" + services = self.get_os_nsx_services() + print("Number of OS rule services to be deleted: %s" % len(services)) + for srv in services: + self.nsxlib.service.delete(srv['id']) + def cleanup_all(self): """ - Cleanup steps: - - Firewall sections - - NSGroups - - VPN objects - - Loadbalancer objects - - Logical router and their ports - - Logical Tier 0 routers ports - - Logical switch ports - - Logical switches - - DHCP servers - - Switching profiles + Per domain cleanup steps: + - Security groups resources + + Global cleanup steps: + - Tier1 routers + - Segments and ports """ + domains = self.get_nsx_os_domains() + for domain_id in domains: + print("Cleaning up openstack resources from domain %s" % domain_id) + self.cleanup_security_groups(domain_id) + + print("Cleaning up openstack global resources") + self.cleanup_segments() + self.cleanup_tier1_routers() + self.cleanup_rules_services() + self.cleanup_domains(domains) return