Feature 10908 pass over upgrade request to Libjuju 95/11895/10
authoraticig <gulsum.atici@canonical.com>
Sun, 17 Apr 2022 21:31:42 +0000 (00:31 +0300)
committeraticig <gulsum.atici@canonical.com>
Mon, 9 May 2022 21:33:53 +0000 (00:33 +0300)
Change-Id: I7a4ea434f22b939a80f58941a892ed92dae62ee6
Signed-off-by: aticig <gulsum.atici@canonical.com>
n2vc/k8s_conn.py
n2vc/k8s_helm_base_conn.py
n2vc/k8s_juju_conn.py
n2vc/n2vc_conn.py
n2vc/n2vc_juju_conn.py
n2vc/tests/unit/test_n2vc_juju_conn.py

index ef4f5f2..f692abc 100644 (file)
@@ -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:
         """
index efca96f..952630a 100644 (file)
@@ -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,
index 737cac6..6744015 100644 (file)
@@ -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,
index 6b0df89..68e8c14 100644 (file)
@@ -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,
index fb36809..261b4b8 100644 (file)
@@ -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
index 3caae03..4fef1f2 100644 (file)
@@ -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,
+        )