Bugfix 1550: Setting a custom release name for Helm based kdus
[osm/NBI.git] / osm_nbi / instance_topics.py
index cabfc1c..ebef36e 100644 (file)
@@ -18,15 +18,30 @@ from uuid import uuid4
 from http import HTTPStatus
 from time import time
 from copy import copy, deepcopy
 from http import HTTPStatus
 from time import time
 from copy import copy, deepcopy
-from osm_nbi.validation import validate_input, ValidationError, ns_instantiate, ns_terminate, ns_action, ns_scale,\
-    nsi_instantiate
-from osm_nbi.base_topic import BaseTopic, EngineException, get_iterable, deep_get, increment_ip_mac
+from osm_nbi.validation import (
+    validate_input,
+    ValidationError,
+    ns_instantiate,
+    ns_terminate,
+    ns_action,
+    ns_scale,
+    nsi_instantiate,
+)
+from osm_nbi.base_topic import (
+    BaseTopic,
+    EngineException,
+    get_iterable,
+    deep_get,
+    increment_ip_mac,
+)
 from yaml import safe_dump
 from osm_common.dbbase import DbException
 from osm_common.msgbase import MsgException
 from osm_common.fsbase import FsException
 from osm_nbi import utils
 from yaml import safe_dump
 from osm_common.dbbase import DbException
 from osm_common.msgbase import MsgException
 from osm_common.fsbase import FsException
 from osm_nbi import utils
-from re import match  # For checking that additional parameter names are valid Jinja2 identifiers
+from re import (
+    match,
+)  # For checking that additional parameter names are valid Jinja2 identifiers
 
 __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
 
 
 __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
 
@@ -51,8 +66,12 @@ class NsrTopic(BaseTopic):
             return
         nsd_id = descriptor["nsdId"]
         if not self.get_item_list(session, "nsds", {"id": nsd_id}):
             return
         nsd_id = descriptor["nsdId"]
         if not self.get_item_list(session, "nsds", {"id": nsd_id}):
-            raise EngineException("Descriptor error at nsdId='{}' references a non exist nsd".format(nsd_id),
-                                  http_code=HTTPStatus.CONFLICT)
+            raise EngineException(
+                "Descriptor error at nsdId='{}' references a non exist nsd".format(
+                    nsd_id
+                ),
+                http_code=HTTPStatus.CONFLICT,
+            )
 
     @staticmethod
     def format_on_new(content, project_id=None, make_public=False):
 
     @staticmethod
     def format_on_new(content, project_id=None, make_public=False):
@@ -72,9 +91,11 @@ class NsrTopic(BaseTopic):
             return
         nsr = db_content
         if nsr["_admin"].get("nsState") == "INSTANTIATED":
             return
         nsr = db_content
         if nsr["_admin"].get("nsState") == "INSTANTIATED":
-            raise EngineException("nsr '{}' cannot be deleted because it is in 'INSTANTIATED' state. "
-                                  "Launch 'terminate' operation first; or force deletion".format(_id),
-                                  http_code=HTTPStatus.CONFLICT)
+            raise EngineException(
+                "nsr '{}' cannot be deleted because it is in 'INSTANTIATED' state. "
+                "Launch 'terminate' operation first; or force deletion".format(_id),
+                http_code=HTTPStatus.CONFLICT,
+            )
 
     def delete_extra(self, session, _id, db_content, not_send_msg=None):
         """
 
     def delete_extra(self, session, _id, db_content, not_send_msg=None):
         """
@@ -91,28 +112,42 @@ class NsrTopic(BaseTopic):
         self.db.del_list("vnfrs", {"nsr-id-ref": _id})
 
         # set all used pdus as free
         self.db.del_list("vnfrs", {"nsr-id-ref": _id})
 
         # set all used pdus as free
-        self.db.set_list("pdus", {"_admin.usage.nsr_id": _id},
-                         {"_admin.usageState": "NOT_IN_USE", "_admin.usage": None})
+        self.db.set_list(
+            "pdus",
+            {"_admin.usage.nsr_id": _id},
+            {"_admin.usageState": "NOT_IN_USE", "_admin.usage": None},
+        )
 
         # Set NSD usageState
         nsr = db_content
         used_nsd_id = nsr.get("nsd-id")
         if used_nsd_id:
             # check if used by another NSR
 
         # Set NSD usageState
         nsr = db_content
         used_nsd_id = nsr.get("nsd-id")
         if used_nsd_id:
             # check if used by another NSR
-            nsrs_list = self.db.get_one("nsrs", {"nsd-id": used_nsd_id},
-                                        fail_on_empty=False, fail_on_more=False)
+            nsrs_list = self.db.get_one(
+                "nsrs", {"nsd-id": used_nsd_id}, fail_on_empty=False, fail_on_more=False
+            )
             if not nsrs_list:
             if not nsrs_list:
-                self.db.set_one("nsds", {"_id": used_nsd_id}, {"_admin.usageState": "NOT_IN_USE"})
+                self.db.set_one(
+                    "nsds", {"_id": used_nsd_id}, {"_admin.usageState": "NOT_IN_USE"}
+                )
 
         # Set VNFD usageState
         used_vnfd_id_list = nsr.get("vnfd-id")
         if used_vnfd_id_list:
             for used_vnfd_id in used_vnfd_id_list:
                 # check if used by another NSR
 
         # Set VNFD usageState
         used_vnfd_id_list = nsr.get("vnfd-id")
         if used_vnfd_id_list:
             for used_vnfd_id in used_vnfd_id_list:
                 # check if used by another NSR
-                nsrs_list = self.db.get_one("nsrs", {"vnfd-id": used_vnfd_id},
-                                            fail_on_empty=False, fail_on_more=False)
+                nsrs_list = self.db.get_one(
+                    "nsrs",
+                    {"vnfd-id": used_vnfd_id},
+                    fail_on_empty=False,
+                    fail_on_more=False,
+                )
                 if not nsrs_list:
                 if not nsrs_list:
-                    self.db.set_one("vnfds", {"_id": used_vnfd_id}, {"_admin.usageState": "NOT_IN_USE"})
+                    self.db.set_one(
+                        "vnfds",
+                        {"_id": used_vnfd_id},
+                        {"_admin.usageState": "NOT_IN_USE"},
+                    )
 
         # delete extra ro_nsrs used for internal RO module
         self.db.del_one("ro_nsrs", q_filter={"_id": _id}, fail_on_empty=False)
 
         # delete extra ro_nsrs used for internal RO module
         self.db.del_one("ro_nsrs", q_filter={"_id": _id}, fail_on_empty=False)
@@ -125,7 +160,9 @@ class NsrTopic(BaseTopic):
         return formated_request
 
     @staticmethod
         return formated_request
 
     @staticmethod
-    def _format_additional_params(ns_request, member_vnf_index=None, vdu_id=None, kdu_name=None, descriptor=None):
+    def _format_additional_params(
+        ns_request, member_vnf_index=None, vdu_id=None, kdu_name=None, descriptor=None
+    ):
         """
         Get and format user additional params for NS or VNF
         :param ns_request: User instantiation additional parameters
         """
         Get and format user additional params for NS or VNF
         :param ns_request: User instantiation additional parameters
@@ -139,15 +176,30 @@ class NsrTopic(BaseTopic):
             additional_params = copy(ns_request.get("additionalParamsForNs"))
             where_ = "additionalParamsForNs"
         elif ns_request.get("additionalParamsForVnf"):
             additional_params = copy(ns_request.get("additionalParamsForNs"))
             where_ = "additionalParamsForNs"
         elif ns_request.get("additionalParamsForVnf"):
-            where_ = "additionalParamsForVnf[member-vnf-index={}]".format(member_vnf_index)
-            item = next((x for x in ns_request["additionalParamsForVnf"] if x["member-vnf-index"] == member_vnf_index),
-                        None)
+            where_ = "additionalParamsForVnf[member-vnf-index={}]".format(
+                member_vnf_index
+            )
+            item = next(
+                (
+                    x
+                    for x in ns_request["additionalParamsForVnf"]
+                    if x["member-vnf-index"] == member_vnf_index
+                ),
+                None,
+            )
             if item:
                 if not vdu_id and not kdu_name:
                     other_params = item
                 additional_params = copy(item.get("additionalParams")) or {}
                 if vdu_id and item.get("additionalParamsForVdu"):
             if item:
                 if not vdu_id and not kdu_name:
                     other_params = item
                 additional_params = copy(item.get("additionalParams")) or {}
                 if vdu_id and item.get("additionalParamsForVdu"):
-                    item_vdu = next((x for x in item["additionalParamsForVdu"] if x["vdu_id"] == vdu_id), None)
+                    item_vdu = next(
+                        (
+                            x
+                            for x in item["additionalParamsForVdu"]
+                            if x["vdu_id"] == vdu_id
+                        ),
+                        None,
+                    )
                     other_params = item_vdu
                     if item_vdu and item_vdu.get("additionalParams"):
                         where_ += ".additionalParamsForVdu[vdu_id={}]".format(vdu_id)
                     other_params = item_vdu
                     if item_vdu and item_vdu.get("additionalParams"):
                         where_ += ".additionalParamsForVdu[vdu_id={}]".format(vdu_id)
@@ -155,24 +207,44 @@ class NsrTopic(BaseTopic):
                 if kdu_name:
                     additional_params = {}
                     if item.get("additionalParamsForKdu"):
                 if kdu_name:
                     additional_params = {}
                     if item.get("additionalParamsForKdu"):
-                        item_kdu = next((x for x in item["additionalParamsForKdu"] if x["kdu_name"] == kdu_name), None)
+                        item_kdu = next(
+                            (
+                                x
+                                for x in item["additionalParamsForKdu"]
+                                if x["kdu_name"] == kdu_name
+                            ),
+                            None,
+                        )
                         other_params = item_kdu
                         if item_kdu and item_kdu.get("additionalParams"):
                         other_params = item_kdu
                         if item_kdu and item_kdu.get("additionalParams"):
-                            where_ += ".additionalParamsForKdu[kdu_name={}]".format(kdu_name)
+                            where_ += ".additionalParamsForKdu[kdu_name={}]".format(
+                                kdu_name
+                            )
                             additional_params = item_kdu["additionalParams"]
 
         if additional_params:
             for k, v in additional_params.items():
                 # BEGIN Check that additional parameter names are valid Jinja2 identifiers if target is not Kdu
                             additional_params = item_kdu["additionalParams"]
 
         if additional_params:
             for k, v in additional_params.items():
                 # BEGIN Check that additional parameter names are valid Jinja2 identifiers if target is not Kdu
-                if not kdu_name and not match('^[a-zA-Z_][a-zA-Z0-9_]*$', k):
-                    raise EngineException("Invalid param name at {}:{}. Must contain only alphanumeric characters "
-                                          "and underscores, and cannot start with a digit"
-                                          .format(where_, k))
+                if not kdu_name and not match("^[a-zA-Z_][a-zA-Z0-9_]*$", k):
+                    raise EngineException(
+                        "Invalid param name at {}:{}. Must contain only alphanumeric characters "
+                        "and underscores, and cannot start with a digit".format(
+                            where_, k
+                        )
+                    )
                 # END Check that additional parameter names are valid Jinja2 identifiers
                 if not isinstance(k, str):
                 # END Check that additional parameter names are valid Jinja2 identifiers
                 if not isinstance(k, str):
-                    raise EngineException("Invalid param at {}:{}. Only string keys are allowed".format(where_, k))
+                    raise EngineException(
+                        "Invalid param at {}:{}. Only string keys are allowed".format(
+                            where_, k
+                        )
+                    )
                 if "." in k or "$" in k:
                 if "." in k or "$" in k:
-                    raise EngineException("Invalid param at {}:{}. Keys must not contain dots or $".format(where_, k))
+                    raise EngineException(
+                        "Invalid param at {}:{}. Keys must not contain dots or $".format(
+                            where_, k
+                        )
+                    )
                 if isinstance(v, (dict, tuple, list)):
                     additional_params[k] = "!!yaml " + safe_dump(v)
 
                 if isinstance(v, (dict, tuple, list)):
                     additional_params[k] = "!!yaml " + safe_dump(v)
 
@@ -182,24 +254,46 @@ class NsrTopic(BaseTopic):
                 # TODO: check for cloud-init
                 if member_vnf_index:
                     initial_primitives = []
                 # TODO: check for cloud-init
                 if member_vnf_index:
                     initial_primitives = []
-                    if "lcm-operations-configuration" in df \
-                       and "operate-vnf-op-config" in df["lcm-operations-configuration"]:
-                        for config in df["lcm-operations-configuration"]["operate-vnf-op-config"].get("day1-2", []):
-                            for primitive in get_iterable(config.get("initial-config-primitive")):
+                    if (
+                        "lcm-operations-configuration" in df
+                        and "operate-vnf-op-config"
+                        in df["lcm-operations-configuration"]
+                    ):
+                        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)
                 else:
                                 initial_primitives.append(primitive)
                 else:
-                    initial_primitives = deep_get(descriptor, ("ns-configuration", "initial-config-primitive"))
+                    initial_primitives = deep_get(
+                        descriptor, ("ns-configuration", "initial-config-primitive")
+                    )
 
                 for initial_primitive in get_iterable(initial_primitives):
                     for param in get_iterable(initial_primitive.get("parameter")):
 
                 for initial_primitive in get_iterable(initial_primitives):
                     for param in get_iterable(initial_primitive.get("parameter")):
-                        if param["value"].startswith("<") and param["value"].endswith(">"):
-                            if param["value"] in ("<rw_mgmt_ip>", "<VDU_SCALE_INFO>", "<ns_config_info>"):
+                        if param["value"].startswith("<") and param["value"].endswith(
+                            ">"
+                        ):
+                            if param["value"] in (
+                                "<rw_mgmt_ip>",
+                                "<VDU_SCALE_INFO>",
+                                "<ns_config_info>",
+                            ):
                                 continue
                                 continue
-                            if not additional_params or param["value"][1:-1] not in additional_params:
-                                raise EngineException("Parameter '{}' needed for vnfd[id={}]:day1-2 configuration:"
-                                                      "initial-config-primitive[name={}] not supplied".
-                                                      format(param["value"], descriptor["id"],
-                                                             initial_primitive["name"]))
+                            if (
+                                not additional_params
+                                or param["value"][1:-1] not in additional_params
+                            ):
+                                raise EngineException(
+                                    "Parameter '{}' needed for vnfd[id={}]:day1-2 configuration:"
+                                    "initial-config-primitive[name={}] not supplied".format(
+                                        param["value"],
+                                        descriptor["id"],
+                                        initial_primitive["name"],
+                                    )
+                                )
 
         return additional_params or None, other_params or None
 
 
         return additional_params or None, other_params or None
 
@@ -233,7 +327,9 @@ class NsrTopic(BaseTopic):
 
             step = "filling nsr from input data"
             nsr_id = str(uuid4())
 
             step = "filling nsr from input data"
             nsr_id = str(uuid4())
-            nsr_descriptor = self._create_nsr_descriptor_from_nsd(nsd, ns_request, nsr_id)
+            nsr_descriptor = self._create_nsr_descriptor_from_nsd(
+                nsd, ns_request, nsr_id, session
+            )
 
             # Create VNFRs
             needed_vnfds = {}
 
             # Create VNFRs
             needed_vnfds = {}
@@ -242,7 +338,11 @@ class NsrTopic(BaseTopic):
             for vnfp in vnf_profiles:
                 vnfd_id = vnfp.get("vnfd-id")
                 vnf_index = vnfp.get("id")
             for vnfp in vnf_profiles:
                 vnfd_id = vnfp.get("vnfd-id")
                 vnf_index = vnfp.get("id")
-                step = "getting vnfd id='{}' constituent-vnfd='{}' from database".format(vnfd_id, vnf_index)
+                step = (
+                    "getting vnfd id='{}' constituent-vnfd='{}' from database".format(
+                        vnfd_id, vnf_index
+                    )
+                )
                 if vnfd_id not in needed_vnfds:
                     vnfd = self._get_vnfd_from_db(vnfd_id, session)
                     needed_vnfds[vnfd_id] = vnfd
                 if vnfd_id not in needed_vnfds:
                     vnfd = self._get_vnfd_from_db(vnfd_id, session)
                     needed_vnfds[vnfd_id] = vnfd
@@ -250,11 +350,22 @@ class NsrTopic(BaseTopic):
                 else:
                     vnfd = needed_vnfds[vnfd_id]
 
                 else:
                     vnfd = needed_vnfds[vnfd_id]
 
