Update from master

Squashed commit of the following:

commit 370e36bafdcb90f212e289b87290f39be141b3d4
Author: elumalai <deepika.e@tataelxsi.co.in>
Date:   Tue Apr 25 16:22:56 2023 +0530

    Feature 10979: Static IPv6 Dual Stack Assignment

    Added support for static dual stack IP assignment

    Change-Id: Ief10ae955fb870a3417f68e1c5f7bda570cb6470
    Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>

commit b1bc66933aa392b9d7518f7cebc711700335389c
Author: Gabriel Cuba <gcuba@whitestack.com>
Date:   Fri Aug 19 18:23:00 2022 -0500

    Fix Bug 2098: Get VDUs from VNFR when Heal op has no additionalPrameters

    When Heal is requested without vdu or count-index parameters, RO will recreate all VDUs from VNFR

    Change-Id: Idf2cf158bcb33e7b0c307298c14504cc7aa77e2a
    Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>
    (cherry picked from commit 2fbb3a264e4117f4a6569fede6558836d67ac4a4)

commit aba1518f487b4b65861eb30f553c4edb72ad972e
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date:   Mon May 15 11:55:13 2023 +0300

    Fix VimAdminThread run method

    The run_coroutine_threadsafe() function is used to schedule a coroutine object from a different thread and returns a concurrent.futures.Future.
    run_coroutine_threadsafe is unnecessary to run the main task and replaced with asyncio.run().

    Change-Id: I8ea31828a9798140d596165443bdf26659b4eef8
    Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>

commit f17e5bb6b6da4432628dd65ce9ad633e6441f67c
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date:   Wed May 10 22:52:57 2023 +0300

    Minor updates in Dockerfile

    Change-Id: I79b43654d181f6976a4e544d58fb92aa1b67e760
    Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>

commit a264b7a460b28d7454fc95fe659da46f55b0c155
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date:   Tue May 9 14:57:22 2023 +0300

    Ubuntu 22.04 and Python 3.10 preparation

    Change-Id: I87164827a8849c16b5e3a804d9673a578e5a5593
    Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>

commit 1c89c08a0dd1c79b5adff3ac1cc123239762e06a
Author: garciadeblas <gerardo.garciadeblas@telefonica.com>
Date:   Tue Apr 18 15:06:30 2023 +0200

    Clean stage-archive.sh and use allowlist_extenals in tox.ini

    Change-Id: I18f0bc3e263063b5b1d2cf211f028f6bb0e4bceb
    Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>

commit 51e72a0f7479b3064b4b11891eb524d42f4738b0
Author: elumalai <deepika.e@tataelxsi.co.in>
Date:   Fri Apr 28 19:41:49 2023 +0530

    Coverity CWE 330: Use of Insufficiently Random Values

    Added support to fix CWE 330: Use of Insufficiently Random Values
    Coverity issue

    Change-Id: Ib12ebeeb9b0cc10af9980fe8661eb6230c2f6d6d
    Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>

commit e17cd946aed699b5feca83d37591d04f129a8f52
Author: elumalai <deepika.e@tataelxsi.co.in>
Date:   Fri Apr 28 18:04:24 2023 +0530

    Coverity CWE 688: Function Call With Incorrect Variable or Reference as Argument

    Added fix for CWE 688 Typo in Identifier

    Change-Id: I53b5142451b809be638d73626265531057722169
    Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>

commit 730cfaff466fb3c9b1446ecef5213916195ff861
Author: Gabriel Cuba <gcuba@whitestack.com>
Date:   Mon Mar 13 22:26:38 2023 -0500

    Feature 10975: get flavor-id from additionalParams if specified

    Change-Id: I1c9b1ec43c80f3793b475187681f4c2005d77375
    Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>

commit 2d3f63b055e6a38e95bcff56a8ddef32767b11ef
Author: garciadeblas <gerardo.garciadeblas@telefonica.com>
Date:   Tue Apr 11 10:08:26 2023 +0200

    Update stage-build to run tox sequentially

    Change-Id: I967f19a8c35700290e93c9d8bd863b63b7c2d239
    Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
    (cherry picked from commit ea063c7a6ae6a5d7e11e8c22f9707d5c8f674ac7)

commit b3dbfcad6f4b2bebc9ebc20fd7129a18879cb20c
Author: Gabriel Cuba <gcuba@whitestack.com>
Date:   Tue Mar 14 10:58:39 2023 -0500

    Feature 10978: Add support of ipv6_address_mode and ipv6_ra_mode to openstack connector

    Change-Id: I8ca741a215bd2c52999dee1ea301d4e02aafcb24
    Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>

