Clean-up of resources created in ODU workflows 65/14565/4
authorgarciadeblas <gerardo.garciadeblas@telefonica.com>
Mon, 16 Sep 2024 10:53:07 +0000 (12:53 +0200)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Tue, 17 Sep 2024 11:11:50 +0000 (13:11 +0200)
Change-Id: Ib2051d5844841d6469a4dc3e854ff2ef88a36a87
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
osm_lcm/k8s.py
osm_lcm/odu_libs/cluster_mgmt.py
osm_lcm/odu_libs/common.py
osm_lcm/odu_libs/vim_mgmt.py
osm_lcm/odu_workflows.py

index c48228e..a02e165 100644 (file)
@@ -69,6 +69,14 @@ class ClusterLcm(LcmBase):
         db_cluster = self.update_operation_history(db_cluster, workflow_status, None)
         self.db.set_one("clusters", {"_id": db_cluster["_id"]}, db_cluster)
 
+        # Clean items used in the workflow, no matter if the workflow succeeded
+        clean_status, clean_msg = await self.odu.clean_items_workflow(
+            "create_cluster", op_id, op_params, content
+        )
+        self.logger.info(
+            f"clean_status is :{clean_status} and clean_msg is :{clean_msg}"
+        )
+
         if workflow_status:
             resource_status, resource_msg = await self.odu.check_resource_status(
                 "create_cluster", op_id, op_params, content
@@ -487,6 +495,13 @@ class ClusterLcm(LcmBase):
         # self.db.set_one(self.db_collection, {"_id": _id}, db_cluster)
         self.db.set_one("clusters", {"_id": db_cluster["_id"]}, db_cluster)
 
+        # Clean items used in the workflow, no matter if the workflow succeeded
+        clean_status, clean_msg = await self.odu.clean_items_workflow(
+            "update_cluster", op_id, op_params, content
+        )
+        self.logger.info(
+            f"clean_status is :{clean_status} and clean_msg is :{clean_msg}"
+        )
         if workflow_status:
             resource_status, resource_msg = await self.odu.check_resource_status(
                 "update_cluster", op_id, op_params, content
@@ -549,6 +564,14 @@ class CloudCredentialsLcm(LcmBase):
             "Workflow Status: {} Workflow Msg: {}".format(workflow_status, workflow_msg)
         )
 
+        # Clean items used in the workflow, no matter if the workflow succeeded
+        clean_status, clean_msg = await self.odu.clean_items_workflow(
+            "create_cloud_credentials", op_id, op_params, content
+        )
+        self.logger.info(
+            f"clean_status is :{clean_status} and clean_msg is :{clean_msg}"
+        )
+
         if workflow_status:
             resource_status, resource_msg = await self.odu.check_resource_status(
                 "create_cloud_credentials", op_id, op_params, content
@@ -571,6 +594,14 @@ class CloudCredentialsLcm(LcmBase):
             "Workflow Status: {} Workflow Msg: {}".format(workflow_status, workflow_msg)
         )
 
+        # Clean items used in the workflow, no matter if the workflow succeeded
+        clean_status, clean_msg = await self.odu.clean_items_workflow(
+            "update_cloud_credentials", op_id, op_params, content
+        )
+        self.logger.info(
+            f"clean_status is :{clean_status} and clean_msg is :{clean_msg}"
+        )
+
         if workflow_status:
             resource_status, resource_msg = await self.odu.check_resource_status(
                 "update_cloud_credentials", op_id, op_params, content
index 8caed34..719c7a8 100644 (file)
@@ -136,27 +136,6 @@ async def create_cluster(self, op_id, op_params, content, bootstrap_only=False):
     )
     return workflow_name
 
-    # self.logger.info(f"Deleting secret {secret_name} in namespace {secret_namespace} ...")
-    # self._kubectl.delete_secret(name=secret_name, namespace=secret_namespace)
-    # self.logger.info("DONE")
-
-    # self.logger.info(f"Listing secrets in namespace {secret_namespace} ...")
-    # secret_list = self._kubectl.get_secrets(secret_namespace)
-    # # print(secret_list)
-    # for item in secret_list:
-    #     print(item.metadata.name)
-    # self.logger.info("DONE")
-
-    # self.logger.info(f"Deleting secrets in namespace {secret_namespace} ...")
-    # for item in secret_list:
-    #     print(f"Deleting {item.metadata.name} ...")
-    #     self._kubectl.delete_secret(
-    #         name=item.metadata.name,
-    #         namespace=secret_namespace,
-    #     )
-    #     self.logger.info("DELETED")
-    # self.logger.info("DONE")
-
 
 async def update_cluster(self, op_id, op_params, content):
     self.logger.info("Update cluster eks workflow Enter")
@@ -338,6 +317,30 @@ async def get_cluster_credentials(self, db_cluster):
         return False, message
 
 
+async def clean_items_cluster_create(self, op_id, op_params, content):
+    self.logger.info("Clean items cluster_create Enter")
+    self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
+    items = {
+        "secrets": [
+            {
+                "name": f"secret-age-{content['cluster']['git_name'].lower()}",
+                "namespace": "osm-workflows",
+            }
+        ]
+    }
+    try:
+        await self.clean_items(items)
+        return True, "OK"
+    except Exception as e:
+        return False, f"Error while cleaning items: {e}"
+
+
+async def clean_items_cluster_update(self, op_id, op_params, content):
+    self.logger.info("Clean items cluster_update Enter")
+    self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
+    return await self.clean_items_cluster_create(op_id, op_params, content)
+
+
 async def check_create_cluster(self, op_id, op_params, content):
     self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
     return True, "OK"
index 179135e..a435aa8 100644 (file)
@@ -35,17 +35,16 @@ async def create_secret(self, secret_name, secret_namespace, secret_key, secret_
         self.logger.debug(f"secret_data_original={secret_value}")
         self.logger.debug(f"secret_data_received={returned_secret_value}")
         self.logger.info(
-            f"Result of secret comparison: {secret_value==returned_secret_value} ..."
+            f"Result of secret comparison: {secret_value==returned_secret_value}"
         )
 
     self.logger.info(
         f"Creating secret {secret_name} in namespace {secret_namespace} ..."
     )
     secret_data = {secret_key: base64.b64encode(secret_value.encode()).decode("utf-8")}
-    self.logger.info(f"Secret name: {secret_name}")
-    self.logger.info(f"Secret data {secret_data}")
-    self.logger.info(f"Namespace: {secret_namespace}")
-    self.logger.info("Calling N2VC kubectl to create secret...")
+    self.logger.info(
+        f"Calling N2VC kubectl to create secret. Namespace: {secret_namespace}. Secret name: {secret_name}. Secret data:{secret_data}."
+    )
     await self._kubectl.create_secret(
         name=secret_name,
         data=secret_data,
@@ -55,3 +54,15 @@ async def create_secret(self, secret_name, secret_namespace, secret_key, secret_
     self.logger.info(f"Secret {secret_name} CREATED")
 
     await check_secret(secret_name, secret_namespace, secret_key, secret_value)
+
+
+def delete_secret(self, secret_name, secret_namespace):
+    try:
+        self._kubectl.delete_secret(name=secret_name, namespace=secret_namespace)
+        self.logger.info(
+            f"Deleted secret {secret_name} in namespace {secret_namespace}"
+        )
+    except Exception as e:
+        self.logger.error(
+            f"Could not delete secret {secret_name} in namespace {secret_namespace}: {e}"
+        )
index e82bc34..8014f0c 100644 (file)
@@ -164,6 +164,7 @@ async def update_cloud_credentials(self, op_id, op_params, content):
         secret_key,
         secret_value,
     )
+
     # Additional params for the workflow
     providerconfig_name = f"{vim_name}-config"
     provider_type = content["vim_type"]
@@ -203,6 +204,29 @@ async def update_cloud_credentials(self, op_id, op_params, content):
     return workflow_name
 
 
+async def clean_items_cloud_credentials_create(self, op_id, op_params, content):
+    self.logger.info("Clean items cloud_credentials_create Enter")
+    items = {
+        "secrets": [
+            {
+                "name": f"create-providerconfig-{content['_id']}",
+                "namespace": "osm-workflows",
+            }
+        ]
+    }
+    try:
+        await self.clean_items(items)
+        return True, "OK"
+    except Exception as e:
+        return False, f"Error while cleaning items: {e}"
+
+
+async def clean_items_cloud_credentials_update(self, op_id, op_params, content):
+    self.logger.info("Clean items cloud_credentials_update Enter")
+    self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
+    return await self.clean_items_cloud_credentials_create(op_id, op_params, content)
+
+
 async def check_create_cloud_credentials(self, op_id, op_params, content):
     self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
     return True, "OK"
index c992f17..cb59d6b 100644 (file)
@@ -45,10 +45,12 @@ class OduWorkflow(LcmBase):
         self._workflows = {
             "create_cluster": {
                 "workflow_function": self.create_cluster,
+                "clean_function": self.clean_items_cluster_create,
                 "check_resource_function": self.check_create_cluster,
             },
             "update_cluster": {
                 "workflow_function": self.update_cluster,
+                "clean_function": self.clean_items_cluster_update,
                 "check_resource_function": self.check_update_cluster,
             },
             "delete_cluster": {
@@ -113,10 +115,12 @@ class OduWorkflow(LcmBase):
             },
             "create_cloud_credentials": {
                 "workflow_function": self.create_cloud_credentials,
+                "clean_function": self.clean_items_cloud_credentials_create,
                 "check_resource_function": self.check_create_cloud_credentials,
             },
             "update_cloud_credentials": {
                 "workflow_function": self.update_cloud_credentials,
+                "clean_function": self.clean_items_cloud_credentials_update,
                 "check_resource_function": self.check_update_cloud_credentials,
             },
             "delete_cloud_credentials": {
@@ -140,6 +144,8 @@ class OduWorkflow(LcmBase):
         create_cloud_credentials,
         update_cloud_credentials,
         delete_cloud_credentials,
+        clean_items_cloud_credentials_create,
+        clean_items_cloud_credentials_update,
         check_create_cloud_credentials,
         check_update_cloud_credentials,
         check_delete_cloud_credentials,
@@ -150,6 +156,8 @@ class OduWorkflow(LcmBase):
         delete_cluster,
         register_cluster,
         deregister_cluster,
+        clean_items_cluster_create,
+        clean_items_cluster_update,
         check_create_cluster,
         check_update_cluster,
         check_delete_cluster,
@@ -194,7 +202,10 @@ class OduWorkflow(LcmBase):
         render_jinja_template,
         render_yaml_template,
     )
-    from osm_lcm.odu_libs.common import create_secret
+    from osm_lcm.odu_libs.common import (
+        create_secret,
+        delete_secret,
+    )
 
     async def launch_workflow(self, key, op_id, op_params, content):
         self.logger.info(
@@ -204,6 +215,14 @@ class OduWorkflow(LcmBase):
         self.logger.info("workflow function : {}".format(workflow_function))
         return await workflow_function(op_id, op_params, content)
 
+    async def clean_items_workflow(self, key, op_id, op_params, content):
+        self.logger.info(
+            f"Cleaning items created during workflow launch. Key: {key}. Operation: {op_id}. Params: {op_params}. Content: {content}"
+        )
+        clean_items_function = self._workflows[key]["clean_function"]
+        self.logger.info("clean items function : {}".format(clean_items_function))
+        return await clean_items_function(op_id, op_params, content)
+
     async def dummy_operation(self, op_id, op_params, content):
         self.logger.info("Empty operation status Enter")
         self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
@@ -220,3 +239,17 @@ class OduWorkflow(LcmBase):
     async def check_dummy_operation(self, op_id, op_params, content):
         self.logger.info(f"Operation {op_id}. Params: {op_params}. Content: {content}")
         return True, "OK"
+
+    async def clean_items(self, items):
+        # Delete secrets
+        for secret in items.get("secrets", []):
+            name = secret["name"]
+            namespace = secret["namespace"]
+            self.logger.info(f"Deleting secret {name} in namespace {namespace}")
+            self.delete_secret(name, namespace)
+        # Delete pvcs
+        for pvc in items.get("pvcs", []):
+            name = pvc["name"]
+            namespace = pvc["namespace"]
+            self.logger.info(f"Deleting pvc {name} in namespace {namespace}")
+            await self._kubectl.delete_pvc(name, namespace)