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 = 5 + len(self.servers) * 2
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 timed out: %d not removed',
74 class NetworkCleaner(object):
75 """A cleaner for network resources."""
77 def __init__(self, neutron_client, network_names):
78 self.neutron_client = neutron_client
79 LOG.info('Discovering networks...')
80 all_networks = self.neutron_client.list_networks()['networks']
82 for net in all_networks:
84 network_names.remove(net['name'])
85 self.networks.append(net)
90 net_ids = [net['id'] for net in self.networks]
92 LOG.info('Discovering ports...')
93 all_ports = self.neutron_client.list_ports()['ports']
94 self.ports = [port for port in all_ports if port['network_id'] in net_ids]
98 def get_resource_list(self):
99 res_list = [["Network", net['name'], net['id']] for net in self.networks]
100 res_list.extend([["Port", port['name'], port['id']] for port in self.ports])
104 for port in self.ports:
105 LOG.info("Deleting port %s...", port['id'])
107 self.neutron_client.delete_port(port['id'])
109 LOG.exception("Port deletion failed")
111 for net in self.networks:
112 LOG.info("Deleting network %s...", net['name'])
114 self.neutron_client.delete_network(net['id'])
116 LOG.exception("Network deletion failed")
118 class FlavorCleaner(object):
119 """Cleaner for NFVbench flavor."""
121 def __init__(self, nova_client, name):
123 LOG.info('Discovering flavor %s...', name)
125 self.flavor = nova_client.flavors.find(name=name)
129 def get_resource_list(self):
131 return [['Flavor', self.name, self.flavor.id]]
136 LOG.info("Deleting flavor %s...", self.flavor.name)
140 LOG.exception("Flavor deletion failed")
142 class Cleaner(object):
143 """Cleaner for all NFVbench resources."""
145 def __init__(self, config):
146 cred = credentials.Credentials(config.openrc_file, None, False)
147 session = cred.get_session()
148 self.neutron_client = nclient.Client('2.0', session=session)
149 self.nova_client = Client(2, session=session)
150 network_names = [inet['name'] for inet in config.internal_networks.values()]
151 self.cleaners = [ComputeCleaner(self.nova_client, config.loop_vm_name),
152 FlavorCleaner(self.nova_client, config.flavor_type),
153 NetworkCleaner(self.neutron_client, network_names)]
155 def show_resources(self):
156 """Show all NFVbench resources."""
157 table = [["Type", "Name", "UUID"]]
158 for cleaner in self.cleaners:
159 res_list = cleaner.get_resource_list()
161 table.extend(res_list)
162 count = len(table) - 1
164 LOG.info('Discovered %d NFVbench resources:', count)
165 print tabulate(table, headers="firstrow", tablefmt="psql")
167 LOG.info('No matching NFVbench resources found')
170 def clean(self, prompt):
171 """Clean all resources."""
172 LOG.info("NFVbench will delete all resources shown...")
174 answer = raw_input("Are you sure? (y/n) ")
175 if answer.lower() != 'y':
176 LOG.info("Exiting without deleting any resource")
178 for cleaner in self.cleaners: