|
|
#!/usr/bin/env python import argparse import openstack import logging import datetime import time
DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' PAUSE_SECONDS = 5
log = logging.getLogger('openstack-cleanup')
parser = argparse.ArgumentParser(description='Cleanup OpenStack resources')
parser.add_argument('-v', '--verbose', action='store_true', help='Increase verbosity') parser.add_argument('--hours', type=int, default=4, help='Age (in hours) of VMs to cleanup (default: 4h)') parser.add_argument('--dry-run', action='store_true', help='Do not delete anything')
args = parser.parse_args()
oldest_allowed = datetime.datetime.now() - datetime.timedelta(hours=args.hours)
def main(): if args.dry_run: print('Running in dry-run mode') else: print('This will delete resources... (ctrl+c to cancel)') time.sleep(PAUSE_SECONDS)
conn = openstack.connect()
print('Servers...') map_if_old(conn.compute.delete_server, conn.compute.servers())
print('Security groups...') map_if_old(conn.network.delete_security_group, conn.network.security_groups())
print('Ports...') try: map_if_old(conn.network.delete_port, conn.network.ports()) except openstack.exceptions.ConflictException as ex: # Need to find subnet-id which should be removed from a router for sn in conn.network.subnets(): try: fn_if_old(conn.network.delete_subnet, sn) except openstack.exceptions.ConflictException: for r in conn.network.routers(): print("Deleting subnet %s from router %s", sn, r) try: conn.network.remove_interface_from_router( r, subnet_id=sn.id) except Exception as ex: print("Failed to delete subnet from router as %s", ex)
# After removing unnecessary subnet from router, retry to delete ports map_if_old(conn.network.delete_port, conn.network.ports())
print('Subnets...') map_if_old(conn.network.delete_subnet, conn.network.subnets())
print('Networks...') for n in conn.network.networks(): if not n.is_router_external: fn_if_old(conn.network.delete_network, n)
# runs the given fn to all elements of the that are older than allowed def map_if_old(fn, items): for item in items: fn_if_old(fn, item)
# run the given fn function only if the passed item is older than allowed def fn_if_old(fn, item): created_at = datetime.datetime.strptime(item.created_at, DATE_FORMAT) if item.name == "default": # skip default security group return if created_at < oldest_allowed: print('Will delete %(name)s (%(id)s)' % item) if not args.dry_run: fn(item)
if __name__ == '__main__': # execute only if run as a script main()
|