Feature-9904: Enhancing NG-UI to enable Juju operational view dashboard 29/10229/12
authorksaikiranr <saikiran.k@tataelxsi.co.in>
Wed, 27 Jan 2021 16:37:46 +0000 (22:07 +0530)
committerksaikiranr <saikiran.k@tataelxsi.co.in>
Tue, 23 Feb 2021 13:57:40 +0000 (19:27 +0530)
Added methods in n2vc_juju_conn and libjuju to suppot configs list
and executed actions/history of actions. Added method in n2vc juju conn
to call libjuju methods to get actions, configs and history of actions.

Change-Id: I845789080d148fa42e859dcda185da1e62b4c489
Signed-off-by: ksaikiranr <saikiran.k@tataelxsi.co.in>
n2vc/exceptions.py
n2vc/libjuju.py
n2vc/n2vc_juju_conn.py

index 256860e..ae9dbfb 100644 (file)
@@ -171,6 +171,18 @@ class N2VCNotFound(N2VCException):
         return "<{}> Not found: {}".format(type(self), super().__str__())
 
 
+class JujuError(N2VCException):
+    """
+    Juju Error
+    """
+
+    def __init__(self, message: str = ""):
+        N2VCException.__init__(self, message=message)
+
+    def __str__(self):
+        return "<{}> Juju Error: {}".format(type(self), super().__str__())
+
+
 class K8sException(Exception):
     """
     K8s exception
index d998475..ff35232 100644 (file)
@@ -34,6 +34,7 @@ from n2vc.exceptions import (
     JujuModelAlreadyExists,
     JujuControllerFailedConnecting,
     JujuApplicationExists,
+    JujuError
 )
 from n2vc.utils import DB_DATA
 from osm_common.dbbase import DbException
@@ -194,6 +195,68 @@ class Libjuju:
                 await self.disconnect_model(model)
             await self.disconnect_controller(controller)
 
+    async def get_executed_actions(self, model_name: str) -> list:
+        """
+        Get executed/history of actions for a model.
+
+        :param: model_name: Model name, str.
+        :return: List of executed actions for a model.
+        """
+        model = None
+        executed_actions = []
+        controller = await self.get_controller()
+        try:
+            model = await self.get_model(controller, model_name)
+            # Get all unique action names
+            actions = {}
+            for application in model.applications:
+                application_actions = await self.get_actions(application, model_name)
+                actions.update(application_actions)
+            # Get status of all actions
+            for application_action in actions:
+                app_action_status_list = await model.get_action_status(name=application_action)
+                for action_id, action_status in app_action_status_list.items():
+                    executed_action = {"id": action_id, "action": application_action,
+                                       "status": action_status}
+                    # Get action output by id
+                    action_status = await model.get_action_output(executed_action["id"])
+                    for k, v in action_status.items():
+                        executed_action[k] = v
+                    executed_actions.append(executed_action)
+        except Exception as e:
+            raise JujuError("Error in getting executed actions for model: {}. Error: {}"
+                            .format(model_name, str(e)))
+        finally:
+            if model:
+                await self.disconnect_model(model)
+            await self.disconnect_controller(controller)
+        return executed_actions
+
+    async def get_application_configs(self, model_name: str, application_name: str) -> dict:
+        """
+        Get available configs for an application.
+
+        :param: model_name: Model name, str.
+        :param: application_name: Application name, str.
+
+        :return: A dict which has key - action name, value - action description
+        """
+        model = None
+        application_configs = {}
+        controller = await self.get_controller()
+        try:
+            model = await self.get_model(controller, model_name)
+            application = self._get_application(model, application_name=application_name)
+            application_configs = await application.get_config()
+        except Exception as e:
+            raise JujuError("Error in getting configs for application: {} in model: {}. Error: {}"
+                            .format(application_name, model_name, str(e)))
+        finally:
+            if model:
+                await self.disconnect_model(model)
+            await self.disconnect_controller(controller)
+        return application_configs
+
     async def get_model(
         self, controller: Controller, model_name: str, id=None
     ) -> Model:
index 951ac6c..1a7a46f 100644 (file)
@@ -243,12 +243,32 @@ class N2VCJujuConnector(N2VCConnector):
 
         for m in models:
             status[m] = await self.libjuju.get_model_status(m)
-
         if yaml_format:
             return obj_to_yaml(status)
         else:
             return obj_to_dict(status)
 
+    async def update_vca_status(self, vcastatus: dict):
+        """
+        Add all configs, actions, executed actions of all applications in a model to vcastatus dict.
+        :param vcastatus: dict containing vcaStatus
+        :return: None
+        """
+        try:
+            for model_name in vcastatus:
+                # Adding executed actions
+                vcastatus[model_name]["executedActions"] = \
+                    await self.libjuju.get_executed_actions(model_name)
+                for application in vcastatus[model_name]["applications"]:
+                    # Adding application actions
+                    vcastatus[model_name]["applications"][application]["actions"] = \
+                        await self.libjuju.get_actions(application, model_name)
+                    # Adding application configs
+                    vcastatus[model_name]["applications"][application]["configs"] = \
+                        await self.libjuju.get_application_configs(model_name, application)
+        except Exception as e:
+            self.log.debug("Error in updating vca status: {}".format(str(e)))
+
     async def create_execution_environment(
         self,
         namespace: str,