]> review.fuel-infra Code Review - tools/sustaining.git/commitdiff
Add stack resources calculation feature 08/41808/2
authorVladimir Khlyunev <vkhlyunev@mirantis.com>
Thu, 7 Oct 2021 10:46:34 +0000 (14:46 +0400)
committerVladimir Khlyunev <vkhlyunev@mirantis.com>
Thu, 7 Oct 2021 11:01:24 +0000 (15:01 +0400)
Change-Id: I18b6a8589449c8f32b001b4938f2708781a2e91c

os_cloud_cleaner/cleaner.py
os_cloud_cleaner/os_connector.py
os_cloud_cleaner/shell.py

index 2f76cc09dd97959e97256f5df68eb5f7c0041973..8531ed0230e087f02a9dbf1d3dcc284926a7b364 100644 (file)
@@ -216,45 +216,48 @@ class Cleaner:
     def get_volumes(self):
         return self.os_conn.get_volumes()
 
-    def cleanup_stack_parallel(self, stack):
-        if not hasattr(stack, 'id'):
-            stack = list(self.os_conn.heat.stacks.list(id=stack))
-            if not stack:
-                logger.info("Can not find stack {}".format(stack))
-            stack = stack[0]
-
+    def get_stack_resources_split(self, stack):
         resources = self.get_os_stack_resources(stack)
-        server_uuids = []
-        router_uuids = []
-        network_uuids = []
-        subnets_uuids = []
-        secgroup_uuids = []
-        floating_ip_uuids = []
-        volumes_uuids = []
-        temp = set()
+        result = {
+            'server_uuids':[],
+            'router_uuids':[],
+            'network_uuids':[],
+            'subnets_uuids':[],
+            'secgroup_uuids':[],
+            'floating_ip_uuids':[],
+            'volumes_uuids':[],
+        }
         for uuid, resource in resources.items():
-            temp.add(resource["resource_type"])
             if resource["resource_type"] == "OS::Nova::Server":
-                server_uuids.append(uuid)
+                result['server_uuids'].append(uuid)
             elif resource["resource_type"] == "OS::Neutron::Router":
-                router_uuids.append(uuid)
+                result['router_uuids'].append(uuid)
             elif resource["resource_type"] == "OS::Neutron::Net":
-                network_uuids.append(uuid)
+                result['network_uuids'].append(uuid)
             elif resource["resource_type"] == "OS::Neutron::Subnet":
-                subnets_uuids.append(uuid)
+                result['subnets_uuids'].append(uuid)
             elif resource["resource_type"] == "OS::Neutron::SecurityGroup":
-                secgroup_uuids.append(uuid)
+                result['secgroup_uuids'].append(uuid)
             elif resource["resource_type"] == "OS::Neutron::FloatingIP":
-                floating_ip_uuids.append(uuid)
+                result['floating_ip_uuids'].append(uuid)
             elif resource["resource_type"] == "OS::Cinder::Volume":
-                volumes_uuids.append(uuid)
-
-        self.os_conn.cleanup_floating_batch(floating_ip_uuids)
-        self.os_conn.cleanup_servers_batch(server_uuids)
-        self.os_conn.cleanup_volumes_batch(volumes_uuids)
-        self.os_conn.cleanup_router_batch(router_uuids)
-        self.os_conn.cleanup_network_batch(network_uuids)
-        self.os_conn.cleanup_subnet_batch(subnets_uuids)
+                result['volumes_uuids'].append(uuid)
+        return result
+
+    def cleanup_stack_parallel(self, stack):
+        if not hasattr(stack, 'id'):
+            stack = list(self.os_conn.heat.stacks.list(id=stack))
+            if not stack:
+                logger.info("Can not find stack {}".format(stack))
+            stack = stack[0]
+
+        resources = self.get_stack_resources_split(stack)
+        self.os_conn.cleanup_floating_batch(resources['floating_ip_uuids'])
+        self.os_conn.cleanup_servers_batch(resources['server_uuids'])
+        self.os_conn.cleanup_volumes_batch(resources['volumes_uuids'])
+        self.os_conn.cleanup_router_batch(resources['router_uuids'])
+        self.os_conn.cleanup_network_batch(resources['network_uuids'])
+        self.os_conn.cleanup_subnet_batch(resources['subnets_uuids'])
         self.os_conn.cleanup_stack(stack.id, ignore_err=True)
 
     def process_resource(self, uuid):
@@ -328,3 +331,26 @@ class Cleaner:
         for keypair in keypairs_to_delete:
             logger.info("Deleting keypair {}".format(keypair.name))
             keypair.delete()
