Add initial support for webhook notifications

This commit is contained in:
Joshua Boniface 2022-07-06 13:30:42 -04:00
parent 4b20a722bd
commit 5563f8921f
5 changed files with 102 additions and 1 deletions

View File

@ -89,3 +89,27 @@ pvc:
base: "base.yml" base: "base.yml"
pvc: "pvc.yml" pvc: "pvc.yml"
bootstrap: "bootstrap.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}"

View File

@ -31,3 +31,16 @@ pvc:
base: "base.yml" base: "base.yml"
pvc: "pvc.yml" pvc: "pvc.yml"
bootstrap: "bootstrap.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}"

View File

@ -25,6 +25,7 @@ import signal
from sys import argv from sys import argv
import pvcbootstrapd.lib.notifications as notifications
import pvcbootstrapd.lib.dnsmasq as dnsmasqd import pvcbootstrapd.lib.dnsmasq as dnsmasqd
import pvcbootstrapd.lib.db as db import pvcbootstrapd.lib.db as db
import pvcbootstrapd.lib.git as git import pvcbootstrapd.lib.git as git
@ -237,6 +238,8 @@ def entrypoint():
print("|----------------------------------------------------------|") print("|----------------------------------------------------------|")
print("") print("")
notifications.send_webhook(config, "begin", "Starting up pvcbootstrapd")
# Initialize the database # Initialize the database
db.init_database(config) db.init_database(config)

View File

@ -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 <joshua@boniface.me>
#
# 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 <https://www.gnu.org/licenses/>.
#
###############################################################################
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}")

View File

@ -219,7 +219,7 @@ echo -n "Press <Enter> once completed to continue. "
read read
echo echo
echo "Edit configuration before proceeding?" echo "Edit configuration before proceeding? (Note: to enable notifications do so now)"
echo -n "[y/N] > " echo -n "[y/N] > "
read edit_flag read edit_flag
case ${edit_flag} in case ${edit_flag} in