Bug 1954 fixed: I added the <OSM> parameter as one of the valid ones that will be...
[osm/NBI.git] / osm_nbi / instance_topics.py
index aac0b0b..8cc7106 100644 (file)
@@ -27,8 +27,10 @@ from osm_nbi.validation import (
     ns_action,
     ns_scale,
     ns_update,
+    ns_heal,
     nsi_instantiate,
     ns_migrate,
+    ns_verticalscale,
 )
 from osm_nbi.base_topic import (
     BaseTopic,
@@ -36,6 +38,7 @@ from osm_nbi.base_topic import (
     get_iterable,
     deep_get,
     increment_ip_mac,
+    update_descriptor_usage_state,
 )
 from yaml import safe_dump
 from osm_common.dbbase import DbException
@@ -167,9 +170,14 @@ class NsrTopic(BaseTopic):
         ns_request, member_vnf_index=None, vdu_id=None, kdu_name=None, descriptor=None
     ):
         """
-        Get and format user additional params for NS or VNF
+        Get and format user additional params for NS or VNF.
+        The vdu_id and kdu_name params are mutually exclusive! If none of them are given, then the method will
+        exclusively search for the VNF/NS LCM additional params.
+
         :param ns_request: User instantiation additional parameters
         :param member_vnf_index: None for extract NS params, or member_vnf_index to extract VNF params
+        :vdu_id: VDU's ID against which we want to format the additional params
+        :kdu_name: KDU's name against which we want to format the additional params
         :param descriptor: If not None it check that needed parameters of descriptor are supplied
         :return: tuple with a formatted copy of additional params or None if not supplied, plus other parameters
         """
@@ -253,6 +261,9 @@ class NsrTopic(BaseTopic):
             if kdu_name:
                 additional_params = json.dumps(additional_params)
 
+        # Select the VDU ID, KDU name or NS/VNF ID, depending on the method's call intent
+        selector = vdu_id if vdu_id else kdu_name if kdu_name else descriptor.get("id")
+
         if descriptor:
             for df in descriptor.get("df", []):
                 # check that enough parameters are supplied for the initial-config-primitive
@@ -267,10 +278,13 @@ class NsrTopic(BaseTopic):
                         for config in df["lcm-operations-configuration"][
                             "operate-vnf-op-config"
                         ].get("day1-2", []):
-                            for primitive in get_iterable(
-                                config.get("initial-config-primitive")
-                            ):
-                                initial_primitives.append(primitive)
+                            # Verify the target object (VNF|NS|VDU|KDU) where we need to populate 
+                            # the params with the additional ones given by the user
+                            if config.get("id") == selector:
+                                for primitive in get_iterable(
+                                    config.get("initial-config-primitive")
+                                ):
+                                    initial_primitives.append(primitive)
                 else:
                     initial_primitives = deep_get(
                         descriptor, ("ns-configuration", "initial-config-primitive")
@@ -285,6 +299,7 @@ class NsrTopic(BaseTopic):
                                 "<rw_mgmt_ip>",
                                 "<VDU_SCALE_INFO>",
                                 "<ns_config_info>",
+                                "<OSM>"
                             ):
                                 continue
                             if (
@@ -376,9 +391,13 @@ class NsrTopic(BaseTopic):
                 )
                 self._add_vnfr_to_db(vnfr_descriptor, rollback, session)
                 nsr_descriptor["constituent-vnfr-ref"].append(vnfr_descriptor["id"])
+                step = "Updating VNFD usageState"
+                update_descriptor_usage_state(vnfd, "vnfds", self.db)
 
             step = "creating nsr at database"
             self._add_nsr_to_db(nsr_descriptor, rollback, session)
+            step = "Updating NSD usageState"
+            update_descriptor_usage_state(nsd, "nsds", self.db)
 
             step = "creating nsr temporal folder"
             self.fs.mkdir(nsr_id)
@@ -439,7 +458,7 @@ class NsrTopic(BaseTopic):
 
         return ns_k8s_namespace
 
-    def _add_flavor_to_nsr(self, vdu, vnfd, nsr_descriptor):
+    def _add_flavor_to_nsr(self, vdu, vnfd, nsr_descriptor, member_vnf_index, revision=None):
         flavor_data = {}
         guest_epa = {}
         # Find this vdu compute and storage descriptors
@@ -509,7 +528,8 @@ class NsrTopic(BaseTopic):
         if guest_epa:
             flavor_data["guest-epa"] = guest_epa
 
-        flavor_data["name"] = vdu["id"][:56] + "-flv"
+        revision = revision if revision is not None else 1
+        flavor_data["name"] = vdu["id"][:56] + "-" + member_vnf_index + "-" + str(revision) + "-flv"
         flavor_data["id"] = str(len(nsr_descriptor["flavor"]))
         nsr_descriptor["flavor"].append(flavor_data)
 
@@ -557,6 +577,9 @@ class NsrTopic(BaseTopic):
             "image": [],
             "affinity-or-anti-affinity-group": [],
         }
+        if "revision" in nsd["_admin"]:
+            nsr_descriptor["revision"] = nsd["_admin"]["revision"]
+
         ns_request["nsr_id"] = nsr_id
         if ns_request and ns_request.get("config-units"):
             nsr_descriptor["config-units"] = ns_request["config-units"]
@@ -588,7 +611,8 @@ class NsrTopic(BaseTopic):
                 vnfd.pop("_admin")
 
                 for vdu in vnfd.get("vdu", ()):
