Feature 10906: Support for Anti-Affinity groups
[osm/LCM.git] / osm_lcm / ns.py
index ab1ee3b..69f2d07 100644 (file)
@@ -414,7 +414,8 @@ class NsLcm(LcmBase):
 
     def _get_vdu_additional_params(self, db_vnfr, vdu_id):
         vdur = next(
-            vdur for vdur in db_vnfr.get("vdur") if vdu_id == vdur["vdu-id-ref"]
+            (vdur for vdur in db_vnfr.get("vdur") if vdu_id == vdur["vdu-id-ref"]),
+            {}
         )
         additional_params = vdur.get("additionalParams")
         return parse_yaml_strings(additional_params)
@@ -491,6 +492,7 @@ class NsLcm(LcmBase):
     def scale_vnfr(self, db_vnfr, vdu_create=None, vdu_delete=None, mark_delete=False):
 
         db_vdu_push_list = []
+        template_vdur = []
         db_update = {"_admin.modified": time()}
         if vdu_create:
             for vdu_id, vdu_count in vdu_create.items():
@@ -503,12 +505,22 @@ class NsLcm(LcmBase):
                     None,
                 )
                 if not vdur:
-                    raise LcmException(
-                        "Error scaling OUT VNFR for {}. There is not any existing vnfr. Scaled to 0?".format(
+                    # Read the template saved in the db:
+                    self.logger.debug(f"No vdur in the database. Using the vdur-template to scale")
+                    vdur_template = db_vnfr.get("vdur-template")
+                    if not vdur_template:
+                        raise LcmException(
+                           "Error scaling OUT VNFR for {}. No vnfr or template exists".format(
                             vdu_id
+                            )
                         )
-                    )
-
+                    vdur = vdur_template[0]
+                    #Delete a template from the database after using it
+                    self.db.set_one("vnfrs",
+                                {"_id": db_vnfr["_id"]},
+                                None,
+                                pull={"vdur-template": {"_id": vdur['_id']}}
+                            )
                 for count in range(vdu_count):
                     vdur_copy = deepcopy(vdur)
                     vdur_copy["status"] = "BUILD"
@@ -533,12 +545,17 @@ class NsLcm(LcmBase):
                             )
                         else:
                             iface.pop("mac-address", None)
-                        iface.pop(
-                            "mgmt_vnf", None
-                        )  # only first vdu can be managment of vnf
+                        if db_vnfr["vdur"]:
+                            iface.pop(
+                                "mgmt_vnf", None
+                            )  # only first vdu can be managment of vnf
                     db_vdu_push_list.append(vdur_copy)
                     # self.logger.debug("scale out, adding vdu={}".format(vdur_copy))
         if vdu_delete:
+            if len(db_vnfr["vdur"]) == 1:
+                # The scale will move to 0 instances
+                self.logger.debug(f"Scaling to 0 !, creating the template with the last vdur")
+                template_vdur = [db_vnfr["vdur"][0]]
             for vdu_id, vdu_count in vdu_delete.items():
                 if mark_delete:
                     indexes_to_delete = [
@@ -566,7 +583,14 @@ class NsLcm(LcmBase):
                             None,
                             pull={"vdur": {"_id": vdu["_id"]}},
                         )
-        db_push = {"vdur": db_vdu_push_list} if db_vdu_push_list else None
+        db_push = {}
+        if db_vdu_push_list:
+            db_push["vdur"] = db_vdu_push_list
+        if template_vdur:
+            db_push["vdur-template"] = template_vdur
+        if not db_push:
+            db_push = None
+        db_vnfr["vdur-template"] = template_vdur
         self.db.set_one("vnfrs", {"_id": db_vnfr["_id"]}, db_update, push_list=db_push)
         # modify passed dictionary db_vnfr
         db_vnfr_ = self.db.get_one("vnfrs", {"_id": db_vnfr["_id"]})
@@ -841,6 +865,10 @@ class NsLcm(LcmBase):
             image["vim_info"] = {}
         for flavor in target["flavor"]:
             flavor["vim_info"] = {}
+        if db_nsr.get("affinity-or-anti-affinity-group"):
+            target["affinity-or-anti-affinity-group"] = deepcopy(db_nsr["affinity-or-anti-affinity-group"])
+            for affinity_or_anti_affinity_group in target["affinity-or-anti-affinity-group"]:
+                affinity_or_anti_affinity_group["vim_info"] = {}
 
         if db_nslcmop.get("lcmOperationType") != "instantiate":
             # get parameters of instantiation:
@@ -1127,6 +1155,13 @@ class NsLcm(LcmBase):
                 if target_vim not in ns_image["vim_info"]:
                     ns_image["vim_info"][target_vim] = {}
 
+                # Affinity groups
+                if vdur.get("affinity-or-anti-affinity-group-id"):
+                    for ags_id in vdur["affinity-or-anti-affinity-group-id"]:
+                        ns_ags = target["affinity-or-anti-affinity-group"][int(ags_id)]
+                        if target_vim not in ns_ags["vim_info"]:
+                            ns_ags["vim_info"][target_vim] = {}
+
                 vdur["vim_info"] = {target_vim: {}}
                 # instantiation parameters
                 # if vnf_params:
@@ -2293,7 +2328,9 @@ class NsLcm(LcmBase):
                     kdur_list = []
                     for kdur in vnfr["kdur"]:
                         if kdur.get("additionalParams"):
-                            kdur["additionalParams"] = json.loads(kdur["additionalParams"])
+                            kdur["additionalParams"] = json.loads(
+                                kdur["additionalParams"]
+                            )
                         kdur_list.append(kdur)
                     vnfr["kdur"] = kdur_list
 
@@ -2491,8 +2528,8 @@ class NsLcm(LcmBase):
                         )
                         deploy_params_kdu = {"OSM": get_osm_params(db_vnfr)}
                         if kdur.get("additionalParams"):
-                            deploy_params_kdu = parse_yaml_strings(
-                                kdur["additionalParams"]
+                            deploy_params_kdu.update(
+                                parse_yaml_strings(kdur["additionalParams"].copy())
                             )
 
                         self._deploy_n2vc(
@@ -4687,7 +4724,9 @@ class NsLcm(LcmBase):
                     kdur_list = []
                     for kdur in db_vnfr["kdur"]:
                         if kdur.get("additionalParams"):
-                            kdur["additionalParams"] = json.loads(kdur["additionalParams"])
+                            kdur["additionalParams"] = json.loads(
+                                kdur["additionalParams"]
+                            )
                         kdur_list.append(kdur)
                     db_vnfr["kdur"] = kdur_list
                 step = "Getting vnfd from database"