From abde8621c0a56ed2f6b1d652290eeca4dcab26ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20L=C3=B6sche?= Date: Thu, 17 Nov 2022 20:36:37 +0100 Subject: [PATCH] [resotoworker][feat] Expose list of loaded collectors (#1288) * [resotoworker][fix] Require a restart when the list of collectors changes * [resotoworker][feat] Expose list of loaded collectors on /info --- resotoworker/requirements.txt | 2 ++ resotoworker/resotoworker/__main__.py | 21 ++++++++++++++++++++- resotoworker/resotoworker/config.py | 2 +- resotoworker/resotoworker/pluginloader.py | 6 +++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/resotoworker/requirements.txt b/resotoworker/requirements.txt index fffafc17d0..ddd8e24459 100644 --- a/resotoworker/requirements.txt +++ b/resotoworker/requirements.txt @@ -1,2 +1,4 @@ resotolib==3.0.0a0 tenacity==8.1.0 +CherryPy==18.8.0 +setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability diff --git a/resotoworker/resotoworker/__main__.py b/resotoworker/resotoworker/__main__.py index 14a3efa0b8..8f0e2c7cc2 100644 --- a/resotoworker/resotoworker/__main__.py +++ b/resotoworker/resotoworker/__main__.py @@ -2,6 +2,7 @@ import os import sys import threading +import cherrypy # type: ignore import time from functools import partial from queue import Queue @@ -124,7 +125,7 @@ def send_request(request: requests.Request) -> requests.Response: "ssl_key": tls_data.key_path, } web_server = WebServer( - WebApp(mountpoint=Config.resotoworker.web_path), + WorkerWebApp(mountpoint=Config.resotoworker.web_path, plugin_loader=plugin_loader), web_host=Config.resotoworker.web_host, web_port=Config.resotoworker.web_port, **web_server_args, @@ -295,5 +296,23 @@ def add_args(arg_parser: ArgumentParser) -> None: ) +class WorkerWebApp(WebApp): + def __init__(self, *args, plugin_loader: PluginLoader, **kwargs) -> None: # type: ignore + super().__init__(*args, **kwargs) + self.plugin_loader = plugin_loader + + @cherrypy.expose # type: ignore + @cherrypy.tools.json_out() # type: ignore + @cherrypy.tools.allow(methods=["GET"]) # type: ignore + def info(self) -> Dict[str, List[str]]: + active_collectors: List[str] = [ + plugin.cloud for plugin in self.plugin_loader.plugins(PluginType.COLLECTOR) # type: ignore + ] + all_collectors: List[str] = [ + plugin.cloud for plugin in self.plugin_loader.all_plugins(PluginType.COLLECTOR) # type: ignore + ] + return {"active_collectors": active_collectors, "all_collectors": all_collectors} + + if __name__ == "__main__": main() diff --git a/resotoworker/resotoworker/config.py b/resotoworker/resotoworker/config.py index 537302eb1c..d14651cf47 100644 --- a/resotoworker/resotoworker/config.py +++ b/resotoworker/resotoworker/config.py @@ -14,7 +14,7 @@ class ResotoWorkerConfig: kind: ClassVar[str] = "resotoworker" collector: List[str] = field( factory=lambda: ["example"], - metadata={"description": "List of collectors to run"}, + metadata={"description": "List of collectors to run", "restart_required": True}, ) graph: str = field( default="resoto", diff --git a/resotoworker/resotoworker/pluginloader.py b/resotoworker/resotoworker/pluginloader.py index bc463c30dd..d1f06f1625 100644 --- a/resotoworker/resotoworker/pluginloader.py +++ b/resotoworker/resotoworker/pluginloader.py @@ -81,9 +81,13 @@ def plugins( return self._plugins.get(plugin_type, []) # type: ignore - def all_plugins(self) -> List[Union[Type[BasePlugin], Type[BaseActionPlugin], Type[BasePostCollectPlugin]]]: + def all_plugins( + self, plugin_type: Optional[PluginType] = None + ) -> List[Union[Type[BasePlugin], Type[BaseActionPlugin], Type[BasePostCollectPlugin]]]: if not self._initialized: self.find_plugins() + if plugin_type is not None: + return self._plugins.get(plugin_type, []) # type: ignore return [plugin for plugins in self._plugins.values() for plugin in plugins] def add_plugin_args(self, arg_parser: ArgumentParser) -> None: