from n2vc.utils import get_ee_id_components, generate_random_alfanum_string
from n2vc.vca.connection import get_connection
from retrying_async import retry
+from typing import Tuple
class N2VCJujuConnector(N2VCConnector):
return get_ee_id_components(ee_id)
- def _get_application_name(self, namespace: str) -> str:
- """
- Build application name from namespace
- :param namespace:
- :return: app-vnf-<vnf id>-vdu-<vdu-id>-cnt-<vdu-count>-<random_value>
+ @staticmethod
+ def _find_charm_level(vnf_id: str, vdu_id: str) -> str:
+ """Decides the charm level.
+ Args:
+ vnf_id (str): VNF id
+ vdu_id (str): VDU id
+
+ Returns:
+ charm_level (str): ns-level or vnf-level or vdu-level
"""
+ if vdu_id and not vnf_id:
+ raise N2VCException(message="If vdu-id exists, vnf-id should be provided.")
+ if vnf_id and vdu_id:
+ return "vdu-level"
+ if vnf_id and not vdu_id:
+ return "vnf-level"
+ if not vnf_id and not vdu_id:
+ return "ns-level"
+
+ @staticmethod
+ def _generate_backward_compatible_application_name(
+ vnf_id: str, vdu_id: str, vdu_count: str
+ ) -> str:
+ """Generate backward compatible application name
+ by limiting the app name to 50 characters.
- # TODO: Enforce the Juju 50-character application limit
+ Args:
+ vnf_id (str): VNF ID
+ vdu_id (str): VDU ID
+ vdu_count (str): vdu-count-index
- # split namespace components
- _, _, vnf_id, vdu_id, vdu_count = self._get_namespace_components(
- namespace=namespace
- )
+ Returns:
+ application_name (str): generated application name
+ """
if vnf_id is None or len(vnf_id) == 0:
vnf_id = ""
else:
application_name = "app-{}{}{}-{}".format(
vnf_id, vdu_id, vdu_count, random_suffix
)
+ return application_name
+
+ @staticmethod
+ def _generate_application_name(
+ charm_level: str,
+ vnfrs: dict,
+ vca_records: list,
+ vnf_count: str = None,
+ vdu_count: str = None,
+ ) -> str:
+ """Generate application name to make the relevant charm of VDU/KDU
+ in the VNFD descriptor become clearly visible.
+ Limiting the app name to 50 characters.
+
+ Args:
+ charm_level (str): VNF ID
+ vnfrs (dict): VDU ID
+ vca_records (list): db_nsr["_admin"]["deployed"]["VCA"] as list
+ vnf_count (str): vnf count index
+ vdu_count (str): vdu count index
+
+ Returns:
+ application_name (str): generated application name
+
+ """
+ application_name = ""
+ if charm_level == "ns-level":
+ if len(vca_records) != 1:
+ raise N2VCException(message="One VCA record is expected.")
+ # Only one VCA record is expected if it's ns-level charm.
+ # Shorten the charm name to its first 40 characters.
+ charm_name = vca_records[0]["charm_name"][:40]
+ if not charm_name:
+ raise N2VCException(message="Charm name should be provided.")
+ application_name = charm_name + "-ns"
+
+ elif charm_level == "vnf-level":
+ if len(vca_records) < 1:
+ raise N2VCException(message="One or more VCA record is expected.")
+ # If VNF is scaled, more than one VCA record may be included in vca_records
+ # but ee_descriptor_id is same.
+ # Shorten the ee_descriptor_id and member-vnf-index-ref
+ # to first 12 characters.
+ application_name = (
+ vca_records[0]["ee_descriptor_id"][:12]
+ + "-"
+ + vnf_count
+ + "-"
+ + vnfrs["member-vnf-index-ref"][:12]
+ + "-vnf"
+ )
+ elif charm_level == "vdu-level":
+ if len(vca_records) < 1:
+ raise N2VCException(message="One or more VCA record is expected.")
+ vdu_profile_id = vnfrs["vdur"][int(vdu_count)]["vdu-id-ref"]
+ # If vnf/vdu is scaled, more than one VCA record may be included in vca_records
+ # but ee_descriptor_id is same.
+ # Shorten the ee_descriptor_id, member-vnf-index-ref and vdu_profile_id
+ # to first 12 characters.
+ application_name = (
+ vca_records[0]["ee_descriptor_id"][:12]
+ + "-"
+ + vnf_count
+ + "-"
+ + vnfrs["member-vnf-index-ref"][:12]
+ + "-"
+ + vdu_profile_id[:12]
+ + "-"
+ + vdu_count
+ + "-vdu"
+ )
+
+ return application_name
+
+ def _get_vnf_count_and_record(
+ self, charm_level: str, vnf_id_and_count: str
+ ) -> Tuple[str, dict]:
+ """Get the vnf count and VNF record depend on charm level
+
+ Args:
+ charm_level (str)
+ vnf_id_and_count (str)
+
+ Returns:
+ (vnf_count (str), db_vnfr(dict)) as Tuple
+
+ """
+ vnf_count = ""
+ db_vnfr = {}
+
+ if charm_level in ("vnf-level", "vdu-level"):
+ vnf_id = "-".join(vnf_id_and_count.split("-")[:-1])
+ vnf_count = vnf_id_and_count.split("-")[-1]
+ db_vnfr = self.db.get_one("vnfrs", {"_id": vnf_id})
+
+ # If the charm is ns level, it returns empty vnf_count and db_vnfr
+ return vnf_count, db_vnfr
+
+ @staticmethod
+ def _get_vca_records(charm_level: str, db_nsr: dict, db_vnfr: dict) -> list:
+ """Get the VCA records from db_nsr dict
+
+ Args:
+ charm_level (str): level of charm
+ db_nsr (dict): NS record from database
+ db_vnfr (dict): VNF record from database
+
+ Returns:
+ vca_records (list): List of VCA record dictionaries
+
+ """
+ vca_records = {}
+ if charm_level == "ns-level":
+ vca_records = list(
+ filter(
+ lambda vca_record: vca_record["target_element"] == "ns",
+ db_nsr["_admin"]["deployed"]["VCA"],
+ )
+ )
+ elif charm_level in ["vnf-level", "vdu-level"]:
+ vca_records = list(
+ filter(
+ lambda vca_record: vca_record["member-vnf-index"]
+ == db_vnfr["member-vnf-index-ref"],
+ db_nsr["_admin"]["deployed"]["VCA"],
+ )
+ )
+
+ return vca_records
+
+ def _get_application_name(self, namespace: str) -> str:
+ """Build application name from namespace
+
+ Application name structure:
+ NS level: <charm-name>-ns
+ VNF level: <ee-name>-z<vnf-ordinal-scale-number>-<vnf-profile-id>-vnf
+ VDU level: <ee-name>-z<vnf-ordinal-scale-number>-<vnf-profile-id>-
+ <vdu-profile-id>-z<vdu-ordinal-scale-number>-vdu
+
+ Application naming for backward compatibility (old structure):
+ NS level: app-<random_value>
+ VNF level: app-vnf-<vnf-id>-z<ordinal-scale-number>-<random_value>
+ VDU level: app-vnf-<vnf-id>-z<vnf-ordinal-scale-number>-vdu-
+ <vdu-id>-cnt-<vdu-count>-z<vdu-ordinal-scale-number>-<random_value>
+
+ Args:
+ namespace (str)
+
+ Returns:
+ application_name (str)
+
+ """
+ # split namespace components
+ (
+ nsi_id,
+ ns_id,
+ vnf_id_and_count,
+ vdu_id,
+ vdu_count,
+ ) = self._get_namespace_components(namespace=namespace)
+
+ if not ns_id:
+ raise N2VCException(message="ns-id should be provided.")
+
+ charm_level = self._find_charm_level(vnf_id_and_count, vdu_id)
+ db_nsr = self.db.get_one("nsrs", {"_id": ns_id})
+ vnf_count, db_vnfr = self._get_vnf_count_and_record(
+ charm_level, vnf_id_and_count
+ )
+ vca_records = self._get_vca_records(charm_level, db_nsr, db_vnfr)
+
+ if all("charm_name" in vca_record.keys() for vca_record in vca_records):
+ application_name = self._generate_application_name(
+ charm_level,
+ db_vnfr,
+ vca_records,
+ vnf_count=vnf_count,
+ vdu_count=vdu_count,
+ )
+ else:
+ application_name = self._generate_backward_compatible_application_name(
+ vnf_id_and_count, vdu_id, vdu_count
+ )
return N2VCJujuConnector._format_app_name(application_name)
import asyncio
import logging
-from unittest.mock import Mock
+from unittest.mock import Mock, MagicMock
from unittest.mock import patch
from n2vc.definitions import Offer, RelationEndpoint
from n2vc.n2vc_juju_conn import N2VCJujuConnector
from osm_common import fslocal
+from osm_common.dbmemory import DbMemory
from n2vc.exceptions import (
N2VCBadArgumentsException,
N2VCException,
)
from n2vc.tests.unit.utils import AsyncMock
from n2vc.vca.connection_data import ConnectionData
+from n2vc.tests.unit.testdata import test_db_descriptors as descriptors
+import yaml
class N2VCJujuConnTestCase(asynctest.TestCase):
self.n2vc.libjuju.get_application_configs.assert_not_called_once()
-@asynctest.mock.patch("osm_common.fslocal.FsLocal.file_exists")
-@asynctest.mock.patch(
- "osm_common.fslocal.FsLocal.path", new_callable=asynctest.PropertyMock, create=True
-)
class K8sProxyCharmsTest(N2VCJujuConnTestCase):
def setUp(self):
super(K8sProxyCharmsTest, self).setUp()
self.n2vc.libjuju.add_model = AsyncMock()
self.n2vc.libjuju.deploy_charm = AsyncMock()
self.n2vc.libjuju.model_exists.return_value = False
+ self.db = DbMemory()
+ self.fs = fslocal.FsLocal()
+ self.fs.path = "/"
+ self.n2vc.fs = self.fs
+ self.n2vc.db = self.db
+ self.db.create_list("nsrs", yaml.safe_load(descriptors.db_nsrs_text))
+ self.db.create_list("vnfrs", yaml.safe_load(descriptors.db_vnfrs_text))
@patch(
"n2vc.n2vc_juju_conn.generate_random_alfanum_string",
def test_success(
self,
mock_generate_random_alfanum_string,
- mock_path,
- mock_file_exists,
):
- mock_file_exists.return_value = True
- mock_path.return_value = "/path"
+ self.n2vc.fs.file_exists = MagicMock(create_autospec=True)
+ self.n2vc.fs.file_exists.return_value = True
ee_id = self.loop.run_until_complete(
self.n2vc.install_k8s_proxy_charm(
- "charm",
- "nsi-id.ns-id.vnf-id.vdu",
- "////path/",
+ "simple",
+ ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
+ "path",
{},
)
)
self.n2vc.libjuju.add_model.assert_called_once()
self.n2vc.libjuju.deploy_charm.assert_called_once_with(
- model_name="ns-id-k8s",
- application_name="app-vnf-vnf-id-vdu-vdu-random",
- path="/path/path/",
+ model_name="dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s",
+ application_name="simple-ee-z0-vnf1-vnf",
+ path="//path",
machine_id=None,
db_dict={},
progress_timeout=None,
total_timeout=None,
config=None,
)
- self.assertEqual(ee_id, "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s")
+ self.assertEqual(
+ ee_id, "dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s.simple-ee-z0-vnf1-vnf.k8s"
+ )
def test_no_artifact_path(
self,
- mock_path,
- mock_file_exists,
):
with self.assertRaises(N2VCBadArgumentsException):
ee_id = self.loop.run_until_complete(
self.n2vc.install_k8s_proxy_charm(
- "charm",
- "nsi-id.ns-id.vnf-id.vdu",
+ "simple",
+ ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
"",
{},
)
def test_no_db(
self,
- mock_path,
- mock_file_exists,
):
with self.assertRaises(N2VCBadArgumentsException):
ee_id = self.loop.run_until_complete(
self.n2vc.install_k8s_proxy_charm(
- "charm",
- "nsi-id.ns-id.vnf-id.vdu",
- "/path/",
+ "simple",
+ ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
+ "path",
None,
)
)
def test_file_not_exists(
self,
- mock_path,
- mock_file_exists,
):
- mock_file_exists.return_value = False
+ self.n2vc.fs.file_exists = MagicMock(create_autospec=True)
+ self.n2vc.fs.file_exists.return_value = False
with self.assertRaises(N2VCBadArgumentsException):
ee_id = self.loop.run_until_complete(
self.n2vc.install_k8s_proxy_charm(
- "charm",
- "nsi-id.ns-id.vnf-id.vdu",
- "/path/",
+ "simple",
+ ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
+ "path",
{},
)
)
def test_exception(
self,
- mock_path,
- mock_file_exists,
):
- mock_file_exists.return_value = True
- mock_path.return_value = "/path"
+ self.n2vc.fs.file_exists = MagicMock(create_autospec=True)
+ self.n2vc.fs.file_exists.return_value = True
+ self.n2vc.fs.path = MagicMock(create_autospec=True)
+ self.n2vc.fs.path.return_value = "path"
self.n2vc.libjuju.deploy_charm.side_effect = Exception()
with self.assertRaises(N2VCException):
ee_id = self.loop.run_until_complete(
self.n2vc.install_k8s_proxy_charm(
- "charm",
- "nsi-id.ns-id.vnf-id.vdu",
- "path/",
+ "simple",
+ ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0",
+ "path",
{},
)
)
model_name="sample_model",
total_timeout=None,
)
+
+
+class GenerateApplicationNameTest(N2VCJujuConnTestCase):
+
+ vnf_id = "dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
+
+ def setUp(self):
+ super(GenerateApplicationNameTest, self).setUp()
+ self.db = MagicMock(DbMemory)
+
+ @patch(
+ "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
+ **{"return_value": "random"}
+ )
+ def test_generate_backward_compatible_application_name(
+ self, mock_generate_random_alfanum
+ ):
+ vdu_id = "mgmtVM"
+ vdu_count = "0"
+ expected_result = "app-vnf-ec5ae0a53898-vdu-mgmtVM-cnt-0-random"
+
+ application_name = self.n2vc._generate_backward_compatible_application_name(
+ GenerateApplicationNameTest.vnf_id, vdu_id, vdu_count
+ )
+ self.assertEqual(application_name, expected_result)
+
+ @patch(
+ "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
+ **{"return_value": "random"}
+ )
+ def test_generate_backward_compatible_application_name_without_vnf_id_vdu_id(
+ self, mock_generate_random_alfanum
+ ):
+ vnf_id = None
+ vdu_id = ""
+ vdu_count = None
+ expected_result = "app--random"
+ application_name = self.n2vc._generate_backward_compatible_application_name(
+ vnf_id, vdu_id, vdu_count
+ )
+
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+
+ def test_find_charm_level_with_vnf_id(self):
+ vdu_id = ""
+ expected_result = "vnf-level"
+ charm_level = self.n2vc._find_charm_level(
+ GenerateApplicationNameTest.vnf_id, vdu_id
+ )
+ self.assertEqual(charm_level, expected_result)
+
+ def test_find_charm_level_with_vdu_id(self):
+ vnf_id = ""
+ vdu_id = "mgmtVM"
+ with self.assertRaises(N2VCException):
+ self.n2vc._find_charm_level(vnf_id, vdu_id)
+
+ def test_find_charm_level_with_vnf_id_and_vdu_id(self):
+ vdu_id = "mgmtVM"
+ expected_result = "vdu-level"
+ charm_level = self.n2vc._find_charm_level(
+ GenerateApplicationNameTest.vnf_id, vdu_id
+ )
+ self.assertEqual(charm_level, expected_result)
+
+ def test_find_charm_level_without_vnf_id_and_vdu_id(self):
+ vnf_id = ""
+ vdu_id = ""
+ expected_result = "ns-level"
+ charm_level = self.n2vc._find_charm_level(vnf_id, vdu_id)
+ self.assertEqual(charm_level, expected_result)
+
+ def test_generate_application_name_ns_charm(self):
+ charm_level = "ns-level"
+ vnfrs = {}
+ vca_records = [
+ {
+ "target_element": "ns",
+ "member-vnf-index": "",
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": None,
+ "vdu_name": None,
+ "type": "proxy_charm",
+ "ee_descriptor_id": None,
+ "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh",
+ "ee_id": None,
+ "application": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vnf_count = ""
+ vdu_count = ""
+ expected_result = "simple-ns-charm-abc-000-rrrr-nnnn-4444-h-ns"
+ application_name = self.n2vc._generate_application_name(
+ charm_level,
+ vnfrs,
+ vca_records,
+ vnf_count=vnf_count,
+ vdu_count=vdu_count,
+ )
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+
+ def test_generate_application_name_ns_charm_empty_vca_records(self):
+ charm_level = "ns-level"
+ vnfrs = {}
+ vca_records = []
+ vnf_count = ""
+ vdu_count = ""
+ with self.assertRaises(N2VCException):
+ self.n2vc._generate_application_name(
+ charm_level,
+ vnfrs,
+ vca_records,
+ vnf_count=vnf_count,
+ vdu_count=vdu_count,
+ )
+
+ def test_generate_application_name_vnf_charm(self):
+ charm_level = "vnf-level"
+ vnfrs = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ }
+ vca_records = [
+ {
+ "target_element": "vnf/vnf1",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vnf_count = "1"
+ vdu_count = ""
+ expected_result = "simple-ee-ab-1-vnf111-xxx-y-vnf"
+ application_name = self.n2vc._generate_application_name(
+ charm_level,
+ vnfrs,
+ vca_records,
+ vnf_count=vnf_count,
+ vdu_count=vdu_count,
+ )
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+
+ def test_generate_application_name_vdu_charm(self):
+ charm_level = "vdu-level"
+ vnfrs = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ "vdur": [
+ {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
+ {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
+ ],
+ }
+ vca_records = [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "vnf/vnf1/datavm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "datavm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vnf_count = "2"
+ vdu_count = "0"
+ expected_result = "simple-ee-ab-2-vnf111-xxx-y-mgmtVM-0-vdu"
+ application_name = self.n2vc._generate_application_name(
+ charm_level,
+ vnfrs,
+ vca_records,
+ vnf_count=vnf_count,
+ vdu_count=vdu_count,
+ )
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+
+ def test_generate_application_name_vdu_charm_wrong_vnfrs(self):
+ charm_level = "vdu-level"
+ vnfrs = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ }
+ vca_records = [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vnf_count = "2"
+ vdu_count = "0"
+ with self.assertRaises(KeyError):
+ self.n2vc._generate_application_name(
+ charm_level,
+ vnfrs,
+ vca_records,
+ vnf_count=vnf_count,
+ vdu_count=vdu_count,
+ )
+
+ def test_get_vnf_count_db_vnfr_ns_charm(self):
+ self.db.get_one.return_value = {"member-vnf-index-ref": "sample-ref"}
+ charm_level = "ns-level"
+ vnf_id_and_count = "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-4"
+ with patch.object(self.n2vc, "db", self.db):
+ vnf_count, db_vnfr = self.n2vc._get_vnf_count_and_record(
+ charm_level, vnf_id_and_count
+ )
+ self.assertEqual(vnf_count, "")
+ self.assertEqual(db_vnfr, {})
+
+ def test_get_vnf_count_db_vnfr_vnf_charm(self):
+ self.db.get_one.return_value = {"member-vnf-index-ref": "sample-ref"}
+ charm_level = "vnf-level"
+ vnf_id_and_count = "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-4"
+ with patch.object(self.n2vc, "db", self.db):
+ vnf_count, db_vnfr = self.n2vc._get_vnf_count_and_record(
+ charm_level, vnf_id_and_count
+ )
+ self.assertEqual(vnf_count, "4")
+ self.assertEqual(db_vnfr, {"member-vnf-index-ref": "sample-ref"})
+
+ def test_get_vnf_count_db_vnfr_vdu_charm(self):
+ self.db.get_one.return_value = {"member-vnf-index-ref": "sample-ref"}
+ charm_level = "vdu-level"
+ vnf_id_and_count = "m7fbd751-3de4-4e68-bd40-ec5ae0a53898-2"
+ with patch.object(self.n2vc, "db", self.db):
+ vnf_count, db_vnfr = self.n2vc._get_vnf_count_and_record(
+ charm_level, vnf_id_and_count
+ )
+ self.assertEqual(vnf_count, "2")
+ self.assertEqual(db_vnfr, {"member-vnf-index-ref": "sample-ref"})
+
+ def test_get_vca_records_vdu_charm(self):
+ charm_level = "vdu-level"
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ "vdur": [
+ {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
+ {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
+ ],
+ }
+ db_nsr = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "vnf/vnf2/datavm",
+ "member-vnf-index": "vnf222-xxx-yyy-zzz",
+ "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "datavm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ expected_result = [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
+ self.assertEqual(vca_records, expected_result)
+
+ def test_get_vca_records_vnf_charm_member_vnf_index_mismatch(self):
+ charm_level = "vnf-level"
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
+ }
+ db_nsr = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "45512ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "datavm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-8888-hhh-3333-yyyy-888-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ expected_result = []
+ vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
+ self.assertEqual(vca_records, expected_result)
+
+ def test_get_vca_records_ns_charm(self):
+ charm_level = "ns-level"
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
+ }
+ db_nsr = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ expected_result = [
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
+ self.assertEqual(vca_records, expected_result)
+
+ def test_get_vca_records_ns_charm_empty_charm_name(self):
+ charm_level = "ns-level"
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
+ }
+ db_nsr = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ expected_result = [
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ vca_records = self.n2vc._get_vca_records(charm_level, db_nsr, db_vnfr)
+ self.assertEqual(vca_records, expected_result)
+
+ def test_get_application_name_vnf_charm(self):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ }
+ vnf_count = "0"
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ expected_result = "simple-ee-ab-z0-vnf111-xxx-y-vnf"
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ application_name = self.n2vc._get_application_name(namespace)
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+ mock_vnf_count_and_record.assert_called_once_with(
+ "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ )
+ self.db.get_one.assert_called_once()
+
+ @patch(
+ "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
+ **{"return_value": "random"}
+ )
+ def test_get_application_name_vnf_charm_old_naming(
+ self, mock_generate_random_alfanum
+ ):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ }
+ vnf_count = "0"
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ expected_result = "app-vnf-eb3161eec0-z0-random"
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ application_name = self.n2vc._get_application_name(namespace)
+ self.assertEqual(application_name, expected_result)
+ mock_vnf_count_and_record.assert_called_once_with(
+ "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ )
+ self.db.get_one.assert_called_once()
+
+ def test_get_application_name_vnf_charm_vnf_index_ref_mismatch(self):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf222-xxx-yyy-zzz",
+ }
+ vnf_count = "0"
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ with self.assertRaises(N2VCException):
+ self.n2vc._get_application_name(namespace)
+ mock_vnf_count_and_record.assert_called_once_with(
+ "vnf-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ )
+ self.db.get_one.assert_called_once()
+
+ def test_get_application_name_vdu_charm(self):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.mgmtVM-0"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ]
+ }
+ }
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ "vdur": [
+ {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
+ {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
+ ],
+ }
+ vnf_count = "0"
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ expected_result = "simple-ee-ab-z0-vnf111-xxx-y-mgmtvm-z0-vdu"
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ application_name = self.n2vc._get_application_name(namespace)
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+ mock_vnf_count_and_record.assert_called_once_with(
+ "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ )
+ self.db.get_one.assert_called_once()
+
+ @patch(
+ "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
+ **{"return_value": "random"}
+ )
+ def test_get_application_name_vdu_charm_old_naming(
+ self, mock_generate_random_alfanum
+ ):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898.1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0.mgmtVM-0"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "vnf/vnf1/mgmtvm",
+ "member-vnf-index": "vnf111-xxx-yyy-zzz",
+ "vdu_id": "38912ff7-5bdd-4228-911f-c2bee259c44a",
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "r7fbd751-3de4-4e68-bd40-ec5ae0a53898",
+ "vdu_name": "mgmtvm",
+ "ee_descriptor_id": "simple-ee-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {
+ "member-vnf-index-ref": "vnf111-xxx-yyy-zzz",
+ "vdur": [
+ {"_id": "38912ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "mgmtVM"},
+ {"_id": "45512ff7-5bdd-4228-911f-c2bee259c44a", "vdu-id-ref": "dataVM"},
+ ],
+ }
+ vnf_count = "0"
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ expected_result = "app-vnf-eb3161eec0-z0-vdu-mgmtvm-cnt-z0-random"
+
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ application_name = self.n2vc._get_application_name(namespace)
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+ mock_vnf_count_and_record.assert_called_once_with(
+ "vdu-level", "1b6a4eb3-4fbf-415e-985c-4aeb3161eec0-0"
+ )
+ self.db.get_one.assert_called_once()
+
+ def test_get_application_name_ns_charm(self):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "simple-ns-charm-abc-000-rrrr-nnnn-4444-hhh-3333-yyyy-333-hhh-ttt-444",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {}
+ vnf_count = ""
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ expected_result = "simple-ns-charm-abc-z000-rrrr-nnnn-z4444-h-ns"
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ application_name = self.n2vc._get_application_name(namespace)
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+ mock_vnf_count_and_record.assert_called_once_with("ns-level", None)
+ self.db.get_one.assert_called_once()
+
+ def test_get_application_name_ns_charm_empty_charm_name(self):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "charm_name": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {}
+ vnf_count = ""
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ with self.assertRaises(N2VCException):
+ self.n2vc._get_application_name(namespace)
+ mock_vnf_count_and_record.assert_called_once_with("ns-level", None)
+ self.db.get_one.assert_called_once()
+
+ @patch(
+ "n2vc.n2vc_juju_conn.generate_random_alfanum_string",
+ **{"return_value": "random"}
+ )
+ def test_get_application_name_ns_charm_old_naming(
+ self, mock_generate_random_alfanum
+ ):
+ namespace = ".dbfbd751-3de4-4e68-bd40-ec5ae0a53898"
+ self.db.get_one.return_value = {
+ "_admin": {
+ "deployed": {
+ "VCA": [
+ {
+ "target_element": "ns",
+ "member-vnf-index": None,
+ "vdu_id": None,
+ "kdu_name": None,
+ "vdu_count_index": None,
+ "vnfd_id": "",
+ "vdu_name": "",
+ "ee_descriptor_id": "",
+ "model": "dbfbd751-3de4-4e68-bd40-ec5ae0a53898",
+ },
+ ],
+ },
+ },
+ }
+ mock_vnf_count_and_record = MagicMock()
+ db_vnfr = {}
+ vnf_count = ""
+ mock_vnf_count_and_record.return_value = (vnf_count, db_vnfr)
+ expected_result = "app-random"
+ with patch.object(self.n2vc, "db", self.db), patch.object(
+ self.n2vc, "_get_vnf_count_and_record", mock_vnf_count_and_record
+ ):
+ application_name = self.n2vc._get_application_name(namespace)
+ self.assertEqual(application_name, expected_result)
+ self.assertLess(len(application_name), 50)
+ mock_vnf_count_and_record.assert_called_once_with("ns-level", None)
+ self.db.get_one.assert_called_once()
--- /dev/null
+# Copyright 2022 Canonical Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+db_nsrs_text = """
+---
+- _id: dbfbd751-3de4-4e68-bd40-ec5ae0a53898
+ name: k8s-ns
+ name-ref: k8s-ns
+ short-name: k8s-ns
+ admin-status: ENABLED
+ nsState: READY
+ currentOperation: IDLE
+ currentOperationID: null
+ errorDescription: null
+ errorDetail: null
+ deploymentStatus: null
+ configurationStatus:
+ - elementType: VNF
+ elementUnderConfiguration: 1b6a4eb3-4fbf-415e-985c-4aeb3161eec0
+ status: READY
+ - elementType: VNF
+ elementUnderConfiguration: 17892d73-aa19-4b87-9a00-1d094f07a6b3
+ status: READY
+ vcaStatus: null
+ nsd:
+ _id: 12f320b5-2a57-40f4-82b5-020a6b1171d7
+ id: k8s_proxy_charm-ns
+ version: '1.0'
+ name: k8s_proxy_charm-ns
+ vnfd-id:
+ - k8s_proxy_charm-vnf
+ virtual-link-desc:
+ - id: mgmtnet
+ mgmt-network: true
+ - id: datanet
+ df:
+ - id: default-df
+ vnf-profile:
+ - id: vnf1
+ virtual-link-connectivity:
+ - constituent-cpd-id:
+ - constituent-base-element-id: vnf1
+ constituent-cpd-id: vnf-mgmt-ext
+ virtual-link-profile-id: mgmtnet
+ - constituent-cpd-id:
+ - constituent-base-element-id: vnf1
+ constituent-cpd-id: vnf-data-ext
+ virtual-link-profile-id: datanet
+ vnfd-id: k8s_proxy_charm-vnf
+ - id: vnf2
+ virtual-link-connectivity:
+ - constituent-cpd-id:
+ - constituent-base-element-id: vnf2
+ constituent-cpd-id: vnf-mgmt-ext
+ virtual-link-profile-id: mgmtnet
+ - constituent-cpd-id:
+ - constituent-base-element-id: vnf2
+ constituent-cpd-id: vnf-data-ext
+ virtual-link-profile-id: datanet
+ vnfd-id: k8s_proxy_charm-vnf
+ description: NS with 2 VNFs with cloudinit connected by datanet and mgmtnet VLs
+ _admin:
+ userDefinedData: {}
+ revision: 1
+ created: 1658990740.88281
+ modified: 1658990741.09266
+ projects_read:
+ - 51e0e80fe533469d98766caa16552a3e
+ projects_write:
+ - 51e0e80fe533469d98766caa16552a3e
+ onboardingState: ONBOARDED
+ operationalState: ENABLED
+ usageState: NOT_IN_USE
+ storage:
+ fs: mongo
+ path: /app/storage/
+ folder: '12f320b5-2a57-40f4-82b5-020a6b1171d7:1'
+ pkg-dir: k8s_proxy_charm_ns
+ descriptor: k8s_proxy_charm_ns/k8s_proxy_charm_nsd.yaml
+ zipfile: k8s_proxy_charm_ns.tar.gz
+ datacenter: bad7338b-ae46-43d4-a434-c3337a8054ac
+ resource-orchestrator: osmopenmano
+ description: default description
+ constituent-vnfr-ref:
+ - 1b6a4eb3-4fbf-415e-985c-4aeb3161eec0
+ - 17892d73-aa19-4b87-9a00-1d094f07a6b3
+ operational-status: running
+ config-status: configured
+ detailed-status: Done
+ orchestration-progress: {}
+ create-time: 1658998097.57611
+ nsd-name-ref: k8s_proxy_charm-ns
+ operational-events: []
+ nsd-ref: k8s_proxy_charm-ns
+ nsd-id: 12f320b5-2a57-40f4-82b5-020a6b1171d7
+ vnfd-id:
+ - 6d9e1ca1-f387-4d01-9876-066fc7311e0f
+ instantiate_params:
+ nsdId: 12f320b5-2a57-40f4-82b5-020a6b1171d7
+ nsName: k8s-ns
+ nsDescription: default description
+ vimAccountId: bad7338b-ae46-43d4-a434-c3337a8054ac
+ vld:
+ - name: mgmtnet
+ vim-network-name: osm-ext
+ additionalParamsForNs: null
+ ns-instance-config-ref: dbfbd751-3de4-4e68-bd40-ec5ae0a53898
+ id: dbfbd751-3de4-4e68-bd40-ec5ae0a53898
+ ssh-authorized-key: null
+ flavor:
+ - id: '0'
+ memory-mb: 1024
+ name: mgmtVM-flv
+ storage-gb: '10'
+ vcpu-count: 1
+ vim_info:
+ 'vim:bad7338b-ae46-43d4-a434-c3337a8054ac':
+ vim_details: null
+ vim_id: 17a9ba76-beb7-4ad4-a481-97de37174866
+ vim_status: DONE
+ - vcpu-count: 1
+ memory-mb: 1024
+ storage-gb: '10'
+ name: mgmtVM-flv
+ id: '1'
+ image:
+ - id: '0'
+ image: ubuntu18.04
+ vim_info:
+ 'vim:bad7338b-ae46-43d4-a434-c3337a8054ac':
+ vim_details: null
+ vim_id: 919fc71a-6acd-4ee3-8123-739a9abbc2e7
+ vim_status: DONE
+ - image: 'Canonical:UbuntuServer:18.04-LTS:latest'
+ vim-type: azure
+ id: '1'
+ - image: 'ubuntu-os-cloud:image-family:ubuntu-1804-lts'
+ vim-type: gcp
+ id: '2'
+ - image: ubuntu/images/hvm-ssd/ubuntu-artful-17.10-amd64-server-20180509
+ vim-type: aws
+ id: '3'
+ affinity-or-anti-affinity-group: []
+ revision: 1
+ vld:
+ - id: mgmtnet
+ mgmt-network: true
+ name: mgmtnet
+ type: null
+ vim_info:
+ 'vim:bad7338b-ae46-43d4-a434-c3337a8054ac':
+ vim_account_id: bad7338b-ae46-43d4-a434-c3337a8054ac
+ vim_network_name: osm-ext
+ vim_details: >
+ {admin_state_up: true, availability_zone_hints: [],
+ availability_zones: [nova], created_at: '2019-10-17T23:44:03Z',
+ description: '', encapsulation: vlan, encapsulation_id: 2148,
+ encapsulation_type: vlan, id: 21ea5d92-24f1-40ab-8d28-83230e277a49,
+ ipv4_address_scope: null,
+ ipv6_address_scope: null, is_default: false, mtu: 1500, name: osm-ext, port_security_enabled: true, project_id: 456b6471010b4737b47a0dd599c920c5, 'provider:network_type': vlan, 'provider:physical_network': physnet1, 'provider:segmentation_id': 2148, revision_number: 1009,
+ 'router:external': true, segmentation_id: 2148, shared: true, status: ACTIVE, subnets: [{subnet: {allocation_pools: [{end: 172.21.249.255, start: 172.21.248.1}], cidr: 172.21.248.0/22, created_at: '2019-10-17T23:44:07Z', description: '', dns_nameservers: [],
+ enable_dhcp: true, gateway_ip: 172.21.251.254, host_routes: [], id: d14f68b7-8287-41fe-b533-dafb2240680a, ip_version: 4, ipv6_address_mode: null, ipv6_ra_mode: null, name: osm-ext-subnet, network_id: 21ea5d92-24f1-40ab-8d28-83230e277a49, project_id: 456b6471010b4737b47a0dd599c920c5,
+ revision_number: 5, service_types: [], subnetpool_id: null, tags: [], tenant_id: 456b6471010b4737b47a0dd599c920c5, updated_at: '2020-09-14T15:15:06Z'}}], tags: [], tenant_id: 456b6471010b4737b47a0dd599c920c5, type: data, updated_at: '2022-07-05T18:39:02Z'}
+ vim_id: 21ea5d92-24f1-40ab-8d28-83230e277a49
+ vim_status: ACTIVE
+ - id: datanet
+ mgmt-network: false
+ name: datanet
+ type: null
+ vim_info:
+ 'vim:bad7338b-ae46-43d4-a434-c3337a8054ac':
+ vim_account_id: bad7338b-ae46-43d4-a434-c3337a8054ac
+ vim_network_name: null
+ vim_details: >
+ {admin_state_up: true, availability_zone_hints: [],
+ availability_zones: [nova], created_at: '2022-07-28T08:41:59Z',
+ description: '', encapsulation: vxlan, encapsulation_id: 27,
+ encapsulation_type: vxlan, id: 34056287-3cd5-42cb-92d3-413382b50813,
+ ipv4_address_scope: null,
+ ipv6_address_scope: null, mtu: 1450, name: k8s-ns-datanet, port_security_enabled: true, project_id: 71c7971a7cab4b72bd5c10dbe6617f1e, 'provider:network_type': vxlan, 'provider:physical_network': null, 'provider:segmentation_id': 27, revision_number: 2, 'router:external': false,
+ segmentation_id: 27, shared: false, status: ACTIVE, subnets: [{subnet: {allocation_pools: [{end: 192.168.181.254, start: 192.168.181.1}], cidr: 192.168.181.0/24, created_at: '2022-07-28T08:41:59Z', description: '', dns_nameservers: [], enable_dhcp: true, gateway_ip: null,
+ host_routes: [], id: ab2920f8-881b-4bef-82a5-9582a7930786, ip_version: 4, ipv6_address_mode: null, ipv6_ra_mode: null, name: k8s-ns-datanet-subnet, network_id: 34056287-3cd5-42cb-92d3-413382b50813, project_id: 71c7971a7cab4b72bd5c10dbe6617f1e, revision_number: 0,
+ service_types: [], subnetpool_id: null, tags: [], tenant_id: 71c7971a7cab4b72bd5c10dbe6617f1e, updated_at: '2022-07-28T08:41:59Z'}}], tags: [], tenant_id: 71c7971a7cab4b72bd5c10dbe6617f1e, type: bridge, updated_at: '2022-07-28T08:41:59Z'}
+ vim_id: 34056287-3cd5-42cb-92d3-413382b50813
+ vim_status: ACTIVE
+ _admin:
+ created: 1658998097.58182
+ modified: 1658998193.42562
+ projects_read:
+ - 51e0e80fe533469d98766caa16552a3e
+ projects_write:
+ - 51e0e80fe533469d98766caa16552a3e
+ nsState: INSTANTIATED
+ current-operation: null
+ nslcmop: null
+ operation-type: null
+ deployed:
+ RO:
+ vnfd: []
+ operational-status: running
+ VCA:
+ - target_element: vnf/vnf1
+ member-vnf-index: vnf1
+ vdu_id: null
+ kdu_name: null
+ vdu_count_index: 0
+ operational-status: init
+ detailed-status: ''
+ step: initial-deploy
+ vnfd_id: k8s_proxy_charm-vnf
+ vdu_name: null
+ type: k8s_proxy_charm
+ ee_descriptor_id: simple-ee
+ charm_name: ''
+ ee_id: dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s.simple-ee-z0-vnf1-vnf.k8s
+ application: simple-ee-z0-vnf1-vnf
+ model: dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s
+ config_sw_installed: true
+ - target_element: vnf/vnf2
+ member-vnf-index: vnf2
+ vdu_id: null
+ kdu_name: null
+ vdu_count_index: 0
+ operational-status: init
+ detailed-status: ''
+ step: initial-deploy
+ vnfd_id: k8s_proxy_charm-vnf
+ vdu_name: null
+ type: k8s_proxy_charm
+ ee_descriptor_id: simple-ee
+ charm_name: ''
+ ee_id: dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s.simple-ee-z0-vnf2-vnf.k8s
+ application: simple-ee-z0-vnf2-vnf
+ model: dbfbd751-3de4-4e68-bd40-ec5ae0a53898-k8s
+ config_sw_installed: true
+ K8s: []
+"""
+
+db_vnfrs_text = """
+- _id: 1b6a4eb3-4fbf-415e-985c-4aeb3161eec0
+ id: 1b6a4eb3-4fbf-415e-985c-4aeb3161eec0
+ nsr-id-ref: dbfbd751-3de4-4e68-bd40-ec5ae0a53898
+ member-vnf-index-ref: vnf1
+ additionalParamsForVnf: null
+ created-time: 1658998097.58036
+ vnfd-ref: k8s_proxy_charm-vnf
+ vnfd-id: 6d9e1ca1-f387-4d01-9876-066fc7311e0f
+ vim-account-id: bad7338b-ae46-43d4-a434-c3337a8054ac
+ vca-id: null
+ vdur:
+ - _id: 38912ff7-5bdd-4228-911f-c2bee259c44a
+ additionalParams:
+ OSM:
+ count_index: 0
+ member_vnf_index: vnf1
+ ns_id: dbfbd751-3de4-4e68-bd40-ec5ae0a53898
+ vdu:
+ mgmtVM-0:
+ count_index: 0
+ interfaces:
+ dataVM-xe0:
+ name: dataVM-xe0
+ mgmtVM-eth0:
+ name: mgmtVM-eth0
+ vdu_id: mgmtVM
+ vdu_id: mgmtVM
+ vim_account_id: bad7338b-ae46-43d4-a434-c3337a8054ac
+ vnf_id: 1b6a4eb3-4fbf-415e-985c-4aeb3161eec0
+ vnfd_id: 6d9e1ca1-f387-4d01-9876-066fc7311e0f
+ vnfd_ref: k8s_proxy_charm-vnf
+ affinity-or-anti-affinity-group-id: []
+ alt-image-ids:
+ - '1'
+ - '2'
+ - '3'
+ cloud-init: '6d9e1ca1-f387-4d01-9876-066fc7311e0f:file:cloud-config.txt'
+ count-index: 0
+ id: 38912ff7-5bdd-4228-911f-c2bee259c44a
+ interfaces:
+ - external-connection-point-ref: vnf-mgmt-ext
+ internal-connection-point-ref: mgmtVM-eth0-int
+ mgmt-interface: true
+ mgmt-vnf: true
+ name: mgmtVM-eth0
+ ns-vld-id: mgmtnet
+ position: 1
+ type: PARAVIRT
+ compute_node: nfvisrv11
+ ip-address: 172.21.248.199
+ mac-address: 'fa:16:3e:4d:65:e9'
+ pci: null
+ vlan: 2148
+ - external-connection-point-ref: vnf-data-ext
+ internal-connection-point-ref: dataVM-xe0-int
+ name: dataVM-xe0
+ ns-vld-id: datanet
+ position: 2
+ type: PARAVIRT
+ compute_node: nfvisrv11
+ ip-address: 192.168.181.179
+ mac-address: 'fa:16:3e:ca:b5:d3'
+ pci: null
+ vlan: null
+ internal-connection-point:
+ - connection-point-id: mgmtVM-eth0-int
+ id: mgmtVM-eth0-int
+ name: mgmtVM-eth0-int
+ - connection-point-id: dataVM-xe0-int
+ id: dataVM-xe0-int
+ name: dataVM-xe0-int
+ ip-address: 172.21.248.199
+ ns-flavor-id: '0'
+ ns-image-id: '0'
+ ssh-access-required: true
+ ssh-keys:
+ - >
+ ssh-rsa
+ AAAAB3NzaC1yc2EAAAADAQABAAACAQDW3dtEDKfwZL0WZp6LeJUZFlZzYAHP7M4AsJwl2YFO/wmblfrTpWZ8tRyGwyjQacB7Zb7J07wD5AZACE71A3Nc9zjI22/gWN7N8X+ZxH6ywcr1GdXBqZDBeOdzD4pRb11E9mydGZ9l++KtFRtlF4G7IFYuxkOiSCJrkgiKuVDGodtQ/6VUKwxuI8U6N7MxtIBN2L3IfvMwuNyTo1daiUabQMwQKt/Q8Zpp78zsZ6SoxU+eYAHzbeTjAfNwhA88nRzRZn7tQW+gWl9wbSINbr2+JetTN+BTot/CMPmKzzul9tZrzhSzck1QSM3UDrD36ctRdaLABnWCoxpm0wJthNt693xVrFP+bMgK2BR0fyu9WwVEcHkC9CZ8yoi37k5rGVtoDw6sW6lxQ5QKS+Plv/YjGKqK3Ro/UoIEhgxcW53uz4PveyMBss4geB9ad/1T8dtugd288qfCWJRBpJBrE497EalhHolF3L/2bEu3uCKN0TY4POzqP/5cuAUc/uTJ2mjZewJdlJtrn7IyFtSUypeuVmXRx5LwByQw9EwPhUZlKVjYEHYmu5YTKlFSWyorWgRLBBIK7LLPj+bCGgLeT+fXmip6eFquAyVtoQfDofQ/gc0OXEA1uKfK2VFKg1le+joz1WA/XieGSvKRQ4aZorYgi/FzbpxKj2a60cZubJMq5w==
+ root@lcm-7b6bcf7cdd-5h2ql
+ - >-
+ ssh-rsa
+ AAAAB3NzaC1yc2EAAAADAQABAAABAQDtg65/Jh3KDWC9+YzkTz8Md/uhalkjPo15DSxlUNWzYQNFUzaG5Pt0trDwQ29UOQIUy1CB9HpWSZMTA1ESet/+cyXWkZ9MznAmGLQBdnwqWU792UQf6rv74Zpned8MbnKQXfs8gog1ZFFKRMcwitNRqs8xs8XsPLE/l1Jo2QemhM0fIRofjJiLKYaKeGP59Fb8UlIeGDaxmIFgLs8bAZvrmjbae3o4b1fZDNboqlQbHb9rakxI9uCnsaBrCmelXpP9EFmENx85vdHEwCAfCRvSWKnbXuOojJJzFM5odoWFZo8AuIhEb5ZiLkGet3CvCfWZZPpQc4TuNDaY0t1XUegH
+ juju-client-key
+ vdu-id-ref: mgmtVM
+ vdu-name: mgmtVM
+ vim_info:
+ 'vim:bad7338b-ae46-43d4-a434-c3337a8054ac':
+ interfaces:
+ - vim_info: >
+ {admin_state_up: true, allowed_address_pairs: [],
+ 'binding:host_id': nfvisrv11, 'binding:profile': {},
+ 'binding:vif_details': {bridge_name: br-int, connectivity: l2,
+ datapath_type: system, ovs_hybrid_plug: true, port_filter: true},
+ 'binding:vif_type': ovs, 'binding:vnic_type': normal,
+ created_at: '2022-07-28T08:42:04Z', description: '', device_id: 1fabddca-0dcf-4702-a5f3-5cc028c2aba7, device_owner: 'compute:nova', extra_dhcp_opts: [], fixed_ips: [{ip_address: 172.21.248.199, subnet_id: d14f68b7-8287-41fe-b533-dafb2240680a}], id: e053d44f-1d67-4274-b85d-1cef243353d6,
+ mac_address: 'fa:16:3e:4d:65:e9', name: mgmtVM-eth0, network_id: 21ea5d92-24f1-40ab-8d28-83230e277a49, port_security_enabled: true, project_id: 71c7971a7cab4b72bd5c10dbe6617f1e, revision_number: 4, security_groups: [1de4b2c2-e4be-4e91-985c-d887e2715949], status: ACTIVE,
+ tags: [], tenant_id: 71c7971a7cab4b72bd5c10dbe6617f1e, updated_at: '2022-07-28T08:42:16Z'}
+ mac_address: 'fa:16:3e:4d:65:e9'
+ vim_net_id: 21ea5d92-24f1-40ab-8d28-83230e277a49
+ vim_interface_id: e053d44f-1d67-4274-b85d-1cef243353d6
+ compute_node: nfvisrv11
+ pci: null
+ vlan: 2148
+ ip_address: 172.21.248.199
+ mgmt_vnf_interface: true
+ mgmt_vdu_interface: true
+ - vim_info: >
+ {admin_state_up: true, allowed_address_pairs: [],
+ 'binding:host_id': nfvisrv11, 'binding:profile': {},
+ 'binding:vif_details': {bridge_name: br-int, connectivity: l2,
+ datapath_type: system, ovs_hybrid_plug: true, port_filter: true},
+ 'binding:vif_type': ovs, 'binding:vnic_type': normal,
+ created_at: '2022-07-28T08:42:04Z', description: '', device_id: 1fabddca-0dcf-4702-a5f3-5cc028c2aba7, device_owner: 'compute:nova', extra_dhcp_opts: [], fixed_ips: [{ip_address: 192.168.181.179, subnet_id: ab2920f8-881b-4bef-82a5-9582a7930786}], id: 8a34c944-0fc1-41ae-9dbc-9743e5988162,
+ mac_address: 'fa:16:3e:ca:b5:d3', name: dataVM-xe0, network_id: 34056287-3cd5-42cb-92d3-413382b50813, port_security_enabled: true, project_id: 71c7971a7cab4b72bd5c10dbe6617f1e, revision_number: 4, security_groups: [1de4b2c2-e4be-4e91-985c-d887e2715949], status: ACTIVE,
+ tags: [], tenant_id: 71c7971a7cab4b72bd5c10dbe6617f1e, updated_at: '2022-07-28T08:42:15Z'}
+ mac_address: 'fa:16:3e:ca:b5:d3'
+ vim_net_id: 34056287-3cd5-42cb-92d3-413382b50813
+ vim_interface_id: 8a34c944-0fc1-41ae-9dbc-9743e5988162
+ compute_node: nfvisrv11
+ pci: null
+ vlan: null
+ ip_address: 192.168.181.179
+ vim_details: >
+ {'OS-DCF:diskConfig': MANUAL, 'OS-EXT-AZ:availability_zone': nova,
+ 'OS-EXT-SRV-ATTR:host': nfvisrv11,
+ 'OS-EXT-SRV-ATTR:hypervisor_hostname': nfvisrv11,
+ 'OS-EXT-SRV-ATTR:instance_name': instance-0002967a,
+ 'OS-EXT-STS:power_state': 1, 'OS-EXT-STS:task_state': null,
+ 'OS-EXT-STS:vm_state': active, 'OS-SRV-USG:launched_at': '2022-07-28T08:42:17.000000', 'OS-SRV-USG:terminated_at': null, accessIPv4: '', accessIPv6: '', addresses: {k8s-ns-datanet: [{'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:ca:b5:d3', 'OS-EXT-IPS:type': fixed,
+ addr: 192.168.181.179, version: 4}], osm-ext: [{'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:4d:65:e9', 'OS-EXT-IPS:type': fixed, addr: 172.21.248.199, version: 4}]}, config_drive: '', created: '2022-07-28T08:42:06Z', flavor: {id: 17a9ba76-beb7-4ad4-a481-97de37174866,
+ links: [{href: 'http://172.21.247.1:8774/flavors/17a9ba76-beb7-4ad4-a481-97de37174866', rel: bookmark}]}, hostId: 2aa7155bd281bd308d8e3776af56d428210c21aab788a8cbdf5ef500, id: 1fabddca-0dcf-4702-a5f3-5cc028c2aba7, image: {id: 919fc71a-6acd-4ee3-8123-739a9abbc2e7,
+ links: [{href: 'http://172.21.247.1:8774/images/919fc71a-6acd-4ee3-8123-739a9abbc2e7', rel: bookmark}]}, key_name: null, links: [{href: 'http://172.21.247.1:8774/v2.1/servers/1fabddca-0dcf-4702-a5f3-5cc028c2aba7', rel: self}, {href: 'http://172.21.247.1:8774/servers/1fabddca-0dcf-4702-a5f3-5cc028c2aba7',
+ rel: bookmark}], metadata: {}, name: k8s-ns-vnf1-mgmtVM-0, 'os-extended-volumes:volumes_attached': [], progress: 0, security_groups: [{name: default}, {name: default}], status: ACTIVE, tenant_id: 71c7971a7cab4b72bd5c10dbe6617f1e, updated: '2022-07-28T08:42:17Z',
+ user_id: f043c84f940b4fc8a01a98714ea97c80}
+ vim_id: 1fabddca-0dcf-4702-a5f3-5cc028c2aba7
+ vim_status: ACTIVE
+ vim_name: k8s-ns-vnf1-mgmtVM-0
+ virtual-storages:
+ - id: mgmtVM-storage
+ size-of-storage: '10'
+ status: ACTIVE
+ vim-id: 1fabddca-0dcf-4702-a5f3-5cc028c2aba7
+ name: k8s-ns-vnf1-mgmtVM-0
+ connection-point:
+ - name: vnf-mgmt-ext
+ connection-point-id: mgmtVM-eth0-int
+ connection-point-vdu-id: mgmtVM
+ id: vnf-mgmt-ext
+ - name: vnf-data-ext
+ connection-point-id: dataVM-xe0-int
+ connection-point-vdu-id: mgmtVM
+ id: vnf-data-ext
+ ip-address: 172.21.248.199
+ revision: 1
+ _admin:
+ created: 1658998097.58048
+ modified: 1658998097.58048
+ projects_read:
+ - 51e0e80fe533469d98766caa16552a3e
+ projects_write:
+ - 51e0e80fe533469d98766caa16552a3e
+ nsState: INSTANTIATED
+"""