From 5563f8921f3457c151b01dbe550c603eb2594349 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Wed, 6 Jul 2022 13:30:42 -0400 Subject: [PATCH] Add initial support for webhook notifications --- bootstrap-daemon/pvcbootstrapd.yaml.sample | 24 ++++++++ bootstrap-daemon/pvcbootstrapd.yaml.template | 13 ++++ bootstrap-daemon/pvcbootstrapd/Daemon.py | 3 + .../pvcbootstrapd/lib/notifications.py | 61 +++++++++++++++++++ install-pvcbootstrapd.sh | 2 +- 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100755 bootstrap-daemon/pvcbootstrapd/lib/notifications.py diff --git a/bootstrap-daemon/pvcbootstrapd.yaml.sample b/bootstrap-daemon/pvcbootstrapd.yaml.sample index b50c7ae..2b0dc8e 100644 --- a/bootstrap-daemon/pvcbootstrapd.yaml.sample +++ b/bootstrap-daemon/pvcbootstrapd.yaml.sample @@ -89,3 +89,27 @@ pvc: base: "base.yml" pvc: "pvc.yml" bootstrap: "bootstrap.yml" + + # Notification webhook configs + # These enable sending notifications from the bootstrap to a JSON webhook, e.g. a chat system + # This feature is optional; if this block is missing or `enabled: false`, nothing here will be used. + notifications: + enabled: true + # The URI endpoint for notifications + uri: https://mattermost.domain.tld/hooks/asecretstring + # The action to use (usually "post") + action: post + # Icons to use for various status types; embedded in the message with `{icon}` + icons: + begin: "🤞" # A task is beginning + success: "✅" # A task succeeded + failure: "❌" # A task failed + # The webhook body elements; this is specific to the webhook target, and is converted into raw + # JSON before sending. + # Two special variables are used: "{icon}" displays one of the above icons, and "{message}" displays + # the actual message coming from pvcbootstrapd. + body: + channel: "mychannel" + username: "pvcbootstrapd" + text: "@person {icon} {message}" + diff --git a/bootstrap-daemon/pvcbootstrapd.yaml.template b/bootstrap-daemon/pvcbootstrapd.yaml.template index afe08a4..5ee35c2 100644 --- a/bootstrap-daemon/pvcbootstrapd.yaml.template +++ b/bootstrap-daemon/pvcbootstrapd.yaml.template @@ -31,3 +31,16 @@ pvc: base: "base.yml" pvc: "pvc.yml" bootstrap: "bootstrap.yml" + notifications: + enabled: false + uri: https://mattermost.domain.tld/hooks/asecretstring + action: post + icons: + begin: "🤞" # A task is beginning + success: "✅" # A task succeeded + failure: "❌" # A task failed + body: + channel: "mychannel" + username: "pvcbootstrapd" + text: "@person {icon} {message}" + diff --git a/bootstrap-daemon/pvcbootstrapd/Daemon.py b/bootstrap-daemon/pvcbootstrapd/Daemon.py index 8820ed1..9f06e65 100755 --- a/bootstrap-daemon/pvcbootstrapd/Daemon.py +++ b/bootstrap-daemon/pvcbootstrapd/Daemon.py @@ -25,6 +25,7 @@ import signal from sys import argv +import pvcbootstrapd.lib.notifications as notifications import pvcbootstrapd.lib.dnsmasq as dnsmasqd import pvcbootstrapd.lib.db as db import pvcbootstrapd.lib.git as git @@ -237,6 +238,8 @@ def entrypoint(): print("|----------------------------------------------------------|") print("") + notifications.send_webhook(config, "begin", "Starting up pvcbootstrapd") + # Initialize the database db.init_database(config) diff --git a/bootstrap-daemon/pvcbootstrapd/lib/notifications.py b/bootstrap-daemon/pvcbootstrapd/lib/notifications.py new file mode 100755 index 0000000..92b12ef --- /dev/null +++ b/bootstrap-daemon/pvcbootstrapd/lib/notifications.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +# notifications.py - PVC Cluster Auto-bootstrap Notifications library +# Part of the Parallel Virtual Cluster (PVC) system +# +# Copyright (C) 2018-2021 Joshua M. Boniface +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################### + +import json +import requests + +from celery.utils.log import get_task_logger + + +logger = get_task_logger(__name__) + + +def send_webhook(config, status, message): + """ + Send an notification webhook + """ + + if not config.get('notifications', None) or not config['notifications']['enabled']: + return + + logger.debug(f"Sending notification to {config['notifications']['uri']}") + + # Get the body data + data = json.dumps(config['notifications']['body']).format( + icon=config['notifications']['icons'][status], + message=message + ) + headers = {"content-type": "application/json"} + + # Craft up a Requests endpoint set for this + requests_actions = { + "get": requests.get, + "post": requests.post, + "put": requests.put, + "patch": requests.patch, + "delete": requests.delete, + "options": requests.options, + } + action = config['notifications']["action"] + + result = requests_actions[action](config['notifications']["uri"], headers=headers, data=data) + + logger.debug(f"Result: {result}") diff --git a/install-pvcbootstrapd.sh b/install-pvcbootstrapd.sh index 2e9ed71..4e08251 100755 --- a/install-pvcbootstrapd.sh +++ b/install-pvcbootstrapd.sh @@ -219,7 +219,7 @@ echo -n "Press once completed to continue. " read echo -echo "Edit configuration before proceeding?" +echo "Edit configuration before proceeding? (Note: to enable notifications do so now)" echo -n "[y/N] > " read edit_flag case ${edit_flag} in