2 # Copyright 2017 Cisco Systems, Inc. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
20 from neutronclient.neutron import client as nclient
21 from novaclient.client import Client
22 from novaclient.exceptions import NotFound
23 from tabulate import tabulate
25 import credentials as credentials
28 class ComputeCleaner(object):
29 """A cleaner for compute resources."""
31 def __init__(self, nova_client, instance_prefix):
32 self.nova_client = nova_client
33 LOG.info('Discovering instances %s...', instance_prefix)
34 all_servers = self.nova_client.servers.list()
35 self.servers = [server for server in all_servers
36 if server.name.startswith(instance_prefix)]
38 def instance_exists(self, server):
40 self.nova_client.servers.get(server.id)
45 def get_resource_list(self):
46 return [["Instance", server.name, server.id] for server in self.servers]
50 for server in self.servers:
52 LOG.info('Deleting instance %s...', server.name)
53 self.nova_client.servers.delete(server.id)
55 LOG.exception("Instance %s deletion failed", server.name)
56 LOG.info(' Waiting for %d instances to be fully deleted...', len(self.servers))
57 retry_count = 15 + len(self.servers) * 5
60 self.servers = [server for server in self.servers if self.instance_exists(server)]
65 LOG.info(' %d yet to be deleted by Nova, retries left=%d...',
66 len(self.servers), retry_count)
69 LOG.warning(' instance deletion verification time-out: %d still not deleted',
74 class NetworkCleaner(object):
75 """A cleaner for network resources."""
77 def __init__(self, neutron_client, network_name_prefixes):
78 self.neutron_client = neutron_client
79 LOG.info('Discovering networks...')
80 all_networks = self.neutron_client.list_networks()['networks']
83 for net in all_networks:
85 for prefix in network_name_prefixes:
86 if netname.startswith(prefix):
87 self.networks.append(net)
88 net_ids.append(net['id'])
91 LOG.info('Discovering ports...')
92 all_ports = self.neutron_client.list_ports()['ports']
93 self.ports = [port for port in all_ports if port['network_id'] in net_ids]
97 def get_resource_list(self):
98 res_list = [["Network", net['name'], net['id']] for net in self.networks]
99 res_list.extend([["Port", port['name'], port['id']] for port in self.ports])
103 for port in self.ports:
104 LOG.info("Deleting port %s...", port['id'])
106 self.neutron_client.delete_port(port['id'])
108 LOG.exception("Port deletion failed")
110 for net in self.networks:
111 LOG.info("Deleting network %s...", net['name'])
113 self.neutron_client.delete_network(net['id'])
115 LOG.exception("Network deletion failed")
117 class FlavorCleaner(object):
118 """Cleaner for NFVbench flavor."""
120 def __init__(self, nova_client, name):
122 LOG.info('Discovering flavor %s...', name)
124 self.flavor = nova_client.flavors.find(name=name)
128 def get_resource_list(self):
130 return [['Flavor', self.name, self.flavor.id]]
135 LOG.info("Deleting flavor %s...", self.flavor.name)
139 LOG.exception("Flavor deletion failed")
141 class Cleaner(object):
142 """Cleaner for all NFVbench resources."""
144 def __init__(self, config):
145 cred = credentials.Credentials(config.openrc_file, None, False)
146 session = cred.get_session()
147 self.neutron_client = nclient.Client('2.0', session=session)
148 self.nova_client = Client(2, session=session)
149 network_names = [inet['name'] for inet in config.internal_networks.values()]
150 self.cleaners = [ComputeCleaner(self.nova_client, config.loop_vm_name),
151 FlavorCleaner(self.nova_client, config.flavor_type),
152 NetworkCleaner(self.neutron_client, network_names)]
154 def show_resources(self):
155 """Show all NFVbench resources."""
156 table = [["Type", "Name", "UUID"]]
157 for cleaner in self.cleaners:
158 res_list = cleaner.get_resource_list()
160 table.extend(res_list)
161 count = len(table) - 1
163 LOG.info('Discovered %d NFVbench resources:\n%s', count,
164 tabulate(table, headers="firstrow", tablefmt="psql"))
166 LOG.info('No matching NFVbench resources found')
169 def clean(self, prompt):
170 """Clean all resources."""
171 LOG.info("NFVbench will delete all resources shown...")
173 answer = raw_input("Are you sure? (y/n) ")
174 if answer.lower() != 'y':
175 LOG.info("Exiting without deleting any resource")
177 for cleaner in self.cleaners: