From: aticig Date: Sun, 17 Apr 2022 21:31:42 +0000 (+0300) Subject: Feature 10908 pass over upgrade request to Libjuju X-Git-Tag: v12.0.0rc1~16 X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=8070c3c8260010f052ee9fe546c85bed4aa6b2eb;p=osm%2FN2VC.git Feature 10908 pass over upgrade request to Libjuju Change-Id: I7a4ea434f22b939a80f58941a892ed92dae62ee6 Signed-off-by: aticig --- diff --git a/n2vc/k8s_conn.py b/n2vc/k8s_conn.py index ef4f5f2..f692abc 100644 --- a/n2vc/k8s_conn.py +++ b/n2vc/k8s_conn.py @@ -329,6 +329,28 @@ class K8sConnector(abc.ABC, Loggable): :return: Returns the output of the action """ + @abc.abstractmethod + async def upgrade_charm( + self, + ee_id: str = None, + path: str = None, + charm_id: str = None, + charm_type: str = None, + timeout: float = None, + ) -> str: + """This method upgrade charms in VNFs + + Args: + ee_id: Execution environment id + path: Local path to the charm + charm_id: charm-id + charm_type: Charm type can be lxc-proxy-charm, native-charm or k8s-proxy-charm + timeout: (Float) Timeout for the ns update operation + + Returns: + The output of the update operation if status equals to "completed" + """ + @abc.abstractmethod async def inspect_kdu(self, kdu_model: str, repo_url: str = None) -> str: """ diff --git a/n2vc/k8s_helm_base_conn.py b/n2vc/k8s_helm_base_conn.py index efca96f..952630a 100644 --- a/n2vc/k8s_helm_base_conn.py +++ b/n2vc/k8s_helm_base_conn.py @@ -938,6 +938,28 @@ class K8sHelmBaseConnector(K8sConnector): self.log.debug("Instance {} not found".format(kdu_instance)) return None + async def upgrade_charm( + self, + ee_id: str = None, + path: str = None, + charm_id: str = None, + charm_type: str = None, + timeout: float = None, + ) -> str: + """This method upgrade charms in VNFs + + Args: + ee_id: Execution environment id + path: Local path to the charm + charm_id: charm-id + charm_type: Charm type can be lxc-proxy-charm, native-charm or k8s-proxy-charm + timeout: (Float) Timeout for the ns update operation + + Returns: + The output of the update operation if status equals to "completed" + """ + raise K8sException("KDUs deployed with Helm do not support charm upgrade") + async def exec_primitive( self, cluster_uuid: str = None, diff --git a/n2vc/k8s_juju_conn.py b/n2vc/k8s_juju_conn.py index 737cac6..6744015 100644 --- a/n2vc/k8s_juju_conn.py +++ b/n2vc/k8s_juju_conn.py @@ -533,6 +533,30 @@ class K8sJujuConnector(K8sConnector): self.log.debug(f"[uninstall] Model {kdu_instance} destroyed") return True + async def upgrade_charm( + self, + ee_id: str = None, + path: str = None, + charm_id: str = None, + charm_type: str = None, + timeout: float = None, + ) -> str: + """This method upgrade charms in VNFs + + Args: + ee_id: Execution environment id + path: Local path to the charm + charm_id: charm-id + charm_type: Charm type can be lxc-proxy-charm, native-charm or k8s-proxy-charm + timeout: (Float) Timeout for the ns update operation + + Returns: + The output of the update operation if status equals to "completed" + """ + raise K8sException( + "KDUs deployed with Juju Bundle do not support charm upgrade" + ) + async def exec_primitive( self, cluster_uuid: str = None, diff --git a/n2vc/n2vc_conn.py b/n2vc/n2vc_conn.py index 6b0df89..68e8c14 100644 --- a/n2vc/n2vc_conn.py +++ b/n2vc/n2vc_conn.py @@ -331,6 +331,28 @@ class N2VCConnector(abc.ABC, Loggable): :param float total_timeout: """ + @abc.abstractmethod + async def upgrade_charm( + self, + ee_id: str = None, + path: str = None, + charm_id: str = None, + charm_type: str = None, + timeout: float = None, + ) -> str: + """This method upgrade charms in VNFs + + Args: + ee_id: Execution environment id + path: Local path to the charm + charm_id: charm-id + charm_type: Charm type can be lxc-proxy-charm, native-charm or k8s-proxy-charm + timeout: (Float) Timeout for the ns update operation + + Returns: + The output of the update operation if status equals to "completed" + """ + @abc.abstractmethod async def exec_primitive( self, diff --git a/n2vc/n2vc_juju_conn.py b/n2vc/n2vc_juju_conn.py index fb36809..261b4b8 100644 --- a/n2vc/n2vc_juju_conn.py +++ b/n2vc/n2vc_juju_conn.py @@ -1068,6 +1068,68 @@ class N2VCJujuConnector(N2VCConnector): primitive_name=primitive_name, ) + async def upgrade_charm( + self, + ee_id: str = None, + path: str = None, + charm_id: str = None, + charm_type: str = None, + timeout: float = None, + ) -> str: + """This method upgrade charms in VNFs + + Args: + ee_id: Execution environment id + path: Local path to the charm + charm_id: charm-id + charm_type: Charm type can be lxc-proxy-charm, native-charm or k8s-proxy-charm + timeout: (Float) Timeout for the ns update operation + + Returns: + The output of the update operation if status equals to "completed" + + """ + self.log.info("Upgrading charm: {} on ee: {}".format(path, ee_id)) + libjuju = await self._get_libjuju(charm_id) + + # check arguments + if ee_id is None or len(ee_id) == 0: + raise N2VCBadArgumentsException( + message="ee_id is mandatory", bad_args=["ee_id"] + ) + try: + ( + model_name, + application_name, + machine_id, + ) = N2VCJujuConnector._get_ee_id_components(ee_id=ee_id) + + except Exception: + raise N2VCBadArgumentsException( + message="ee_id={} is not a valid execution environment id".format( + ee_id + ), + bad_args=["ee_id"], + ) + + try: + + await libjuju.upgrade_charm( + application_name=application_name, + path=path, + model_name=model_name, + total_timeout=timeout, + ) + + return f"Charm upgraded with application name {application_name}" + + except Exception as e: + self.log.error("Error upgrading charm {}: {}".format(path, e)) + + raise N2VCException( + message="Error upgrading charm {} in ee={} : {}".format(path, ee_id, e) + ) + async def disconnect(self, vca_id: str = None): """ Disconnect from VCA diff --git a/n2vc/tests/unit/test_n2vc_juju_conn.py b/n2vc/tests/unit/test_n2vc_juju_conn.py index 3caae03..4fef1f2 100644 --- a/n2vc/tests/unit/test_n2vc_juju_conn.py +++ b/n2vc/tests/unit/test_n2vc_juju_conn.py @@ -26,6 +26,7 @@ from osm_common import fslocal from n2vc.exceptions import ( N2VCBadArgumentsException, N2VCException, + JujuApplicationNotFound, ) from n2vc.tests.unit.utils import AsyncMock from n2vc.vca.connection_data import ConnectionData @@ -291,3 +292,88 @@ class AddRelationTest(N2VCJujuConnTestCase): self.loop.run_until_complete( self.n2vc.add_relation(relation_endpoint_1, relation_endpoint_2) ) + + +class UpgradeCharmTest(N2VCJujuConnTestCase): + def setUp(self): + super(UpgradeCharmTest, self).setUp() + self.n2vc._get_libjuju = AsyncMock(return_value=self.n2vc.libjuju) + N2VCJujuConnector._get_ee_id_components = Mock() + self.n2vc.libjuju.upgrade_charm = AsyncMock() + + def test_empty_ee_id(self): + with self.assertRaises(N2VCBadArgumentsException): + self.loop.run_until_complete( + self.n2vc.upgrade_charm( + "", "/sample_charm_path", "sample_charm_id", "native-charm", None + ) + ) + self.n2vc._get_libjuju.assert_called() + self.n2vc._get_ee_id_components.assert_not_called() + self.n2vc.libjuju.upgrade_charm.assert_not_called() + + def test_wrong_ee_id(self): + N2VCJujuConnector._get_ee_id_components.side_effect = Exception + with self.assertRaises(N2VCBadArgumentsException): + self.loop.run_until_complete( + self.n2vc.upgrade_charm( + "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s", + "/sample_charm_path", + "sample_charm_id", + "native-charm", + 500, + ) + ) + self.n2vc._get_libjuju.assert_called() + self.n2vc._get_ee_id_components.assert_called() + self.n2vc.libjuju.upgrade_charm.assert_not_called() + + def test_charm_upgrade_succeded(self): + N2VCJujuConnector._get_ee_id_components.return_value = ( + "sample_model", + "sample_app", + "sample_machine_id", + ) + self.loop.run_until_complete( + self.n2vc.upgrade_charm( + "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s", + "/sample_charm_path", + "sample_charm_id", + "native-charm", + 500, + ) + ) + self.n2vc._get_libjuju.assert_called() + self.n2vc._get_ee_id_components.assert_called() + self.n2vc.libjuju.upgrade_charm.assert_called_with( + application_name="sample_app", + path="/sample_charm_path", + model_name="sample_model", + total_timeout=500, + ) + + def test_charm_upgrade_failed(self): + N2VCJujuConnector._get_ee_id_components.return_value = ( + "sample_model", + "sample_app", + "sample_machine_id", + ) + self.n2vc.libjuju.upgrade_charm.side_effect = JujuApplicationNotFound + with self.assertRaises(N2VCException): + self.loop.run_until_complete( + self.n2vc.upgrade_charm( + "ns-id-k8s.app-vnf-vnf-id-vdu-vdu-random.k8s", + "/sample_charm_path", + "sample_charm_id", + "native-charm", + None, + ) + ) + self.n2vc._get_libjuju.assert_called() + self.n2vc._get_ee_id_components.assert_called() + self.n2vc.libjuju.upgrade_charm.assert_called_with( + application_name="sample_app", + path="/sample_charm_path", + model_name="sample_model", + total_timeout=None, + )