commit 01619d5b596e01ac8cd6d27bf01a1174e6b3f97b
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date:   Wed Mar 22 22:57:26 2023 +0300

    Keep vim_details while reporting VM deletion

    Change-Id: I27577b2fc93a585affc947abcec8352562f23f49
    Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>

commit 98740c03567ff8c5a22f06fd3f049248a9e5f98d
Author: Pedro Escaleira <escaleira@av.it.pt>
Date:   Wed Feb 22 10:48:52 2023 +0000

    Bug 2217 fixed: modified the cloud-init merge configs and defined the default SSH keys within the system_info instead of users

    Change-Id: I12e26a88fb9b50c4a78b9fa8ee2cb5d4b4bf6d00
    Signed-off-by: Pedro Escaleira <escaleira@av.it.pt>

commit d586d89bde00acaf22debd7f657d605c9d095571
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date:   Mon Feb 13 18:40:03 2023 +0300

    Feature 10960 Performance optimizations for the polling of VM status in RO

    Change-Id: If785bbeaab66e0839541bf94184ce37114e67bd4
    Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>

commit 4c1dd54ae02e82f11a60058a1b7c7b0137ac572e
Author: Gabriel Cuba <gcuba@whitestack.com>
Date:   Tue Feb 14 12:43:32 2023 -0500

    Refactor ns.py so that RO uses the IP profile as it comes from LCM

    Change-Id: I36983c86d7c76ad8a9b93eb6eae254f844717e0e
    Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>

commit 3822010a26b2e21290b6acdf288db277c7f36605
Author: garciadeblas <gerardo.garciadeblas@telefonica.com>
Date:   Mon Feb 13 17:48:32 2023 +0100

    Fix bug 2216 to remove hardcoded numa affinity in VIO

    Change-Id: I0912c2841e7c5c1febe056ba092afedaea77f6a1
    Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>

commit 778f3cc8c052bd17d0da32f07b880616d25f935a
Author: Lovejeet Singh <lovejeet.singh@hsc.com>
Date:   Mon Feb 13 16:15:40 2023 +0530

    Bug 2202: Adding support for cinder V3 API with V2 API for persistent volumes.

    Change-Id: I7034564b91b94e6be242cb2ce0f4a5b147b87d64
    Signed-off-by: Lovejeet Singh <lovejeet.singh@hsc.com>

Change-Id: Ie85ab8100feb93ba059def8cceafbe646e32b1a6
Signed-off-by: Dario Faccin <dario.faccin@canonical.com>
diff --git a/NG-RO/osm_ng_ro/ns.py b/NG-RO/osm_ng_ro/ns.py
index 4e88cc4..fd0ad07 100644
--- a/NG-RO/osm_ng_ro/ns.py
+++ b/NG-RO/osm_ng_ro/ns.py
@@ -863,44 +863,6 @@
         return extra_dict
 
     @staticmethod
-    def _ip_profile_to_ro(
-        ip_profile: Dict[str, Any],
-    ) -> Dict[str, Any]:
-        """[summary]
-
-        Args:
-            ip_profile (Dict[str, Any]): [description]
-
-        Returns:
-            Dict[str, Any]: [description]
-        """
-        if not ip_profile:
-            return None
-
-        ro_ip_profile = {
-            "ip_version": "IPv4"
-            if "v4" in ip_profile.get("ip-version", "ipv4")
-            else "IPv6",
-            "subnet_address": ip_profile.get("subnet-address"),
-            "gateway_address": ip_profile.get("gateway-address"),
-            "dhcp_enabled": ip_profile.get("dhcp-params", {}).get("enabled", False),
-            "dhcp_start_address": ip_profile.get("dhcp-params", {}).get(
-                "start-address", None
-            ),
-            "dhcp_count": ip_profile.get("dhcp-params", {}).get("count", None),
-        }
-
-        if ip_profile.get("dns-server"):
-            ro_ip_profile["dns_address"] = ";".join(
-                [v["address"] for v in ip_profile["dns-server"] if v.get("address")]
-            )
-
-        if ip_profile.get("security-group"):
-            ro_ip_profile["security_group"] = ip_profile["security-group"]
-
-        return ro_ip_profile
-
-    @staticmethod
     def _process_net_params(
         target_vld: Dict[str, Any],
         indata: Dict[str, Any],
@@ -963,7 +925,7 @@
                 "net_name": (
                     f"{indata.get('name')[:16]}-{target_vld.get('name', target_vld.get('id'))[:16]}"
                 ),
-                "ip_profile": Ns._ip_profile_to_ro(vim_info.get("ip_profile")),
+                "ip_profile": vim_info.get("ip_profile"),
                 "provider_network_profile": vim_info.get("provider_network"),
             }
 
