Feature 10922: Stop, start and rebuild
[osm/LCM.git] / osm_lcm / ns.py
index 5345d78..2e9c1bc 100644 (file)
@@ -133,7 +133,7 @@ class NsLcm(LcmBase):
         10 * 60
     )  # timeout for some progress in a primitive execution
     timeout_migrate = 1800  # default global timeout for migrating vnfs
-
+    timeout_operate = 1800  # default global timeout for migrating vnfs
     SUBOPERATION_STATUS_NOT_FOUND = -1
     SUBOPERATION_STATUS_NEW = -2
     SUBOPERATION_STATUS_SKIP = -3
@@ -5913,6 +5913,26 @@ class NsLcm(LcmBase):
                     )
                 )
 
+            elif update_type == "OPERATE_VNF":
+                vnf_id = db_nslcmop["operationParams"]["operateVnfData"]["vnfInstanceId"]
+                operation_type = db_nslcmop["operationParams"]["operateVnfData"]["changeStateTo"]
+                additional_param = db_nslcmop["operationParams"]["operateVnfData"]["additionalParam"]
+                (result, detailed_status) = await self.rebuild_start_stop(
+                    nsr_id, nslcmop_id, vnf_id, additional_param, operation_type
+                    )
+                if result == "FAILED":
+                    nslcmop_operation_state = result
+                    error_description_nslcmop = detailed_status
+                db_nslcmop_update["detailed-status"] = detailed_status
+                if not nslcmop_operation_state:
+                    nslcmop_operation_state = "COMPLETED"
+                self.logger.debug(
+                    logging_text
+                    + " task Done with result {} {}".format(
+                        nslcmop_operation_state, detailed_status
+                    )
+                )
+
             #  If nslcmop_operation_state is None, so any operation is not failed.
             #  All operations are executed in overall.
             if not nslcmop_operation_state:
@@ -7202,6 +7222,79 @@ class NsLcm(LcmBase):
             job["vnfr_id"] = vnfr_id
         return job_list
 
+    async def rebuild_start_stop(self, nsr_id, nslcmop_id, vnf_id, additional_param, operation_type):
+        logging_text = "Task ns={} {}={} ".format(nsr_id, operation_type, nslcmop_id)
+        self.logger.info(logging_text + "Enter")
+        stage = ["Preparing the environment", ""]
+        # database nsrs record
+        db_nsr_update = {}
+        vdu_vim_name = None
+        vim_vm_id = None
+        # in case of error, indicates what part of scale was failed to put nsr at error status
+        start_deploy = time()
+        try:
+            db_vnfr = self.db.get_one("vnfrs", {"_id": vnf_id})
+            vim_account_id = db_vnfr.get("vim-account-id")
+            vim_info_key = "vim:" + vim_account_id
+            vdur = find_in_list(
+                db_vnfr["vdur"], lambda vdu: vdu["count-index"] == additional_param["count-index"]
+                )
+            if vdur:
+                vdu_vim_name = vdur["name"]
+                vim_vm_id = vdur["vim_info"][vim_info_key]["vim_id"]
+                target_vim, _ = next(k_v for k_v in vdur["vim_info"].items())
+            self.logger.info("vdu_vim_name >> {} ".format(vdu_vim_name))
+            # wait for any previous tasks in process
+            stage[1] = "Waiting for previous operations to terminate"
+            self.logger.info(stage[1])
+            await self.lcm_tasks.waitfor_related_HA('ns', 'nslcmops', nslcmop_id)
+
+            stage[1] = "Reading from database."
+            self.logger.info(stage[1])
+            self._write_ns_status(
+                nsr_id=nsr_id,
+                ns_state=None,
+                current_operation=operation_type.upper(),
+                current_operation_id=nslcmop_id
+            )
+            self._write_op_status(op_id=nslcmop_id, stage=stage, queuePosition=0)
+
+            # read from db: ns
+            stage[1] = "Getting nsr={} from db.".format(nsr_id)
+            db_nsr_update["operational-status"] = operation_type
+            self.update_db_2("nsrs", nsr_id, db_nsr_update)
+            # Payload for RO
+            desc = {
+                operation_type: {
+                    "vim_vm_id": vim_vm_id,
+                    "vnf_id": vnf_id,
+                    "vdu_index": additional_param["count-index"],
+                    "vdu_id": vdur["id"],
+                    "target_vim": target_vim,
+                    "vim_account_id": vim_account_id
+                }
+            }
+            stage[1] = "Sending rebuild request to RO... {}".format(desc)
+            self._write_op_status(op_id=nslcmop_id, stage=stage, queuePosition=0)
+            self.logger.info("ro nsr id: {}".format(nsr_id))
+            result_dict = await self.RO.operate(nsr_id, desc, operation_type)
+            self.logger.info("response from RO: {}".format(result_dict))
+            action_id = result_dict["action_id"]
+            await self._wait_ng_ro(
+                nsr_id, action_id, nslcmop_id, start_deploy, self.timeout_operate
+            )
+            return "COMPLETED", "Done"
+        except (ROclient.ROClientException, DbException, LcmException) as e:
+            self.logger.error("Exit Exception {}".format(e))
+            exc = e
+        except asyncio.CancelledError:
+            self.logger.error("Cancelled Exception while '{}'".format(stage))
+            exc = "Operation was cancelled"
+        except Exception as e:
+            exc = traceback.format_exc()
+            self.logger.critical("Exit Exception {} {}".format(type(e).__name__, e), exc_info=True)
+            return "FAILED", "Error in operate VNF {}".format(exc)
+
     def get_vca_cloud_and_credentials(self, vim_account_id: str) -> (str, str):
         """
         Get VCA Cloud and VCA Cloud Credentials for the VIM account