From 8d9ec5c73bffd823339f5f7c3225ac2b6c0cfadf Mon Sep 17 00:00:00 2001 From: Johannes Findeisen Date: Tue, 27 Sep 2022 07:00:17 +0200 Subject: [PATCH] Added dynamic loading of tasks and services, refactoring and fixes. --- bin/linspector | 3 ++- etc/linspector.ini | 8 ++++++-- etc/monitors/network1/gateway.ini | 13 +++++++++--- etc/monitors/network2/gateway.ini | 7 +++---- linspector/core/monitor.py | 29 +++++++++++++++++++------- linspector/core/monitors.py | 4 ++-- linspector/core/notification.py | 33 ------------------------------ linspector/core/notifications.py | 33 ------------------------------ linspector/core/plugin.py | 33 ------------------------------ linspector/core/plugins.py | 34 ------------------------------- linspector/core/task.py | 33 ------------------------------ linspector/core/tasks.py | 33 ------------------------------ linspector/plugins/httpserver.py | 4 +--- linspector/plugins/lish.py | 4 +--- linspector/tasks/filelogger.py | 4 +--- linspector/tasks/mariadb.py | 4 +--- linspector/tasks/redis.py | 4 +--- linspector/tasks/sqlite.py | 4 +--- 18 files changed, 51 insertions(+), 236 deletions(-) delete mode 100644 linspector/core/notification.py delete mode 100644 linspector/core/notifications.py delete mode 100644 linspector/core/plugin.py delete mode 100644 linspector/core/plugins.py delete mode 100644 linspector/core/task.py delete mode 100644 linspector/core/tasks.py diff --git a/bin/linspector b/bin/linspector index 2fe7735..0b71b33 100755 --- a/bin/linspector +++ b/bin/linspector @@ -65,6 +65,7 @@ def main(): monitors = None notifications = {} services = {} + tasks = {} try: configuration = Configuration(args.configuration_path, environment) @@ -74,7 +75,7 @@ def main(): sys.exit(1) try: - monitors = Monitors(configuration, environment, notifications, services) + monitors = Monitors(configuration, environment, notifications, services, tasks) except Exception as err: logger.warning('[linspector] monitor initialization error: {0}'.format(err)) diff --git a/etc/linspector.ini b/etc/linspector.ini index e3ae2a8..d9ce24b 100644 --- a/etc/linspector.ini +++ b/etc/linspector.ini @@ -7,8 +7,12 @@ log_level= verbose log_count = 5 log_size = 10485760 pid_file = /var/run/user/1000/linspector.pid -; default delimiters '=' and ':' should be changed to ',' to be more native +; plugins separated by ','. no whitespaces allowed plugins = HTTPServer +; globally configured tasks will always run on all monitors when no task is configured there. if tasks are configured in +; a monitor then maybe only run tasks from the dedicated monitor. maybe it is a good idea to run global tasks in every +; monitor and the monitor can add tasks to the global settings... need to think about it. +; tasks separated by ','. no whitespaces allowed tasks = MariaDB,Logger ; maybe the run_mode is obsolete because this will be a daemon but maybe it is useful for one time execution? ; in uplink the available run_modes were cron, daemon and foreground @@ -18,7 +22,7 @@ run_mode = cron ; is needed. see email example. [notifications] ; values can be overridden in each defined monitor -sms_receivers = +number1:+number2 +sms_receivers = +number1,+number2 sms_configuration_file = ~/linspector/etc/gammurc ; retry to send interval and number of retries if something failed sms_resend = 10 diff --git a/etc/monitors/network1/gateway.ini b/etc/monitors/network1/gateway.ini index 7e04ad7..4d2d54b 100644 --- a/etc/monitors/network1/gateway.ini +++ b/etc/monitors/network1/gateway.ini @@ -1,11 +1,18 @@ [monitor] +; currently i get errors when the service option is not spelled correct. error handling need to fix this. same for +; notifications and tasks. service = FritzboxUplink interval = 60 +; notifications separated by ','. no whitespaces allowed notifications = SMS,Email ; values from main configuration can be overridden for each defined monitor -email_receivers = admin@example.com:fallback@example.com -sms_receivers = +329084320984:+39804932409 -tasks = None +; email_receivers separated by ','. no whitespaces allowed +email_receivers = admin@example.com,fallback@example.com +; sms_receivers separated by ','. no whitespaces allowed +sms_receivers = +329084320984,+39804932409 +; setting to None fails. just do not set this option. currently i get an error when tasks is not set here. need to be +; fixed. setting it like below works but is no good design for optional options. same for notifications. +tasks = Redis host = 192.168.0.1 user = USERNAME password = PASSWORD diff --git a/etc/monitors/network2/gateway.ini b/etc/monitors/network2/gateway.ini index 0cfc0f3..b139f81 100644 --- a/etc/monitors/network2/gateway.ini +++ b/etc/monitors/network2/gateway.ini @@ -2,11 +2,10 @@ identifier = dsl service = FritzboxUplink interval = 60 -# default delimiters '=' and ':' should be changed to ',' to be more native notifications = SMS,Email -email_receivers = admin@example.com:fallback@example.com -sms_receivers = +329084320984:+39804932409 -tasks = MariaDB:Logger:Redis +email_receivers = admin@example.com,fallback@example.com +sms_receivers = +329084320984,+39804932409 +tasks = MariaDB host = 192.168.1.1 user = USERNAME password = PASSWORD diff --git a/linspector/core/monitor.py b/linspector/core/monitor.py index c7e538c..9866c7f 100644 --- a/linspector/core/monitor.py +++ b/linspector/core/monitor.py @@ -31,15 +31,16 @@ logger = getLogger('linspector') class Monitor: def __init__(self, configuration, environment, identifier, monitor_configuration, notifications, - services): + services, tasks): self.__configuration = configuration self.__environment = environment self.__identifier = identifier self.__monitor_configuration = monitor_configuration self.__notifications = notifications self.__services = services + self.__tasks = tasks - #print(__file__ + ' (42): ' + str(monitor_configuration)) + #print(__file__ + ' (43): ' + str(monitor_configuration)) if self.__monitor_configuration.get('monitor', 'service'): # TODO: the exception handling later!!! @@ -48,13 +49,13 @@ class Monitor: self.__monitor_configuration.get('monitor', 'service').lower() service_module = importlib.import_module(service_package) - service = getattr(service_module, self.__monitor_configuration.get('monitor', 'service') + - 'Service') + service = getattr(service_module, + self.__monitor_configuration.get('monitor', 'service') + 'Service') service.__init__(self, configuration, environment) if self.__monitor_configuration.get('monitor', 'service') not in services: services[self.__monitor_configuration.get('monitor', 'service')] = service - #print(__file__ + ' (57): ' + str(services)) + #print(__file__ + ' (58): ' + str(services)) #else: # do some logging @@ -69,7 +70,7 @@ class Monitor: for notification_option in self.__monitor_configuration.get('monitor', 'notifications').split(','): - #print(__file__ + ' (72): ' + str(notification_option)) + #print(__file__ + ' (73): ' + str(notification_option)) notification_package = 'linspector.notifications.' + notification_option.lower() notification_module = importlib.import_module(notification_package) @@ -78,7 +79,21 @@ class Monitor: if notification_option not in notifications: notifications[notification_option] = notification - #print(__file__ + ' (81): ' + str(notifications)) + #print(__file__ + ' (82): ' + str(notifications)) + + if self.__monitor_configuration.get('monitor', 'tasks'): + for task_option in self.__monitor_configuration.get('monitor', + 'tasks').split(','): + #print(__file__ + ' (87): ' + str(task_option)) + task_package = 'linspector.tasks.' + task_option.lower() + task_module = importlib.import_module(task_package) + + task = getattr(task_module, task_option + 'Task') + task.__init__(self, configuration, environment) + + if task_option not in tasks: + tasks[task_option] = task + #print(__file__ + ' (96): ' + str(tasks)) def get_identifier(self): return self.__identifier diff --git a/linspector/core/monitors.py b/linspector/core/monitors.py index 4a65a1a..2a34496 100644 --- a/linspector/core/monitors.py +++ b/linspector/core/monitors.py @@ -38,7 +38,7 @@ logger = getLogger('linspector') # when changed dynamically. class Monitors: - def __init__(self, configuration, environment, notifications, services): + def __init__(self, configuration, environment, notifications, services, tasks): self.__configuration = configuration self.__environment = environment self.__monitors = {} @@ -60,7 +60,7 @@ class Monitors: # they else refer to the same object. self.__monitors[identifier] = Monitor(configuration, environment, identifier, copy.deepcopy(monitor_configuration), - notifications, services) + notifications, services, tasks) def get_monitors(self): return self.__monitors diff --git a/linspector/core/notification.py b/linspector/core/notification.py deleted file mode 100644 index 7eb32eb..0000000 --- a/linspector/core/notification.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -This file is part of Linspector (https://linspector.org/) -Copyright (c) 2022 Johannes Findeisen . All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -from logging import getLogger - -logger = getLogger('linspector') - - -class Notification: - - def __init__(self, configuration, environment): - self.__configuration = configuration - self.__environment = environment diff --git a/linspector/core/notifications.py b/linspector/core/notifications.py deleted file mode 100644 index ba1ecb1..0000000 --- a/linspector/core/notifications.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -This file is part of Linspector (https://linspector.org/) -Copyright (c) 2022 Johannes Findeisen . All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -from logging import getLogger - -logger = getLogger('linspector') - - -class Notifications: - - def __init__(self, configuration, environment): - self.__configuration = configuration - self.__environment = environment diff --git a/linspector/core/plugin.py b/linspector/core/plugin.py deleted file mode 100644 index d06989d..0000000 --- a/linspector/core/plugin.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -This file is part of Linspector (https://linspector.org/) -Copyright (c) 2022 Johannes Findeisen . All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -from logging import getLogger - -logger = getLogger('linspector') - - -class Plugin: - - def __init__(self, configuration, environment): - self.__configuration = configuration - self.__environment = environment diff --git a/linspector/core/plugins.py b/linspector/core/plugins.py deleted file mode 100644 index df65525..0000000 --- a/linspector/core/plugins.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -This file is part of Linspector (https://linspector.org/) -Copyright (c) 2022 Johannes Findeisen . All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -from logging import getLogger - -logger = getLogger('linspector') - - -class Plugins: - - def __init__(self, configuration, environment): - super().__init__() - self.__configuration = configuration - self.__environment = environment diff --git a/linspector/core/task.py b/linspector/core/task.py deleted file mode 100644 index dcc2aae..0000000 --- a/linspector/core/task.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -This file is part of Linspector (https://linspector.org/) -Copyright (c) 2022 Johannes Findeisen . All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -from logging import getLogger - -logger = getLogger('linspector') - - -class Task: - - def __init__(self, configuration, environment): - self.__configuration = configuration - self.__environment = environment diff --git a/linspector/core/tasks.py b/linspector/core/tasks.py deleted file mode 100644 index 198cc00..0000000 --- a/linspector/core/tasks.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -This file is part of Linspector (https://linspector.org/) -Copyright (c) 2022 Johannes Findeisen . All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -from logging import getLogger - -logger = getLogger('linspector') - - -class Tasks: - - def __init__(self, configuration, environment): - self.__configuration = configuration - self.__environment = environment diff --git a/linspector/plugins/httpserver.py b/linspector/plugins/httpserver.py index 436f383..3790edd 100644 --- a/linspector/plugins/httpserver.py +++ b/linspector/plugins/httpserver.py @@ -25,16 +25,14 @@ import cherrypy import json from logging import getLogger -from linspector.core.plugin import Plugin logger = getLogger('linspector') # TODO: check for all required configuration options and set defaults if needed. -class HTTPServerPlugin(Plugin): +class HTTPServerPlugin: def __init__(self, configuration, environment): - super().__init__(configuration, environment) self.__configuration = configuration self.__environment = environment diff --git a/linspector/plugins/lish.py b/linspector/plugins/lish.py index e235089..c6c52ba 100644 --- a/linspector/plugins/lish.py +++ b/linspector/plugins/lish.py @@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from logging import getLogger -from linspector.core.plugin import Plugin logger = getLogger('linspector') # TODO: check for all required configuration options and set defaults if needed. -class LishPlugin(Plugin): +class LishPlugin: def __init__(self, configuration, environment): - super().__init__(configuration, environment) self.__configuration = configuration self.__environment = environment diff --git a/linspector/tasks/filelogger.py b/linspector/tasks/filelogger.py index acc5471..10442af 100644 --- a/linspector/tasks/filelogger.py +++ b/linspector/tasks/filelogger.py @@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from logging import getLogger -from linspector.core.task import Task logger = getLogger('linspector') # TODO: check for all required configuration options and set defaults if needed. -class FileLoggerTask(Task): +class FileLoggerTask: def __init__(self, configuration, environment): - super().__init__(configuration, environment) self.__configuration = configuration self.__environment = environment diff --git a/linspector/tasks/mariadb.py b/linspector/tasks/mariadb.py index 83850e1..1ea8968 100644 --- a/linspector/tasks/mariadb.py +++ b/linspector/tasks/mariadb.py @@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from logging import getLogger -from linspector.core.task import Task logger = getLogger('linspector') # TODO: check for all required configuration options and set defaults if needed. -class MariaDBTask(Task): +class MariaDBTask: def __init__(self, configuration, environment): - super().__init__(configuration, environment) self.__configuration = configuration self.__environment = environment diff --git a/linspector/tasks/redis.py b/linspector/tasks/redis.py index b8e0d70..125cfc2 100644 --- a/linspector/tasks/redis.py +++ b/linspector/tasks/redis.py @@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from logging import getLogger -from linspector.core.task import Task logger = getLogger('linspector') # TODO: check for all required configuration options and set defaults if needed. -class RedisTask(Task): +class RedisTask: def __init__(self, configuration, environment): - super().__init__(configuration, environment) self.__configuration = configuration self.__environment = environment diff --git a/linspector/tasks/sqlite.py b/linspector/tasks/sqlite.py index bdde4c6..a4e476e 100644 --- a/linspector/tasks/sqlite.py +++ b/linspector/tasks/sqlite.py @@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from logging import getLogger -from linspector.core.task import Task logger = getLogger('linspector') # TODO: check for all required configuration options and set defaults if needed. -class SQLiteTask(Task): +class SQLiteTask: def __init__(self, configuration, environment): - super().__init__(configuration, environment) self.__configuration = configuration self.__environment = environment