Fix 1425 NG-RO unable to pin VNF with vim_account config
[osm/LCM.git] / osm_lcm / ns.py
index 2f0d6f6..ab1ee3b 100644 (file)
@@ -513,7 +513,7 @@ class NsLcm(LcmBase):
                     vdur_copy = deepcopy(vdur)
                     vdur_copy["status"] = "BUILD"
                     vdur_copy["status-detailed"] = None
-                    vdur_copy["ip-address"]: None
+                    vdur_copy["ip-address"] = None
                     vdur_copy["_id"] = str(uuid4())
                     vdur_copy["count-index"] += count + 1
                     vdur_copy["id"] = "{}-{}".format(
@@ -796,6 +796,37 @@ class NsLcm(LcmBase):
             if vld_params.get("common_id"):
                 target_vld["common_id"] = vld_params.get("common_id")
 
+        # modify target["ns"]["vld"] with instantiation parameters to override vnf vim-account
+        def update_ns_vld_target(target, ns_params):
+            for vnf_params in ns_params.get("vnf", ()):
+                if vnf_params.get("vimAccountId"):
+                    target_vnf = next(
+                        (
+                            vnfr
+                            for vnfr in db_vnfrs.values()
+                            if vnf_params["member-vnf-index"]
+                            == vnfr["member-vnf-index-ref"]
+                        ),
+                        None,
+                    )
+                    vdur = next((vdur for vdur in target_vnf.get("vdur", ())), None)
+                    for a_index, a_vld in enumerate(target["ns"]["vld"]):
+                        target_vld = find_in_list(
+                            get_iterable(vdur, "interfaces"),
+                            lambda iface: iface.get("ns-vld-id") == a_vld["name"],
+                        )
+                        if target_vld:
+                            if vnf_params.get("vimAccountId") not in a_vld.get(
+                                "vim_info", {}
+                            ):
+                                target["ns"]["vld"][a_index].get("vim_info").update(
+                                    {
+                                        "vim:{}".format(vnf_params["vimAccountId"]): {
+                                            "vim_network_name": ""
+                                        }
+                                    }
+                                )
+
         nslcmop_id = db_nslcmop["_id"]
         target = {
             "name": db_nsr["name"],
@@ -911,6 +942,8 @@ class NsLcm(LcmBase):
                 vld_params.update(vld_instantiation_params)
             parse_vld_instantiation_params(target_vim, target_vld, vld_params, None)
             target["ns"]["vld"].append(target_vld)
+        # Update the target ns_vld if vnf vim_account is overriden by instantiation params
+        update_ns_vld_target(target, ns_params)
 
         for vnfr in db_vnfrs.values():
             vnfd = find_in_list(
@@ -1557,9 +1590,13 @@ class NsLcm(LcmBase):
         raise LcmException("Configuration aborted because dependent charm/s timeout")
 
     def get_vca_id(self, db_vnfr: dict, db_nsr: dict):
-        return deep_get(db_vnfr, ("vca-id",)) or deep_get(
-            db_nsr, ("instantiate_params", "vcaId")
-        )
+        vca_id = None
+        if db_vnfr:
+            vca_id = deep_get(db_vnfr, ("vca-id",))
+        elif db_nsr:
+            vim_account_id = deep_get(db_nsr, ("instantiate_params", "vimAccountId"))
+            vca_id = VimAccountDB.get_vim_account_with_id(vim_account_id).get("vca")
+        return vca_id
 
     async def instantiate_N2VC(
         self,
@@ -1603,17 +1640,22 @@ class NsLcm(LcmBase):
 
             namespace = "{nsi}.{ns}".format(nsi=nsi_id if nsi_id else "", ns=nsr_id)
 
+            if vca_type == "native_charm":
+                index_number = 0
+            else:
+                index_number = vdu_index or 0
+
             if vnfr_id:
                 element_type = "VNF"
                 element_under_configuration = vnfr_id
-                namespace += ".{}-{}".format(vnfr_id, vdu_index or 0)
+                namespace += ".{}-{}".format(vnfr_id, index_number)
                 if vdu_id:
-                    namespace += ".{}-{}".format(vdu_id, vdu_index or 0)
+                    namespace += ".{}-{}".format(vdu_id, index_number)
                     element_type = "VDU"
-                    element_under_configuration = "{}-{}".format(vdu_id, vdu_index or 0)
+                    element_under_configuration = "{}-{}".format(vdu_id, index_number)
                     osm_config["osm"]["vdu_id"] = vdu_id
                 elif kdu_name:
-                    namespace += ".{}.{}".format(kdu_name, vdu_index or 0)
+                    namespace += ".{}".format(kdu_name)
                     element_type = "KDU"
                     element_under_configuration = kdu_name
                     osm_config["osm"]["kdu_name"] = kdu_name
@@ -1806,6 +1848,7 @@ class NsLcm(LcmBase):
                     config=config,
                     num_units=num_units,
                     vca_id=vca_id,
+                    vca_type=vca_type,
                 )
 
             # write in db flag of configuration_sw already installed
@@ -1922,6 +1965,7 @@ class NsLcm(LcmBase):
                     params_dict=primitive_params_,
                     db_dict=db_dict,
                     vca_id=vca_id,
+                    vca_type=vca_type,
                 )
                 # Once some primitive has been exec, check and write at db if it needs to exec terminated primitives
                 if check_if_terminated_needed:
@@ -2214,6 +2258,10 @@ class NsLcm(LcmBase):
             # read from db: operation
             stage[1] = "Getting nslcmop={} from db.".format(nslcmop_id)
             db_nslcmop = self.db.get_one("nslcmops", {"_id": nslcmop_id})
+            if db_nslcmop["operationParams"].get("additionalParamsForVnf"):
+                db_nslcmop["operationParams"]["additionalParamsForVnf"] = json.loads(
+                    db_nslcmop["operationParams"]["additionalParamsForVnf"]
+                )
             ns_params = db_nslcmop.get("operationParams")
             if ns_params and ns_params.get("timeout_ns_deploy"):
                 timeout_ns_deploy = ns_params["timeout_ns_deploy"]
@@ -2241,6 +2289,14 @@ class NsLcm(LcmBase):
 
             # for each vnf in ns, read vnfd
             for vnfr in db_vnfrs_list:
+                if vnfr.get("kdur"):
+                    kdur_list = []
+                    for kdur in vnfr["kdur"]:
+                        if kdur.get("additionalParams"):
+                            kdur["additionalParams"] = json.loads(kdur["additionalParams"])
+                        kdur_list.append(kdur)
+                    vnfr["kdur"] = kdur_list
+
                 db_vnfrs[vnfr["member-vnf-index-ref"]] = vnfr
                 vnfd_id = vnfr["vnfd-id"]
                 vnfd_ref = vnfr["vnfd-ref"]
@@ -2390,9 +2446,7 @@ class NsLcm(LcmBase):
                     deploy_params_vdu["OSM"] = get_osm_params(
                         db_vnfr, vdu_id, vdu_count_index=0
                     )
-                    vdud_count = get_vdu_profile(vnfd, vdu_id).get(
-                        "max-number-of-instances", 1
-                    )
+                    vdud_count = get_number_of_instances(vnfd, vdu_id)
 
                     self.logger.debug("VDUD > {}".format(vdud))
                     self.logger.debug(
@@ -3287,6 +3341,8 @@ class NsLcm(LcmBase):
         )
         if "execution-environment-list" in descriptor_config:
             ee_list = descriptor_config.get("execution-environment-list", [])
+        elif "juju" in descriptor_config:
+            ee_list = [descriptor_config]  # ns charms
         else:  # other types as script are not supported
             ee_list = []
 
@@ -3745,6 +3801,7 @@ class NsLcm(LcmBase):
             await self.vca_map[vca_type].delete_execution_environment(
                 vca_deployed["ee_id"],
                 scaling_in=scaling_in,
+                vca_type=vca_type,
                 vca_id=vca_id,
             )
 
@@ -4040,8 +4097,13 @@ class NsLcm(LcmBase):
 
             for vca_index, vca in enumerate(get_iterable(nsr_deployed, "VCA")):
                 config_descriptor = None
-
-                vca_id = self.get_vca_id(db_vnfrs_dict[vca["member-vnf-index"]], db_nsr)
+                vca_member_vnf_index = vca.get("member-vnf-index")
+                vca_id = self.get_vca_id(
+                    db_vnfrs_dict.get(vca_member_vnf_index)
+                    if vca_member_vnf_index
+                    else None,
+                    db_nsr,
+                )
                 if not vca or not vca.get("ee_id"):
                     continue
                 if not vca.get("member-vnf-index"):
@@ -4513,6 +4575,7 @@ class NsLcm(LcmBase):
                             total_timeout=self.timeout_primitive,
                             db_dict=db_dict,
                             vca_id=vca_id,
+                            vca_type=vca_type,
                         ),
                         timeout=timeout or self.timeout_primitive,
                     )
