Address performance issues with listorphans.py script

listorphans.py lists orphaned Neutron objects.  'Orphans' in this
context are objects which OpenStack knows about and manages but which do
not have a valid project (tenant) ID.

The previous version was very inefficient in that for every object being
checked, it would do a discrete Keystone API call to see if the
associated tenant ID was valid or not.  For an installation of any
reasonable size, i.e one with 100s of Neutron routers, this method was
particularly slow.

The script has been updated to first build a list of all tenant IDs, and
then for every Neutron object check project ownership validity against
this list instead.

Output has also changed slightly to print out a list of discovered
orphans, simplifying workflow e.g when piping to another command which
cleans up these objects.

Closes-Bug: #1515300

Change-Id: I72ca84fe48beb623d43ee446a32ea1bb30730bcc
This commit is contained in:
Nick Jones 2015-11-11 15:21:12 +00:00
parent a93d2ddbad
commit 7bf037d32d
1 changed files with 52 additions and 0 deletions

52
listorphans.py Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env python
import os
import sys
import keystoneclient.v2_0.client as ksclient
import neutronclient.v2_0.client as nclient
def usage():
print "listorphans.py <object> where object is one or more of",
print "'networks', 'routers', 'subnets', 'floatingips' or 'all'"
def get_credentials():
d = {}
d['username'] = os.environ['OS_USERNAME']
d['password'] = os.environ['OS_PASSWORD']
d['auth_url'] = os.environ['OS_AUTH_URL']
d['tenant_name'] = os.environ['OS_TENANT_NAME']
return d
credentials = get_credentials()
neutron = nclient.Client(**credentials)
keystone = ksclient.Client(**credentials)
def get_tenantids():
tenantids = []
for tenant in keystone.tenants.list():
tenantids.append(tenant.id)
return tenantids
def get_orphaned_neutron_objects(object):
objects = getattr(neutron, 'list_' + object)()
orphans = []
for object in objects.get(object):
if object['tenant_id'] not in tenantids:
orphans.append(object['id'])
return orphans
if __name__ == '__main__':
if len(sys.argv) > 1:
tenantids = get_tenantids()
if sys.argv[1] == 'all':
objects = [ 'networks', 'routers', 'subnets', 'floatingips' ]
else:
objects = sys.argv[1:]
for object in objects:
orphans = get_orphaned_neutron_objects(object)
print len(orphans), 'orphan(s) found of type', object
print '\n'.join(map(str, orphans))
else:
usage()
sys.exit(1)