-                step = "filling vnfr  vnfd-id='{}' constituent-vnfd='{}'".format(vnfd_id, vnf_index)
-                vnfr_descriptor = self._create_vnfr_descriptor_from_vnfd(nsd, vnfd, vnfd_id, vnf_index, nsr_descriptor,
-                                                                         ns_request, ns_k8s_namespace)
+                step = "filling vnfr  vnfd-id='{}' constituent-vnfd='{}'".format(
+                    vnfd_id, vnf_index
+                )
+                vnfr_descriptor = self._create_vnfr_descriptor_from_vnfd(
+                    nsd,
+                    vnfd,
+                    vnfd_id,
+                    vnf_index,
+                    nsr_descriptor,
+                    ns_request,
+                    ns_k8s_namespace,
+                )
 
 
-                step = "creating vnfr vnfd-id='{}' constituent-vnfd='{}' at database".format(vnfd_id, vnf_index)
+                step = "creating vnfr vnfd-id='{}' constituent-vnfd='{}' at database".format(
+                    vnfd_id, vnf_index
+                )
                 self._add_vnfr_to_db(vnfr_descriptor, rollback, session)
                 nsr_descriptor["constituent-vnfr-ref"].append(vnfr_descriptor["id"])
 
                 self._add_vnfr_to_db(vnfr_descriptor, rollback, session)
                 nsr_descriptor["constituent-vnfr-ref"].append(vnfr_descriptor["id"])
 
@@ -265,7 +376,13 @@ class NsrTopic(BaseTopic):
             self.fs.mkdir(nsr_id)
 
             return nsr_id, None
             self.fs.mkdir(nsr_id)
 
             return nsr_id, None
-        except (ValidationError, EngineException, DbException, MsgException, FsException) as e:
+        except (
+            ValidationError,
+            EngineException,
+            DbException,
+            MsgException,
+            FsException,
+        ) as e:
             raise type(e)("{} while '{}'".format(e, step), http_code=e.http_code)
 
     def _get_nsd_from_db(self, nsd_id, session):
             raise type(e)("{} while '{}'".format(e, step), http_code=e.http_code)
 
     def _get_nsd_from_db(self, nsd_id, session):
@@ -281,22 +398,31 @@ class NsrTopic(BaseTopic):
         return vnfd
 
     def _add_nsr_to_db(self, nsr_descriptor, rollback, session):
         return vnfd
 
     def _add_nsr_to_db(self, nsr_descriptor, rollback, session):
-        self.format_on_new(nsr_descriptor, session["project_id"], make_public=session["public"])
+        self.format_on_new(
+            nsr_descriptor, session["project_id"], make_public=session["public"]
+        )
         self.db.create("nsrs", nsr_descriptor)
         rollback.append({"topic": "nsrs", "_id": nsr_descriptor["id"]})
 
     def _add_vnfr_to_db(self, vnfr_descriptor, rollback, session):
         self.db.create("nsrs", nsr_descriptor)
         rollback.append({"topic": "nsrs", "_id": nsr_descriptor["id"]})
 
     def _add_vnfr_to_db(self, vnfr_descriptor, rollback, session):
-        self.format_on_new(vnfr_descriptor, session["project_id"], make_public=session["public"])
+        self.format_on_new(
+            vnfr_descriptor, session["project_id"], make_public=session["public"]
+        )
         self.db.create("vnfrs", vnfr_descriptor)
         rollback.append({"topic": "vnfrs", "_id": vnfr_descriptor["id"]})
 
     def _check_nsd_operational_state(self, nsd, ns_request):
         if nsd["_admin"]["operationalState"] == "DISABLED":
         self.db.create("vnfrs", vnfr_descriptor)
         rollback.append({"topic": "vnfrs", "_id": vnfr_descriptor["id"]})
 
     def _check_nsd_operational_state(self, nsd, ns_request):
         if nsd["_admin"]["operationalState"] == "DISABLED":
-            raise EngineException("nsd with id '{}' is DISABLED, and thus cannot be used to create "
-                                  "a network service".format(ns_request["nsdId"]), http_code=HTTPStatus.CONFLICT)
+            raise EngineException(
+                "nsd with id '{}' is DISABLED, and thus cannot be used to create "
+                "a network service".format(ns_request["nsdId"]),
+                http_code=HTTPStatus.CONFLICT,
+            )
 
     def _get_ns_k8s_namespace(self, nsd, ns_request, session):
 
     def _get_ns_k8s_namespace(self, nsd, ns_request, session):
-        additional_params, _ = self._format_additional_params(ns_request, descriptor=nsd)
+        additional_params, _ = self._format_additional_params(
+            ns_request, descriptor=nsd
+        )
         # use for k8s-namespace from ns_request or additionalParamsForNs. By default, the project_id
         ns_k8s_namespace = session["project_id"][0] if session["project_id"] else None
         if ns_request and ns_request.get("k8s-namespace"):
         # use for k8s-namespace from ns_request or additionalParamsForNs. By default, the project_id
         ns_k8s_namespace = session["project_id"][0] if session["project_id"] else None
         if ns_request and ns_request.get("k8s-namespace"):
@@ -306,9 +432,11 @@ class NsrTopic(BaseTopic):
 
         return ns_k8s_namespace
 
 
         return ns_k8s_namespace
 
-    def _create_nsr_descriptor_from_nsd(self, nsd, ns_request, nsr_id):
+    def _create_nsr_descriptor_from_nsd(self, nsd, ns_request, nsr_id, session):
         now = time()
         now = time()
