feat(sol006): LCM migration to SOL006
[osm/LCM.git] / osm_lcm / ns.py
index 0f92f9d..ea2320f 100644 (file)
@@ -27,6 +27,15 @@ from jinja2 import Environment, TemplateError, TemplateNotFound, StrictUndefined
 from osm_lcm import ROclient
 from osm_lcm.ng_ro import NgRoClient, NgRoException
 from osm_lcm.lcm_utils import LcmException, LcmExceptionNoMgmtIP, LcmBase, deep_get, get_iterable, populate_dict
+from osm_lcm.data_utils.nsd import get_vnf_profiles
+from osm_lcm.data_utils.vnfd import get_vnf_configuration, get_vdu_list, get_vdu_profile, \
+    get_ee_sorted_initial_config_primitive_list, get_ee_sorted_terminate_config_primitive_list, \
+    get_kdu_list, get_virtual_link_profiles, get_vdu, get_vdu_configuration, get_kdu_configuration, \
+    get_vdu_index
+from osm_lcm.data_utils.list_utils import find_in_list
+from osm_lcm.data_utils.vnfr import get_osm_params
+from osm_lcm.data_utils.dict_utils import parse_yaml_strings
+from osm_lcm.data_utils.database.vim_account import VimAccountDB
 from n2vc.k8s_helm_conn import K8sHelmConnector
 from n2vc.k8s_helm3_conn import K8sHelm3Connector
 from n2vc.k8s_juju_conn import K8sJujuConnector
@@ -34,13 +43,15 @@ from n2vc.k8s_juju_conn import K8sJujuConnector
 from osm_common.dbbase import DbException
 from osm_common.fsbase import FsException
 
+from osm_lcm.data_utils.database.database import Database
+from osm_lcm.data_utils.filesystem.filesystem import Filesystem
+
 from n2vc.n2vc_juju_conn import N2VCJujuConnector
 from n2vc.exceptions import N2VCException, N2VCNotFound, K8sException
 
 from osm_lcm.lcm_helm_conn import LCMHelmConn
 
 from copy import copy, deepcopy
-from http import HTTPStatus
 from time import time
 from uuid import uuid4
 
@@ -62,19 +73,19 @@ class NsLcm(LcmBase):
     SUBOPERATION_STATUS_SKIP = -3
     task_name_deploy_vca = "Deploying VCA"
 
-    def __init__(self, db, msg, fs, lcm_tasks, config, loop, prometheus=None):
+    def __init__(self, msg, lcm_tasks, config, loop, prometheus=None):
         """
         Init, Connect to database, filesystem storage, and messaging
         :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
         :return: None
         """
         super().__init__(
-            db=db,
             msg=msg,
-            fs=fs,
             logger=logging.getLogger('lcm.ns')
         )
 
+        self.db = Database().instance.db
+        self.fs = Filesystem().instance.fs
         self.loop = loop
         self.lcm_tasks = lcm_tasks
         self.timeout = config["timeout"]