@@ -4599,6 +4662,10 @@ class NsLcm(LcmBase):
             step = "Getting information from database"
             db_nslcmop = self.db.get_one("nslcmops", {"_id": nslcmop_id})
             db_nsr = self.db.get_one("nsrs", {"_id": nsr_id})
+            if db_nslcmop["operationParams"].get("primitive_params"):
+                db_nslcmop["operationParams"]["primitive_params"] = json.loads(
+                    db_nslcmop["operationParams"]["primitive_params"]
+                )
 
             nsr_deployed = db_nsr["_admin"].get("deployed")
             vnf_index = db_nslcmop["operationParams"].get("member_vnf_index")
@@ -4616,6 +4683,13 @@ class NsLcm(LcmBase):
                 db_vnfr = self.db.get_one(
                     "vnfrs", {"member-vnf-index-ref": vnf_index, "nsr-id-ref": nsr_id}
                 )
+                if db_vnfr.get("kdur"):
+                    kdur_list = []
+                    for kdur in db_vnfr["kdur"]:
+                        if kdur.get("additionalParams"):
+                            kdur["additionalParams"] = json.loads(kdur["additionalParams"])
+                        kdur_list.append(kdur)
+                    db_vnfr["kdur"] = kdur_list
                 step = "Getting vnfd from database"
                 db_vnfd = self.db.get_one("vnfds", {"_id": db_vnfr["vnfd-id"]})
             else:
@@ -5379,7 +5453,6 @@ class NsLcm(LcmBase):
                         # Pre-scale retry check: Check if this sub-operation has been executed before
                         op_index = self._check_or_add_scale_suboperation(
                             db_nslcmop,
-                            nslcmop_id,
                             vnf_index,
                             vnf_config_primitive,
                             primitive_params,
@@ -5788,7 +5861,6 @@ class NsLcm(LcmBase):
                         # Post-scale retry check: Check if this sub-operation has been executed before
                         op_index = self._check_or_add_scale_suboperation(
                             db_nslcmop,
-                            nslcmop_id,
                             vnf_index,
                             vnf_config_primitive,
                             primitive_params,