+
+    def calculate_resources(self, stack):
+        if isinstance(stack, str):
+            stack = self.os_conn.get_stacks_by_name_or_uuid(stack)[0]
+        resources = self.get_stack_resources_split(stack)
+        result = {'vcpus': 0, 'ram': 0, 'name': stack.stack_name,
+                  'volumes': 0}
+        for uuid in resources['server_uuids']:
+            server = self.os_conn.get_server_by_uuid(uuid)
+            if not server:
+                continue
+            fl_uuid = server.flavor['id']
+            flavor = self.os_conn.get_flavor(fl_uuid)
+            fl_dict = flavor.to_dict()
+            for key in ['vcpus', 'ram']:
+                if key in fl_dict:
+                    result[key] += fl_dict[key]
+        for vol_uuid in resources['volumes_uuids']:
+            volume = self.os_conn.get_volume(vol_uuid)
+            if not volume:
+                continue
+            result['volumes'] += volume.size
+        return result
\ No newline at end of file
index c6c8ce58d3bb6b03fe8e1b2074214b3a73ca9c86..cd0871da04deff88ebc0bd47c66fe6a01575d7c1 100644 (file)
@@ -115,6 +115,12 @@ class OpenStackActions(object):
             if f_ip_data['floating_ip_address'] == floating_ip:
                 return f_ip_data['id']
 
+    def get_flavor(self, uuid):
+        return self.nova.flavors.get(uuid)
+
+    def get_volume(self, uuid):
+        return self.cinder.volumes.get(uuid)
+
     def get_keypairs(self):
         keypairs = self.nova.keypairs.list()
         resp = []
@@ -146,6 +152,13 @@ class OpenStackActions(object):
         except NovaNotFoundException:
             return None
 
+    def get_server_by_uuid(self, uuid):
+        try:
+            server = self.nova.servers.get(uuid)
+            return server
+        except NovaNotFoundException:
+            return None
+
     def get_keystone_endpoints(self):
         endpoints = self.keystone.endpoints.list()
         return endpoints
index c80b7e64de70da6b90e50d40b9b50b638a35977a..511e5f1da9ecb9061b5386849028bc1ba9a1c046 100644 (file)
@@ -50,6 +50,25 @@ def do_search_keypair(name='', fingerprint='', lifetime=''):
     print table
 
 
+def do_calculate(name=''):
+    table = PrettyTable()
+    table.field_names = ['stack_name', 'vcpus', 'ram_gb', 'volumes_gb']
+    table.align = 'l'
+
+    if name is '':
+        logger.info("Stack resources calculation initiated without stack name, this will take long time.")
+        logger.info("Please standby")
+        stacks = cleaner.get_stacks()
+    else:
+        stacks = [name]
+
+    for stack in stacks:
+        data = cleaner.calculate_resources(stack)
+        ram_gb = data['ram'] / 1024
+        table.add_row([data['name'], data['vcpus'], ram_gb, data['volumes']])
+    print table
+
+
 parser = argparse.ArgumentParser()
 parser.add_argument('--os-auth-url', type=str)
 parser.add_argument('--os-username', type=str)
@@ -116,17 +135,21 @@ search_subparser.add_argument('--fingerprint',
                                    'that only contains given fingerprint',
                               default='')
 
+calculate_subparser = subparsers.add_parser('calculate')
+calculate_subparser.add_argument('--name', type=str, default='')
 # args = parser.parse_args("cleanup stack bm-cicd-pike-ovs-maas".split(" "))
 # args = parser.parse_args("search -i -n bm-cicd-pike-ovs-maas".split(" "))
 # args = parser.parse_args("cleanup misc 6637ecb1-661f-4d6e-a160-b05ee8b81cd0".split(" "))
 # args = parser.parse_args("search -i".split(" "))
 # args = parser.parse_args("search".split(" "))
 
-# debug_args = "cleanup stack heat-cicd-queens-dvr-sl"
+# debug_args = "cleanup stack pike-ci-dvr-2k19-2"
 # debug_args = "search non-stack -n vkhlyunev"
 # debug_args = "search non-stack"
 # debug_args = "search keypair -l 1d"
 # debug_args = "cleanup keypair --name test -l 1m"
+# debug_args = "calculate --name vkhlyunev-released-queens-2.6"
+# debug_args = "calculate"
 # args = parser.parse_args(debug_args.split(" "))
 args = parser.parse_args()
 
@@ -190,3 +213,5 @@ elif args.action == "search":
     elif args.resource_type == "keypair":
         do_search_keypair(args.name, args.fingerprint, args.lifetime)
 
+elif args.action == "calculate":
+    do_calculate(args.name)