@@ -84,19 +95,17 @@ class NsLcm(LcmBase):
 
         # create N2VC connector
         self.n2vc = N2VCJujuConnector(
-            db=self.db,
-            fs=self.fs,
             log=self.logger,
             loop=self.loop,
             url='{}:{}'.format(self.vca_config['host'], self.vca_config['port']),
             username=self.vca_config.get('user', None),
             vca_config=self.vca_config,
-            on_update_db=self._on_update_n2vc_db
+            on_update_db=self._on_update_n2vc_db,
+            fs=self.fs,
+            db=self.db
         )
 
         self.conn_helm_ee = LCMHelmConn(
-            db=self.db,
-            fs=self.fs,
             log=self.logger,
             loop=self.loop,
             url=None,
@@ -108,10 +117,10 @@ class NsLcm(LcmBase):
         self.k8sclusterhelm2 = K8sHelmConnector(
             kubectl_command=self.vca_config.get("kubectlpath"),
             helm_command=self.vca_config.get("helmpath"),
-            fs=self.fs,
             log=self.logger,
-            db=self.db,
             on_update_db=None,
+            fs=self.fs,
+            db=self.db
         )
 
         self.k8sclusterhelm3 = K8sHelm3Connector(
@@ -126,12 +135,12 @@ class NsLcm(LcmBase):
         self.k8sclusterjuju = K8sJujuConnector(
             kubectl_command=self.vca_config.get("kubectlpath"),
             juju_command=self.vca_config.get("jujupath"),
-            fs=self.fs,
             log=self.logger,
-            db=self.db,
             loop=self.loop,
             on_update_db=None,
             vca_config=self.vca_config,
+            fs=self.fs,
+            db=self.db
         )
 
         self.k8scluster_map = {
@@ -153,10 +162,7 @@ class NsLcm(LcmBase):
         self.prometheus = prometheus
 
         # create RO client
-        if self.ng_ro:
-            self.RO = NgRoClient(self.loop, **self.ro_config)
-        else:
-            self.RO = ROclient.ROClient(self.loop, **self.ro_config)
+        self.RO = NgRoClient(self.loop, **self.ro_config)
 
     @staticmethod
     def increment_ip_mac(ip_mac, vm_index=1):
@@ -297,9 +303,9 @@ class NsLcm(LcmBase):
             raise LcmException("Error parsing Jinja2 to cloud-init content at vnfd[id={}]:vdu[id={}]: {}".
                                format(vnfd_id, vdu_id, e))
 
-    def _get_cloud_init(self, vdu, vnfd):
+    def _get_vdu_cloud_init_content(self, vdu, vnfd):
+        cloud_init_content = cloud_init_file = None
         try:
-            cloud_init_content = cloud_init_file = None
             if vdu.get("cloud-init-file"):
                 base_folder = vnfd["_admin"]["storage"]
                 cloud_init_file = "{}/{}/cloud_init/{}".format(base_folder["folder"], base_folder["pkg-dir"],
@@ -314,37 +320,10 @@ class NsLcm(LcmBase):
             raise LcmException("Error reading vnfd[id={}]:vdu[id={}]:cloud-init-file={}: {}".
                                format(vnfd["id"], vdu["id"], cloud_init_file, e))
 
-    def _get_osm_params(self, db_vnfr, vdu_id=None, vdu_count_index=0):
-        osm_params = {x.replace("-", "_"): db_vnfr[x] for x in ("ip-address", "vim-account-id", "vnfd-id", "vnfd-ref")
-                      if db_vnfr.get(x) is not None}
-        osm_params["ns_id"] = db_vnfr["nsr-id-ref"]
-        osm_params["vnf_id"] = db_vnfr["_id"]
-        osm_params["member_vnf_index"] = db_vnfr["member-vnf-index-ref"]
-        if db_vnfr.get("vdur"):
-            osm_params["vdu"] = {}
-            for vdur in db_vnfr["vdur"]:
-                vdu = {
-                    "count_index": vdur["count-index"],
-                    "vdu_id": vdur["vdu-id-ref"],
-                    "interfaces": {}
-                }
-                if vdur.get("ip-address"):
-                    vdu["ip_address"] = vdur["ip-address"]
-                for iface in vdur["interfaces"]:
-                    vdu["interfaces"][iface["name"]] = \
-                        {x.replace("-", "_"): iface[x] for x in ("mac-address", "ip-address", "vnf-vld-id", "name")
-                         if iface.get(x) is not None}
-                vdu_id_index = "{}-{}".format(vdur["vdu-id-ref"], vdur["count-index"])
-                osm_params["vdu"][vdu_id_index] = vdu
-            if vdu_id:
-                osm_params["vdu_id"] = vdu_id
-                osm_params["count_index"] = vdu_count_index
-        return osm_params
-
     def _get_vdu_additional_params(self, db_vnfr, vdu_id):
         vdur = next(vdur for vdur in db_vnfr.get("vdur") if vdu_id == vdur["vdu-id-ref"])
         additional_params = vdur.get("additionalParams")
-        return self._format_additional_params(additional_params)
+        return parse_yaml_strings(additional_params)
 
     def vnfd2RO(self, vnfd, new_id=None, additionalParams=None, nsrId=None):
         """
@@ -391,284 +370,24 @@ class NsLcm(LcmBase):
             RO_ip_profile["dhcp"] = RO_ip_profile.pop("dhcp-params")
         return RO_ip_profile
 
-    def _ns_params_2_RO(self, ns_params, nsd, vnfd_dict, db_vnfrs, n2vc_key_list):
-        """
-        Creates a RO ns descriptor from OSM ns_instantiate params
-        :param ns_params: OSM instantiate params
-        :param vnfd_dict: database content of vnfds, indexed by id (not _id). {id: {vnfd_object}, ...}
-        :param db_vnfrs: database content of vnfrs, indexed by member-vnf-index. {member-vnf-index: {vnfr_object}, ...}
-        :return: The RO ns descriptor
-        """
-        vim_2_RO = {}
-        wim_2_RO = {}
-        # TODO feature 1417: Check that no instantiation is set over PDU
-        # check if PDU forces a concrete vim-network-id and add it
-        # check if PDU contains a SDN-assist info (dpid, switch, port) and pass it to RO
-
-        def vim_account_2_RO(vim_account):
-            if vim_account in vim_2_RO:
-                return vim_2_RO[vim_account]
-
-            db_vim = self.db.get_one("vim_accounts", {"_id": vim_account})
-            if db_vim["_admin"]["operationalState"] != "ENABLED":
-                raise LcmException("VIM={} is not available. operationalState={}".format(
-                    vim_account, db_vim["_admin"]["operationalState"]))
-            RO_vim_id = db_vim["_admin"]["deployed"]["RO"]
-            vim_2_RO[vim_account] = RO_vim_id
-            return RO_vim_id
-
-        def wim_account_2_RO(wim_account):
-            if isinstance(wim_account, str):
-                if wim_account in wim_2_RO:
-                    return wim_2_RO[wim_account]
-
-                db_wim = self.db.get_one("wim_accounts", {"_id": wim_account})
-                if db_wim["_admin"]["operationalState"] != "ENABLED":
-                    raise LcmException("WIM={} is not available. operationalState={}".format(
-                        wim_account, db_wim["_admin"]["operationalState"]))
-                RO_wim_id = db_wim["_admin"]["deployed"]["RO-account"]
-                wim_2_RO[wim_account] = RO_wim_id
-                return RO_wim_id
-            else:
-                return wim_account
-
-        if not ns_params:
-            return None
-        RO_ns_params = {
-            # "name": ns_params["nsName"],
-            # "description": ns_params.get("nsDescription"),
-            "datacenter": vim_account_2_RO(ns_params["vimAccountId"]),
-            "wim_account": wim_account_2_RO(ns_params.get("wimAccountId")),
-            # "scenario": ns_params["nsdId"],
-        }
-        # set vim_account of each vnf if different from general vim_account.
-        # Get this information from <vnfr> database content, key vim-account-id
-        # Vim account can be set by placement_engine and it may be different from
-        # the instantiate parameters (vnfs.member-vnf-index.datacenter).
-        for vnf_index, vnfr in db_vnfrs.items():
-            if vnfr.get("vim-account-id") and vnfr["vim-account-id"] != ns_params["vimAccountId"]:
-                populate_dict(RO_ns_params, ("vnfs", vnf_index, "datacenter"), vim_account_2_RO(vnfr["vim-account-id"]))
-
-        n2vc_key_list = n2vc_key_list or []
-        for vnfd_ref, vnfd in vnfd_dict.items():
-            vdu_needed_access = []
-            mgmt_cp = None
-            if vnfd.get("vnf-configuration"):
-                ssh_required = deep_get(vnfd, ("vnf-configuration", "config-access", "ssh-access", "required"))
-                if ssh_required and vnfd.get("mgmt-interface"):
-                    if vnfd["mgmt-interface"].get("vdu-id"):
-                        vdu_needed_access.append(vnfd["mgmt-interface"]["vdu-id"])
-                    elif vnfd["mgmt-interface"].get("cp"):
-                        mgmt_cp = vnfd["mgmt-interface"]["cp"]
-
-            for vdu in vnfd.get("vdu", ()):
-                if vdu.get("vdu-configuration"):
-                    ssh_required = deep_get(vdu, ("vdu-configuration", "config-access", "ssh-access", "required"))
-                    if ssh_required:
-                        vdu_needed_access.append(vdu["id"])
-                elif mgmt_cp:
-                    for vdu_interface in vdu.get("interface"):
-                        if vdu_interface.get("external-connection-point-ref") and \
-                                vdu_interface["external-connection-point-ref"] == mgmt_cp:
-                            vdu_needed_access.append(vdu["id"])
-                            mgmt_cp = None
-                            break
-
-            if vdu_needed_access:
-                for vnf_member in nsd.get("constituent-vnfd"):
-                    if vnf_member["vnfd-id-ref"] != vnfd_ref:
-                        continue
-                    for vdu in vdu_needed_access:
-                        populate_dict(RO_ns_params,
-                                      ("vnfs", vnf_member["member-vnf-index"], "vdus", vdu, "mgmt_keys"),
-                                      n2vc_key_list)
-            # cloud init
-            for vdu in get_iterable(vnfd, "vdu"):
-                cloud_init_text = self._get_cloud_init(vdu, vnfd)
-                if not cloud_init_text:
-                    continue
-                for vnf_member in nsd.get("constituent-vnfd"):
-                    if vnf_member["vnfd-id-ref"] != vnfd_ref:
-                        continue
-                    db_vnfr = db_vnfrs[vnf_member["member-vnf-index"]]
-                    additional_params = self._get_vdu_additional_params(db_vnfr, vdu["id"]) or {}
-
-                    cloud_init_list = []
-                    for vdu_index in range(0, int(vdu.get("count", 1))):
-                        additional_params["OSM"] = self._get_osm_params(db_vnfr, vdu["id"], vdu_index)
-                        cloud_init_list.append(self._parse_cloud_init(cloud_init_text, additional_params, vnfd["id"],
-                                                                      vdu["id"]))
-                    populate_dict(RO_ns_params,
-                                  ("vnfs", vnf_member["member-vnf-index"], "vdus", vdu["id"], "cloud_init"),
-                                  cloud_init_list)
-
-        if ns_params.get("vduImage"):
-            RO_ns_params["vduImage"] = ns_params["vduImage"]
-
-        if ns_params.get("ssh_keys"):
-            RO_ns_params["cloud-config"] = {"key-pairs": ns_params["ssh_keys"]}
-        for vnf_params in get_iterable(ns_params, "vnf"):
-            for constituent_vnfd in nsd["constituent-vnfd"]:
-                if constituent_vnfd["member-vnf-index"] == vnf_params["member-vnf-index"]:
-                    vnf_descriptor = vnfd_dict[constituent_vnfd["vnfd-id-ref"]]
-                    break
-            else:
-                raise LcmException("Invalid instantiate parameter vnf:member-vnf-index={} is not present at nsd:"
-                                   "constituent-vnfd".format(vnf_params["member-vnf-index"]))
-
-            for vdu_params in get_iterable(vnf_params, "vdu"):
-                # TODO feature 1417: check that this VDU exist and it is not a PDU
-                if vdu_params.get("volume"):
-                    for volume_params in vdu_params["volume"]:
-                        if volume_params.get("vim-volume-id"):
-                            populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "vdus",
-                                                         vdu_params["id"], "devices", volume_params["name"], "vim_id"),
-                                          volume_params["vim-volume-id"])
-                if vdu_params.get("interface"):
-                    for interface_params in vdu_params["interface"]:
-                        if interface_params.get("ip-address"):
-                            populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "vdus",
-                                                         vdu_params["id"], "interfaces", interface_params["name"],
-                                                         "ip_address"),
-                                          interface_params["ip-address"])
-                        if interface_params.get("mac-address"):
-                            populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "vdus",
-                                                         vdu_params["id"], "interfaces", interface_params["name"],
-                                                         "mac_address"),
-                                          interface_params["mac-address"])
-                        if interface_params.get("floating-ip-required"):
-                            populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "vdus",
-                                                         vdu_params["id"], "interfaces", interface_params["name"],
-                                                         "floating-ip"),
-                                          interface_params["floating-ip-required"])
-
-            for internal_vld_params in get_iterable(vnf_params, "internal-vld"):
-                if internal_vld_params.get("vim-network-name"):
-                    populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "networks",
-                                                 internal_vld_params["name"], "vim-network-name"),
-                                  internal_vld_params["vim-network-name"])
-                if internal_vld_params.get("vim-network-id"):
-                    populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "networks",
-                                                 internal_vld_params["name"], "vim-network-id"),
-                                  internal_vld_params["vim-network-id"])
-                if internal_vld_params.get("ip-profile"):
-                    populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "networks",
-                                                 internal_vld_params["name"], "ip-profile"),
-                                  self.ip_profile_2_RO(internal_vld_params["ip-profile"]))
-                if internal_vld_params.get("provider-network"):
-
-                    populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "networks",
-                                                 internal_vld_params["name"], "provider-network"),
-                                  internal_vld_params["provider-network"].copy())
-
-                for icp_params in get_iterable(internal_vld_params, "internal-connection-point"):
-                    # look for interface
-                    iface_found = False
-                    for vdu_descriptor in vnf_descriptor["vdu"]:
-                        for vdu_interface in vdu_descriptor["interface"]:
-                            if vdu_interface.get("internal-connection-point-ref") == icp_params["id-ref"]:
-                                if icp_params.get("ip-address"):
-                                    populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "vdus",
-                                                                 vdu_descriptor["id"], "interfaces",
-                                                                 vdu_interface["name"], "ip_address"),
-                                                  icp_params["ip-address"])
-
-                                if icp_params.get("mac-address"):
-                                    populate_dict(RO_ns_params, ("vnfs", vnf_params["member-vnf-index"], "vdus",
-                                                                 vdu_descriptor["id"], "interfaces",
-                                                                 vdu_interface["name"], "mac_address"),
-                                                  icp_params["mac-address"])
-                                iface_found = True
-                                break
-                        if iface_found:
-                            break
-                    else:
-                        raise LcmException("Invalid instantiate parameter vnf:member-vnf-index[{}]:"
-                                           "internal-vld:id-ref={} is not present at vnfd:internal-"
-                                           "connection-point".format(vnf_params["member-vnf-index"],
-                                                                     icp_params["id-ref"]))
-
-        for vld_params in get_iterable(ns_params, "vld"):
-            if "ip-profile" in vld_params:
-                populate_dict(RO_ns_params, ("networks", vld_params["name"], "ip-profile"),
-                              self.ip_profile_2_RO(vld_params["ip-profile"]))
-
-            if vld_params.get("provider-network"):
-
-                populate_dict(RO_ns_params, ("networks", vld_params["name"], "provider-network"),
-                              vld_params["provider-network"].copy())
-
-            if "wimAccountId" in vld_params and vld_params["wimAccountId"] is not None:
-                populate_dict(RO_ns_params, ("networks", vld_params["name"], "wim_account"),
-                              wim_account_2_RO(vld_params["wimAccountId"])),
-            if vld_params.get("vim-network-name"):
-                RO_vld_sites = []
-                if isinstance(vld_params["vim-network-name"], dict):
-                    for vim_account, vim_net in vld_params["vim-network-name"].items():
-                        RO_vld_sites.append({
-                            "netmap-use": vim_net,
-                            "datacenter": vim_account_2_RO(vim_account)
-                        })
-                else:  # isinstance str
-                    RO_vld_sites.append({"netmap-use": vld_params["vim-network-name"]})
-                if RO_vld_sites:
-                    populate_dict(RO_ns_params, ("networks", vld_params["name"], "sites"), RO_vld_sites)
-
-            if vld_params.get("vim-network-id"):
-                RO_vld_sites = []
-                if isinstance(vld_params["vim-network-id"], dict):
-                    for vim_account, vim_net in vld_params["vim-network-id"].items():
-                        RO_vld_sites.append({
-                            "netmap-use": vim_net,
-                            "datacenter": vim_account_2_RO(vim_account)
-                        })
-                else:  # isinstance str
-                    RO_vld_sites.append({"netmap-use": vld_params["vim-network-id"]})
-                if RO_vld_sites:
-                    populate_dict(RO_ns_params, ("networks", vld_params["name"], "sites"), RO_vld_sites)
-            if vld_params.get("ns-net"):
-                if isinstance(vld_params["ns-net"], dict):
-                    for vld_id, instance_scenario_id in vld_params["ns-net"].items():
-                        RO_vld_ns_net = {"instance_scenario_id": instance_scenario_id, "osm_id": vld_id}
-                        populate_dict(RO_ns_params, ("networks", vld_params["name"], "use-network"), RO_vld_ns_net)
-            if "vnfd-connection-point-ref" in vld_params:
-                for cp_params in vld_params["vnfd-connection-point-ref"]:
-                    # look for interface
-                    for constituent_vnfd in nsd["constituent-vnfd"]:
-                        if constituent_vnfd["member-vnf-index"] == cp_params["member-vnf-index-ref"]:
-                            vnf_descriptor = vnfd_dict[constituent_vnfd["vnfd-id-ref"]]
-                            break
-                    else:
-                        raise LcmException(
-                            "Invalid instantiate parameter vld:vnfd-connection-point-ref:member-vnf-index-ref={} "
-                            "is not present at nsd:constituent-vnfd".format(cp_params["member-vnf-index-ref"]))
-                    match_cp = False
-                    for vdu_descriptor in vnf_descriptor["vdu"]:
-                        for interface_descriptor in vdu_descriptor["interface"]:
-                            if interface_descriptor.get("external-connection-point-ref") == \
-                                    cp_params["vnfd-connection-point-ref"]:
-                                match_cp = True
-                                break
-                        if match_cp:
-                            break
-                    else:
-                        raise LcmException(
-                            "Invalid instantiate parameter vld:vnfd-connection-point-ref:member-vnf-index-ref={}:"
-                            "vnfd-connection-point-ref={} is not present at vnfd={}".format(
-                                cp_params["member-vnf-index-ref"],
-                                cp_params["vnfd-connection-point-ref"],
-                                vnf_descriptor["id"]))
-                    if cp_params.get("ip-address"):
-                        populate_dict(RO_ns_params, ("vnfs", cp_params["member-vnf-index-ref"], "vdus",
-                                                     vdu_descriptor["id"], "interfaces",
-                                                     interface_descriptor["name"], "ip_address"),
-                                      cp_params["ip-address"])
-                    if cp_params.get("mac-address"):
-                        populate_dict(RO_ns_params, ("vnfs", cp_params["member-vnf-index-ref"], "vdus",
-                                                     vdu_descriptor["id"], "interfaces",
-                                                     interface_descriptor["name"], "mac_address"),
-                                      cp_params["mac-address"])
-        return RO_ns_params
+    def _get_ro_vim_id_for_vim_account(self, vim_account):
+        db_vim = self.db.get_one("vim_accounts", {"_id": vim_account})
+        if db_vim["_admin"]["operationalState"] != "ENABLED":
+            raise LcmException("VIM={} is not available. operationalState={}".format(
+                vim_account, db_vim["_admin"]["operationalState"]))
+        RO_vim_id = db_vim["_admin"]["deployed"]["RO"]
+        return RO_vim_id
+
+    def get_ro_wim_id_for_wim_account(self, wim_account):
+        if isinstance(wim_account, str):
+            db_wim = self.db.get_one("wim_accounts", {"_id": wim_account})
+            if db_wim["_admin"]["operationalState"] != "ENABLED":
+                raise LcmException("WIM={} is not available. operationalState={}".format(
+                    wim_account, db_wim["_admin"]["operationalState"]))
+            RO_wim_id = db_wim["_admin"]["deployed"]["RO-account"]
+            return RO_wim_id
+        else:
+            return wim_account
 
     def scale_vnfr(self, db_vnfr, vdu_create=None, vdu_delete=None, mark_delete=False):
 
@@ -850,45 +569,7 @@ class NsLcm(LcmBase):
                     vca["application"]
         return ns_config_info
 
-    @staticmethod
-    def _get_initial_config_primitive_list(desc_primitive_list, vca_deployed, ee_descriptor_id):
-        """
-        Generates a list of initial-config-primitive based on the list provided by the descriptor. It includes internal
-        primitives as verify-ssh-credentials, or config when needed
-        :param desc_primitive_list: information of the descriptor
-        :param vca_deployed: information of the deployed, needed for known if it is related to an NS, VNF, VDU and if
-            this element contains a ssh public key
-        :param ee_descriptor_id: execution environment descriptor id. It is the value of
-            XXX_configuration.execution-environment-list.INDEX.id; it can be None
-        :return: The modified list. Can ba an empty list, but always a list
-        """
-
-        primitive_list = desc_primitive_list or []
-
-        # filter primitives by ee_id
-        primitive_list = [p for p in primitive_list if p.get("execution-environment-ref") == ee_descriptor_id]
-
-        # sort by 'seq'
-        if primitive_list:
-            primitive_list.sort(key=lambda val: int(val['seq']))
-
-        # look for primitive config, and get the position. None if not present
-        config_position = None
-        for index, primitive in enumerate(primitive_list):
-            if primitive["name"] == "config":
-                config_position = index
-                break
-
-        # for NS, add always a config primitive if not present (bug 874)
-        if not vca_deployed["member-vnf-index"] and config_position is None:
-            primitive_list.insert(0, {"name": "config", "parameter": []})
-            config_position = 0
-        # TODO revise if needed: for VNF/VDU add verify-ssh-credentials after config
-        if vca_deployed["member-vnf-index"] and config_position is not None and vca_deployed.get("ssh-public-key"):
-            primitive_list.insert(config_position + 1, {"name": "verify-ssh-credentials", "parameter": []})
-        return primitive_list
-
-    async def _instantiate_ng_ro(self, logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs, db_vnfds_ref,
+    async def _instantiate_ng_ro(self, logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs, db_vnfds,
                                  n2vc_key_list, stage, start_deploy, timeout_ns_deploy):
 
         db_vims = {}
@@ -915,12 +596,13 @@ class NsLcm(LcmBase):
             for param in ("vim-network-name", "vim-network-id"):
                 if vld_params.get(param):
                     if isinstance(vld_params[param], dict):
-                        pass
-                        # for vim_account, vim_net in vld_params[param].items():
-                        # TODO populate vim_info   RO_vld_sites.append({
+                        for vim, vim_net in vld_params[param]:
+                            other_target_vim = "vim:" + vim
+                            populate_dict(target_vld["vim_info"], (other_target_vim, param.replace("-", "_")), vim_net)
                     else:  # isinstance str
                         target_vld["vim_info"][target_vim][param.replace("-", "_")] = vld_params[param]
-            # TODO  if vld_params.get("ns-net"):
+            if vld_params.get("common_id"):
+                target_vld["common_id"] = vld_params.get("common_id")
 
         nslcmop_id = db_nslcmop["_id"]
         target = {
@@ -944,11 +626,8 @@ class NsLcm(LcmBase):
             ns_params = db_nslcmop_instantiate.get("operationParams")
         else:
             ns_params = db_nslcmop.get("operationParams")
-        ssh_keys = []
-        if ns_params.get("ssh_keys"):
-            ssh_keys += ns_params.get("ssh_keys")
-        if n2vc_key_list:
-            ssh_keys += n2vc_key_list
+        ssh_keys_instantiation = ns_params.get("ssh_keys") or []
+        ssh_keys_all = ssh_keys_instantiation + (n2vc_key_list or [])
 
         cp2target = {}
         for vld_index, vld in enumerate(db_nsr.get("vld")):
@@ -959,52 +638,60 @@ class NsLcm(LcmBase):
                 "mgmt-network": vld.get("mgmt-network", False),
                 "type": vld.get("type"),
                 "vim_info": {
-                    target_vim: {"vim-network-name": vld.get("vim-network-name")}
+                    target_vim: {
+                        "vim_network_name": vld.get("vim-network-name"),
+                        "vim_account_id": ns_params["vimAccountId"]
+                    }
                 }
             }
             # check if this network needs SDN assist
-            target_sdn = None
             if vld.get("pci-interfaces"):
-                db_vim = get_vim_account(ns_params["vimAccountId"])
+                db_vim = VimAccountDB.get_vim_account_with_id(target_vld["vim_info"][0]["vim_account_id"])
                 sdnc_id = db_vim["config"].get("sdn-controller")
                 if sdnc_id:
-                    sdn_vld = "nsrs:{}:vld.{}".format(nsr_id, vld["id"])
-                    target_sdn = "sdn:{}".format(sdnc_id)
-                    target_vld["vim_info"][target_sdn] = {
-                        "sdn": True, "target_vim": target_vim, "vlds": [sdn_vld], "type": vld.get("type")}
+                    target_vld["vim_info"].append({"sdnc_id": sdnc_id})
 
-            nsd_vld = next(v for v in nsd["vld"] if v["id"] == vld["id"])
-            for cp in nsd_vld["vnfd-connection-point-ref"]:
-                cp2target["member_vnf:{}.{}".format(cp["member-vnf-index-ref"], cp["vnfd-connection-point-ref"])] = \
-                    "nsrs:{}:vld.{}".format(nsr_id, vld_index)
+            nsd_vnf_profiles = get_vnf_profiles(nsd)
+            for nsd_vnf_profile in nsd_vnf_profiles:
+                for cp in nsd_vnf_profile["virtual-link-connectivity"]:
+                    if cp["virtual-link-profile-id"] == vld["id"]:
+                        cp2target["member_vnf:{}.{}".format(
+                            cp["constituent-cpd-id"][0]["constituent-base-element-id"],
+                            cp["constituent-cpd-id"][0]["constituent-cpd-id"]
+                        )] = "nsrs:{}:vld.{}".format(nsr_id, vld_index)
 
             # check at nsd descriptor, if there is an ip-profile
             vld_params = {}
-            if nsd_vld.get("ip-profile-ref"):
-                ip_profile = next(ipp for ipp in nsd["ip-profiles"] if ipp["name"] == nsd_vld["ip-profile-ref"])
+            virtual_link_profiles = get_virtual_link_profiles(nsd)
+
+            for vlp in virtual_link_profiles:
+                ip_profile = find_in_list(nsd["ip-profiles"],
+                                          lambda profile: profile["name"] == vlp["ip-profile-ref"])
                 vld_params["ip-profile"] = ip_profile["ip-profile-params"]
             # update vld_params with instantiation params
-            vld_instantiation_params = next((v for v in get_iterable(ns_params, "vld")
-                                             if v["name"] in (vld["name"], vld["id"])), None)
+            vld_instantiation_params = find_in_list(get_iterable(ns_params, "vld"),
+                                                    lambda a_vld: a_vld["name"] in (vld["name"], vld["id"]))
             if vld_instantiation_params:
                 vld_params.update(vld_instantiation_params)
-            parse_vld_instantiation_params(target_vim, target_vld, vld_params, target_sdn)
+            parse_vld_instantiation_params(target_vim, target_vld, vld_params, None)
             target["ns"]["vld"].append(target_vld)
+
         for vnfr in db_vnfrs.values():
-            vnfd = db_vnfds_ref[vnfr["vnfd-ref"]]
-            vnf_params = next((v for v in get_iterable(ns_params, "vnf")
-                               if v["member-vnf-index"] == vnfr["member-vnf-index-ref"]), None)
+            vnfd = find_in_list(db_vnfds, lambda db_vnf: db_vnf["id"] == vnfr["vnfd-ref"])
+            vnf_params = find_in_list(get_iterable(ns_params, "vnf"),
+                                      lambda a_vnf: a_vnf["member-vnf-index"] == vnfr["member-vnf-index-ref"])
             target_vnf = deepcopy(vnfr)
             target_vim = "vim:{}".format(vnfr["vim-account-id"])
             for vld in target_vnf.get("vld", ()):
                 # check if connected to a ns.vld, to fill target'
-                vnf_cp = next((cp for cp in vnfd.get("connection-point", ()) if
-                               cp.get("internal-vld-ref") == vld["id"]), None)
+                vnf_cp = find_in_list(vnfd.get("int-virtual-link-desc", ()),
+                                      lambda cpd: cpd.get("id") == vld["id"])
                 if vnf_cp:
                     ns_cp = "member_vnf:{}.{}".format(vnfr["member-vnf-index-ref"], vnf_cp["id"])
                     if cp2target.get(ns_cp):
                         vld["target"] = cp2target[ns_cp]
-                vld["vim_info"] = {target_vim: {"vim-network-name": vld.get("vim-network-name")}}
+
+                vld["vim_info"] = {target_vim: {"vim_network_name": vld.get("vim-network-name")}}
                 # check if this network needs SDN assist
                 target_sdn = None
                 if vld.get("pci-interfaces"):
@@ -1018,14 +705,30 @@ class NsLcm(LcmBase):
 
                 # check at vnfd descriptor, if there is an ip-profile
                 vld_params = {}
-                vnfd_vld = next(v for v in vnfd["internal-vld"] if v["id"] == vld["id"])
-                if vnfd_vld.get("ip-profile-ref"):
-                    ip_profile = next(ipp for ipp in vnfd["ip-profiles"] if ipp["name"] == vnfd_vld["ip-profile-ref"])
-                    vld_params["ip-profile"] = ip_profile["ip-profile-params"]
+                vnfd_vlp = find_in_list(
+                    get_virtual_link_profiles(vnfd),
+                    lambda a_link_profile: a_link_profile["id"] == vld["id"]
+                )
+                if vnfd_vlp and vnfd_vlp.get("virtual-link-protocol-data") and \
+                   vnfd_vlp["virtual-link-protocol-data"].get("l3-protocol-data"):
+                    ip_profile_source_data = vnfd_vlp["virtual-link-protocol-data"]["l3-protocol-data"]
+                    ip_profile_dest_data = {}
+                    if "ip-version" in ip_profile_source_data:
+                        ip_profile_dest_data["ip-version"] = ip_profile_source_data["ip-version"]
+                    if "cidr" in ip_profile_source_data:
+                        ip_profile_dest_data["subnet-address"] = ip_profile_source_data["cidr"]
+                    if "gateway-ip" in ip_profile_source_data:
+                        ip_profile_dest_data["gateway-address"] = ip_profile_source_data["gateway-ip"]
+                    if "dhcp-enabled" in ip_profile_source_data:
+                        ip_profile_dest_data["dhcp-params"] = {
+                            "enabled": ip_profile_source_data["dhcp-enabled"]
+                        }
+
+                    vld_params["ip-profile"] = ip_profile_dest_data
                 # update vld_params with instantiation params
                 if vnf_params:
-                    vld_instantiation_params = next((v for v in get_iterable(vnf_params, "internal-vld")
-                                                     if v["name"] == vld["id"]), None)
+                    vld_instantiation_params = find_in_list(get_iterable(vnf_params, "internal-vld"),
+                                                            lambda i_vld: i_vld["name"] == vld["id"])
                     if vld_instantiation_params:
                         vld_params.update(vld_instantiation_params)
                 parse_vld_instantiation_params(target_vim, vld, vld_params, target_sdn)
@@ -1034,18 +737,29 @@ class NsLcm(LcmBase):
             for vdur in target_vnf.get("vdur", ()):
                 if vdur.get("status") == "DELETING" or vdur.get("pdu-type"):
                     continue  # This vdu must not be created
-                vdur["vim_info"] = {target_vim: {}}
-                vdud_index, vdud = next(k for k in enumerate(vnfd["vdu"]) if k[1]["id"] == vdur["vdu-id-ref"])
-
-                if ssh_keys:
-                    if deep_get(vdud, ("vdu-configuration", "config-access", "ssh-access", "required")):
-                        vdur["ssh-keys"] = ssh_keys
-                        vdur["ssh-access-required"] = True
-                    elif deep_get(vnfd, ("vnf-configuration", "config-access", "ssh-access", "required")) and \
+                vdur["vim_info"] = {"vim_account_id": vnfr["vim-account-id"]}
+
+                self.logger.debug("NS > ssh_keys > {}".format(ssh_keys_all))
+
+                if ssh_keys_all:
+                    vdu_configuration = get_vdu_configuration(vnfd, vdur["vdu-id-ref"])
+                    vnf_configuration = get_vnf_configuration(vnfd)
+                    if vdu_configuration and vdu_configuration.get("config-access") and \
+                       vdu_configuration.get("config-access").get("ssh-access"):
+                        vdur["ssh-keys"] = ssh_keys_all
+                        vdur["ssh-access-required"] = vdu_configuration["config-access"]["ssh-access"]["required"]
+                    elif vnf_configuration and vnf_configuration.get("config-access") and \
+                        vnf_configuration.get("config-access").get("ssh-access") and \
                             any(iface.get("mgmt-vnf") for iface in vdur["interfaces"]):
-                        vdur["ssh-keys"] = ssh_keys
-                        vdur["ssh-access-required"] = True
+                        vdur["ssh-keys"] = ssh_keys_all
+                        vdur["ssh-access-required"] = vnf_configuration["config-access"]["ssh-access"]["required"]
+                    elif ssh_keys_instantiation and \
+                            find_in_list(vdur["interfaces"], lambda iface: iface.get("mgmt-vnf")):
+                        vdur["ssh-keys"] = ssh_keys_instantiation
+
+                self.logger.debug("NS > vdur > {}".format(vdur))
 
+                vdud = get_vdu(vnfd, vdur["vdu-id-ref"])
                 # cloud-init
                 if vdud.get("cloud-init-file"):
                     vdur["cloud-init"] = "{}:file:{}".format(vnfd["_id"], vdud.get("cloud-init-file"))
@@ -1057,12 +771,12 @@ class NsLcm(LcmBase):
                         with self.fs.file_open(cloud_init_file, "r") as ci_file:
                             target["cloud_init_content"][vdur["cloud-init"]] = ci_file.read()
                 elif vdud.get("cloud-init"):
-                    vdur["cloud-init"] = "{}:vdu:{}".format(vnfd["_id"], vdud_index)
+                    vdur["cloud-init"] = "{}:vdu:{}".format(vnfd["_id"], get_vdu_index(vnfd, vdur["vdu-id-ref"]))
                     # put content at target.cloul_init_content. Avoid ng_ro read vnfd descriptor
                     target["cloud_init_content"][vdur["cloud-init"]] = vdud["cloud-init"]
                 vdur["additionalParams"] = vdur.get("additionalParams") or {}
                 deploy_params_vdu = self._format_additional_params(vdur.get("additionalParams") or {})
-                deploy_params_vdu["OSM"] = self._get_osm_params(vnfr, vdur["vdu-id-ref"], vdur["count-index"])
+                deploy_params_vdu["OSM"] = get_osm_params(vnfr, vdur["vdu-id-ref"], vdur["count-index"])
                 vdur["additionalParams"] = deploy_params_vdu
 
                 # flavor
@@ -1084,6 +798,7 @@ class NsLcm(LcmBase):
             target["vnf"].append(target_vnf)
 
         desc = await self.RO.deploy(nsr_id, target)
+        self.logger.debug("RO return > {}".format(desc))
         action_id = desc["action_id"]
         await self._wait_ng_ro(nsr_id, action_id, nslcmop_id, start_deploy, timeout_ns_deploy, stage)
 
@@ -1104,6 +819,7 @@ class NsLcm(LcmBase):
         start_time = start_time or time()
         while time() <= start_time + timeout:
             desc_status = await self.RO.status(nsr_id, action_id)
+            self.logger.debug("Wait NG RO > {}".format(desc_status))
             if desc_status["status"] == "FAILED":
                 raise NgRoException(desc_status["details"])
             elif desc_status["status"] == "BUILD":
@@ -1120,7 +836,7 @@ class NsLcm(LcmBase):
                 db_nsr_update["detailed-status"] = " ".join(stage)
                 self.update_db_2("nsrs", nsr_id, db_nsr_update)
                 self._write_op_status(nslcmop_id, stage)
-            await asyncio.sleep(5, loop=self.loop)
+            await asyncio.sleep(15, loop=self.loop)
         else:  # timeout_ns_deploy
             raise NgRoException("Timeout waiting ns to deploy")
 
@@ -1176,7 +892,7 @@ class NsLcm(LcmBase):
             raise LcmException("; ".join(failed_detail))
         return
 
-    async def instantiate_RO(self, logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs, db_vnfds_ref,
+    async def instantiate_RO(self, logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs, db_vnfds,
                              n2vc_key_list, stage):
         """
         Instantiate at RO
@@ -1186,16 +902,12 @@ class NsLcm(LcmBase):
         :param db_nsr: database content of ns record
         :param db_nslcmop: database content of ns operation, in this case, 'instantiate'
         :param db_vnfrs:
-        :param db_vnfds_ref: database content of vnfds, indexed by id (not _id). {id: {vnfd_object}, ...}
+        :param db_vnfds: database content of vnfds, indexed by id (not _id). {id: {vnfd_object}, ...}
         :param n2vc_key_list: ssh-public-key list to be inserted to management vdus via cloud-init
         :param stage: list with 3 items: [general stage, tasks, vim_specific]. This task will write over vim_specific
         :return: None or exception
         """
         try:
-            db_nsr_update = {}
-            RO_descriptor_number = 0   # number of descriptors created at RO
-            vnf_index_2_RO_id = {}    # map between vnfd/nsd id to the id used at RO
-            nslcmop_id = db_nslcmop["_id"]
             start_deploy = time()
             ns_params = db_nslcmop.get("operationParams")
             if ns_params and ns_params.get("timeout_ns_deploy"):
@@ -1213,205 +925,8 @@ class NsLcm(LcmBase):
                 else:
                     ns_params["vimAccountId"] == vnfr["vim-account-id"]
 
-            if self.ng_ro:
-                return await self._instantiate_ng_ro(logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs,
-                                                     db_vnfds_ref, n2vc_key_list, stage, start_deploy,
-                                                     timeout_ns_deploy)
-            # deploy RO
-            # get vnfds, instantiate at RO
-            for c_vnf in nsd.get("constituent-vnfd", ()):
-                member_vnf_index = c_vnf["member-vnf-index"]
-                vnfd = db_vnfds_ref[c_vnf['vnfd-id-ref']]
-                vnfd_ref = vnfd["id"]
-
-                stage[2] = "Creating vnfd='{}' member_vnf_index='{}' at RO".format(vnfd_ref, member_vnf_index)
-                db_nsr_update["detailed-status"] = " ".join(stage)
-                self.update_db_2("nsrs", nsr_id, db_nsr_update)
-                self._write_op_status(nslcmop_id, stage)
-
-                # self.logger.debug(logging_text + stage[2])
-                vnfd_id_RO = "{}.{}.{}".format(nsr_id, RO_descriptor_number, member_vnf_index[:23])
-                vnf_index_2_RO_id[member_vnf_index] = vnfd_id_RO
-                RO_descriptor_number += 1
-
-                # look position at deployed.RO.vnfd if not present it will be appended at the end
-                for index, vnf_deployed in enumerate(db_nsr["_admin"]["deployed"]["RO"]["vnfd"]):
-                    if vnf_deployed["member-vnf-index"] == member_vnf_index:
-                        break
-                else:
-                    index = len(db_nsr["_admin"]["deployed"]["RO"]["vnfd"])
-                    db_nsr["_admin"]["deployed"]["RO"]["vnfd"].append(None)
-
-                # look if present
-                RO_update = {"member-vnf-index": member_vnf_index}
-                vnfd_list = await self.RO.get_list("vnfd", filter_by={"osm_id": vnfd_id_RO})
-                if vnfd_list:
-                    RO_update["id"] = vnfd_list[0]["uuid"]
-                    self.logger.debug(logging_text + "vnfd='{}'  member_vnf_index='{}' exists at RO. Using RO_id={}".
-                                      format(vnfd_ref, member_vnf_index, vnfd_list[0]["uuid"]))
-                else:
-                    vnfd_RO = self.vnfd2RO(vnfd, vnfd_id_RO, db_vnfrs[c_vnf["member-vnf-index"]].
-                                           get("additionalParamsForVnf"), nsr_id)
-                    desc = await self.RO.create("vnfd", descriptor=vnfd_RO)
-                    RO_update["id"] = desc["uuid"]
-                    self.logger.debug(logging_text + "vnfd='{}' member_vnf_index='{}' created at RO. RO_id={}".format(
-                        vnfd_ref, member_vnf_index, desc["uuid"]))
-                db_nsr_update["_admin.deployed.RO.vnfd.{}".format(index)] = RO_update
-                db_nsr["_admin"]["deployed"]["RO"]["vnfd"][index] = RO_update
-
-            # create nsd at RO
-            nsd_ref = nsd["id"]
-
-            stage[2] = "Creating nsd={} at RO".format(nsd_ref)
-            db_nsr_update["detailed-status"] = " ".join(stage)
-            self.update_db_2("nsrs", nsr_id, db_nsr_update)
-            self._write_op_status(nslcmop_id, stage)
-
-            # self.logger.debug(logging_text + stage[2])
-            RO_osm_nsd_id = "{}.{}.{}".format(nsr_id, RO_descriptor_number, nsd_ref[:23])
-            RO_descriptor_number += 1
-            nsd_list = await self.RO.get_list("nsd", filter_by={"osm_id": RO_osm_nsd_id})
-            if nsd_list:
-                db_nsr_update["_admin.deployed.RO.nsd_id"] = RO_nsd_uuid = nsd_list[0]["uuid"]
-                self.logger.debug(logging_text + "nsd={} exists at RO. Using RO_id={}".format(
-                    nsd_ref, RO_nsd_uuid))
-            else:
-                nsd_RO = deepcopy(nsd)
-                nsd_RO["id"] = RO_osm_nsd_id
-                nsd_RO.pop("_id", None)
-                nsd_RO.pop("_admin", None)
-                for c_vnf in nsd_RO.get("constituent-vnfd", ()):
-                    member_vnf_index = c_vnf["member-vnf-index"]
-                    c_vnf["vnfd-id-ref"] = vnf_index_2_RO_id[member_vnf_index]
-                for c_vld in nsd_RO.get("vld", ()):
-                    for cp in c_vld.get("vnfd-connection-point-ref", ()):
-                        member_vnf_index = cp["member-vnf-index-ref"]
-                        cp["vnfd-id-ref"] = vnf_index_2_RO_id[member_vnf_index]
-
-                desc = await self.RO.create("nsd", descriptor=nsd_RO)
-                db_nsr_update["_admin.nsState"] = "INSTANTIATED"
-                db_nsr_update["_admin.deployed.RO.nsd_id"] = RO_nsd_uuid = desc["uuid"]
-                self.logger.debug(logging_text + "nsd={} created at RO. RO_id={}".format(nsd_ref, RO_nsd_uuid))
-            self.update_db_2("nsrs", nsr_id, db_nsr_update)
-
-            # Crate ns at RO
-            stage[2] = "Creating nsd={} at RO".format(nsd_ref)
-            db_nsr_update["detailed-status"] = " ".join(stage)
-            self.update_db_2("nsrs", nsr_id, db_nsr_update)
-            self._write_op_status(nslcmop_id, stage)
-
-            # if present use it unless in error status
-            RO_nsr_id = deep_get(db_nsr, ("_admin", "deployed", "RO", "nsr_id"))
-            if RO_nsr_id:
-                try:
-                    stage[2] = "Looking for existing ns at RO"
-                    db_nsr_update["detailed-status"] = " ".join(stage)
-                    self.update_db_2("nsrs", nsr_id, db_nsr_update)
-                    self._write_op_status(nslcmop_id, stage)
-                    # self.logger.debug(logging_text + stage[2] + " RO_ns_id={}".format(RO_nsr_id))
-                    desc = await self.RO.show("ns", RO_nsr_id)
-
-                except ROclient.ROClientException as e:
-                    if e.http_code != HTTPStatus.NOT_FOUND:
-                        raise
-                    RO_nsr_id = db_nsr_update["_admin.deployed.RO.nsr_id"] = None
-                if RO_nsr_id:
-                    ns_status, ns_status_info = self.RO.check_ns_status(desc)
-                    db_nsr_update["_admin.deployed.RO.nsr_status"] = ns_status
-                    if ns_status == "ERROR":
-                        stage[2] = "Deleting ns at RO. RO_ns_id={}".format(RO_nsr_id)
-                        self.logger.debug(logging_text + stage[2])
-                        await self.RO.delete("ns", RO_nsr_id)
-                        RO_nsr_id = db_nsr_update["_admin.deployed.RO.nsr_id"] = None
-            if not RO_nsr_id:
-                stage[2] = "Checking dependencies"
-                db_nsr_update["detailed-status"] = " ".join(stage)
-                self.update_db_2("nsrs", nsr_id, db_nsr_update)
-                self._write_op_status(nslcmop_id, stage)
-                # self.logger.debug(logging_text + stage[2])
-
-                # check if VIM is creating and wait  look if previous tasks in process
-                task_name, task_dependency = self.lcm_tasks.lookfor_related("vim_account", ns_params["vimAccountId"])
-                if task_dependency:
-                    stage[2] = "Waiting for related tasks '{}' to be completed".format(task_name)
-                    self.logger.debug(logging_text + stage[2])
-                    await asyncio.wait(task_dependency, timeout=3600)
-                if ns_params.get("vnf"):
-                    for vnf in ns_params["vnf"]:
-                        if "vimAccountId" in vnf:
-                            task_name, task_dependency = self.lcm_tasks.lookfor_related("vim_account",
-                                                                                        vnf["vimAccountId"])
-                        if task_dependency:
-                            stage[2] = "Waiting for related tasks '{}' to be completed.".format(task_name)
-                            self.logger.debug(logging_text + stage[2])
-                            await asyncio.wait(task_dependency, timeout=3600)
-
-                stage[2] = "Checking instantiation parameters."
-                RO_ns_params = self._ns_params_2_RO(ns_params, nsd, db_vnfds_ref, db_vnfrs, n2vc_key_list)
-                stage[2] = "Deploying ns at VIM."
-                db_nsr_update["detailed-status"] = " ".join(stage)
-                self.update_db_2("nsrs", nsr_id, db_nsr_update)
-                self._write_op_status(nslcmop_id, stage)
-
-                desc = await self.RO.create("ns", descriptor=RO_ns_params, name=db_nsr["name"], scenario=RO_nsd_uuid)
-                RO_nsr_id = db_nsr_update["_admin.deployed.RO.nsr_id"] = desc["uuid"]
-                db_nsr_update["_admin.nsState"] = "INSTANTIATED"
-                db_nsr_update["_admin.deployed.RO.nsr_status"] = "BUILD"
-                self.logger.debug(logging_text + "ns created at RO. RO_id={}".format(desc["uuid"]))
-
-            # wait until NS is ready
-            stage[2] = "Waiting VIM to deploy ns."
-            db_nsr_update["detailed-status"] = " ".join(stage)
-            self.update_db_2("nsrs", nsr_id, db_nsr_update)
-            self._write_op_status(nslcmop_id, stage)
-            detailed_status_old = None
-            self.logger.debug(logging_text + stage[2] + " RO_ns_id={}".format(RO_nsr_id))
-
-            old_desc = None
-            while time() <= start_deploy + timeout_ns_deploy:
-                desc = await self.RO.show("ns", RO_nsr_id)
-
-                # deploymentStatus
-                if desc != old_desc:
-                    # desc has changed => update db
-                    self._on_update_ro_db(nsrs_id=nsr_id, ro_descriptor=desc)
-                    old_desc = desc
-
-                    ns_status, ns_status_info = self.RO.check_ns_status(desc)
-                    db_nsr_update["_admin.deployed.RO.nsr_status"] = ns_status
-                    if ns_status == "ERROR":
-                        raise ROclient.ROClientException(ns_status_info)
-                    elif ns_status == "BUILD":
-                        stage[2] = "VIM: ({})".format(ns_status_info)
-                    elif ns_status == "ACTIVE":
-                        stage[2] = "Waiting for management IP address reported by the VIM. Updating VNFRs."
-                        try:
-                            self.ns_update_vnfr(db_vnfrs, desc)
-                            break
-                        except LcmExceptionNoMgmtIP:
-                            pass
-                    else:
-                        assert False, "ROclient.check_ns_status returns unknown {}".format(ns_status)
-                    if stage[2] != detailed_status_old:
-                        detailed_status_old = stage[2]
-                        db_nsr_update["detailed-status"] = " ".join(stage)
-                        self.update_db_2("nsrs", nsr_id, db_nsr_update)
-                        self._write_op_status(nslcmop_id, stage)
-                    await asyncio.sleep(5, loop=self.loop)
-            else:  # timeout_ns_deploy
-                raise ROclient.ROClientException("Timeout waiting ns to be ready")
-
-            # Updating NSR
-            self.ns_update_nsr(db_nsr_update, db_nsr, desc)
-
-            db_nsr_update["_admin.deployed.RO.operational-status"] = "running"
-            # db_nsr["_admin.deployed.RO.detailed-status"] = "Deployed at VIM"
-            stage[2] = "Deployed at VIM"
-            db_nsr_update["detailed-status"] = " ".join(stage)
-            self.update_db_2("nsrs", nsr_id, db_nsr_update)
-            self._write_op_status(nslcmop_id, stage)
-            # await self._on_update_n2vc_db("nsrs", {"_id": nsr_id}, "_admin.deployed", db_nsr_update)
-            # self.logger.debug(logging_text + "Deployed at VIM")
+            return await self._instantiate_ng_ro(logging_text, nsr_id, nsd, db_nsr, db_nslcmop, db_vnfrs,
+                                                 db_vnfds, n2vc_key_list, stage, start_deploy, timeout_ns_deploy)
         except Exception as e:
             stage[2] = "ERROR deploying at VIM"
             self.set_vnfr_at_error(db_vnfrs, str(e))
@@ -1507,10 +1022,7 @@ class NsLcm(LcmBase):
                     if not ip_address:
                         continue
                     target_vdu_id = vdur["vdu-id-ref"]
-                elif (
-                    vdur.get("status") == "ERROR" or
-                    vdur.get("vim_info", {}).get(target_vim, {}).get("vim_status") == "ERROR"
-                ):
+                elif vdur.get("status") == "ERROR" or ng_ro_status == "ERROR":
                     raise LcmException("Cannot inject ssh-key because target VM is in error state")
 
             if not target_vdu_id:
@@ -1519,13 +1031,14 @@ class NsLcm(LcmBase):
             # inject public key into machine
             if pub_key and user:
                 self.logger.debug(logging_text + "Inserting RO key")
+                self.logger.debug("SSH > PubKey > {}".format(pub_key))
                 if vdur.get("pdu-type"):
                     self.logger.error(logging_text + "Cannot inject ssh-ky to a PDU")
                     return ip_address
                 try:
                     ro_vm_id = "{}-{}".format(db_vnfr["member-vnf-index-ref"], target_vdu_id)  # TODO add vdu_index
                     if self.ng_ro:
-                        target = {"action": "inject_ssh_key", "key": pub_key, "user": user,
+                        target = {"action": {"action": "inject_ssh_key", "key": pub_key, "user": user},
                                   "vnf": [{"_id": vnfr_id, "vdur": [{"id": vdur["id"]}]}],
                                   }
                         desc = await self.RO.deploy(nsr_id, target)
@@ -1652,14 +1165,21 @@ class NsLcm(LcmBase):
                 "charms" if vca_type in ("native_charm", "lxc_proxy_charm", "k8s_proxy_charm") else "helm-charts",
                 vca_name
             )
+
+            self.logger.debug("Artifact path > {}".format(artifact_path))
+
             # get initial_config_primitive_list that applies to this element
             initial_config_primitive_list = config_descriptor.get('initial-config-primitive')
 
+            self.logger.debug("Initial config primitive list > {}".format(initial_config_primitive_list))
+
             # add config if not present for NS charm
             ee_descriptor_id = ee_config_descriptor.get("id")
-            initial_config_primitive_list = self._get_initial_config_primitive_list(initial_config_primitive_list,
-                                                                                    vca_deployed, ee_descriptor_id)
+            self.logger.debug("EE Descriptor > {}".format(ee_descriptor_id))
+            initial_config_primitive_list = get_ee_sorted_initial_config_primitive_list(initial_config_primitive_list,
+                                                                                        vca_deployed, ee_descriptor_id)
 
+            self.logger.debug("Initial config primitive list #2 > {}".format(initial_config_primitive_list))
             # n2vc_redesign STEP 3.1
             # find old ee_id if exists
             ee_id = vca_deployed.get("ee_id")
@@ -1695,6 +1215,14 @@ class NsLcm(LcmBase):
                         cloud_name=vca_k8s_cloud,
                         credential_name=vca_k8s_cloud_credential,
                     )
+                elif vca_type == "helm" or vca_type == "helm-v3":
+                    ee_id, credentials = await self.vca_map[vca_type].create_execution_environment(
+                        namespace=namespace,
+                        reuse_ee_id=ee_id,
+                        db_dict=db_dict,
+                        cloud_name=vca_cloud,
+                        credential_name=vca_cloud_credential,
+                    )
                 else:
                     ee_id, credentials = await self.vca_map[vca_type].create_execution_environment(
                         namespace=namespace,
@@ -2142,15 +1670,13 @@ class NsLcm(LcmBase):
             db_vnfrs_list = self.db.get_list("vnfrs", {"nsr-id-ref": nsr_id})
 
             # read from db: vnfd's for every vnf
-            db_vnfds_ref = {}     # every vnfd data indexed by vnf name
-            db_vnfds = {}         # every vnfd data indexed by vnf id
-            db_vnfds_index = {}   # every vnfd data indexed by vnf member-index
+            db_vnfds = []         # every vnfd data
 
             # for each vnf in ns, read vnfd
             for vnfr in db_vnfrs_list:
-                db_vnfrs[vnfr["member-vnf-index-ref"]] = vnfr   # vnf's dict indexed by member-index: '1', '2', etc
-                vnfd_id = vnfr["vnfd-id"]                       # vnfd uuid for this vnf
-                vnfd_ref = vnfr["vnfd-ref"]                     # vnfd name for this vnf
+                db_vnfrs[vnfr["member-vnf-index-ref"]] = vnfr
+                vnfd_id = vnfr["vnfd-id"]
+                vnfd_ref = vnfr["vnfd-ref"]
 
                 # if we haven't this vnfd, read it from db
                 if vnfd_id not in db_vnfds:
@@ -2160,9 +1686,7 @@ class NsLcm(LcmBase):
                     vnfd = self.db.get_one("vnfds", {"_id": vnfd_id})
 
                     # store vnfd
-                    db_vnfds_ref[vnfd_ref] = vnfd     # vnfd's indexed by name
-                    db_vnfds[vnfd_id] = vnfd          # vnfd's indexed by id
-                db_vnfds_index[vnfr["member-vnf-index-ref"]] = db_vnfds[vnfd_id]  # vnfd's indexed by member-index
+                    db_vnfds.append(vnfd)          # vnfd's indexed by id
 
             # Get or generates the _admin.deployed.VCA list
             vca_deployed_list = None
@@ -2226,7 +1750,7 @@ class NsLcm(LcmBase):
                     db_nsr=db_nsr,
                     db_nslcmop=db_nslcmop,
                     db_vnfrs=db_vnfrs,
-                    db_vnfds_ref=db_vnfds_ref,
+                    db_vnfds=db_vnfds,
                     n2vc_key_list=n2vc_key_list,
                     stage=stage
                 )
@@ -2239,11 +1763,10 @@ class NsLcm(LcmBase):
             self.logger.debug(logging_text + stage[1])
 
             nsi_id = None  # TODO put nsi_id when this nsr belongs to a NSI
-            # get_iterable() returns a value from a dict or empty tuple if key does not exist
-            for c_vnf in get_iterable(nsd, "constituent-vnfd"):
-                vnfd_id = c_vnf["vnfd-id-ref"]
-                vnfd = db_vnfds_ref[vnfd_id]
-                member_vnf_index = str(c_vnf["member-vnf-index"])
+            for vnf_profile in get_vnf_profiles(nsd):
+                vnfd_id = vnf_profile["vnfd-id"]
+                vnfd = find_in_list(db_vnfds, lambda a_vnf: a_vnf["id"] == vnfd_id)
+                member_vnf_index = str(vnf_profile["id"])
                 db_vnfr = db_vnfrs[member_vnf_index]
                 base_folder = vnfd["_admin"]["storage"]
                 vdu_id = None
@@ -2252,11 +1775,11 @@ class NsLcm(LcmBase):
                 kdu_name = None
 
                 # Get additional parameters
-                deploy_params = {"OSM": self._get_osm_params(db_vnfr)}
+                deploy_params = {"OSM": get_osm_params(db_vnfr)}
                 if db_vnfr.get("additionalParamsForVnf"):
-                    deploy_params.update(self._format_additional_params(db_vnfr["additionalParamsForVnf"].copy()))
+                    deploy_params.update(parse_yaml_strings(db_vnfr["additionalParamsForVnf"].copy()))
 
-                descriptor_config = vnfd.get("vnf-configuration")
+                descriptor_config = get_vnf_configuration(vnfd)
                 if descriptor_config:
                     self._deploy_n2vc(
                         logging_text=logging_text + "member_vnf_index={} ".format(member_vnf_index),
@@ -2279,19 +1802,24 @@ class NsLcm(LcmBase):
                     )
 
                 # Deploy charms for each VDU that supports one.
-                for vdud in get_iterable(vnfd, 'vdu'):
+                for vdud in get_vdu_list(vnfd):
                     vdu_id = vdud["id"]
-                    descriptor_config = vdud.get('vdu-configuration')
-                    vdur = next((x for x in db_vnfr["vdur"] if x["vdu-id-ref"] == vdu_id), None)
+                    descriptor_config = get_vdu_configuration(vnfd, vdu_id)
+                    vdur = find_in_list(db_vnfr["vdur"], lambda vdu: vdu["vdu-id-ref"] == vdu_id)
+
                     if vdur.get("additionalParams"):
-                        deploy_params_vdu = self._format_additional_params(vdur["additionalParams"])
+                        deploy_params_vdu = parse_yaml_strings(vdur["additionalParams"])
                     else:
                         deploy_params_vdu = deploy_params
-                    deploy_params_vdu["OSM"] = self._get_osm_params(db_vnfr, vdu_id, vdu_count_index=0)
+                    deploy_params_vdu["OSM"] = get_osm_params(db_vnfr, vdu_id, vdu_count_index=0)
+                    vdud_count = get_vdu_profile(vnfd, vdu_id).get("max-number-of-instances", 1)
+
+                    self.logger.debug("VDUD > {}".format(vdud))
+                    self.logger.debug("Descriptor config > {}".format(descriptor_config))
                     if descriptor_config:
                         vdu_name = None
                         kdu_name = None
-                        for vdu_index in range(int(vdud.get("count", 1))):
+                        for vdu_index in range(vdud_count):
                             # TODO vnfr_params["rw_mgmt_ip"] = vdur["ip-address"]
                             self._deploy_n2vc(
                                 logging_text=logging_text + "member_vnf_index={}, vdu_id={}, vdu_index={} ".format(
@@ -2313,17 +1841,17 @@ class NsLcm(LcmBase):
                                 task_instantiation_info=tasks_dict_info,
                                 stage=stage
                             )
-                for kdud in get_iterable(vnfd, 'kdu'):
+                for kdud in get_kdu_list(vnfd):
                     kdu_name = kdud["name"]
-                    descriptor_config = kdud.get('kdu-configuration')
+                    descriptor_config = get_kdu_configuration(vnfd, kdu_name)
                     if descriptor_config:
                         vdu_id = None
                         vdu_index = 0
                         vdu_name = None
                         kdur = next(x for x in db_vnfr["kdur"] if x["kdu-name"] == kdu_name)
-                        deploy_params_kdu = {"OSM": self._get_osm_params(db_vnfr)}
+                        deploy_params_kdu = {"OSM": get_osm_params(db_vnfr)}
                         if kdur.get("additionalParams"):
-                            deploy_params_kdu = self._format_additional_params(kdur["additionalParams"])
+                            deploy_params_kdu = parse_yaml_strings(kdur["additionalParams"])
 
                         self._deploy_n2vc(
                             logging_text=logging_text,
@@ -2357,9 +1885,9 @@ class NsLcm(LcmBase):
                 vdu_name = None
 
                 # Get additional parameters
-                deploy_params = {"OSM": self._get_osm_params(db_vnfr)}
+                deploy_params = {"OSM": get_osm_params(db_vnfr)}
                 if db_nsr.get("additionalParamsForNs"):
-                    deploy_params.update(self._format_additional_params(db_nsr["additionalParamsForNs"].copy()))
+                    deploy_params.update(parse_yaml_strings(db_nsr["additionalParamsForNs"].copy()))
                 base_folder = nsd["_admin"]["storage"]
                 self._deploy_n2vc(
                     logging_text=logging_text,
@@ -2778,7 +2306,7 @@ class NsLcm(LcmBase):
             for vnfr_data in db_vnfrs.values():
                 for kdu_index, kdur in enumerate(get_iterable(vnfr_data, "kdur")):
                     # Step 0: Prepare and set parameters
-                    desc_params = self._format_additional_params(kdur.get("additionalParams"))
+                    desc_params = parse_yaml_strings(kdur.get("additionalParams"))
                     vnfd_id = vnfr_data.get('vnfd-id')
                     kdud = next(kdud for kdud in db_vnfds[vnfd_id]["kdu"] if kdud["name"] == kdur["kdu-name"])
                     namespace = kdur.get("k8s-namespace")
@@ -2950,6 +2478,10 @@ class NsLcm(LcmBase):
 
                 db_nsr["_admin"]["deployed"]["VCA"].append(vca_deployed)
 
+            self.logger.debug("N2VC > NSR_ID > {}".format(nsr_id))
+            self.logger.debug("N2VC > DB_NSR > {}".format(db_nsr))
+            self.logger.debug("N2VC > VCA_DEPLOYED > {}".format(vca_deployed))
+
             # Launch task
             task_n2vc = asyncio.ensure_future(
                 self.instantiate_N2VC(
@@ -2975,21 +2507,6 @@ class NsLcm(LcmBase):
             task_instantiation_info[task_n2vc] = self.task_name_deploy_vca + " {}.{}".format(
                 member_vnf_index or "", vdu_id or "")
 
-    @staticmethod
-    def _get_terminate_config_primitive(primitive_list, vca_deployed):
-        """ Get a sorted terminate config primitive list. In case ee_descriptor_id is present at vca_deployed,
-         it get only those primitives for this execution envirom"""
-
-        primitive_list = primitive_list or []
-        # filter primitives by ee_descriptor_id
-        ee_descriptor_id = vca_deployed.get("ee_descriptor_id")
-        primitive_list = [p for p in primitive_list if p.get("execution-environment-ref") == ee_descriptor_id]
-
-        if primitive_list:
-            primitive_list.sort(key=lambda val: int(val['seq']))
-
-        return primitive_list
-
     @staticmethod
     def _create_nslcmop(nsr_id, operation, params):
         """
@@ -3222,8 +2739,8 @@ class NsLcm(LcmBase):
 
         # execute terminate_primitives
         if exec_primitives:
-            terminate_primitives = self._get_terminate_config_primitive(
-                config_descriptor.get("terminate-config-primitive"), vca_deployed)
+            terminate_primitives = get_ee_sorted_terminate_config_primitive_list(
+                config_descriptor.get("terminate-config-primitive"), vca_deployed.get("ee_descriptor_id"))
             vdu_id = vca_deployed.get("vdu_id")
             vdu_count_index = vca_deployed.get("vdu_count_index")
             vdu_name = vca_deployed.get("vdu_name")
@@ -3491,7 +3008,7 @@ class NsLcm(LcmBase):
             self.logger.debug(logging_text + stage[0])
             stage[1] = "Looking execution environment that needs terminate."
             self.logger.debug(logging_text + stage[1])
-            # self.logger.debug("nsr_deployed: {}".format(nsr_deployed))
+
             for vca_index, vca in enumerate(get_iterable(nsr_deployed, "VCA")):
                 config_descriptor = None
                 if not vca or not vca.get("ee_id"):
@@ -3741,8 +3258,8 @@ class NsLcm(LcmBase):
                                    format(param_name, primitive_desc["name"]))
 
             if isinstance(calculated_params[param_name], (dict, list, tuple)):
-                calculated_params[param_name] = yaml.safe_dump(calculated_params[param_name], default_flow_style=True,
-                                                               width=256)
+                calculated_params[param_name] = yaml.safe_dump(calculated_params[param_name],
+                                                               default_flow_style=True, width=256)
             elif isinstance(calculated_params[param_name], str) and calculated_params[param_name].startswith("!!yaml "):
                 calculated_params[param_name] = calculated_params[param_name][7:]
             if parameter.get("data-type") == "INTEGER":
@@ -3780,7 +3297,6 @@ class NsLcm(LcmBase):
             raise LcmException("charm for member_vnf_index={} vdu_id={}.{} kdu_name={} execution-environment-list.id={}"
                                " is not deployed".format(member_vnf_index, vdu_id, vdu_count_index, kdu_name,
                                                          ee_descriptor_id))
-
         # get ee_id
         ee_id = vca.get("ee_id")
         vca_type = vca.get("type", "lxc_proxy_charm")  # default value for backward compatibility - proxy charm
@@ -3790,9 +3306,8 @@ class NsLcm(LcmBase):
                                .format(member_vnf_index, vdu_id, kdu_name, vdu_count_index))
         return ee_id, vca_type
 
-    async def _ns_execute_primitive(self, ee_id, primitive, primitive_params, retries=0,
-                                    retries_interval=30, timeout=None,
-                                    vca_type=None, db_dict=None) -> (str, str):
+    async def _ns_execute_primitive(self, ee_id, primitive, primitive_params, retries=0, retries_interval=30,
+                                    timeout=None, vca_type=None, db_dict=None) -> (str, str):
         try:
             if primitive == "config":
                 primitive_params = {"params": primitive_params}
@@ -3833,7 +3348,6 @@ class NsLcm(LcmBase):
             return 'FAIL', 'Error executing action {}: {}'.format(primitive, e)
 
     async def action(self, nsr_id, nslcmop_id):
-
         # Try to lock HA task here
         task_is_locked_by_me = self.lcm_tasks.lock_HA('ns', 'nslcmops', nslcmop_id)
         if not task_is_locked_by_me:
@@ -3892,17 +3406,11 @@ class NsLcm(LcmBase):
             # look for primitive
             config_primitive_desc = descriptor_configuration = None
             if vdu_id:
-                for vdu in get_iterable(db_vnfd, "vdu"):
-                    if vdu_id == vdu["id"]:
-                        descriptor_configuration = vdu.get("vdu-configuration")
-                        break
+                descriptor_configuration = get_vdu_configuration(db_vnfd, vdu_id)
             elif kdu_name:
-                for kdu in get_iterable(db_vnfd, "kdu"):
-                    if kdu_name == kdu["name"]:
-                        descriptor_configuration = kdu.get("kdu-configuration")
-                        break
+                descriptor_configuration = get_kdu_configuration(db_vnfd, kdu_name)
             elif vnf_index:
-                descriptor_configuration = db_vnfd.get("vnf-configuration")
+                descriptor_configuration = get_vnf_configuration(db_vnfd)
             else:
                 descriptor_configuration = db_nsd.get("ns-configuration")
 
@@ -3925,17 +3433,17 @@ class NsLcm(LcmBase):
             if vnf_index:
                 if vdu_id:
                     vdur = next((x for x in db_vnfr["vdur"] if x["vdu-id-ref"] == vdu_id), None)
-                    desc_params = self._format_additional_params(vdur.get("additionalParams"))
+                    desc_params = parse_yaml_strings(vdur.get("additionalParams"))
                 elif kdu_name:
                     kdur = next((x for x in db_vnfr["kdur"] if x["kdu-name"] == kdu_name), None)
-                    desc_params = self._format_additional_params(kdur.get("additionalParams"))
+                    desc_params = parse_yaml_strings(kdur.get("additionalParams"))
                 else:
-                    desc_params = self._format_additional_params(db_vnfr.get("additionalParamsForVnf"))
+                    desc_params = parse_yaml_strings(db_vnfr.get("additionalParamsForVnf"))
             else:
-                desc_params = self._format_additional_params(db_nsr.get("additionalParamsForNs"))
+                desc_params = parse_yaml_strings(db_nsr.get("additionalParamsForNs"))
 
-            if kdu_name:
-                kdu_action = True if not deep_get(kdu, ("kdu-configuration", "juju")) else False
+            if kdu_name and get_kdu_configuration(db_vnfd):
+                kdu_action = True if not get_kdu_configuration(db_vnfd)["juju"] else False
 
             # TODO check if ns is in a proper status
             if kdu_name and (primitive_name in ("upgrade", "rollback", "status") or kdu_action):
@@ -4009,10 +3517,8 @@ class NsLcm(LcmBase):
                     detailed_status = ''
                     nslcmop_operation_state = 'FAILED'
             else:
-                ee_id, vca_type = self._look_for_deployed_vca(nsr_deployed["VCA"],
-                                                              member_vnf_index=vnf_index,
-                                                              vdu_id=vdu_id,
-                                                              vdu_count_index=vdu_count_index,
+                ee_id, vca_type = self._look_for_deployed_vca(nsr_deployed["VCA"], member_vnf_index=vnf_index,
+                                                              vdu_id=vdu_id, vdu_count_index=vdu_count_index,
                                                               ee_descriptor_id=ee_descriptor_id)
                 db_nslcmop_notif = {"collection": "nslcmops",
                                     "filter": {"_id": nslcmop_id},
@@ -4059,13 +3565,8 @@ class NsLcm(LcmBase):
                     other_update=db_nsr_update
                 )
 
-            self._write_op_status(
-                op_id=nslcmop_id,
-                stage="",
-                error_message=error_description_nslcmop,
-                operation_state=nslcmop_operation_state,
-                other_update=db_nslcmop_update,
-            )
+            self._write_op_status(op_id=nslcmop_id, stage="", error_message=error_description_nslcmop,
+                                  operation_state=nslcmop_operation_state, other_update=db_nslcmop_update)
 
             if nslcmop_operation_state:
                 try:
@@ -4079,7 +3580,6 @@ class NsLcm(LcmBase):
             return nslcmop_operation_state, detailed_status
 
     async def scale(self, nsr_id, nslcmop_id):
-
         # Try to lock HA task here
         task_is_locked_by_me = self.lcm_tasks.lock_HA('ns', 'nslcmops', nslcmop_id)
         if not task_is_locked_by_me:
@@ -4091,9 +3591,7 @@ class NsLcm(LcmBase):
         self.logger.debug(logging_text + "Enter")
         # get all needed from database
         db_nsr = None
-        db_nslcmop = None
         db_nslcmop_update = {}
-        nslcmop_operation_state = None
         db_nsr_update = {}
         exc = None
         # in case of error, indicates what part of scale was failed to put nsr at error status
@@ -4104,24 +3602,19 @@ class NsLcm(LcmBase):
             # wait for any previous tasks in process
             step = "Waiting for previous operations to terminate"
             await self.lcm_tasks.waitfor_related_HA('ns', 'nslcmops', nslcmop_id)
-
-            self._write_ns_status(
-                nsr_id=nsr_id,
-                ns_state=None,
-                current_operation="SCALING",
-                current_operation_id=nslcmop_id
-            )
+            self._write_ns_status(nsr_id=nsr_id, ns_state=None,
+                                  current_operation="SCALING", current_operation_id=nslcmop_id)
 
             step = "Getting nslcmop from database"
             self.logger.debug(step + " after having waited for previous tasks to be completed")
             db_nslcmop = self.db.get_one("nslcmops", {"_id": nslcmop_id})
+
             step = "Getting nsr from database"
             db_nsr = self.db.get_one("nsrs", {"_id": nsr_id})
-
             old_operational_status = db_nsr["operational-status"]
             old_config_status = db_nsr["config-status"]
+
             step = "Parsing scaling parameters"
-            # self.logger.debug(step)
             db_nsr_update["operational-status"] = "scaling"
             self.update_db_2("nsrs", nsr_id, db_nsr_update)
             nsr_deployed = db_nsr["_admin"].get("deployed")
@@ -4138,8 +3631,6 @@ class NsLcm(LcmBase):
             vnf_index = db_nslcmop["operationParams"]["scaleVnfData"]["scaleByStepData"]["member-vnf-index"]
             scaling_group = db_nslcmop["operationParams"]["scaleVnfData"]["scaleByStepData"]["scaling-group-descriptor"]
             scaling_type = db_nslcmop["operationParams"]["scaleVnfData"]["scaleVnfType"]
-            # scaling_policy = db_nslcmop["operationParams"]["scaleVnfData"]["scaleByStepData"].get("scaling-policy")
-
             # for backward compatibility
             if nsr_deployed and isinstance(nsr_deployed.get("VCA"), dict):
                 nsr_deployed["VCA"] = list(nsr_deployed["VCA"].values())
@@ -4148,6 +3639,7 @@ class NsLcm(LcmBase):
 
             step = "Getting vnfr from database"
             db_vnfr = self.db.get_one("vnfrs", {"member-vnf-index-ref": vnf_index, "nsr-id-ref": nsr_id})
+
             step = "Getting vnfd from database"
             db_vnfd = self.db.get_one("vnfds", {"_id": db_vnfr["vnfd-id"]})
 
@@ -4159,14 +3651,8 @@ class NsLcm(LcmBase):
                 raise LcmException("input parameter 'scaleByStepData':'scaling-group-descriptor':'{}' is not present "
                                    "at vnfd:scaling-group-descriptor".format(scaling_group))
 
-            # cooldown_time = 0
-            # for scaling_policy_descriptor in scaling_descriptor.get("scaling-policy", ()):
-            #     cooldown_time = scaling_policy_descriptor.get("cooldown-time", 0)
-            #     if scaling_policy and scaling_policy == scaling_policy_descriptor.get("name"):
-            #         break
-
-            # TODO check if ns is in a proper status
             step = "Sending scale order to VIM"
+            # TODO check if ns is in a proper status
             nb_scale_op = 0
             if not db_nsr["_admin"].get("scaling-group"):
                 self.update_db_2("nsrs", nsr_id, {"_admin.scaling-group": [{"name": scaling_group, "nb-scale-op": 0}]})
@@ -4198,17 +3684,26 @@ class NsLcm(LcmBase):
                     vdu_index = len([x for x in db_vnfr.get("vdur", ())
                                      if x.get("vdu-id-ref") == vdu_scale_info["vdu-id-ref"] and
                                      x.get("member-vnf-index-ref") == vnf_index])
-                    cloud_init_text = self._get_cloud_init(vdud, db_vnfd)
+                    cloud_init_text = self._get_vdu_cloud_init_content(vdud, db_vnfd)
                     if cloud_init_text:
                         additional_params = self._get_vdu_additional_params(db_vnfr, vdud["id"]) or {}
                     cloud_init_list = []
                     for x in range(vdu_scale_info.get("count", 1)):
                         if cloud_init_text:
                             # TODO Information of its own ip is not available because db_vnfr is not updated.
-                            additional_params["OSM"] = self._get_osm_params(db_vnfr, vdu_scale_info["vdu-id-ref"],
-                                                                            vdu_index + x)
-                            cloud_init_list.append(self._parse_cloud_init(cloud_init_text, additional_params,
-                                                                          db_vnfd["id"], vdud["id"]))
+                            additional_params["OSM"] = get_osm_params(
+                                db_vnfr,
+                                vdu_scale_info["vdu-id-ref"],
+                                vdu_index + x
+                            )
+                            cloud_init_list.append(
+                                self._parse_cloud_init(
+                                    cloud_init_text,
+                                    additional_params,
+                                    db_vnfd["id"],
+                                    vdud["id"]
+                                )
+                            )
                     RO_scaling_info.append({"osm_vdu_id": vdu_scale_info["vdu-id-ref"], "member-vnf-index": vnf_index,
                                             "type": "create", "count": vdu_scale_info.get("count", 1)})
                     if cloud_init_list:
@@ -4433,12 +3928,7 @@ class NsLcm(LcmBase):
             exc = traceback.format_exc()
             self.logger.critical(logging_text + "Exit Exception {} {}".format(type(e).__name__, e), exc_info=True)
         finally:
-            self._write_ns_status(
-                nsr_id=nsr_id,
-                ns_state=None,
-                current_operation="IDLE",
-                current_operation_id=None
-            )
+            self._write_ns_status(nsr_id=nsr_id, ns_state=None, current_operation="IDLE", current_operation_id=None)
             if exc:
                 db_nslcmop_update["detailed-status"] = error_description_nslcmop = "FAILED {}: {}".format(step, exc)
                 nslcmop_operation_state = "FAILED"
@@ -4458,30 +3948,16 @@ class NsLcm(LcmBase):
                 nslcmop_operation_state = "COMPLETED"
                 db_nslcmop_update["detailed-status"] = "Done"
 
-            self._write_op_status(
-                op_id=nslcmop_id,
-                stage="",
-                error_message=error_description_nslcmop,
-                operation_state=nslcmop_operation_state,
-                other_update=db_nslcmop_update,
-            )
+            self._write_op_status(op_id=nslcmop_id, stage="", error_message=error_description_nslcmop,
+                                  operation_state=nslcmop_operation_state, other_update=db_nslcmop_update)
             if db_nsr:
-                self._write_ns_status(
-                    nsr_id=nsr_id,
-                    ns_state=None,
-                    current_operation="IDLE",
-                    current_operation_id=None,
-                    other_update=db_nsr_update
-                )
+                self._write_ns_status(nsr_id=nsr_id, ns_state=None, current_operation="IDLE",
+                                      current_operation_id=None, other_update=db_nsr_update)
 
             if nslcmop_operation_state:
                 try:
-                    await self.msg.aiowrite("ns", "scaled", {"nsr_id": nsr_id, "nslcmop_id": nslcmop_id,
-                                                             "operationState": nslcmop_operation_state},
-                                            loop=self.loop)
-                    # if cooldown_time:
-                    #     await asyncio.sleep(cooldown_time, loop=self.loop)
-                    # await self.msg.aiowrite("ns","scaled-cooldown-time", {"nsr_id": nsr_id, "nslcmop_id": nslcmop_id})
+                    msg = {"nsr_id": nsr_id, "nslcmop_id": nslcmop_id, "operationState": nslcmop_operation_state}
+                    await self.msg.aiowrite("ns", "scaled", msg, loop=self.loop)
                 except Exception as e:
                     self.logger.error(logging_text + "kafka_write notification Exception {}".format(e))
             self.logger.debug(logging_text + "Exit")
@@ -4494,19 +3970,16 @@ class NsLcm(LcmBase):
 
         # read from db: vnfd's for every vnf
         db_vnfds = {}  # every vnfd data indexed by vnf id
-        db_vnfds_ref = {}  # every vnfd data indexed by vnfd id
         db_vnfds = {}
 
         # for each vnf in ns, read vnfd
         for vnfr in self.db.get_list("vnfrs", {"nsr-id-ref": nsr_id}):
             db_vnfrs[vnfr["member-vnf-index-ref"]] = vnfr
             vnfd_id = vnfr["vnfd-id"]  # vnfd uuid for this vnf
-            vnfd_ref = vnfr["vnfd-ref"]  # vnfd name for this vnf
             # if we haven't this vnfd, read it from db
             if vnfd_id not in db_vnfds:
                 # read from db
                 vnfd = self.db.get_one("vnfds", {"_id": vnfd_id})
-                db_vnfds_ref[vnfd_ref] = vnfd  # vnfd's indexed by name
                 db_vnfds[vnfd_id] = vnfd  # vnfd's indexed by id
         n2vc_key = self.n2vc.get_public_key()
         n2vc_key_list = [n2vc_key]
@@ -4515,7 +3988,7 @@ class NsLcm(LcmBase):
         # db_vnfr has been updated, update db_vnfrs to use it
         db_vnfrs[db_vnfr["member-vnf-index-ref"]] = db_vnfr
         await self._instantiate_ng_ro(logging_text, nsr_id, db_nsd, db_nsr, db_nslcmop, db_vnfrs,
-                                      db_vnfds_ref, n2vc_key_list, stage=stage, start_deploy=time(),
+                                      db_vnfds, n2vc_key_list, stage=stage, start_deploy=time(),
                                       timeout_ns_deploy=self.timeout_ns_deploy)
         if vdu_scaling_info.get("vdu-delete"):
             self.scale_vnfr(db_vnfr, None, vdu_scaling_info["vdu-delete"], mark_delete=False)
@@ -4669,7 +4142,7 @@ class NsLcm(LcmBase):
 
         :return: (cloud_name, cloud_credential)
         """
-        config = self.get_vim_account_config(vim_account_id)
+        config = VimAccountDB.get_vim_account_with_id(vim_account_id).get("config", {})
         return config.get("vca_cloud"), config.get("vca_cloud_credential")
 
     def get_vca_k8s_cloud_and_credentials(self, vim_account_id: str) -> (str, str):
@@ -4680,16 +4153,5 @@ class NsLcm(LcmBase):
 
         :return: (cloud_name, cloud_credential)
         """
-        config = self.get_vim_account_config(vim_account_id)
+        config = VimAccountDB.get_vim_account_with_id(vim_account_id).get("config", {})
         return config.get("vca_k8s_cloud"), config.get("vca_k8s_cloud_credential")
-
-    def get_vim_account_config(self, vim_account_id: str) -> dict:
-        """
-        Get VIM Account config from the OSM Database
-
-        :param: vim_account_id:     VIM Account ID
-
-        :return: Dictionary with the config of the vim account
-        """
-        vim_account = self.db.get_one(table="vim_accounts", q_filter={"_id": vim_account_id}, fail_on_empty=False)
-        return vim_account.get("config", {}) if vim_account else {}