add kubespray to the XTesting as it provides newer version of kubenetes and can be...
[it/test.git] / XTesting / kubespray / scripts / openstack-cleanup / main.py
diff --git a/XTesting/kubespray/scripts/openstack-cleanup/main.py b/XTesting/kubespray/scripts/openstack-cleanup/main.py
new file mode 100755 (executable)
index 0000000..511f060
--- /dev/null
@@ -0,0 +1,95 @@
+#!/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()