@@ -1522,13 +1484,13 @@
         vnf_preffix = "vnfrs:{}".format(vnfr_id)
         ns_preffix = "nsrs:{}".format(nsr_id)
         image_text = ns_preffix + ":image." + target_vdu["ns-image-id"]
-        flavor_text = ns_preffix + ":flavor." + target_vdu["ns-flavor-id"]
-        extra_dict = {"depends_on": [image_text, flavor_text]}
+        extra_dict = {"depends_on": [image_text]}
         net_list = []
 
         persistent_root_disk = {}
         persistent_ordinary_disk = {}
         vdu_instantiation_volumes_list = []
+        vdu_instantiation_flavor_id = None
         disk_list = []
         vnfd_id = vnfr["vnfd-id"]
         vnfd = db.get_one("vnfds", {"_id": vnfd_id})
@@ -1566,8 +1528,19 @@
 
         if target_vdu.get("additionalParams"):
             vdu_instantiation_volumes_list = (
-                target_vdu.get("additionalParams").get("OSM").get("vdu_volumes")
+                target_vdu.get("additionalParams").get("OSM", {}).get("vdu_volumes")
             )
+            vdu_instantiation_flavor_id = (
+                target_vdu.get("additionalParams").get("OSM", {}).get("vim_flavor_id")
+            )
+
+        # flavor id
+        if vdu_instantiation_flavor_id:
+            flavor_id = vdu_instantiation_flavor_id
+        else:
+            flavor_text = ns_preffix + ":flavor." + target_vdu["ns-flavor-id"]
+            flavor_id = "TASK-" + flavor_text
+            extra_dict["depends_on"].append(flavor_text)
 
         if vdu_instantiation_volumes_list:
             # Find the root volumes and add to the disk_list
@@ -1609,7 +1582,7 @@
             "description": target_vdu["vdu-name"],
             "start": True,
             "image_id": "TASK-" + image_text,
-            "flavor_id": "TASK-" + flavor_text,
+            "flavor_id": flavor_id,
             "affinity_group_list": affinity_group_list,
             "net_list": net_list,
             "cloud_config": cloud_config or None,
@@ -2341,15 +2314,23 @@
 
         # Check each VNF of the target
         for target_vnf in target_list:
-            # Find this VNF in the list from DB
-            vnfr_id = target_vnf.get("vnfInstanceId", None)
-            if vnfr_id:
-                existing_vnf = db_vnfrs.get(vnfr_id)
-                db_record = "vnfrs:{}:{}".format(vnfr_id, db_path)
-                # vim_account_id = existing_vnf.get("vim-account-id", "")
+            # Find this VNF in the list from DB, raise exception if vnfInstanceId is not found
+            vnfr_id = target_vnf["vnfInstanceId"]
+            existing_vnf = db_vnfrs.get(vnfr_id)
+            db_record = "vnfrs:{}:{}".format(vnfr_id, db_path)
+            # vim_account_id = existing_vnf.get("vim-account-id", "")
 
+            target_vdus = target_vnf.get("additionalParams", {}).get("vdu", [])
             # Check each VDU of this VNF
-            for target_vdu in target_vnf["additionalParams"].get("vdu", None):
+            if not target_vdus:
+                # Create target_vdu_list from DB, if VDUs are not specified
+                target_vdus = []
+                for existing_vdu in existing_vnf.get("vdur"):
+                    vdu_name = existing_vdu.get("vdu-name", None)
+                    vdu_index = existing_vdu.get("count-index", 0)
+                    vdu_to_be_healed = {"vdu-id": vdu_name, "count-index": vdu_index}
+                    target_vdus.append(vdu_to_be_healed)
+            for target_vdu in target_vdus:
                 vdu_name = target_vdu.get("vdu-id", None)
                 # For multi instance VDU count-index is mandatory
                 # For single session VDU count-indes is 0