-                    self._add_flavor_to_nsr(vdu, vnfd, nsr_descriptor)
+                    member_vnf_index = vnf_profile.get("id")
+                    self._add_flavor_to_nsr(vdu, vnfd, nsr_descriptor, member_vnf_index)
                     sw_image_id = vdu.get("sw-image-desc")
                     if sw_image_id:
                         image_data = self._get_image_data_from_vnfd(vnfd, sw_image_id)
@@ -714,6 +738,7 @@ class NsrTopic(BaseTopic):
         nsr_descriptor,
         ns_request,
         ns_k8s_namespace,
+        revision=None,
     ):
         vnfr_id = str(uuid4())
         nsr_id = nsr_descriptor["id"]
@@ -891,7 +916,10 @@ class NsrTopic(BaseTopic):
                 vdur["internal-connection-point"].append(vdu_icp)
 
                 for iface in icp.get("virtual-network-interface-requirement", ()):
-                    iface_fields = ("name", "mac-address")
+                    # Name, mac-address and interface position is taken from VNFD
+                    # and included into VNFR. By this way RO can process this information
+                    # while creating the VDU.
+                    iface_fields = ("name", "mac-address", "position")
                     vdu_iface = {
                         x: iface[x] for x in iface_fields if iface.get(x) is not None
                     }
@@ -1015,7 +1043,8 @@ class NsrTopic(BaseTopic):
                     alt_image_ids.append(nsr_sw_image_data["id"])
                 vdur["alt-image-ids"] = alt_image_ids
 
-            flavor_data_name = vdu["id"][:56] + "-flv"
+            revision = revision if revision is not None else 1
+            flavor_data_name = vdu["id"][:56] + "-" + vnf_index + "-" + str(revision) + "-flv"
             nsr_flavor_desc = utils.find_in_list(
                 nsr_descriptor["flavor"],
                 lambda flavor: flavor["name"] == flavor_data_name,
@@ -1160,8 +1189,10 @@ class NsLcmOpTopic(BaseTopic):
         "action": ns_action,
         "update": ns_update,
         "scale": ns_scale,
+        "heal": ns_heal,
         "terminate": ns_terminate,
         "migrate": ns_migrate,
+        "verticalscale": ns_verticalscale,
     }
 
     def __init__(self, db, fs, msg, auth):
@@ -1172,7 +1203,7 @@ class NsLcmOpTopic(BaseTopic):
         """
         Check that user has enter right parameters for the operation
         :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
-        :param operation: it can be: instantiate, terminate, action, update. TODO: heal
+        :param operation: it can be: instantiate, terminate, action, update, heal
         :param indata: descriptor with the parameters of the operation
         :return: None
         """
@@ -1182,6 +1213,8 @@ class NsLcmOpTopic(BaseTopic):
             self._check_scale_ns_operation(indata, nsr)
         elif operation == "update":
             self._check_update_ns_operation(indata, nsr)
+        elif operation == "heal":
+            self._check_heal_ns_operation(indata, nsr)
         elif operation == "instantiate":
             self._check_instantiate_ns_operation(indata, nsr, session)
 
@@ -1384,6 +1417,9 @@ class NsLcmOpTopic(BaseTopic):
                 )
             )
 
+    def _check_heal_ns_operation(self, indata, nsr):
+        return
+
     def _check_instantiate_ns_operation(self, indata, nsr, session):
         vnf_member_index_to_vnfd = {}  # map between vnf_member_index to vnf descriptor.
         vim_accounts = []
@@ -1478,7 +1514,7 @@ class NsLcmOpTopic(BaseTopic):
                 if in_vdu["id"] == vdu["id"]:
                     for volume in get_iterable(in_vdu.get("volume")):
                         for volumed in get_iterable(vdu.get("virtual-storage-desc")):
-                            if volumed["id"] == volume["name"]:
+                            if volumed == volume["name"]:
                                 break
                         else:
                             raise EngineException(
@@ -1498,7 +1534,7 @@ class NsLcmOpTopic(BaseTopic):
                         ):
                             vdu_if_names.add(iface.get("name"))
 
-                    for in_iface in get_iterable(in_vdu["interface"]):
+                    for in_iface in get_iterable(in_vdu.get("interface")):
                         if in_iface["name"] in vdu_if_names:
                             break
                         else:
@@ -1583,7 +1619,7 @@ class NsLcmOpTopic(BaseTopic):
         if wim_account in wim_accounts:
             return
         try:
-            db_filter = self._get_project_filter(session, write=False, show_all=True)
+            db_filter = self._get_project_filter(session)
             db_filter["_id"] = wim_account
             self.db.get_one("wim_accounts", db_filter)
         except Exception:
@@ -2244,7 +2280,7 @@ class NsLcmOpTopic(BaseTopic):
                         vnf_index = vnfr["member-vnf-index-ref"]
                         self.logger.info("nsr {}".format(nsr))
                         for vdu in vnfd["vdu"]:
-                            self.nsrtopic._add_flavor_to_nsr(vdu, vnfd, nsr)
+                            self.nsrtopic._add_flavor_to_nsr(vdu, vnfd, nsr, vnf_index, latest_vnfd_revision)
                             sw_image_id = vdu.get("sw-image-desc")
                             if sw_image_id:
                                 image_data = self.nsrtopic._get_image_data_from_vnfd(vnfd, sw_image_id)
@@ -2264,6 +2300,7 @@ class NsLcmOpTopic(BaseTopic):
                             nsr,
                             ns_request,
                             ns_k8s_namespace,
+                            latest_vnfd_revision,
                         )
                         indata["newVdur"] = vnfr_descriptor["vdur"]
             nslcmop_desc = self._create_nslcmop(nsInstanceId, operation, indata)