-        additional_params, _ = self._format_additional_params(ns_request, descriptor=nsd)
+        additional_params, _ = self._format_additional_params(
+            ns_request, descriptor=nsd
+        )
 
         nsr_descriptor = {
             "name": ns_request["nsName"],
 
         nsr_descriptor = {
             "name": ns_request["nsName"],
@@ -361,16 +489,21 @@ class NsrTopic(BaseTopic):
             for vnf_profile in vnf_profiles:
                 for vlc in vnf_profile.get("virtual-link-connectivity", ()):
                     for cpd in vlc.get("constituent-cpd-id", ()):
             for vnf_profile in vnf_profiles:
                 for vlc in vnf_profile.get("virtual-link-connectivity", ()):
                     for cpd in vlc.get("constituent-cpd-id", ()):
-                        all_vld_connection_point_data[vlc.get("virtual-link-profile-id")].append({
-                            "member-vnf-index-ref": cpd.get("constituent-base-element-id"),
-                            "vnfd-connection-point-ref": cpd.get("constituent-cpd-id"),
-                            "vnfd-id-ref": vnf_profile.get("vnfd-id")
-                        })
-
-                vnfd = self.db.get_one("vnfds",
-                                       {"id": vnf_profile.get("vnfd-id")},
-                                       fail_on_empty=True,
-                                       fail_on_more=True)
+                        all_vld_connection_point_data[
+                            vlc.get("virtual-link-profile-id")
+                        ].append(
+                            {
+                                "member-vnf-index-ref": cpd.get(
+                                    "constituent-base-element-id"
+                                ),
+                                "vnfd-connection-point-ref": cpd.get(
+                                    "constituent-cpd-id"
+                                ),
+                                "vnfd-id-ref": vnf_profile.get("vnfd-id"),
+                            }
+                        )
+
+                vnfd = self._get_vnfd_from_db(vnf_profile.get("vnfd-id"), session)
 
                 for vdu in vnfd.get("vdu", ()):
                     flavor_data = {}
 
                 for vdu in vnfd.get("vdu", ()):
                     flavor_data = {}
@@ -385,30 +518,59 @@ class NsrTopic(BaseTopic):
                         if vsd.get("id") == vdu.get("virtual-storage-desc", [[]])[0]:
                             vdu_virtual_storage = vsd
                     # Get this vdu vcpus, memory and storage info for flavor_data
                         if vsd.get("id") == vdu.get("virtual-storage-desc", [[]])[0]:
                             vdu_virtual_storage = vsd
                     # Get this vdu vcpus, memory and storage info for flavor_data
-                    if vdu_virtual_compute.get("virtual-cpu", {}).get("num-virtual-cpu"):
-                        flavor_data["vcpu-count"] = vdu_virtual_compute["virtual-cpu"]["num-virtual-cpu"]
+                    if vdu_virtual_compute.get("virtual-cpu", {}).get(
+                        "num-virtual-cpu"
+                    ):
+                        flavor_data["vcpu-count"] = vdu_virtual_compute["virtual-cpu"][
+                            "num-virtual-cpu"
+                        ]
                     if vdu_virtual_compute.get("virtual-memory", {}).get("size"):
                     if vdu_virtual_compute.get("virtual-memory", {}).get("size"):
-                        flavor_data["memory-mb"] = float(vdu_virtual_compute["virtual-memory"]["size"]) * 1024.0
+                        flavor_data["memory-mb"] = (
+                            float(vdu_virtual_compute["virtual-memory"]["size"])
+                            * 1024.0
+                        )
                     if vdu_virtual_storage.get("size-of-storage"):
                     if vdu_virtual_storage.get("size-of-storage"):
-                        flavor_data["storage-gb"] = vdu_virtual_storage["size-of-storage"]
+                        flavor_data["storage-gb"] = vdu_virtual_storage[
+                            "size-of-storage"
+                        ]
                     # Get this vdu EPA info for guest_epa
                     if vdu_virtual_compute.get("virtual-cpu", {}).get("cpu-quota"):
                     # Get this vdu EPA info for guest_epa
                     if vdu_virtual_compute.get("virtual-cpu", {}).get("cpu-quota"):
-                        guest_epa["cpu-quota"] = vdu_virtual_compute["virtual-cpu"]["cpu-quota"]
+                        guest_epa["cpu-quota"] = vdu_virtual_compute["virtual-cpu"][
+                            "cpu-quota"
+                        ]
                     if vdu_virtual_compute.get("virtual-cpu", {}).get("pinning"):
                         vcpu_pinning = vdu_virtual_compute["virtual-cpu"]["pinning"]
                         if vcpu_pinning.get("thread-policy"):
                     if vdu_virtual_compute.get("virtual-cpu", {}).get("pinning"):
                         vcpu_pinning = vdu_virtual_compute["virtual-cpu"]["pinning"]
                         if vcpu_pinning.get("thread-policy"):
-                            guest_epa["cpu-thread-pinning-policy"] = vcpu_pinning["thread-policy"]
+                            guest_epa["cpu-thread-pinning-policy"] = vcpu_pinning[
+                                "thread-policy"
+                            ]
                         if vcpu_pinning.get("policy"):
                         if vcpu_pinning.get("policy"):
-                            cpu_policy = "SHARED" if vcpu_pinning["policy"] == "dynamic" else "DEDICATED"
+                            cpu_policy = (
+                                "SHARED"
+                                if vcpu_pinning["policy"] == "dynamic"
+                                else "DEDICATED"
+                            )
                             guest_epa["cpu-pinning-policy"] = cpu_policy
                     if vdu_virtual_compute.get("virtual-memory", {}).get("mem-quota"):
                             guest_epa["cpu-pinning-policy"] = cpu_policy
                     if vdu_virtual_compute.get("virtual-memory", {}).get("mem-quota"):
-                        guest_epa["mem-quota"] = vdu_virtual_compute["virtual-memory"]["mem-quota"]
-                    if vdu_virtual_compute.get("virtual-memory", {}).get("mempage-size"):
-                        guest_epa["mempage-size"] = vdu_virtual_compute["virtual-memory"]["mempage-size"]
-                    if vdu_virtual_compute.get("virtual-memory", {}).get("numa-node-policy"):
-                        guest_epa["numa-node-policy"] = vdu_virtual_compute["virtual-memory"]["numa-node-policy"]
+                        guest_epa["mem-quota"] = vdu_virtual_compute["virtual-memory"][
+                            "mem-quota"
+                        ]
+                    if vdu_virtual_compute.get("virtual-memory", {}).get(
+                        "mempage-size"
+                    ):
+                        guest_epa["mempage-size"] = vdu_virtual_compute[
+                            "virtual-memory"
+                        ]["mempage-size"]
+                    if vdu_virtual_compute.get("virtual-memory", {}).get(
+                        "numa-node-policy"
+                    ):
+                        guest_epa["numa-node-policy"] = vdu_virtual_compute[
+                            "virtual-memory"
+                        ]["numa-node-policy"]
                     if vdu_virtual_storage.get("disk-io-quota"):
                     if vdu_virtual_storage.get("disk-io-quota"):
-                        guest_epa["disk-io-quota"] = vdu_virtual_storage["disk-io-quota"]
+                        guest_epa["disk-io-quota"] = vdu_virtual_storage[
+                            "disk-io-quota"
+                        ]
 
                     if guest_epa:
                         flavor_data["guest-epa"] = guest_epa
 
                     if guest_epa:
                         flavor_data["guest-epa"] = guest_epa
@@ -428,15 +590,18 @@ class NsrTopic(BaseTopic):
                         self._add_image_to_nsr(nsr_descriptor, image_data)
 
             for vld in nsr_vld:
                         self._add_image_to_nsr(nsr_descriptor, image_data)
 
             for vld in nsr_vld:
-                vld["vnfd-connection-point-ref"] = all_vld_connection_point_data.get(vld.get("id"), [])
+                vld["vnfd-connection-point-ref"] = all_vld_connection_point_data.get(
+                    vld.get("id"), []
+                )
                 vld["name"] = vld["id"]
             nsr_descriptor["vld"] = nsr_vld
 
         return nsr_descriptor
 
     def _get_image_data_from_vnfd(self, vnfd, sw_image_id):
                 vld["name"] = vld["id"]
             nsr_descriptor["vld"] = nsr_vld
 
         return nsr_descriptor
 
     def _get_image_data_from_vnfd(self, vnfd, sw_image_id):
-        sw_image_desc = utils.find_in_list(vnfd.get("sw-image-desc", ()),
-                                           lambda sw: sw["id"] == sw_image_id)
+        sw_image_desc = utils.find_in_list(
+            vnfd.get("sw-image-desc", ()), lambda sw: sw["id"] == sw_image_id
+        )
         image_data = {}
         if sw_image_desc.get("image"):
             image_data["image"] = sw_image_desc["image"]
         image_data = {}
         if sw_image_desc.get("image"):
             image_data["image"] = sw_image_desc["image"]
@@ -450,18 +615,34 @@ class NsrTopic(BaseTopic):
         """
         Adds image to nsr checking first it is not already added
         """
         """
         Adds image to nsr checking first it is not already added
         """
-        img = next((f for f in nsr_descriptor["image"] if
-                    all(f.get(k) == image_data[k] for k in image_data)), None)
+        img = next(
+            (
+                f
+                for f in nsr_descriptor["image"]
+                if all(f.get(k) == image_data[k] for k in image_data)
+            ),
+            None,
+        )
         if not img:
             image_data["id"] = str(len(nsr_descriptor["image"]))
             nsr_descriptor["image"].append(image_data)
 
         if not img:
             image_data["id"] = str(len(nsr_descriptor["image"]))
             nsr_descriptor["image"].append(image_data)
 
-    def _create_vnfr_descriptor_from_vnfd(self, nsd, vnfd, vnfd_id, vnf_index, nsr_descriptor,
-                                          ns_request, ns_k8s_namespace):
+    def _create_vnfr_descriptor_from_vnfd(
+        self,
+        nsd,
+        vnfd,
+        vnfd_id,
+        vnf_index,
+        nsr_descriptor,
+        ns_request,
+        ns_k8s_namespace,
+    ):
         vnfr_id = str(uuid4())
         nsr_id = nsr_descriptor["id"]
         now = time()
         vnfr_id = str(uuid4())
         nsr_id = nsr_descriptor["id"]
         now = time()
-        additional_params, vnf_params = self._format_additional_params(ns_request, vnf_index, descriptor=vnfd)
+        additional_params, vnf_params = self._format_additional_params(
+            ns_request, vnf_index, descriptor=vnfd
+        )
 
         vnfr_descriptor = {
             "id": vnfr_id,
 
         vnfr_descriptor = {
             "id": vnfr_id,
@@ -474,6 +655,7 @@ class NsrTopic(BaseTopic):
             "vnfd-ref": vnfd_id,
             "vnfd-id": vnfd["_id"],  # not at OSM model, but useful
             "vim-account-id": None,
             "vnfd-ref": vnfd_id,
             "vnfd-id": vnfd["_id"],  # not at OSM model, but useful
             "vim-account-id": None,
+            "vca-id": None,
             "vdur": [],
             "connection-point": [],
             "ip-address": None,  # mgmt-interface filled by LCM
             "vdur": [],
             "connection-point": [],
             "ip-address": None,  # mgmt-interface filled by LCM
@@ -509,25 +691,33 @@ class NsrTopic(BaseTopic):
             all_k8s_cluster_nets_cpds = {}
             for cpd in get_iterable(vnfd.get("ext-cpd")):
                 if cpd.get("k8s-cluster-net"):
             all_k8s_cluster_nets_cpds = {}
             for cpd in get_iterable(vnfd.get("ext-cpd")):
                 if cpd.get("k8s-cluster-net"):
-                    all_k8s_cluster_nets_cpds[cpd.get("k8s-cluster-net")] = cpd.get("id")
+                    all_k8s_cluster_nets_cpds[cpd.get("k8s-cluster-net")] = cpd.get(
+                        "id"
+                    )
             for net in get_iterable(vnfr_descriptor["k8s-cluster"].get("nets")):
                 if net.get("id") in all_k8s_cluster_nets_cpds:
             for net in get_iterable(vnfr_descriptor["k8s-cluster"].get("nets")):
                 if net.get("id") in all_k8s_cluster_nets_cpds:
-                    net["external-connection-point-ref"] = all_k8s_cluster_nets_cpds[net.get("id")]
+                    net["external-connection-point-ref"] = all_k8s_cluster_nets_cpds[
+                        net.get("id")
+                    ]
 
         # update kdus
         for kdu in get_iterable(vnfd.get("kdu")):
 
         # update kdus
         for kdu in get_iterable(vnfd.get("kdu")):
-            additional_params, kdu_params = self._format_additional_params(ns_request,
-                                                                           vnf_index,
-                                                                           kdu_name=kdu["name"],
-                                                                           descriptor=vnfd)
+            additional_params, kdu_params = self._format_additional_params(
+                ns_request, vnf_index, kdu_name=kdu["name"], descriptor=vnfd
+            )
             kdu_k8s_namespace = vnf_k8s_namespace
             kdu_model = kdu_params.get("kdu_model") if kdu_params else None
             if kdu_params and kdu_params.get("k8s-namespace"):
                 kdu_k8s_namespace = kdu_params["k8s-namespace"]
 
             kdu_k8s_namespace = vnf_k8s_namespace
             kdu_model = kdu_params.get("kdu_model") if kdu_params else None
             if kdu_params and kdu_params.get("k8s-namespace"):
                 kdu_k8s_namespace = kdu_params["k8s-namespace"]
 
+            kdu_deployment_name = ""
+            if kdu_params and kdu_params.get("kdu-deployment-name"):
+                kdu_deployment_name = kdu_params.get("kdu-deployment-name")
+
             kdur = {
                 "additionalParams": additional_params,
                 "k8s-namespace": kdu_k8s_namespace,
             kdur = {
                 "additionalParams": additional_params,
                 "k8s-namespace": kdu_k8s_namespace,
+                "kdu-deployment-name": kdu_deployment_name,
                 "kdu-name": kdu["name"],
                 # TODO      "name": ""     Name of the VDU in the VIM
                 "ip-address": None,  # mgmt-interface filled by LCM
                 "kdu-name": kdu["name"],
                 # TODO      "name": ""     Name of the VDU in the VIM
                 "ip-address": None,  # mgmt-interface filled by LCM
@@ -547,8 +737,36 @@ class NsrTopic(BaseTopic):
         vnfd_mgmt_cp = vnfd.get("mgmt-cp")
 
         for vdu in vnfd.get("vdu", ()):
         vnfd_mgmt_cp = vnfd.get("mgmt-cp")
 
         for vdu in vnfd.get("vdu", ()):
+            vdu_mgmt_cp = []
+            try:
+                configs = vnfd.get("df")[0]["lcm-operations-configuration"][
+                    "operate-vnf-op-config"
+                ]["day1-2"]
+                vdu_config = utils.find_in_list(
+                    configs, lambda config: config["id"] == vdu["id"]
+                )
+            except Exception:
+                vdu_config = None
+
+            try:
+                vdu_instantiation_level = utils.find_in_list(
+                    vnfd.get("df")[0]["instantiation-level"][0]["vdu-level"],
+                    lambda a_vdu_profile: a_vdu_profile["vdu-id"] == vdu["id"],
+                )
+            except Exception:
+                vdu_instantiation_level = None
+
+            if vdu_config:
+                external_connection_ee = utils.filter_in_list(
+                    vdu_config.get("execution-environment-list", []),
+                    lambda ee: "external-connection-point-ref" in ee,
+                )
+                for ee in external_connection_ee:
+                    vdu_mgmt_cp.append(ee["external-connection-point-ref"])
+
             additional_params, vdu_params = self._format_additional_params(
             additional_params, vdu_params = self._format_additional_params(
-                ns_request, vnf_index, vdu_id=vdu["id"], descriptor=vnfd)
+                ns_request, vnf_index, vdu_id=vdu["id"], descriptor=vnfd
+            )
             vdur = {
                 "vdu-id-ref": vdu["id"],
                 # TODO      "name": ""     Name of the VDU in the VIM
             vdur = {
                 "vdu-id-ref": vdu["id"],
                 # TODO      "name": ""     Name of the VDU in the VIM
@@ -557,12 +775,14 @@ class NsrTopic(BaseTopic):
                 "internal-connection-point": [],
                 "interfaces": [],
                 "additionalParams": additional_params,
                 "internal-connection-point": [],
                 "interfaces": [],
                 "additionalParams": additional_params,
-                "vdu-name": vdu["name"]
+                "vdu-name": vdu["name"],
             }
             if vdu_params and vdu_params.get("config-units"):
                 vdur["config-units"] = vdu_params["config-units"]
             if deep_get(vdu, ("supplemental-boot-data", "boot-data-drive")):
             }
             if vdu_params and vdu_params.get("config-units"):
                 vdur["config-units"] = vdu_params["config-units"]
             if deep_get(vdu, ("supplemental-boot-data", "boot-data-drive")):
-                vdur["boot-data-drive"] = vdu["supplemental-boot-data"]["boot-data-drive"]
+                vdur["boot-data-drive"] = vdu["supplemental-boot-data"][
+                    "boot-data-drive"
+                ]
             if vdu.get("pdu-type"):
                 vdur["pdu-type"] = vdu["pdu-type"]
                 vdur["name"] = vdu["pdu-type"]
             if vdu.get("pdu-type"):
                 vdur["pdu-type"] = vdu["pdu-type"]
                 vdur["name"] = vdu["pdu-type"]
@@ -574,31 +794,58 @@ class NsrTopic(BaseTopic):
                     "name": icp.get("id"),
                 }
 
                     "name": icp.get("id"),
                 }
 
-                if "port-security-enabled" in icp:
-                    vdu_icp["port-security-enabled"] = icp["port-security-enabled"]
-
-                if "port-security-disable-strategy" in icp:
-                    vdu_icp["port-security-disable-strategy"] = icp["port-security-disable-strategy"]
-
                 vdur["internal-connection-point"].append(vdu_icp)
 
                 for iface in icp.get("virtual-network-interface-requirement", ()):
                     iface_fields = ("name", "mac-address")
                 vdur["internal-connection-point"].append(vdu_icp)
 
                 for iface in icp.get("virtual-network-interface-requirement", ()):
                     iface_fields = ("name", "mac-address")
-                    vdu_iface = {x: iface[x] for x in iface_fields if iface.get(x) is not None}
+                    vdu_iface = {
+                        x: iface[x] for x in iface_fields if iface.get(x) is not None
+                    }
 
                     vdu_iface["internal-connection-point-ref"] = vdu_icp["id"]
 
                     vdu_iface["internal-connection-point-ref"] = vdu_icp["id"]
+                    if "port-security-enabled" in icp:
+                        vdu_iface["port-security-enabled"] = icp[
+                            "port-security-enabled"
+                        ]
+
+                    if "port-security-disable-strategy" in icp:
+                        vdu_iface["port-security-disable-strategy"] = icp[
+                            "port-security-disable-strategy"
+                        ]
+
                     for ext_cp in vnfd.get("ext-cpd", ()):
                         if not ext_cp.get("int-cpd"):
                             continue
                         if ext_cp["int-cpd"].get("vdu-id") != vdu["id"]:
                             continue
                         if icp["id"] == ext_cp["int-cpd"].get("cpd"):
                     for ext_cp in vnfd.get("ext-cpd", ()):
                         if not ext_cp.get("int-cpd"):
                             continue
                         if ext_cp["int-cpd"].get("vdu-id") != vdu["id"]:
                             continue
                         if icp["id"] == ext_cp["int-cpd"].get("cpd"):
-                            vdu_iface["external-connection-point-ref"] = ext_cp.get("id")
+                            vdu_iface["external-connection-point-ref"] = ext_cp.get(
+                                "id"
+                            )
+
+                            if "port-security-enabled" in ext_cp:
+                                vdu_iface["port-security-enabled"] = ext_cp[
+                                    "port-security-enabled"
+                                ]
+
+                            if "port-security-disable-strategy" in ext_cp:
+                                vdu_iface["port-security-disable-strategy"] = ext_cp[
+                                    "port-security-disable-strategy"
+                                ]
+
                             break
 
                             break
 
-                    if vnfd_mgmt_cp and vdu_iface.get("external-connection-point-ref") == vnfd_mgmt_cp:
+                    if (
+                        vnfd_mgmt_cp
+                        and vdu_iface.get("external-connection-point-ref")
+                        == vnfd_mgmt_cp
+                    ):
                         vdu_iface["mgmt-vnf"] = True
                         vdu_iface["mgmt-vnf"] = True
-                        vdu_iface["mgmt-interface"] = True  # TODO change to mgmt-vdu
+                        vdu_iface["mgmt-interface"] = True
+
+                    for ecp in vdu_mgmt_cp:
+                        if vdu_iface.get("external-connection-point-ref") == ecp:
+                            vdu_iface["mgmt-interface"] = True
 
                     if iface.get("virtual-interface"):
                         vdu_iface.update(deepcopy(iface["virtual-interface"]))
 
                     if iface.get("virtual-interface"):
                         vdu_iface.update(deepcopy(iface["virtual-interface"]))
@@ -609,24 +856,40 @@ class NsrTopic(BaseTopic):
                         # TODO: Change for multiple df support
                         for df in get_iterable(nsd.get("df")):
                             for vnf_profile in get_iterable(df.get("vnf-profile")):
                         # TODO: Change for multiple df support
                         for df in get_iterable(nsd.get("df")):
                             for vnf_profile in get_iterable(df.get("vnf-profile")):
-                                for vlc_index, vlc in \
-                                        enumerate(get_iterable(vnf_profile.get("virtual-link-connectivity"))):
-                                    for cpd in get_iterable(vlc.get("constituent-cpd-id")):
-                                        if cpd.get("constituent-cpd-id") == iface_ext_cp:
-                                            vdu_iface["ns-vld-id"] = vlc.get("virtual-link-profile-id")
+                                for vlc_index, vlc in enumerate(
+                                    get_iterable(
+                                        vnf_profile.get("virtual-link-connectivity")
+                                    )
+                                ):
+                                    for cpd in get_iterable(
+                                        vlc.get("constituent-cpd-id")
+                                    ):
+                                        if (
+                                            cpd.get("constituent-cpd-id")
+                                            == iface_ext_cp
+                                        ):
+                                            vdu_iface["ns-vld-id"] = vlc.get(
+                                                "virtual-link-profile-id"
+                                            )
                                             # if iface type is SRIOV or PASSTHROUGH, set pci-interfaces flag to True
                                             # if iface type is SRIOV or PASSTHROUGH, set pci-interfaces flag to True
-                                            if vdu_iface.get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
-                                                nsr_descriptor["vld"][vlc_index]["pci-interfaces"] = True
+                                            if vdu_iface.get("type") in (
+                                                "SR-IOV",
+                                                "PCI-PASSTHROUGH",
+                                            ):
+                                                nsr_descriptor["vld"][vlc_index][
+                                                    "pci-interfaces"
+                                                ] = True
                                             break
                     elif vdu_iface.get("internal-connection-point-ref"):
                         vdu_iface["vnf-vld-id"] = icp.get("int-virtual-link-desc")
                         # TODO: store fixed IP address in the record (if it exists in the ICP)
                         # if iface type is SRIOV or PASSTHROUGH, set pci-interfaces flag to True
                         if vdu_iface.get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
                                             break
                     elif vdu_iface.get("internal-connection-point-ref"):
                         vdu_iface["vnf-vld-id"] = icp.get("int-virtual-link-desc")
                         # TODO: store fixed IP address in the record (if it exists in the ICP)
                         # if iface type is SRIOV or PASSTHROUGH, set pci-interfaces flag to True
                         if vdu_iface.get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
-                            ivld_index = utils.find_index_in_list(vnfd.get("int-virtual-link-desc", ()),
-                                                                  lambda ivld:
-                                                                  ivld["id"] == icp.get("int-virtual-link-desc")
-                                                                  )
+                            ivld_index = utils.find_index_in_list(
+                                vnfd.get("int-virtual-link-desc", ()),
+                                lambda ivld: ivld["id"]
+                                == icp.get("int-virtual-link-desc"),
+                            )
                             vnfr_descriptor["vld"][ivld_index]["pci-interfaces"] = True
 
                     vdur["interfaces"].append(vdu_iface)
                             vnfr_descriptor["vld"][ivld_index]["pci-interfaces"] = True
 
                     vdur["interfaces"].append(vdu_iface)
@@ -634,10 +897,11 @@ class NsrTopic(BaseTopic):
             if vdu.get("sw-image-desc"):
                 sw_image = utils.find_in_list(
                     vnfd.get("sw-image-desc", ()),
             if vdu.get("sw-image-desc"):
                 sw_image = utils.find_in_list(
                     vnfd.get("sw-image-desc", ()),
-                    lambda image: image["id"] == vdu.get("sw-image-desc"))
+                    lambda image: image["id"] == vdu.get("sw-image-desc"),
+                )
                 nsr_sw_image_data = utils.find_in_list(
                     nsr_descriptor["image"],
                 nsr_sw_image_data = utils.find_in_list(
                     nsr_descriptor["image"],
-                    lambda nsr_image: (nsr_image.get("image") == sw_image.get("image"))
+                    lambda nsr_image: (nsr_image.get("image") == sw_image.get("image")),
                 )
                 vdur["ns-image-id"] = nsr_sw_image_data["id"]
 
                 )
                 vdur["ns-image-id"] = nsr_sw_image_data["id"]
 
@@ -646,10 +910,13 @@ class NsrTopic(BaseTopic):
                 for alt_image_id in vdu.get("alternative-sw-image-desc", ()):
                     sw_image = utils.find_in_list(
                         vnfd.get("sw-image-desc", ()),
                 for alt_image_id in vdu.get("alternative-sw-image-desc", ()):
                     sw_image = utils.find_in_list(
                         vnfd.get("sw-image-desc", ()),
-                        lambda image: image["id"] == alt_image_id)
+                        lambda image: image["id"] == alt_image_id,
+                    )
                     nsr_sw_image_data = utils.find_in_list(
                         nsr_descriptor["image"],
                     nsr_sw_image_data = utils.find_in_list(
                         nsr_descriptor["image"],
-                        lambda nsr_image: (nsr_image.get("image") == sw_image.get("image"))
+                        lambda nsr_image: (
+                            nsr_image.get("image") == sw_image.get("image")
+                        ),
                     )
                     alt_image_ids.append(nsr_sw_image_data["id"])
                 vdur["alt-image-ids"] = alt_image_ids
                     )
                     alt_image_ids.append(nsr_sw_image_data["id"])
                 vdur["alt-image-ids"] = alt_image_ids
@@ -657,12 +924,17 @@ class NsrTopic(BaseTopic):
             flavor_data_name = vdu["id"][:56] + "-flv"
             nsr_flavor_desc = utils.find_in_list(
                 nsr_descriptor["flavor"],
             flavor_data_name = vdu["id"][:56] + "-flv"
             nsr_flavor_desc = utils.find_in_list(
                 nsr_descriptor["flavor"],
-                lambda flavor: flavor["name"] == flavor_data_name)
+                lambda flavor: flavor["name"] == flavor_data_name,
+            )
 
             if nsr_flavor_desc:
                 vdur["ns-flavor-id"] = nsr_flavor_desc["id"]
 
 
             if nsr_flavor_desc:
                 vdur["ns-flavor-id"] = nsr_flavor_desc["id"]
 
-            count = int(vdu.get("count", 1))
+            if vdu_instantiation_level:
+                count = vdu_instantiation_level.get("number-of-instances")
+            else:
+                count = 1
+
             for index in range(0, count):
                 vdur = deepcopy(vdur)
                 for iface in vdur["interfaces"]:
             for index in range(0, count):
                 vdur = deepcopy(vdur)
                 for iface in vdur["interfaces"]:
@@ -678,8 +950,45 @@ class NsrTopic(BaseTopic):
 
         return vnfr_descriptor
 
 
         return vnfr_descriptor
 
+    def vca_status_refresh(self, session, ns_instance_content, filter_q):
+        """
+        vcaStatus in ns_instance_content maybe stale, check if it is stale and create lcm op
+        to refresh vca status by sending message to LCM when it is stale. Ignore otherwise.
+        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
+        :param ns_instance_content:  ns instance content
+        :param filter_q: dict: query parameter containing vcaStatus-refresh as true or false
+        :return: None
+        """
+        time_now, time_delta = time(), time() - ns_instance_content["_admin"]["modified"]
+        force_refresh = isinstance(filter_q, dict) and filter_q.get('vcaStatusRefresh') == 'true'
+        threshold_reached = time_delta > 120
+        if force_refresh or threshold_reached:
+            operation, _id = "vca_status_refresh", ns_instance_content["_id"]
+            ns_instance_content["_admin"]["modified"] = time_now
+            self.db.set_one(self.topic, {"_id": _id}, ns_instance_content)
+            nslcmop_desc = NsLcmOpTopic._create_nslcmop(_id, operation, None)
+            self.format_on_new(nslcmop_desc, session["project_id"], make_public=session["public"])
+            nslcmop_desc["_admin"].pop("nsState")
+            self.msg.write("ns", operation, nslcmop_desc)
+        return
+
+    def show(self, session, _id, filter_q=None, api_req=False):
+        """
+        Get complete information on an ns instance.
+        :param session: contains "username", "admin", "force", "public", "project_id", "set_project"
+        :param _id: string, ns instance id
+        :param filter_q: dict: query parameter containing vcaStatusRefresh as true or false
+        :param api_req: True if this call is serving an external API request. False if serving internal request.
+        :return: dictionary, raise exception if not found.
+        """
+        ns_instance_content = super().show(session, _id, api_req)
+        self.vca_status_refresh(session, ns_instance_content, filter_q)
+        return ns_instance_content
+
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
-        raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
 
 class VnfrTopic(BaseTopic):
 
 
 class VnfrTopic(BaseTopic):
@@ -690,20 +999,26 @@ class VnfrTopic(BaseTopic):
         BaseTopic.__init__(self, db, fs, msg, auth)
 
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
         BaseTopic.__init__(self, db, fs, msg, auth)
 
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
-        raise EngineException("Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
-        raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
     def new(self, rollback, session, indata=None, kwargs=None, headers=None):
         # Not used because vnfrs are created and deleted by NsrTopic class directly
 
     def new(self, rollback, session, indata=None, kwargs=None, headers=None):
         # Not used because vnfrs are created and deleted by NsrTopic class directly
-        raise EngineException("Method new called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method new called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
 
 class NsLcmOpTopic(BaseTopic):
     topic = "nslcmops"
     topic_msg = "ns"
 
 
 class NsLcmOpTopic(BaseTopic):
     topic = "nslcmops"
     topic_msg = "ns"
-    operation_schema = {    # mapping between operation and jsonschema to validate
+    operation_schema = {  # mapping between operation and jsonschema to validate
         "instantiate": ns_instantiate,
         "action": ns_action,
         "scale": ns_scale,
         "instantiate": ns_instantiate,
         "action": ns_action,
         "scale": ns_scale,
@@ -732,40 +1047,58 @@ class NsLcmOpTopic(BaseTopic):
         nsd = nsr["nsd"]
         # check vnf_member_index
         if indata.get("vnf_member_index"):
         nsd = nsr["nsd"]
         # check vnf_member_index
         if indata.get("vnf_member_index"):
-            indata["member_vnf_index"] = indata.pop("vnf_member_index")  # for backward compatibility
+            indata["member_vnf_index"] = indata.pop(
+                "vnf_member_index"
+            )  # for backward compatibility
         if indata.get("member_vnf_index"):
         if indata.get("member_vnf_index"):
-            vnfd = self._get_vnfd_from_vnf_member_index(indata["member_vnf_index"], nsr["_id"])
+            vnfd = self._get_vnfd_from_vnf_member_index(
+                indata["member_vnf_index"], nsr["_id"]
+            )
             try:
             try:
-                configs = vnfd.get("df")[0]["lcm-operations-configuration"]["operate-vnf-op-config"]["day1-2"]
+                configs = vnfd.get("df")[0]["lcm-operations-configuration"][
+                    "operate-vnf-op-config"
+                ]["day1-2"]
             except Exception:
                 configs = []
 
             if indata.get("vdu_id"):
                 self._check_valid_vdu(vnfd, indata["vdu_id"])
                 descriptor_configuration = utils.find_in_list(
             except Exception:
                 configs = []
 
             if indata.get("vdu_id"):
                 self._check_valid_vdu(vnfd, indata["vdu_id"])
                 descriptor_configuration = utils.find_in_list(
-                    configs,
-                    lambda config: config["id"] == indata["vdu_id"]
-                ).get("config-primitive")
+                    configs, lambda config: config["id"] == indata["vdu_id"]
+                )
             elif indata.get("kdu_name"):
                 self._check_valid_kdu(vnfd, indata["kdu_name"])
                 descriptor_configuration = utils.find_in_list(
             elif indata.get("kdu_name"):
                 self._check_valid_kdu(vnfd, indata["kdu_name"])
                 descriptor_configuration = utils.find_in_list(
-                    configs,
-                    lambda config: config["id"] == indata.get("kdu_name")
-                ).get("config-primitive")
+                    configs, lambda config: config["id"] == indata.get("kdu_name")
+                )
             else:
                 descriptor_configuration = utils.find_in_list(
             else:
                 descriptor_configuration = utils.find_in_list(
-                    configs,
-                    lambda config: config["id"] == vnfd["id"]
-                ).get("config-primitive")
+                    configs, lambda config: config["id"] == vnfd["id"]
+                )
+            if descriptor_configuration is not None:
+                descriptor_configuration = descriptor_configuration.get(
+                    "config-primitive"
+                )
         else:  # use a NSD
         else:  # use a NSD
-            descriptor_configuration = nsd.get("ns-configuration", {}).get("config-primitive")
+            descriptor_configuration = nsd.get("ns-configuration", {}).get(
+                "config-primitive"
+            )
 
         # For k8s allows default primitives without validating the parameters
 
         # For k8s allows default primitives without validating the parameters
-        if indata.get("kdu_name") and indata["primitive"] in ("upgrade", "rollback", "status", "inspect", "readme"):
+        if indata.get("kdu_name") and indata["primitive"] in (
+            "upgrade",
+            "rollback",
+            "status",
+            "inspect",
+            "readme",
+        ):
             # TODO should be checked that rollback only can contains revsision_numbe????
             if not indata.get("member_vnf_index"):
             # TODO should be checked that rollback only can contains revsision_numbe????
             if not indata.get("member_vnf_index"):
-                raise EngineException("Missing action parameter 'member_vnf_index' for default KDU primitive '{}'"
-                                      .format(indata["primitive"]))
+                raise EngineException(
+                    "Missing action parameter 'member_vnf_index' for default KDU primitive '{}'".format(
+                        indata["primitive"]
+                    )
+                )
             return
         # if not, check primitive
         for config_primitive in get_iterable(descriptor_configuration):
             return
         # if not, check primitive
         for config_primitive in get_iterable(descriptor_configuration):
@@ -779,26 +1112,45 @@ class NsLcmOpTopic(BaseTopic):
                     if paramd["name"] in in_primitive_params_copy:
                         del in_primitive_params_copy[paramd["name"]]
                     elif not paramd.get("default-value"):
                     if paramd["name"] in in_primitive_params_copy:
                         del in_primitive_params_copy[paramd["name"]]
                     elif not paramd.get("default-value"):
-                        raise EngineException("Needed parameter {} not provided for primitive '{}'".format(
-                            paramd["name"], indata["primitive"]))
+                        raise EngineException(
+                            "Needed parameter {} not provided for primitive '{}'".format(
+                                paramd["name"], indata["primitive"]
+                            )
+                        )
                 # check no extra primitive params are provided
                 if in_primitive_params_copy:
                 # check no extra primitive params are provided
                 if in_primitive_params_copy:
-                    raise EngineException("parameter/s '{}' not present at vnfd /nsd for primitive '{}'".format(
-                        list(in_primitive_params_copy.keys()), indata["primitive"]))
+                    raise EngineException(
+                        "parameter/s '{}' not present at vnfd /nsd for primitive '{}'".format(
+                            list(in_primitive_params_copy.keys()), indata["primitive"]
+                        )
+                    )
                 break
         else:
                 break
         else:
-            raise EngineException("Invalid primitive '{}' is not present at vnfd/nsd".format(indata["primitive"]))
+            raise EngineException(
+                "Invalid primitive '{}' is not present at vnfd/nsd".format(
+                    indata["primitive"]
+                )
+            )
 
     def _check_scale_ns_operation(self, indata, nsr):
 
     def _check_scale_ns_operation(self, indata, nsr):
-        vnfd = self._get_vnfd_from_vnf_member_index(indata["scaleVnfData"]["scaleByStepData"]["member-vnf-index"],
-                                                    nsr["_id"])
+        vnfd = self._get_vnfd_from_vnf_member_index(
+            indata["scaleVnfData"]["scaleByStepData"]["member-vnf-index"], nsr["_id"]
+        )
         for scaling_aspect in get_iterable(vnfd.get("df", ())[0]["scaling-aspect"]):
         for scaling_aspect in get_iterable(vnfd.get("df", ())[0]["scaling-aspect"]):
-            if indata["scaleVnfData"]["scaleByStepData"]["scaling-group-descriptor"] == scaling_aspect["id"]:
+            if (
+                indata["scaleVnfData"]["scaleByStepData"]["scaling-group-descriptor"]
+                == scaling_aspect["id"]
+            ):
                 break
         else:
                 break
         else:
-            raise EngineException("Invalid scaleVnfData:scaleByStepData:scaling-group-descriptor '{}' is not "
-                                  "present at vnfd:scaling-aspect"
-                                  .format(indata["scaleVnfData"]["scaleByStepData"]["scaling-group-descriptor"]))
+            raise EngineException(
+                "Invalid scaleVnfData:scaleByStepData:scaling-group-descriptor '{}' is not "
+                "present at vnfd:scaling-aspect".format(
+                    indata["scaleVnfData"]["scaleByStepData"][
+                        "scaling-group-descriptor"
+                    ]
+                )
+            )
 
     def _check_instantiate_ns_operation(self, indata, nsr, session):
         vnf_member_index_to_vnfd = {}  # map between vnf_member_index to vnf descriptor.
 
     def _check_instantiate_ns_operation(self, indata, nsr, session):
         vnf_member_index_to_vnfd = {}  # map between vnf_member_index to vnf descriptor.
@@ -812,33 +1164,51 @@ class NsLcmOpTopic(BaseTopic):
             if vnf_member_index_to_vnfd.get(member_vnf_index):
                 vnfd = vnf_member_index_to_vnfd[member_vnf_index]
             else:
             if vnf_member_index_to_vnfd.get(member_vnf_index):
                 vnfd = vnf_member_index_to_vnfd[member_vnf_index]
             else:
-                vnfd = self._get_vnfd_from_vnf_member_index(member_vnf_index, nsr["_id"])
-                vnf_member_index_to_vnfd[member_vnf_index] = vnfd  # add to cache, avoiding a later look for
+                vnfd = self._get_vnfd_from_vnf_member_index(
+                    member_vnf_index, nsr["_id"]
+                )
+                vnf_member_index_to_vnfd[
+                    member_vnf_index
+                ] = vnfd  # add to cache, avoiding a later look for
             self._check_vnf_instantiation_params(in_vnf, vnfd)
             if in_vnf.get("vimAccountId"):
             self._check_vnf_instantiation_params(in_vnf, vnfd)
             if in_vnf.get("vimAccountId"):
-                self._check_valid_vim_account(in_vnf["vimAccountId"], vim_accounts, session)
+                self._check_valid_vim_account(
+                    in_vnf["vimAccountId"], vim_accounts, session
+                )
 
         for in_vld in get_iterable(indata.get("vld")):
 
         for in_vld in get_iterable(indata.get("vld")):
-            self._check_valid_wim_account(in_vld.get("wimAccountId"), wim_accounts, session)
+            self._check_valid_wim_account(
+                in_vld.get("wimAccountId"), wim_accounts, session
+            )
             for vldd in get_iterable(nsd.get("virtual-link-desc")):
                 if in_vld["name"] == vldd["id"]:
                     break
             else:
             for vldd in get_iterable(nsd.get("virtual-link-desc")):
                 if in_vld["name"] == vldd["id"]:
                     break
             else:
-                raise EngineException("Invalid parameter vld:name='{}' is not present at nsd:vld".format(
-                    in_vld["name"]))
+                raise EngineException(
+                    "Invalid parameter vld:name='{}' is not present at nsd:vld".format(
+                        in_vld["name"]
+                    )
+                )
 
     def _get_vnfd_from_vnf_member_index(self, member_vnf_index, nsr_id):
         # Obtain vnf descriptor. The vnfr is used to get the vnfd._id used for this member_vnf_index
 
     def _get_vnfd_from_vnf_member_index(self, member_vnf_index, nsr_id):
         # Obtain vnf descriptor. The vnfr is used to get the vnfd._id used for this member_vnf_index
-        vnfr = self.db.get_one("vnfrs",
-                               {"nsr-id-ref": nsr_id, "member-vnf-index-ref": member_vnf_index},
-                               fail_on_empty=False)
+        vnfr = self.db.get_one(
+            "vnfrs",
+            {"nsr-id-ref": nsr_id, "member-vnf-index-ref": member_vnf_index},
+            fail_on_empty=False,
+        )
         if not vnfr:
         if not vnfr:
-            raise EngineException("Invalid parameter member_vnf_index='{}' is not one of the "
-                                  "nsd:constituent-vnfd".format(member_vnf_index))
+            raise EngineException(
+                "Invalid parameter member_vnf_index='{}' is not one of the "
+                "nsd:constituent-vnfd".format(member_vnf_index)
+            )
         vnfd = self.db.get_one("vnfds", {"_id": vnfr["vnfd-id"]}, fail_on_empty=False)
         if not vnfd:
         vnfd = self.db.get_one("vnfds", {"_id": vnfr["vnfd-id"]}, fail_on_empty=False)
         if not vnfd:
-            raise EngineException("vnfd id={} has been deleted!. Operation cannot be performed".
-                                  format(vnfr["vnfd-id"]))
+            raise EngineException(
+                "vnfd id={} has been deleted!. Operation cannot be performed".format(
+                    vnfr["vnfd-id"]
+                )
+            )
         return vnfd
 
     def _check_valid_vdu(self, vnfd, vdu_id):
         return vnfd
 
     def _check_valid_vdu(self, vnfd, vdu_id):
@@ -846,14 +1216,22 @@ class NsLcmOpTopic(BaseTopic):
             if vdud["id"] == vdu_id:
                 return vdud
         else:
             if vdud["id"] == vdu_id:
                 return vdud
         else:
-            raise EngineException("Invalid parameter vdu_id='{}' not present at vnfd:vdu:id".format(vdu_id))
+            raise EngineException(
+                "Invalid parameter vdu_id='{}' not present at vnfd:vdu:id".format(
+                    vdu_id
+                )
+            )
 
     def _check_valid_kdu(self, vnfd, kdu_name):
         for kdud in get_iterable(vnfd.get("kdu")):
             if kdud["name"] == kdu_name:
                 return kdud
         else:
 
     def _check_valid_kdu(self, vnfd, kdu_name):
         for kdud in get_iterable(vnfd.get("kdu")):
             if kdud["name"] == kdu_name:
                 return kdud
         else:
-            raise EngineException("Invalid parameter kdu_name='{}' not present at vnfd:kdu:name".format(kdu_name))
+            raise EngineException(
+                "Invalid parameter kdu_name='{}' not present at vnfd:kdu:name".format(
+                    kdu_name
+                )
+            )
 
     def _check_vnf_instantiation_params(self, in_vnf, vnfd):
         for in_vdu in get_iterable(in_vnf.get("vdu")):
 
     def _check_vnf_instantiation_params(self, in_vnf, vnfd):
         for in_vdu in get_iterable(in_vnf.get("vdu")):
@@ -864,32 +1242,47 @@ class NsLcmOpTopic(BaseTopic):
                             if volumed["id"] == volume["name"]:
                                 break
                         else:
                             if volumed["id"] == volume["name"]:
                                 break
                         else:
-                            raise EngineException("Invalid parameter vnf[member-vnf-index='{}']:vdu[id='{}']:"
-                                                  "volume:name='{}' is not present at "
-                                                  "vnfd:vdu:virtual-storage-desc list".
-                                                  format(in_vnf["member-vnf-index"], in_vdu["id"],
-                                                         volume["id"]))
+                            raise EngineException(
+                                "Invalid parameter vnf[member-vnf-index='{}']:vdu[id='{}']:"
+                                "volume:name='{}' is not present at "
+                                "vnfd:vdu:virtual-storage-desc list".format(
+                                    in_vnf["member-vnf-index"],
+                                    in_vdu["id"],
+                                    volume["id"],
+                                )
+                            )
 
                     vdu_if_names = set()
                     for cpd in get_iterable(vdu.get("int-cpd")):
 
                     vdu_if_names = set()
                     for cpd in get_iterable(vdu.get("int-cpd")):
-                        for iface in get_iterable(cpd.get("virtual-network-interface-requirement")):
+                        for iface in get_iterable(
+                            cpd.get("virtual-network-interface-requirement")
+                        ):
                             vdu_if_names.add(iface.get("name"))
 
                     for in_iface in get_iterable(in_vdu["interface"]):
                         if in_iface["name"] in vdu_if_names:
                             break
                         else:
                             vdu_if_names.add(iface.get("name"))
 
                     for in_iface in get_iterable(in_vdu["interface"]):
                         if in_iface["name"] in vdu_if_names:
                             break
                         else:
-                            raise EngineException("Invalid parameter vnf[member-vnf-index='{}']:vdu[id='{}']:"
-                                                  "int-cpd[id='{}'] is not present at vnfd:vdu:int-cpd"
-                                                  .format(in_vnf["member-vnf-index"], in_vdu["id"],
-                                                          in_iface["name"]))
+                            raise EngineException(
+                                "Invalid parameter vnf[member-vnf-index='{}']:vdu[id='{}']:"
+                                "int-cpd[id='{}'] is not present at vnfd:vdu:int-cpd".format(
+                                    in_vnf["member-vnf-index"],
+                                    in_vdu["id"],
+                                    in_iface["name"],
+                                )
+                            )
                     break
 
             else:
                     break
 
             else:
-                raise EngineException("Invalid parameter vnf[member-vnf-index='{}']:vdu[id='{}'] is not present "
-                                      "at vnfd:vdu".format(in_vnf["member-vnf-index"], in_vdu["id"]))
+                raise EngineException(
+                    "Invalid parameter vnf[member-vnf-index='{}']:vdu[id='{}'] is not present "
+                    "at vnfd:vdu".format(in_vnf["member-vnf-index"], in_vdu["id"])
+                )
 
 
-        vnfd_ivlds_cpds = {ivld.get("id"): set() for ivld in get_iterable(vnfd.get("int-virtual-link-desc"))}
+        vnfd_ivlds_cpds = {
+            ivld.get("id"): set()
+            for ivld in get_iterable(vnfd.get("int-virtual-link-desc"))
+        }
         for vdu in get_iterable(vnfd.get("vdu")):
             for cpd in get_iterable(vnfd.get("int-cpd")):
                 if cpd.get("int-virtual-link-desc"):
         for vdu in get_iterable(vnfd.get("vdu")):
             for cpd in get_iterable(vnfd.get("int-cpd")):
                 if cpd.get("int-virtual-link-desc"):
@@ -901,15 +1294,22 @@ class NsLcmOpTopic(BaseTopic):
                     if in_icp["id-ref"] in vnfd_ivlds_cpds[in_ivld.get("name")]:
                         break
                     else:
                     if in_icp["id-ref"] in vnfd_ivlds_cpds[in_ivld.get("name")]:
                         break
                     else:
-                        raise EngineException("Invalid parameter vnf[member-vnf-index='{}']:internal-vld[name"
-                                              "='{}']:internal-connection-point[id-ref:'{}'] is not present at "
-                                              "vnfd:internal-vld:name/id:internal-connection-point"
-                                              .format(in_vnf["member-vnf-index"], in_ivld["name"],
-                                                      in_icp["id-ref"]))
+                        raise EngineException(
+                            "Invalid parameter vnf[member-vnf-index='{}']:internal-vld[name"
+                            "='{}']:internal-connection-point[id-ref:'{}'] is not present at "
+                            "vnfd:internal-vld:name/id:internal-connection-point".format(
+                                in_vnf["member-vnf-index"],
+                                in_ivld["name"],
+                                in_icp["id-ref"],
+                            )
+                        )
             else:
             else:
-                raise EngineException("Invalid parameter vnf[member-vnf-index='{}']:internal-vld:name='{}'"
-                                      " is not present at vnfd '{}'".format(in_vnf["member-vnf-index"],
-                                                                            in_ivld["name"], vnfd["id"]))
+                raise EngineException(
+                    "Invalid parameter vnf[member-vnf-index='{}']:internal-vld:name='{}'"
+                    " is not present at vnfd '{}'".format(
+                        in_vnf["member-vnf-index"], in_ivld["name"], vnfd["id"]
+                    )
+                )
 
     def _check_valid_vim_account(self, vim_account, vim_accounts, session):
         if vim_account in vim_accounts:
 
     def _check_valid_vim_account(self, vim_account, vim_accounts, session):
         if vim_account in vim_accounts:
@@ -919,7 +1319,11 @@ class NsLcmOpTopic(BaseTopic):
             db_filter["_id"] = vim_account
             self.db.get_one("vim_accounts", db_filter)
         except Exception:
             db_filter["_id"] = vim_account
             self.db.get_one("vim_accounts", db_filter)
         except Exception:
-            raise EngineException("Invalid vimAccountId='{}' not present for the project".format(vim_account))
+            raise EngineException(
+                "Invalid vimAccountId='{}' not present for the project".format(
+                    vim_account
+                )
+            )
         vim_accounts.append(vim_account)
 
     def _check_valid_wim_account(self, wim_account, wim_accounts, session):
         vim_accounts.append(vim_account)
 
     def _check_valid_wim_account(self, wim_account, wim_accounts, session):
@@ -932,10 +1336,16 @@ class NsLcmOpTopic(BaseTopic):
             db_filter["_id"] = wim_account
             self.db.get_one("wim_accounts", db_filter)
         except Exception:
             db_filter["_id"] = wim_account
             self.db.get_one("wim_accounts", db_filter)
         except Exception:
-            raise EngineException("Invalid wimAccountId='{}' not present for the project".format(wim_account))
+            raise EngineException(
+                "Invalid wimAccountId='{}' not present for the project".format(
+                    wim_account
+                )
+            )
         wim_accounts.append(wim_account)
 
         wim_accounts.append(wim_account)
 
-    def _look_for_pdu(self, session, rollback, vnfr, vim_account, vnfr_update, vnfr_update_rollback):
+    def _look_for_pdu(
+        self, session, rollback, vnfr, vim_account, vnfr_update, vnfr_update_rollback
+    ):
         """
         Look for a free PDU in the catalog matching vdur type and interfaces. Fills vnfr.vdur with the interface
         (ip_address, ...) information.
         """
         Look for a free PDU in the catalog matching vdur type and interfaces. Fills vnfr.vdur with the interface
         (ip_address, ...) information.
@@ -985,7 +1395,13 @@ class NsLcmOpTopic(BaseTopic):
             else:
                 raise EngineException(
                     "No PDU of type={} at vim_account={} found for member_vnf_index={}, vdu={} matching interface "
             else:
                 raise EngineException(
                     "No PDU of type={} at vim_account={} found for member_vnf_index={}, vdu={} matching interface "
-                    "names".format(pdu_type, vim_account, vnfr["member-vnf-index-ref"], vdur["vdu-id-ref"]))
+                    "names".format(
+                        pdu_type,
+                        vim_account,
+                        vnfr["member-vnf-index-ref"],
+                        vdur["vdu-id-ref"],
+                    )
+                )
 
             # step 2. Update pdu
             rollback_pdu = {
 
             # step 2. Update pdu
             rollback_pdu = {
@@ -994,13 +1410,26 @@ class NsLcmOpTopic(BaseTopic):
                 "_admin.usage.nsr_id": None,
                 "_admin.usage.vdur": None,
             }
                 "_admin.usage.nsr_id": None,
                 "_admin.usage.vdur": None,
             }
-            self.db.set_one("pdus", {"_id": pdu["_id"]},
-                            {"_admin.usageState": "IN_USE",
-                             "_admin.usage": {"vnfr_id": vnfr["_id"],
-                                              "nsr_id": vnfr["nsr-id-ref"],
-                                              "vdur": vdur["vdu-id-ref"]}
-                             })
-            rollback.append({"topic": "pdus", "_id": pdu["_id"], "operation": "set", "content": rollback_pdu})
+            self.db.set_one(
+                "pdus",
+                {"_id": pdu["_id"]},
+                {
+                    "_admin.usageState": "IN_USE",
+                    "_admin.usage": {
+                        "vnfr_id": vnfr["_id"],
+                        "nsr_id": vnfr["nsr-id-ref"],
+                        "vdur": vdur["vdu-id-ref"],
+                    },
+                },
+            )
+            rollback.append(
+                {
+                    "topic": "pdus",
+                    "_id": pdu["_id"],
+                    "operation": "set",
+                    "content": rollback_pdu,
+                }
+            )
 
             # step 3. Fill vnfr info by filling vdur
             vdu_text = "vdur.{}".format(vdur_index)
 
             # step 3. Fill vnfr info by filling vdur
             vdu_text = "vdur.{}".format(vdur_index)
@@ -1011,31 +1440,58 @@ class NsLcmOpTopic(BaseTopic):
                     if pdu_interface["name"] == vdur_interface["name"]:
                         iface_text = vdu_text + ".interfaces.{}".format(iface_index)
                         for k, v in pdu_interface.items():
                     if pdu_interface["name"] == vdur_interface["name"]:
                         iface_text = vdu_text + ".interfaces.{}".format(iface_index)
                         for k, v in pdu_interface.items():
-                            if k in ("ip-address", "mac-address"):  # TODO: switch-xxxxx must be inserted
+                            if k in (
+                                "ip-address",
+                                "mac-address",
+                            ):  # TODO: switch-xxxxx must be inserted
                                 vnfr_update[iface_text + ".{}".format(k)] = v
                                 vnfr_update[iface_text + ".{}".format(k)] = v
-                                vnfr_update_rollback[iface_text + ".{}".format(k)] = vdur_interface.get(v)
+                                vnfr_update_rollback[
+                                    iface_text + ".{}".format(k)
+                                ] = vdur_interface.get(v)
                         if pdu_interface.get("ip-address"):
                         if pdu_interface.get("ip-address"):
-                            if vdur_interface.get("mgmt-interface") or vdur_interface.get("mgmt-vnf"):
-                                vnfr_update_rollback[vdu_text + ".ip-address"] = vdur.get("ip-address")
-                                vnfr_update[vdu_text + ".ip-address"] = pdu_interface["ip-address"]
+                            if vdur_interface.get(
+                                "mgmt-interface"
+                            ) or vdur_interface.get("mgmt-vnf"):
+                                vnfr_update_rollback[
+                                    vdu_text + ".ip-address"
+                                ] = vdur.get("ip-address")
+                                vnfr_update[vdu_text + ".ip-address"] = pdu_interface[
+                                    "ip-address"
+                                ]
                             if vdur_interface.get("mgmt-vnf"):
                             if vdur_interface.get("mgmt-vnf"):
-                                vnfr_update_rollback["ip-address"] = vnfr.get("ip-address")
+                                vnfr_update_rollback["ip-address"] = vnfr.get(
+                                    "ip-address"
+                                )
                                 vnfr_update["ip-address"] = pdu_interface["ip-address"]
                                 vnfr_update["ip-address"] = pdu_interface["ip-address"]
-                                vnfr_update[vdu_text + ".ip-address"] = pdu_interface["ip-address"]
-                        if pdu_interface.get("vim-network-name") or pdu_interface.get("vim-network-id"):
-                            ifaces_forcing_vim_network.append({
-                                "name": vdur_interface.get("vnf-vld-id") or vdur_interface.get("ns-vld-id"),
-                                "vnf-vld-id": vdur_interface.get("vnf-vld-id"),
-                                "ns-vld-id": vdur_interface.get("ns-vld-id")})
+                                vnfr_update[vdu_text + ".ip-address"] = pdu_interface[
+                                    "ip-address"
+                                ]
+                        if pdu_interface.get("vim-network-name") or pdu_interface.get(
+                            "vim-network-id"
+                        ):
+                            ifaces_forcing_vim_network.append(
+                                {
+                                    "name": vdur_interface.get("vnf-vld-id")
+                                    or vdur_interface.get("ns-vld-id"),
+                                    "vnf-vld-id": vdur_interface.get("vnf-vld-id"),
+                                    "ns-vld-id": vdur_interface.get("ns-vld-id"),
+                                }
+                            )
                             if pdu_interface.get("vim-network-id"):
                             if pdu_interface.get("vim-network-id"):
-                                ifaces_forcing_vim_network[-1]["vim-network-id"] = pdu_interface["vim-network-id"]
+                                ifaces_forcing_vim_network[-1][
+                                    "vim-network-id"
+                                ] = pdu_interface["vim-network-id"]
                             if pdu_interface.get("vim-network-name"):
                             if pdu_interface.get("vim-network-name"):
-                                ifaces_forcing_vim_network[-1]["vim-network-name"] = pdu_interface["vim-network-name"]
+                                ifaces_forcing_vim_network[-1][
+                                    "vim-network-name"
+                                ] = pdu_interface["vim-network-name"]
                         break
 
         return ifaces_forcing_vim_network
 
                         break
 
         return ifaces_forcing_vim_network
 
-    def _look_for_k8scluster(self, session, rollback, vnfr, vim_account, vnfr_update, vnfr_update_rollback):
+    def _look_for_k8scluster(
+        self, session, rollback, vnfr, vim_account, vnfr_update, vnfr_update_rollback
+    ):
         """
         Look for an available k8scluster for all the kuds in the vnfd matching version and cni requirements.
         Fills vnfr.kdur with the selected k8scluster
         """
         Look for an available k8scluster for all the kuds in the vnfd matching version and cni requirements.
         Fills vnfr.kdur with the selected k8scluster
@@ -1072,7 +1528,9 @@ class NsLcmOpTopic(BaseTopic):
             # restrict by cni
             if vnfr["k8s-cluster"].get("cni"):
                 k8s_requirements["cni"] = vnfr["k8s-cluster"]["cni"]
             # restrict by cni
             if vnfr["k8s-cluster"].get("cni"):
                 k8s_requirements["cni"] = vnfr["k8s-cluster"]["cni"]
-                if not set(vnfr["k8s-cluster"]["cni"]).intersection(k8scluster.get("cni", ())):
+                if not set(vnfr["k8s-cluster"]["cni"]).intersection(
+                    k8scluster.get("cni", ())
+                ):
                     continue
             # restrict by version
             if vnfr["k8s-cluster"].get("version"):
                     continue
             # restrict by version
             if vnfr["k8s-cluster"].get("version"):
@@ -1082,12 +1540,17 @@ class NsLcmOpTopic(BaseTopic):
             # restrict by number of networks
             if vnfr["k8s-cluster"].get("nets"):
                 k8s_requirements["networks"] = len(vnfr["k8s-cluster"]["nets"])
             # restrict by number of networks
             if vnfr["k8s-cluster"].get("nets"):
                 k8s_requirements["networks"] = len(vnfr["k8s-cluster"]["nets"])
-                if not k8scluster.get("nets") or len(k8scluster["nets"]) < len(vnfr["k8s-cluster"]["nets"]):
+                if not k8scluster.get("nets") or len(k8scluster["nets"]) < len(
+                    vnfr["k8s-cluster"]["nets"]
+                ):
                     continue
             break
         else:
                     continue
             break
         else:
-            raise EngineException("No k8scluster with requirements='{}' at vim_account={} found for member_vnf_index={}"
-                                  .format(k8s_requirements, vim_account, vnfr["member-vnf-index-ref"]))
+            raise EngineException(
+                "No k8scluster with requirements='{}' at vim_account={} found for member_vnf_index={}".format(
+                    k8s_requirements, vim_account, vnfr["member-vnf-index-ref"]
+                )
+            )
 
         for kdur_index, kdur in enumerate(get_iterable(vnfr.get("kdur"))):
             # step 3. Fill vnfr info by filling kdur
 
         for kdur_index, kdur in enumerate(get_iterable(vnfr.get("kdur"))):
             # step 3. Fill vnfr info by filling kdur
@@ -1106,15 +1569,22 @@ class NsLcmOpTopic(BaseTopic):
                 else:
                     vim_net = k8scluster["nets"][k8scluster_net_list[0]]
                     k8scluster_net_list.pop(0)
                 else:
                     vim_net = k8scluster["nets"][k8scluster_net_list[0]]
                     k8scluster_net_list.pop(0)
-                vnfr_update_rollback["k8s-cluster.nets.{}.vim_net".format(net_index)] = None
+                vnfr_update_rollback[
+                    "k8s-cluster.nets.{}.vim_net".format(net_index)
+                ] = None
                 vnfr_update["k8s-cluster.nets.{}.vim_net".format(net_index)] = vim_net
                 vnfr_update["k8s-cluster.nets.{}.vim_net".format(net_index)] = vim_net
-                if vim_net and (kdur_net.get("vnf-vld-id") or kdur_net.get("ns-vld-id")):
-                    ifaces_forcing_vim_network.append({
-                        "name": kdur_net.get("vnf-vld-id") or kdur_net.get("ns-vld-id"),
-                        "vnf-vld-id": kdur_net.get("vnf-vld-id"),
-                        "ns-vld-id": kdur_net.get("ns-vld-id"),
-                        "vim-network-name": vim_net,   # TODO can it be vim-network-id ???
-                    })
+                if vim_net and (
+                    kdur_net.get("vnf-vld-id") or kdur_net.get("ns-vld-id")
+                ):
+                    ifaces_forcing_vim_network.append(
+                        {
+                            "name": kdur_net.get("vnf-vld-id")
+                            or kdur_net.get("ns-vld-id"),
+                            "vnf-vld-id": kdur_net.get("vnf-vld-id"),
+                            "ns-vld-id": kdur_net.get("ns-vld-id"),
+                            "vim-network-name": vim_net,  # TODO can it be vim-network-id ???
+                        }
+                    )
             # TODO check that this forcing is not incompatible with other forcing
         return ifaces_forcing_vim_network
 
             # TODO check that this forcing is not incompatible with other forcing
         return ifaces_forcing_vim_network
 
@@ -1130,84 +1600,152 @@ class NsLcmOpTopic(BaseTopic):
             # update vim-account-id
 
             vim_account = indata["vimAccountId"]
             # update vim-account-id
 
             vim_account = indata["vimAccountId"]
+            vca_id = indata.get("vcaId")
             # check instantiate parameters
             for vnf_inst_params in get_iterable(indata.get("vnf")):
                 if vnf_inst_params["member-vnf-index"] != member_vnf_index:
                     continue
                 if vnf_inst_params.get("vimAccountId"):
                     vim_account = vnf_inst_params.get("vimAccountId")
             # check instantiate parameters
             for vnf_inst_params in get_iterable(indata.get("vnf")):
                 if vnf_inst_params["member-vnf-index"] != member_vnf_index:
                     continue
                 if vnf_inst_params.get("vimAccountId"):
                     vim_account = vnf_inst_params.get("vimAccountId")
+                if vnf_inst_params.get("vcaId"):
+                    vca_id = vnf_inst_params.get("vcaId")
 
                 # get vnf.vdu.interface instantiation params to update vnfr.vdur.interfaces ip, mac
                 for vdu_inst_param in get_iterable(vnf_inst_params.get("vdu")):
                     for vdur_index, vdur in enumerate(vnfr["vdur"]):
                         if vdu_inst_param["id"] != vdur["vdu-id-ref"]:
                             continue
 
                 # get vnf.vdu.interface instantiation params to update vnfr.vdur.interfaces ip, mac
                 for vdu_inst_param in get_iterable(vnf_inst_params.get("vdu")):
                     for vdur_index, vdur in enumerate(vnfr["vdur"]):
                         if vdu_inst_param["id"] != vdur["vdu-id-ref"]:
                             continue
-                        for iface_inst_param in get_iterable(vdu_inst_param.get("interface")):
-                            iface_index, _ = next(i for i in enumerate(vdur["interfaces"])
-                                                  if i[1]["name"] == iface_inst_param["name"])
-                            vnfr_update_text = "vdur.{}.interfaces.{}".format(vdur_index, iface_index)
+                        for iface_inst_param in get_iterable(
+                            vdu_inst_param.get("interface")
+                        ):
+                            iface_index, _ = next(
+                                i
+                                for i in enumerate(vdur["interfaces"])
+                                if i[1]["name"] == iface_inst_param["name"]
+                            )
+                            vnfr_update_text = "vdur.{}.interfaces.{}".format(
+                                vdur_index, iface_index
+                            )
                             if iface_inst_param.get("ip-address"):
                             if iface_inst_param.get("ip-address"):
-                                vnfr_update[vnfr_update_text + ".ip-address"] = increment_ip_mac(
-                                    iface_inst_param.get("ip-address"), vdur.get("count-index", 0))
+                                vnfr_update[
+                                    vnfr_update_text + ".ip-address"
+                                ] = increment_ip_mac(
+                                    iface_inst_param.get("ip-address"),
+                                    vdur.get("count-index", 0),
+                                )
                                 vnfr_update[vnfr_update_text + ".fixed-ip"] = True
                             if iface_inst_param.get("mac-address"):
                                 vnfr_update[vnfr_update_text + ".fixed-ip"] = True
                             if iface_inst_param.get("mac-address"):
-                                vnfr_update[vnfr_update_text + ".mac-address"] = increment_ip_mac(
-                                    iface_inst_param.get("mac-address"), vdur.get("count-index", 0))
+                                vnfr_update[
+                                    vnfr_update_text + ".mac-address"
+                                ] = increment_ip_mac(
+                                    iface_inst_param.get("mac-address"),
+                                    vdur.get("count-index", 0),
+                                )
                                 vnfr_update[vnfr_update_text + ".fixed-mac"] = True
                             if iface_inst_param.get("floating-ip-required"):
                                 vnfr_update[vnfr_update_text + ".fixed-mac"] = True
                             if iface_inst_param.get("floating-ip-required"):
-                                vnfr_update[vnfr_update_text + ".floating-ip-required"] = True
+                                vnfr_update[
+                                    vnfr_update_text + ".floating-ip-required"
+                                ] = True
                 # get vnf.internal-vld.internal-conection-point instantiation params to update vnfr.vdur.interfaces
                 # TODO update vld with the ip-profile
                 # get vnf.internal-vld.internal-conection-point instantiation params to update vnfr.vdur.interfaces
                 # TODO update vld with the ip-profile
-                for ivld_inst_param in get_iterable(vnf_inst_params.get("internal-vld")):
-                    for icp_inst_param in get_iterable(ivld_inst_param.get("internal-connection-point")):
+                for ivld_inst_param in get_iterable(
+                    vnf_inst_params.get("internal-vld")
+                ):
+                    for icp_inst_param in get_iterable(
+                        ivld_inst_param.get("internal-connection-point")
+                    ):
                         # look for iface
                         for vdur_index, vdur in enumerate(vnfr["vdur"]):
                             for iface_index, iface in enumerate(vdur["interfaces"]):
                         # look for iface
                         for vdur_index, vdur in enumerate(vnfr["vdur"]):
                             for iface_index, iface in enumerate(vdur["interfaces"]):
-                                if iface.get("internal-connection-point-ref") == icp_inst_param["id-ref"]:
-                                    vnfr_update_text = "vdur.{}.interfaces.{}".format(vdur_index, iface_index)
+                                if (
+                                    iface.get("internal-connection-point-ref")
+                                    == icp_inst_param["id-ref"]
+                                ):
+                                    vnfr_update_text = "vdur.{}.interfaces.{}".format(
+                                        vdur_index, iface_index
+                                    )
                                     if icp_inst_param.get("ip-address"):
                                     if icp_inst_param.get("ip-address"):
-                                        vnfr_update[vnfr_update_text + ".ip-address"] = increment_ip_mac(
-                                            icp_inst_param.get("ip-address"), vdur.get("count-index", 0))
-                                        vnfr_update[vnfr_update_text + ".fixed-ip"] = True
+                                        vnfr_update[
+                                            vnfr_update_text + ".ip-address"
+                                        ] = increment_ip_mac(
+                                            icp_inst_param.get("ip-address"),
+                                            vdur.get("count-index", 0),
+                                        )
+                                        vnfr_update[
+                                            vnfr_update_text + ".fixed-ip"
+                                        ] = True
                                     if icp_inst_param.get("mac-address"):
                                     if icp_inst_param.get("mac-address"):
-                                        vnfr_update[vnfr_update_text + ".mac-address"] = increment_ip_mac(
-                                            icp_inst_param.get("mac-address"), vdur.get("count-index", 0))
-                                        vnfr_update[vnfr_update_text + ".fixed-mac"] = True
+                                        vnfr_update[
+                                            vnfr_update_text + ".mac-address"
+                                        ] = increment_ip_mac(
+                                            icp_inst_param.get("mac-address"),
+                                            vdur.get("count-index", 0),
+                                        )
+                                        vnfr_update[
+                                            vnfr_update_text + ".fixed-mac"
+                                        ] = True
                                     break
             # get ip address from instantiation parameters.vld.vnfd-connection-point-ref
             for vld_inst_param in get_iterable(indata.get("vld")):
                                     break
             # get ip address from instantiation parameters.vld.vnfd-connection-point-ref
             for vld_inst_param in get_iterable(indata.get("vld")):
-                for vnfcp_inst_param in get_iterable(vld_inst_param.get("vnfd-connection-point-ref")):
+                for vnfcp_inst_param in get_iterable(
+                    vld_inst_param.get("vnfd-connection-point-ref")
+                ):
                     if vnfcp_inst_param["member-vnf-index-ref"] != member_vnf_index:
                         continue
                     # look for iface
                     for vdur_index, vdur in enumerate(vnfr["vdur"]):
                         for iface_index, iface in enumerate(vdur["interfaces"]):
                     if vnfcp_inst_param["member-vnf-index-ref"] != member_vnf_index:
                         continue
                     # look for iface
                     for vdur_index, vdur in enumerate(vnfr["vdur"]):
                         for iface_index, iface in enumerate(vdur["interfaces"]):
-                            if iface.get("external-connection-point-ref") == \
-                                    vnfcp_inst_param["vnfd-connection-point-ref"]:
-                                vnfr_update_text = "vdur.{}.interfaces.{}".format(vdur_index, iface_index)
+                            if (
+                                iface.get("external-connection-point-ref")
+                                == vnfcp_inst_param["vnfd-connection-point-ref"]
+                            ):
+                                vnfr_update_text = "vdur.{}.interfaces.{}".format(
+                                    vdur_index, iface_index
+                                )
                                 if vnfcp_inst_param.get("ip-address"):
                                 if vnfcp_inst_param.get("ip-address"):
-                                    vnfr_update[vnfr_update_text + ".ip-address"] = increment_ip_mac(
-                                        vnfcp_inst_param.get("ip-address"), vdur.get("count-index", 0))
+                                    vnfr_update[
+                                        vnfr_update_text + ".ip-address"
+                                    ] = increment_ip_mac(
+                                        vnfcp_inst_param.get("ip-address"),
+                                        vdur.get("count-index", 0),
+                                    )
                                     vnfr_update[vnfr_update_text + ".fixed-ip"] = True
                                 if vnfcp_inst_param.get("mac-address"):
                                     vnfr_update[vnfr_update_text + ".fixed-ip"] = True
                                 if vnfcp_inst_param.get("mac-address"):
-                                    vnfr_update[vnfr_update_text + ".mac-address"] = increment_ip_mac(
-                                        vnfcp_inst_param.get("mac-address"), vdur.get("count-index", 0))
+                                    vnfr_update[
+                                        vnfr_update_text + ".mac-address"
+                                    ] = increment_ip_mac(
+                                        vnfcp_inst_param.get("mac-address"),
+                                        vdur.get("count-index", 0),
+                                    )
                                     vnfr_update[vnfr_update_text + ".fixed-mac"] = True
                                 break
 
             vnfr_update["vim-account-id"] = vim_account
             vnfr_update_rollback["vim-account-id"] = vnfr.get("vim-account-id")
 
                                     vnfr_update[vnfr_update_text + ".fixed-mac"] = True
                                 break
 
             vnfr_update["vim-account-id"] = vim_account
             vnfr_update_rollback["vim-account-id"] = vnfr.get("vim-account-id")
 
+            if vca_id:
+                vnfr_update["vca-id"] = vca_id
+                vnfr_update_rollback["vca-id"] = vnfr.get("vca-id")
+
             # get pdu
             # get pdu
-            ifaces_forcing_vim_network = self._look_for_pdu(session, rollback, vnfr, vim_account, vnfr_update,
-                                                            vnfr_update_rollback)
+            ifaces_forcing_vim_network = self._look_for_pdu(
+                session, rollback, vnfr, vim_account, vnfr_update, vnfr_update_rollback
+            )
 
             # get kdus
 
             # get kdus
-            ifaces_forcing_vim_network += self._look_for_k8scluster(session, rollback, vnfr, vim_account, vnfr_update,
-                                                                    vnfr_update_rollback)
+            ifaces_forcing_vim_network += self._look_for_k8scluster(
+                session, rollback, vnfr, vim_account, vnfr_update, vnfr_update_rollback
+            )
             # update database vnfr
             self.db.set_one("vnfrs", {"_id": vnfr["_id"]}, vnfr_update)
             # update database vnfr
             self.db.set_one("vnfrs", {"_id": vnfr["_id"]}, vnfr_update)
-            rollback.append({"topic": "vnfrs", "_id": vnfr["_id"], "operation": "set", "content": vnfr_update_rollback})
+            rollback.append(
+                {
+                    "topic": "vnfrs",
+                    "_id": vnfr["_id"],
+                    "operation": "set",
+                    "content": vnfr_update_rollback,
+                }
+            )
 
             # Update indada in case pdu forces to use a concrete vim-network-name
             # TODO check if user has already insert a vim-network-name and raises an error
 
             # Update indada in case pdu forces to use a concrete vim-network-name
             # TODO check if user has already insert a vim-network-name and raises an error
@@ -1217,17 +1755,33 @@ class NsLcmOpTopic(BaseTopic):
                 if iface_info.get("ns-vld-id"):
                     if "vld" not in indata:
                         indata["vld"] = []
                 if iface_info.get("ns-vld-id"):
                     if "vld" not in indata:
                         indata["vld"] = []
-                    indata["vld"].append({key: iface_info[key] for key in
-                                          ("name", "vim-network-name", "vim-network-id") if iface_info.get(key)})
+                    indata["vld"].append(
+                        {
+                            key: iface_info[key]
+                            for key in ("name", "vim-network-name", "vim-network-id")
+                            if iface_info.get(key)
+                        }
+                    )
 
                 elif iface_info.get("vnf-vld-id"):
                     if "vnf" not in indata:
                         indata["vnf"] = []
 
                 elif iface_info.get("vnf-vld-id"):
                     if "vnf" not in indata:
                         indata["vnf"] = []
-                    indata["vnf"].append({
-                        "member-vnf-index": member_vnf_index,
-                        "internal-vld": [{key: iface_info[key] for key in
-                                          ("name", "vim-network-name", "vim-network-id") if iface_info.get(key)}]
-                    })
+                    indata["vnf"].append(
+                        {
+                            "member-vnf-index": member_vnf_index,
+                            "internal-vld": [
+                                {
+                                    key: iface_info[key]
+                                    for key in (
+                                        "name",
+                                        "vim-network-name",
+                                        "vim-network-id",
+                                    )
+                                    if iface_info.get(key)
+                                }
+                            ],
+                        }
+                    )
 
     @staticmethod
     def _create_nslcmop(nsr_id, operation, params):
 
     @staticmethod
     def _create_nslcmop(nsr_id, operation, params):
@@ -1258,7 +1812,7 @@ class NsLcmOpTopic(BaseTopic):
             "links": {
                 "self": "/osm/nslcm/v1/ns_lcm_op_occs/" + _id,
                 "nsInstance": "/osm/nslcm/v1/ns_instances/" + nsr_id,
             "links": {
                 "self": "/osm/nslcm/v1/ns_lcm_op_occs/" + _id,
                 "nsInstance": "/osm/nslcm/v1/ns_instances/" + nsr_id,
-            }
+            },
         }
         return nslcmop
 
         }
         return nslcmop
 
@@ -1272,10 +1826,18 @@ class NsLcmOpTopic(BaseTopic):
         vims = self.db.get_list("vim_accounts", db_filter)
         vimAccounts = []
         for vim in vims:
         vims = self.db.get_list("vim_accounts", db_filter)
         vimAccounts = []
         for vim in vims:
-            vimAccounts.append(vim['_id'])
+            vimAccounts.append(vim["_id"])
         return vimAccounts
 
         return vimAccounts
 
-    def new(self, rollback, session, indata=None, kwargs=None, headers=None, slice_object=False):
+    def new(
+        self,
+        rollback,
+        session,
+        indata=None,
+        kwargs=None,
+        headers=None,
+        slice_object=False,
+    ):
         """
         Performs a new operation over a ns
         :param rollback: list to append created items at database in case a rollback must to be done
         """
         Performs a new operation over a ns
         :param rollback: list to append created items at database in case a rollback must to be done
@@ -1287,14 +1849,21 @@ class NsLcmOpTopic(BaseTopic):
         :param headers: http request headers
         :return: id of the nslcmops
         """
         :param headers: http request headers
         :return: id of the nslcmops
         """
+
         def check_if_nsr_is_not_slice_member(session, nsr_id):
             nsis = None
             db_filter = self._get_project_filter(session)
             db_filter["_admin.nsrs-detailed-list.ANYINDEX.nsrId"] = nsr_id
         def check_if_nsr_is_not_slice_member(session, nsr_id):
             nsis = None
             db_filter = self._get_project_filter(session)
             db_filter["_admin.nsrs-detailed-list.ANYINDEX.nsrId"] = nsr_id
-            nsis = self.db.get_one("nsis", db_filter, fail_on_empty=False, fail_on_more=False)
+            nsis = self.db.get_one(
+                "nsis", db_filter, fail_on_empty=False, fail_on_more=False
+            )
             if nsis:
             if nsis:
-                raise EngineException("The NS instance {} cannot be terminated because is used by the slice {}".format(
-                                      nsr_id, nsis["_id"]), http_code=HTTPStatus.CONFLICT)
+                raise EngineException(
+                    "The NS instance {} cannot be terminated because is used by the slice {}".format(
+                        nsr_id, nsis["_id"]
+                    ),
+                    http_code=HTTPStatus.CONFLICT,
+                )
 
         try:
             # Override descriptor with query string kwargs
 
         try:
             # Override descriptor with query string kwargs
@@ -1311,17 +1880,31 @@ class NsLcmOpTopic(BaseTopic):
             # initial checking
             if operation == "terminate" and slice_object is False:
                 check_if_nsr_is_not_slice_member(session, nsr["_id"])
             # initial checking
             if operation == "terminate" and slice_object is False:
                 check_if_nsr_is_not_slice_member(session, nsr["_id"])
-            if not nsr["_admin"].get("nsState") or nsr["_admin"]["nsState"] == "NOT_INSTANTIATED":
+            if (
+                not nsr["_admin"].get("nsState")
+                or nsr["_admin"]["nsState"] == "NOT_INSTANTIATED"
+            ):
                 if operation == "terminate" and indata.get("autoremove"):
                     # NSR must be deleted
                 if operation == "terminate" and indata.get("autoremove"):
                     # NSR must be deleted
-                    return None, None    # a none in this case is used to indicate not instantiated. It can be removed
+                    return (
+                        None,
+                        None,
+                    )  # a none in this case is used to indicate not instantiated. It can be removed
                 if operation != "instantiate":
                 if operation != "instantiate":
-                    raise EngineException("ns_instance '{}' cannot be '{}' because it is not instantiated".format(
-                        nsInstanceId, operation), HTTPStatus.CONFLICT)
+                    raise EngineException(
+                        "ns_instance '{}' cannot be '{}' because it is not instantiated".format(
+                            nsInstanceId, operation
+                        ),
+                        HTTPStatus.CONFLICT,
+                    )
             else:
                 if operation == "instantiate" and not session["force"]:
             else:
                 if operation == "instantiate" and not session["force"]:
-                    raise EngineException("ns_instance '{}' cannot be '{}' because it is already instantiated".format(
-                        nsInstanceId, operation), HTTPStatus.CONFLICT)
+                    raise EngineException(
+                        "ns_instance '{}' cannot be '{}' because it is already instantiated".format(
+                            nsInstanceId, operation
+                        ),
+                        HTTPStatus.CONFLICT,
+                    )
             self._check_ns_operation(session, nsr, operation, indata)
 
             if operation == "instantiate":
             self._check_ns_operation(session, nsr, operation, indata)
 
             if operation == "instantiate":
@@ -1329,10 +1912,14 @@ class NsLcmOpTopic(BaseTopic):
 
             nslcmop_desc = self._create_nslcmop(nsInstanceId, operation, indata)
             _id = nslcmop_desc["_id"]
 
             nslcmop_desc = self._create_nslcmop(nsInstanceId, operation, indata)
             _id = nslcmop_desc["_id"]
-            self.format_on_new(nslcmop_desc, session["project_id"], make_public=session["public"])
+            self.format_on_new(
+                nslcmop_desc, session["project_id"], make_public=session["public"]
+            )
             if indata.get("placement-engine"):
                 # Save valid vim accounts in lcm operation descriptor
             if indata.get("placement-engine"):
                 # Save valid vim accounts in lcm operation descriptor
-                nslcmop_desc['operationParams']['validVimAccounts'] = self._get_enabled_vims(session)
+                nslcmop_desc["operationParams"][
+                    "validVimAccounts"
+                ] = self._get_enabled_vims(session)
             self.db.create("nslcmops", nslcmop_desc)
             rollback.append({"topic": "nslcmops", "_id": _id})
             if not slice_object:
             self.db.create("nslcmops", nslcmop_desc)
             rollback.append({"topic": "nslcmops", "_id": _id})
             if not slice_object:
@@ -1344,10 +1931,14 @@ class NsLcmOpTopic(BaseTopic):
         #     raise EngineException("Cannot get ns_instance '{}': {}".format(e), HTTPStatus.NOT_FOUND)
 
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
         #     raise EngineException("Cannot get ns_instance '{}': {}".format(e), HTTPStatus.NOT_FOUND)
 
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
-        raise EngineException("Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
-        raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
 
 class NsiTopic(BaseTopic):
 
 
 class NsiTopic(BaseTopic):
@@ -1376,11 +1967,17 @@ class NsiTopic(BaseTopic):
         if additional_params:
             for k, v in additional_params.items():
                 if not isinstance(k, str):
         if additional_params:
             for k, v in additional_params.items():
                 if not isinstance(k, str):
-                    raise EngineException("Invalid param at additionalParamsForNsi:{}. Only string keys are allowed".
-                                          format(k))
+                    raise EngineException(
+                        "Invalid param at additionalParamsForNsi:{}. Only string keys are allowed".format(
+                            k
+                        )
+                    )
                 if "." in k or "$" in k:
                 if "." in k or "$" in k:
-                    raise EngineException("Invalid param at additionalParamsForNsi:{}. Keys must not contain dots or $".
-                                          format(k))
+                    raise EngineException(
+                        "Invalid param at additionalParamsForNsi:{}. Keys must not contain dots or $".format(
+                            k
+                        )
+                    )
                 if isinstance(v, (dict, tuple, list)):
                     additional_params[k] = "!!yaml " + safe_dump(v)
         return additional_params
                 if isinstance(v, (dict, tuple, list)):
                     additional_params[k] = "!!yaml " + safe_dump(v)
         return additional_params
@@ -1396,8 +1993,12 @@ class NsiTopic(BaseTopic):
             return
         nstd_id = descriptor["nst-ref"]
         if not self.get_item_list(session, "nsts", {"id": nstd_id}):
             return
         nstd_id = descriptor["nst-ref"]
         if not self.get_item_list(session, "nsts", {"id": nstd_id}):
-            raise EngineException("Descriptor error at nst-ref='{}' references a non exist nstd".format(nstd_id),
-                                  http_code=HTTPStatus.CONFLICT)
+            raise EngineException(
+                "Descriptor error at nst-ref='{}' references a non exist nstd".format(
+                    nstd_id
+                ),
+                http_code=HTTPStatus.CONFLICT,
+            )
 
     def check_conflict_on_del(self, session, _id, db_content):
         """
 
     def check_conflict_on_del(self, session, _id, db_content):
         """
@@ -1411,9 +2012,11 @@ class NsiTopic(BaseTopic):
             return
         nsi = db_content
         if nsi["_admin"].get("nsiState") == "INSTANTIATED":
             return
         nsi = db_content
         if nsi["_admin"].get("nsiState") == "INSTANTIATED":
-            raise EngineException("nsi '{}' cannot be deleted because it is in 'INSTANTIATED' state. "
-                                  "Launch 'terminate' operation first; or force deletion".format(_id),
-                                  http_code=HTTPStatus.CONFLICT)
+            raise EngineException(
+                "nsi '{}' cannot be deleted because it is in 'INSTANTIATED' state. "
+                "Launch 'terminate' operation first; or force deletion".format(_id),
+                http_code=HTTPStatus.CONFLICT,
+            )
 
     def delete_extra(self, session, _id, db_content, not_send_msg=None):
         """
 
     def delete_extra(self, session, _id, db_content, not_send_msg=None):
         """
@@ -1431,14 +2034,20 @@ class NsiTopic(BaseTopic):
         for nsrs_detailed_item in nsir["_admin"]["nsrs-detailed-list"]:
             nsr_id = nsrs_detailed_item["nsrId"]
             if nsrs_detailed_item.get("shared"):
         for nsrs_detailed_item in nsir["_admin"]["nsrs-detailed-list"]:
             nsr_id = nsrs_detailed_item["nsrId"]
             if nsrs_detailed_item.get("shared"):
-                _filter = {"_admin.nsrs-detailed-list.ANYINDEX.shared": True,
-                           "_admin.nsrs-detailed-list.ANYINDEX.nsrId": nsr_id,
-                           "_id.ne": nsir["_id"]}
-                nsi = self.db.get_one("nsis", _filter, fail_on_empty=False, fail_on_more=False)
+                _filter = {
+                    "_admin.nsrs-detailed-list.ANYINDEX.shared": True,
+                    "_admin.nsrs-detailed-list.ANYINDEX.nsrId": nsr_id,
+                    "_id.ne": nsir["_id"],
+                }
+                nsi = self.db.get_one(
+                    "nsis", _filter, fail_on_empty=False, fail_on_more=False
+                )
                 if nsi:  # last one using nsr
                     continue
             try:
                 if nsi:  # last one using nsr
                     continue
             try:
-                self.nsrTopic.delete(session, nsr_id, dry_run=False, not_send_msg=not_send_msg)
+                self.nsrTopic.delete(
+                    session, nsr_id, dry_run=False, not_send_msg=not_send_msg
+                )
             except (DbException, EngineException) as e:
                 if e.http_code == HTTPStatus.NOT_FOUND:
                     pass
             except (DbException, EngineException) as e:
                 if e.http_code == HTTPStatus.NOT_FOUND:
                     pass
@@ -1452,10 +2061,18 @@ class NsiTopic(BaseTopic):
         nsir_admin = nsir.get("_admin")
         if nsir_admin and nsir_admin.get("nst-id"):
             # check if used by another NSI
         nsir_admin = nsir.get("_admin")
         if nsir_admin and nsir_admin.get("nst-id"):
             # check if used by another NSI
-            nsis_list = self.db.get_one("nsis", {"nst-id": nsir_admin["nst-id"]},
-                                        fail_on_empty=False, fail_on_more=False)
+            nsis_list = self.db.get_one(
+                "nsis",
+                {"nst-id": nsir_admin["nst-id"]},
+                fail_on_empty=False,
+                fail_on_more=False,
+            )
             if not nsis_list:
             if not nsis_list:
-                self.db.set_one("nsts", {"_id": nsir_admin["nst-id"]}, {"_admin.usageState": "NOT_IN_USE"})
+                self.db.set_one(
+                    "nsts",
+                    {"_id": nsir_admin["nst-id"]},
+                    {"_admin.usageState": "NOT_IN_USE"},
+                )
 
     def new(self, rollback, session, indata=None, kwargs=None, headers=None):
         """
 
     def new(self, rollback, session, indata=None, kwargs=None, headers=None):
         """
@@ -1479,22 +2096,30 @@ class NsiTopic(BaseTopic):
             slice_request = self._validate_input_new(slice_request, session["force"])
 
             # look for nstd
             slice_request = self._validate_input_new(slice_request, session["force"])
 
             # look for nstd
-            step = "getting nstd id='{}' from database".format(slice_request.get("nstId"))
+            step = "getting nstd id='{}' from database".format(
+                slice_request.get("nstId")
+            )
             _filter = self._get_project_filter(session)
             _filter["_id"] = slice_request["nstId"]
             nstd = self.db.get_one("nsts", _filter)
             # check NST is not disabled
             step = "checking NST operationalState"
             if nstd["_admin"]["operationalState"] == "DISABLED":
             _filter = self._get_project_filter(session)
             _filter["_id"] = slice_request["nstId"]
             nstd = self.db.get_one("nsts", _filter)
             # check NST is not disabled
             step = "checking NST operationalState"
             if nstd["_admin"]["operationalState"] == "DISABLED":
-                raise EngineException("nst with id '{}' is DISABLED, and thus cannot be used to create a netslice "
-                                      "instance".format(slice_request["nstId"]), http_code=HTTPStatus.CONFLICT)
+                raise EngineException(
+                    "nst with id '{}' is DISABLED, and thus cannot be used to create a netslice "
+                    "instance".format(slice_request["nstId"]),
+                    http_code=HTTPStatus.CONFLICT,
+                )
             del _filter["_id"]
 
             # check NSD is not disabled
             step = "checking operationalState"
             if nstd["_admin"]["operationalState"] == "DISABLED":
             del _filter["_id"]
 
             # check NSD is not disabled
             step = "checking operationalState"
             if nstd["_admin"]["operationalState"] == "DISABLED":
-                raise EngineException("nst with id '{}' is DISABLED, and thus cannot be used to create "
-                                      "a network slice".format(slice_request["nstId"]), http_code=HTTPStatus.CONFLICT)
+                raise EngineException(
+                    "nst with id '{}' is DISABLED, and thus cannot be used to create "
+                    "a network slice".format(slice_request["nstId"]),
+                    http_code=HTTPStatus.CONFLICT,
+                )
 
             nstd.pop("_admin", None)
             nstd_id = nstd.pop("_id", None)
 
             nstd.pop("_admin", None)
             nstd_id = nstd.pop("_id", None)
@@ -1513,11 +2138,13 @@ class NsiTopic(BaseTopic):
                 "nsr-ref-list": [],
                 "vlr-list": [],
                 "_id": nsi_id,
                 "nsr-ref-list": [],
                 "vlr-list": [],
                 "_id": nsi_id,
-                "additionalParamsForNsi": self._format_addional_params(slice_request)
+                "additionalParamsForNsi": self._format_addional_params(slice_request),
             }
 
             step = "creating nsi at database"
             }
 
             step = "creating nsi at database"
-            self.format_on_new(nsi_descriptor, session["project_id"], make_public=session["public"])
+            self.format_on_new(
+                nsi_descriptor, session["project_id"], make_public=session["public"]
+            )
             nsi_descriptor["_admin"]["nsiState"] = "NOT_INSTANTIATED"
             nsi_descriptor["_admin"]["netslice-subnet"] = None
             nsi_descriptor["_admin"]["deployed"] = {}
             nsi_descriptor["_admin"]["nsiState"] = "NOT_INSTANTIATED"
             nsi_descriptor["_admin"]["netslice-subnet"] = None
             nsi_descriptor["_admin"]["deployed"] = {}
@@ -1547,11 +2174,14 @@ class NsiTopic(BaseTopic):
             for member_ns in nstd["netslice-subnet"]:
                 nsd_id = member_ns["nsd-ref"]
                 step = "getting nstd id='{}' constituent-nsd='{}' from database".format(
             for member_ns in nstd["netslice-subnet"]:
                 nsd_id = member_ns["nsd-ref"]
                 step = "getting nstd id='{}' constituent-nsd='{}' from database".format(
-                    member_ns["nsd-ref"], member_ns["id"])
+                    member_ns["nsd-ref"], member_ns["id"]
+                )
                 if nsd_id not in needed_nsds:
                     # Obtain nsd
                     _filter["id"] = nsd_id
                 if nsd_id not in needed_nsds:
                     # Obtain nsd
                     _filter["id"] = nsd_id
-                    nsd = self.db.get_one("nsds", _filter, fail_on_empty=True, fail_on_more=True)
+                    nsd = self.db.get_one(
+                        "nsds", _filter, fail_on_empty=True, fail_on_more=True
+                    )
                     del _filter["id"]
                     nsd.pop("_admin")
                     needed_nsds[nsd_id] = nsd
                     del _filter["id"]
                     nsd.pop("_admin")
                     needed_nsds[nsd_id] = nsd
@@ -1561,7 +2191,8 @@ class NsiTopic(BaseTopic):
                 services.append(member_ns)
 
                 step = "filling nsir nsd-id='{}' constituent-nsd='{}' from database".format(
                 services.append(member_ns)
 
                 step = "filling nsir nsd-id='{}' constituent-nsd='{}' from database".format(
-                    member_ns["nsd-ref"], member_ns["id"])
+                    member_ns["nsd-ref"], member_ns["id"]
+                )
 
             # creates Network Services records (NSRs)
             step = "creating nsrs at database using NsrTopic.new()"
 
             # creates Network Services records (NSRs)
             step = "creating nsrs at database using NsrTopic.new()"
@@ -1574,9 +2205,13 @@ class NsiTopic(BaseTopic):
                 indata_ns = {}
                 # Is the nss shared and instantiated?
                 _filter["_admin.nsrs-detailed-list.ANYINDEX.shared"] = True
                 indata_ns = {}
                 # Is the nss shared and instantiated?
                 _filter["_admin.nsrs-detailed-list.ANYINDEX.shared"] = True
-                _filter["_admin.nsrs-detailed-list.ANYINDEX.nsd-id"] = service["nsd-ref"]
+                _filter["_admin.nsrs-detailed-list.ANYINDEX.nsd-id"] = service[
+                    "nsd-ref"
+                ]
                 _filter["_admin.nsrs-detailed-list.ANYINDEX.nss-id"] = service["id"]
                 _filter["_admin.nsrs-detailed-list.ANYINDEX.nss-id"] = service["id"]
-                nsi = self.db.get_one("nsis", _filter, fail_on_empty=False, fail_on_more=False)
+                nsi = self.db.get_one(
+                    "nsis", _filter, fail_on_empty=False, fail_on_more=False
+                )
                 if nsi and service.get("is-shared-nss"):
                     nsrs_detailed_list = nsi["_admin"]["nsrs-detailed-list"]
                     for nsrs_detailed_item in nsrs_detailed_list:
                 if nsi and service.get("is-shared-nss"):
                     nsrs_detailed_list = nsi["_admin"]["nsrs-detailed-list"]
                     for nsrs_detailed_item in nsrs_detailed_list:
@@ -1593,9 +2228,11 @@ class NsiTopic(BaseTopic):
                     if service.get("instantiation-parameters"):
                         indata_ns = deepcopy(service["instantiation-parameters"])
                         # del service["instantiation-parameters"]
                     if service.get("instantiation-parameters"):
                         indata_ns = deepcopy(service["instantiation-parameters"])
                         # del service["instantiation-parameters"]
-                        
+
                     indata_ns["nsdId"] = service["_id"]
                     indata_ns["nsdId"] = service["_id"]
-                    indata_ns["nsName"] = slice_request.get("nsiName") + "." + service["id"]
+                    indata_ns["nsName"] = (
+                        slice_request.get("nsiName") + "." + service["id"]
+                    )
                     indata_ns["vimAccountId"] = slice_request.get("vimAccountId")
                     indata_ns["nsDescription"] = service["description"]
                     if slice_request.get("ssh_keys"):
                     indata_ns["vimAccountId"] = slice_request.get("vimAccountId")
                     indata_ns["nsDescription"] = service["description"]
                     if slice_request.get("ssh_keys"):
@@ -1607,12 +2244,19 @@ class NsiTopic(BaseTopic):
                                 copy_ns_param = deepcopy(ns_param)
                                 del copy_ns_param["id"]
                                 indata_ns.update(copy_ns_param)
                                 copy_ns_param = deepcopy(ns_param)
                                 del copy_ns_param["id"]
                                 indata_ns.update(copy_ns_param)
-                                break                   
+                                break
 
                     # Creates Nsr objects
 
                     # Creates Nsr objects
-                    _id_nsr, _ = self.nsrTopic.new(rollback, session, indata_ns, kwargs, headers)
-                nsrs_item = {"nsrId": _id_nsr, "shared": service.get("is-shared-nss"), "nsd-id": service["nsd-ref"], 
-                             "nss-id": service["id"], "nslcmop_instantiate": None}
+                    _id_nsr, _ = self.nsrTopic.new(
+                        rollback, session, indata_ns, kwargs, headers
+                    )
+                nsrs_item = {
+                    "nsrId": _id_nsr,
+                    "shared": service.get("is-shared-nss"),
+                    "nsd-id": service["nsd-ref"],
+                    "nss-id": service["id"],
+                    "nslcmop_instantiate": None,
+                }
                 indata_ns["nss-id"] = service["id"]
                 nsrs_list.append(nsrs_item)
                 nsi_netslice_subnet.append(indata_ns)
                 indata_ns["nss-id"] = service["id"]
                 nsrs_list.append(nsrs_item)
                 nsi_netslice_subnet.append(indata_ns)
@@ -1622,20 +2266,26 @@ class NsiTopic(BaseTopic):
             # Adding the nsrs list to the nsi
             nsi_descriptor["_admin"]["nsrs-detailed-list"] = nsrs_list
             nsi_descriptor["_admin"]["netslice-subnet"] = nsi_netslice_subnet
             # Adding the nsrs list to the nsi
             nsi_descriptor["_admin"]["nsrs-detailed-list"] = nsrs_list
             nsi_descriptor["_admin"]["netslice-subnet"] = nsi_netslice_subnet
-            self.db.set_one("nsts", {"_id": slice_request["nstId"]}, {"_admin.usageState": "IN_USE"})
+            self.db.set_one(
+                "nsts", {"_id": slice_request["nstId"]}, {"_admin.usageState": "IN_USE"}
+            )
 
             # Creating the entry in the database
             self.db.create("nsis", nsi_descriptor)
             rollback.append({"topic": "nsis", "_id": nsi_id})
             return nsi_id, None
 
             # Creating the entry in the database
             self.db.create("nsis", nsi_descriptor)
             rollback.append({"topic": "nsis", "_id": nsi_id})
             return nsi_id, None
-        except Exception as e:   # TODO remove try Except, it is captured at nbi.py
-            self.logger.exception("Exception {} at NsiTopic.new()".format(e), exc_info=True)
+        except Exception as e:  # TODO remove try Except, it is captured at nbi.py
+            self.logger.exception(
+                "Exception {} at NsiTopic.new()".format(e), exc_info=True
+            )
             raise EngineException("Error {}: {}".format(step, e))
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
             raise EngineException("Error {}: {}".format(step, e))
         except ValidationError as e:
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
-        raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
 
 class NsiLcmOpTopic(BaseTopic):
 
 
 class NsiLcmOpTopic(BaseTopic):
@@ -1643,9 +2293,9 @@ class NsiLcmOpTopic(BaseTopic):
     topic_msg = "nsi"
     operation_schema = {  # mapping between operation and jsonschema to validate
         "instantiate": nsi_instantiate,
     topic_msg = "nsi"
     operation_schema = {  # mapping between operation and jsonschema to validate
         "instantiate": nsi_instantiate,
-        "terminate": None
+        "terminate": None,
     }
     }
-    
+
     def __init__(self, db, fs, msg, auth):
         BaseTopic.__init__(self, db, fs, msg, auth)
         self.nsi_NsLcmOpTopic = NsLcmOpTopic(self.db, self.fs, self.msg, self.auth)
     def __init__(self, db, fs, msg, auth):
         BaseTopic.__init__(self, db, fs, msg, auth)
         self.nsi_NsLcmOpTopic = NsLcmOpTopic(self.db, self.fs, self.msg, self.auth)
@@ -1672,11 +2322,14 @@ class NsiLcmOpTopic(BaseTopic):
                         nsds[nsd_id] = self.db.get_one("nsds", _filter)
                     return nsds[nsd_id]
             else:
                         nsds[nsd_id] = self.db.get_one("nsds", _filter)
                     return nsds[nsd_id]
             else:
-                raise EngineException("Invalid parameter nstId='{}' is not one of the "
-                                      "nst:netslice-subnet".format(nstId))
+                raise EngineException(
+                    "Invalid parameter nstId='{}' is not one of the "
+                    "nst:netslice-subnet".format(nstId)
+                )
+
         if operation == "instantiate":
             # check the existance of netslice-subnet items
         if operation == "instantiate":
             # check the existance of netslice-subnet items
-            for in_nst in get_iterable(indata.get("netslice-subnet")):   
+            for in_nst in get_iterable(indata.get("netslice-subnet")):
                 check_valid_netslice_subnet_id(in_nst["id"])
 
     def _create_nsilcmop(self, session, netsliceInstanceId, operation, params):
                 check_valid_netslice_subnet_id(in_nst["id"])
 
     def _create_nsilcmop(self, session, netsliceInstanceId, operation, params):
@@ -1695,8 +2348,9 @@ class NsiLcmOpTopic(BaseTopic):
             "isCancelPending": False,
             "links": {
                 "self": "/osm/nsilcm/v1/nsi_lcm_op_occs/" + _id,
             "isCancelPending": False,
             "links": {
                 "self": "/osm/nsilcm/v1/nsi_lcm_op_occs/" + _id,
-                "netsliceInstanceId": "/osm/nsilcm/v1/netslice_instances/" + netsliceInstanceId,
-            }
+                "netsliceInstanceId": "/osm/nsilcm/v1/netslice_instances/"
+                + netsliceInstanceId,
+            },
         }
         return nsilcmop
 
         }
         return nsilcmop
 
@@ -1706,13 +2360,27 @@ class NsiLcmOpTopic(BaseTopic):
                 for admin_subnet_item in nsir["_admin"].get("netslice-subnet"):
                     if admin_subnet_item["nss-id"] == nst_sb_item["id"]:
                         for admin_vld_item in nsir["_admin"].get("netslice-vld"):
                 for admin_subnet_item in nsir["_admin"].get("netslice-subnet"):
                     if admin_subnet_item["nss-id"] == nst_sb_item["id"]:
                         for admin_vld_item in nsir["_admin"].get("netslice-vld"):
-                            for admin_vld_nss_cp_ref_item in admin_vld_item["nss-connection-point-ref"]:
-                                if admin_subnet_item["nss-id"] == admin_vld_nss_cp_ref_item["nss-ref"]:
-                                    if not nsr_item["nsrId"] in admin_vld_item["shared-nsrs-list"]:
-                                        admin_vld_item["shared-nsrs-list"].append(nsr_item["nsrId"])
+                            for admin_vld_nss_cp_ref_item in admin_vld_item[
+                                "nss-connection-point-ref"
+                            ]:
+                                if (
+                                    admin_subnet_item["nss-id"]
+                                    == admin_vld_nss_cp_ref_item["nss-ref"]
+                                ):
+                                    if (
+                                        not nsr_item["nsrId"]
+                                        in admin_vld_item["shared-nsrs-list"]
+                                    ):
+                                        admin_vld_item["shared-nsrs-list"].append(
+                                            nsr_item["nsrId"]
+                                        )
                                     break
         # self.db.set_one("nsis", {"_id": nsir["_id"]}, nsir)
                                     break
         # self.db.set_one("nsis", {"_id": nsir["_id"]}, nsir)
-        self.db.set_one("nsis", {"_id": nsir["_id"]}, {"_admin.netslice-vld": nsir["_admin"].get("netslice-vld")})
+        self.db.set_one(
+            "nsis",
+            {"_id": nsir["_id"]},
+            {"_admin.netslice-vld": nsir["_admin"].get("netslice-vld")},
+        )
 
     def new(self, rollback, session, indata=None, kwargs=None, headers=None):
         """
 
     def new(self, rollback, session, indata=None, kwargs=None, headers=None):
         """
@@ -1741,18 +2409,32 @@ class NsiLcmOpTopic(BaseTopic):
             del _filter["_id"]
 
             # initial checking
             del _filter["_id"]
 
             # initial checking
-            if not nsir["_admin"].get("nsiState") or nsir["_admin"]["nsiState"] == "NOT_INSTANTIATED":
+            if (
+                not nsir["_admin"].get("nsiState")
+                or nsir["_admin"]["nsiState"] == "NOT_INSTANTIATED"
+            ):
                 if operation == "terminate" and indata.get("autoremove"):
                     # NSIR must be deleted
                 if operation == "terminate" and indata.get("autoremove"):
                     # NSIR must be deleted
-                    return None, None    # a none in this case is used to indicate not instantiated. It can be removed
+                    return (
+                        None,
+                        None,
+                    )  # a none in this case is used to indicate not instantiated. It can be removed
                 if operation != "instantiate":
                 if operation != "instantiate":
-                    raise EngineException("netslice_instance '{}' cannot be '{}' because it is not instantiated".format(
-                        netsliceInstanceId, operation), HTTPStatus.CONFLICT)
+                    raise EngineException(
+                        "netslice_instance '{}' cannot be '{}' because it is not instantiated".format(
+                            netsliceInstanceId, operation
+                        ),
+                        HTTPStatus.CONFLICT,
+                    )
             else:
                 if operation == "instantiate" and not session["force"]:
             else:
                 if operation == "instantiate" and not session["force"]:
-                    raise EngineException("netslice_instance '{}' cannot be '{}' because it is already instantiated".
-                                          format(netsliceInstanceId, operation), HTTPStatus.CONFLICT)
-            
+                    raise EngineException(
+                        "netslice_instance '{}' cannot be '{}' because it is already instantiated".format(
+                            netsliceInstanceId, operation
+                        ),
+                        HTTPStatus.CONFLICT,
+                    )
+
             # Creating all the NS_operation (nslcmop)
             # Get service list from db
             nsrs_list = nsir["_admin"]["nsrs-detailed-list"]
             # Creating all the NS_operation (nslcmop)
             # Get service list from db
             nsrs_list = nsir["_admin"]["nsrs-detailed-list"]
@@ -1763,23 +2445,41 @@ class NsiLcmOpTopic(BaseTopic):
                 if nsr_item.get("shared"):
                     _filter["_admin.nsrs-detailed-list.ANYINDEX.shared"] = True
                     _filter["_admin.nsrs-detailed-list.ANYINDEX.nsrId"] = nsr_id
                 if nsr_item.get("shared"):
                     _filter["_admin.nsrs-detailed-list.ANYINDEX.shared"] = True
                     _filter["_admin.nsrs-detailed-list.ANYINDEX.nsrId"] = nsr_id
-                    _filter["_admin.nsrs-detailed-list.ANYINDEX.nslcmop_instantiate.ne"] = None
+                    _filter[
+                        "_admin.nsrs-detailed-list.ANYINDEX.nslcmop_instantiate.ne"
+                    ] = None
                     _filter["_id.ne"] = netsliceInstanceId
                     _filter["_id.ne"] = netsliceInstanceId
-                    nsi = self.db.get_one("nsis", _filter, fail_on_empty=False, fail_on_more=False)
+                    nsi = self.db.get_one(
+                        "nsis", _filter, fail_on_empty=False, fail_on_more=False
+                    )
                     if operation == "terminate":
                     if operation == "terminate":
-                        _update = {"_admin.nsrs-detailed-list.{}.nslcmop_instantiate".format(index): None}
+                        _update = {
+                            "_admin.nsrs-detailed-list.{}.nslcmop_instantiate".format(
+                                index
+                            ): None
+                        }
                         self.db.set_one("nsis", {"_id": nsir["_id"]}, _update)
                         self.db.set_one("nsis", {"_id": nsir["_id"]}, _update)
-                        if nsi:  # other nsi is using this nsr and it needs this nsr instantiated
+                        if (
+                            nsi
+                        ):  # other nsi is using this nsr and it needs this nsr instantiated
                             continue  # do not create nsilcmop
                     else:  # instantiate
                         # looks the first nsi fulfilling the conditions but not being the current NSIR
                         if nsi:
                             continue  # do not create nsilcmop
                     else:  # instantiate
                         # looks the first nsi fulfilling the conditions but not being the current NSIR
                         if nsi:
-                            nsi_nsr_item = next(n for n in nsi["_admin"]["nsrs-detailed-list"] if
-                                                n["nsrId"] == nsr_id and n["shared"] and
-                                                n["nslcmop_instantiate"])
+                            nsi_nsr_item = next(
+                                n
+                                for n in nsi["_admin"]["nsrs-detailed-list"]
+                                if n["nsrId"] == nsr_id
+                                and n["shared"]
+                                and n["nslcmop_instantiate"]
+                            )
                             self.add_shared_nsr_2vld(nsir, nsr_item)
                             nslcmops.append(nsi_nsr_item["nslcmop_instantiate"])
                             self.add_shared_nsr_2vld(nsir, nsr_item)
                             nslcmops.append(nsi_nsr_item["nslcmop_instantiate"])
-                            _update = {"_admin.nsrs-detailed-list.{}".format(index): nsi_nsr_item}
+                            _update = {
+                                "_admin.nsrs-detailed-list.{}".format(
+                                    index
+                                ): nsi_nsr_item
+                            }
                             self.db.set_one("nsis", {"_id": nsir["_id"]}, _update)
                             # continue to not create nslcmop since nsrs is shared and nsrs was created
                             continue
                             self.db.set_one("nsis", {"_id": nsir["_id"]}, _update)
                             # continue to not create nslcmop since nsrs is shared and nsrs was created
                             continue
@@ -1800,15 +2500,23 @@ class NsiLcmOpTopic(BaseTopic):
 
                     # Creating NS_LCM_OP with the flag slice_object=True to not trigger the service instantiation
                     # message via kafka bus
 
                     # Creating NS_LCM_OP with the flag slice_object=True to not trigger the service instantiation
                     # message via kafka bus
-                    nslcmop, _ = self.nsi_NsLcmOpTopic.new(rollback, session, indata_ns, None, headers,
-                                                           slice_object=True)
+                    nslcmop, _ = self.nsi_NsLcmOpTopic.new(
+                        rollback, session, indata_ns, None, headers, slice_object=True
+                    )
                     nslcmops.append(nslcmop)
                     if operation == "instantiate":
                     nslcmops.append(nslcmop)
                     if operation == "instantiate":
-                        _update = {"_admin.nsrs-detailed-list.{}.nslcmop_instantiate".format(index): nslcmop}
+                        _update = {
+                            "_admin.nsrs-detailed-list.{}.nslcmop_instantiate".format(
+                                index
+                            ): nslcmop
+                        }
                         self.db.set_one("nsis", {"_id": nsir["_id"]}, _update)
                 except (DbException, EngineException) as e:
                     if e.http_code == HTTPStatus.NOT_FOUND:
                         self.db.set_one("nsis", {"_id": nsir["_id"]}, _update)
                 except (DbException, EngineException) as e:
                     if e.http_code == HTTPStatus.NOT_FOUND:
-                        self.logger.info(logging_prefix + "skipping NS={} because not found".format(nsr_id))
+                        self.logger.info(
+                            logging_prefix
+                            + "skipping NS={} because not found".format(nsr_id)
+                        )
                         pass
                     else:
                         raise
                         pass
                     else:
                         raise
@@ -1817,8 +2525,12 @@ class NsiLcmOpTopic(BaseTopic):
             indata["nslcmops_ids"] = nslcmops
             self._check_nsi_operation(session, nsir, operation, indata)
 
             indata["nslcmops_ids"] = nslcmops
             self._check_nsi_operation(session, nsir, operation, indata)
 
-            nsilcmop_desc = self._create_nsilcmop(session, netsliceInstanceId, operation, indata)
-            self.format_on_new(nsilcmop_desc, session["project_id"], make_public=session["public"])
+            nsilcmop_desc = self._create_nsilcmop(
+                session, netsliceInstanceId, operation, indata
+            )
+            self.format_on_new(
+                nsilcmop_desc, session["project_id"], make_public=session["public"]
+            )
             _id = self.db.create("nsilcmops", nsilcmop_desc)
             rollback.append({"topic": "nsilcmops", "_id": _id})
             self.msg.write("nsi", operation, nsilcmop_desc)
             _id = self.db.create("nsilcmops", nsilcmop_desc)
             rollback.append({"topic": "nsilcmops", "_id": _id})
             self.msg.write("nsi", operation, nsilcmop_desc)
@@ -1827,7 +2539,11 @@ class NsiLcmOpTopic(BaseTopic):
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
             raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
 
     def delete(self, session, _id, dry_run=False, not_send_msg=None):
-        raise EngineException("Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
 
     def edit(self, session, _id, indata=None, kwargs=None, content=None):
-        raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+        raise EngineException(
+            "Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR
+        )