From d8c57227e5a81d7aaef9c34ec3a4ea47fda9dcb9 Mon Sep 17 00:00:00 2001 From: dirtycajunrice Date: Sun, 13 Jan 2019 02:25:04 -0600 Subject: [PATCH 1/6] add pushover functionality. Finishes other half of #80 --- pyouroboros/config.py | 24 ++++++++++++++++++++---- pyouroboros/logger.py | 5 +++-- pyouroboros/notifiers.py | 16 ++++++++++++++-- pyouroboros/ouroboros.py | 25 +++++++++++++++---------- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/pyouroboros/config.py b/pyouroboros/config.py index 480bb8fa..2b70f3a6 100644 --- a/pyouroboros/config.py +++ b/pyouroboros/config.py @@ -5,15 +5,13 @@ class Config(object): options = ['INTERVAL', 'PROMETHEUS', 'DOCKER_SOCKETS', 'MONITOR', 'IGNORE', 'LOG_LEVEL', 'PROMETHEUS_ADDR', 'PROMETHEUS_PORT', 'WEBHOOK_URLS', 'REPO_USER', 'REPO_PASS', 'CLEANUP', 'RUN_ONCE', 'LATEST', - 'INFLUX_URL', 'INFLUX_PORT', 'INFLUX_USERNAME', 'INFLUX_PASSWORD', 'INFLUX_DATABASE', - 'INFLUX_SSL', 'INFLUX_VERIFY_SSL', 'DATA_EXPORT'] + 'INFLUX_URL', 'INFLUX_PORT', 'INFLUX_USERNAME', 'INFLUX_PASSWORD', 'INFLUX_DATABASE', 'INFLUX_SSL', + 'INFLUX_VERIFY_SSL', 'DATA_EXPORT', 'PUSHOVER_TOKEN', 'PUSHOVER_USER', 'PUSHOVER_DEVICE'] interval = 300 docker_sockets = 'unix://var/run/docker.sock' monitor = [] ignore = [] - webhook_urls = [] - webhook_type = 'slack' data_export = None log_level = 'info' latest = False @@ -36,6 +34,12 @@ class Config(object): influx_password = 'root' influx_database = None + webhook_urls = [] + + pushover_token = None + pushover_user = None + pushover_device = None + def __init__(self, environment_vars, cli_args): self.cli_args = cli_args self.environment_vars = environment_vars @@ -93,4 +97,16 @@ def parse(self): string_list = getattr(self, option) setattr(self, option, [string.strip(' ') for string in string_list.split(' ')]) + # Config sanity checks + if self.data_export == 'influxdb' and not self.influx_database: + self.logger.error("You need to specify an influx database if you want to export to influxdb. Disabling " + "influxdb data export.") + + pushover_config = [self.pushover_token, self.pushover_device, self.pushover_user] + if any(pushover_config) and not all(pushover_config): + self.logger.error('You must specify a pushover user, token, and device to use pushover. Disabling ' + 'pushover notifications') + elif all(pushover_config): + self.webhook_urls.append('https://api.pushover.net/1/messages.json') + self.config_blacklist() diff --git a/pyouroboros/logger.py b/pyouroboros/logger.py index 2ba19c5c..9bf350cd 100644 --- a/pyouroboros/logger.py +++ b/pyouroboros/logger.py @@ -6,8 +6,9 @@ class BlacklistFilter(Filter): Log filter for blacklisted tokens and passwords """ - blacklisted_keys = ['repo_user', 'repo_pass', 'auth_json', 'webhook_urls', 'docker_sockets', - 'prometheus_exporter_addr', 'influx_username', 'influx_password', 'influx_url'] + blacklisted_keys = ['repo_user', 'repo_pass', 'auth_json', 'webhook_urls', 'docker_sockets', 'pushover_user', + 'prometheus_addr', 'influx_username', 'influx_password', 'influx_url', 'pushover_token', + 'pushover_device'] def __init__(self, filteredstrings): super().__init__() diff --git a/pyouroboros/notifiers.py b/pyouroboros/notifiers.py index 8eadbc40..91777eda 100644 --- a/pyouroboros/notifiers.py +++ b/pyouroboros/notifiers.py @@ -19,6 +19,8 @@ def send(self, container_tuples, socket): format_type = 'discord' elif 'slack' in webhook_url: format_type = 'slack' + elif 'pushover' in webhook_url: + format_type = 'pushover' else: format_type = 'default' @@ -29,7 +31,7 @@ def send(self, container_tuples, socket): def format(self, container_tuples, socket, format_type): clean_socket = socket.split("//")[1] now = str(datetime.now(timezone.utc)).replace(" ", "T") - if format_type in ['slack', 'default']: + if format_type in ['slack', 'default', 'pushover']: text = "Host Socket: {}\n".format(clean_socket) text += "Containers Monitored: {}\n".format(self.data_manager.monitored_containers[socket]) text += "Containers Updated: {}\n".format(self.data_manager.total_updated[socket]) @@ -40,7 +42,17 @@ def format(self, container_tuples, socket, format_type): new_image.short_id.split(":")[1] ) text += now - json = {"text": text} + if format_type == 'pushover': + json = { + "html": 1, + "token": self.config.pushover_token, + "user": self.config.pushover_user, + "device": self.config.pushover_device, + "title": "Ouroboros updated containers:", + "message": text + } + else: + json = {"text": text} return json elif format_type == 'discord': diff --git a/pyouroboros/ouroboros.py b/pyouroboros/ouroboros.py index e55b0565..c36b87e9 100644 --- a/pyouroboros/ouroboros.py +++ b/pyouroboros/ouroboros.py @@ -96,19 +96,24 @@ def main(): data_group.add_argument('-V', '--influx-verify-ssl', default=False, dest='INFLUX_VERIFY_SSL', action='store_true', help='Verify SSL certificate when connecting to influxdb') - data_group.add_argument('-w', '--webhook-urls', nargs='+', default=Config.webhook_urls, dest='WEBHOOK_URLS', - help='Webhook POST urls\n' - 'EXAMPLE: -w https://domain.tld/1234/asdf http://123.123.123.123:4040/re235') + notification_group = parser.add_argument_group('Notifications', 'Configuration of notification functionality') + notification_group.add_argument('-w', '--webhook-urls', nargs='+', default=Config.webhook_urls, dest='WEBHOOK_URLS', + help='Webhook POST urls\n' + 'EXAMPLE: -w https://domain.tld/1234/asdf http://123.123.123.123:4040/re235') - args = parser.parse_args() + notification_group.add_argument('-y', '--pushover-token', default=Config.pushover_token, dest='PUSHOVER_TOKEN', + help='Pushover token to authenticate against application\n' + 'EXAMPLE: -y af2r52352asd') - if environ.get('DATA_EXPORT'): - data_export = environ['DATA_EXPORT'] - else: - data_export = args.DATA_EXPORT + notification_group.add_argument('-Y', '--pushover-device', default=Config.pushover_device, dest='PUSHOVER_DEVICE', + help='Device to receive pushover notification\n' + 'EXAMPLE: -Y SamsungGalaxyS8') - if data_export == 'influxdb' and not (environ.get('INFLUX_DATABASE') or args.INFLUX_DATABASE): - exit("You need to specify an influx database if you want to export to influxdb") + notification_group.add_argument('-y', '--pushover-user', default=Config.pushover_user, dest='PUSHOVER_USER', + help='Pushover user bound to application\n' + 'EXAMPLE: -y johndoe123') + + args = parser.parse_args() if environ.get('LOG_LEVEL'): log_level = environ.get('LOG_LEVEL') From 0aa48835c8d0c2d4bfec1078c7459cc074a758c3 Mon Sep 17 00:00:00 2001 From: dirtycajunrice Date: Sun, 13 Jan 2019 02:29:21 -0600 Subject: [PATCH 2/6] fix regression in keep_alive --- pyouroboros/notifiers.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pyouroboros/notifiers.py b/pyouroboros/notifiers.py index 91777eda..262308f0 100644 --- a/pyouroboros/notifiers.py +++ b/pyouroboros/notifiers.py @@ -11,18 +11,22 @@ def __init__(self, config, data_manager): self.data_manager = data_manager self.logger = getLogger() - def send(self, container_tuples, socket): + def send(self, container_tuples=None, socket=None, notification_type='data'): formatted_webhooks = [] if self.config.webhook_urls: for webhook_url in self.config.webhook_urls: - if 'discord' in webhook_url: - format_type = 'discord' - elif 'slack' in webhook_url: - format_type = 'slack' - elif 'pushover' in webhook_url: - format_type = 'pushover' + if notification_type == "keep_alive": + if "hc-ping" in webhook_url: + formatted_webhooks.append((webhook_url, {})) else: - format_type = 'default' + if 'discord' in webhook_url: + format_type = 'discord' + elif 'slack' in webhook_url: + format_type = 'slack' + elif 'pushover' in webhook_url: + format_type = 'pushover' + else: + format_type = 'default' formatted_webhooks.append((webhook_url, self.format(container_tuples, socket, format_type))) From 608093c30c07812b0ead44e6ff0ba74bd8bb1081 Mon Sep 17 00:00:00 2001 From: dirtycajunrice Date: Sun, 13 Jan 2019 02:30:37 -0600 Subject: [PATCH 3/6] fix regression in keep_alive x2 --- pyouroboros/notifiers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyouroboros/notifiers.py b/pyouroboros/notifiers.py index 262308f0..5614c632 100644 --- a/pyouroboros/notifiers.py +++ b/pyouroboros/notifiers.py @@ -25,6 +25,8 @@ def send(self, container_tuples=None, socket=None, notification_type='data'): format_type = 'slack' elif 'pushover' in webhook_url: format_type = 'pushover' + elif 'hc-ping' in webhook_url: + continue else: format_type = 'default' From 7c9d12115c7675c25f18ecdaaede028bf82f6d5d Mon Sep 17 00:00:00 2001 From: dirtycajunrice Date: Sun, 13 Jan 2019 02:35:35 -0600 Subject: [PATCH 4/6] change missing duplicate cli flag --- pyouroboros/ouroboros.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyouroboros/ouroboros.py b/pyouroboros/ouroboros.py index c36b87e9..4779e533 100644 --- a/pyouroboros/ouroboros.py +++ b/pyouroboros/ouroboros.py @@ -109,7 +109,7 @@ def main(): help='Device to receive pushover notification\n' 'EXAMPLE: -Y SamsungGalaxyS8') - notification_group.add_argument('-y', '--pushover-user', default=Config.pushover_user, dest='PUSHOVER_USER', + notification_group.add_argument('-z', '--pushover-user', default=Config.pushover_user, dest='PUSHOVER_USER', help='Pushover user bound to application\n' 'EXAMPLE: -y johndoe123') From 395d371231adac2980e73795bd3434951abcfc1d Mon Sep 17 00:00:00 2001 From: dirtycajunrice Date: Sun, 13 Jan 2019 03:41:07 -0600 Subject: [PATCH 5/6] changed dockerfile to explicit again, and fixed config typecasing to true --- Dockerfile | 2 +- pyouroboros/config.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index cbcfbe71..782c8f75 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ WORKDIR /app RUN apk add --no-cache tzdata && \ pip install --no-cache-dir . -ENTRYPOINT ["ouroboros"] +ENTRYPOINT ["python3", "ouroboros"] diff --git a/pyouroboros/config.py b/pyouroboros/config.py index 2b70f3a6..5e01caaf 100644 --- a/pyouroboros/config.py +++ b/pyouroboros/config.py @@ -80,6 +80,12 @@ def parse(self): setattr(self, option.lower(), opt) except ValueError as e: print(e) + elif option in ['LATEST', 'CLEANUP', 'RUN_ONCE', 'INFLUX_SSL', 'INFLUX_VERIFY_SSL']: + if self.environment_vars[option].lower() == 'true': + setattr(self, option.lower(), True) + else: + self.logger.error('%s is not a valid option for %s. setting to false', + self.environment_vars[option], option) else: setattr(self, option.lower(), self.environment_vars[option]) elif vars(self.cli_args).get(option): From ea6b8b765b3790f28ace7febe92161f3f1ffe4a4 Mon Sep 17 00:00:00 2001 From: dirtycajunrice Date: Sun, 13 Jan 2019 13:37:15 -0600 Subject: [PATCH 6/6] undo my redo --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 782c8f75..cbcfbe71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ WORKDIR /app RUN apk add --no-cache tzdata && \ pip install --no-cache-dir . -ENTRYPOINT ["python3", "ouroboros"] +ENTRYPOINT ["ouroboros"]