- New notification script (incidentio-notification.sh) that POSTs JSON
payloads to incident.io HTTP alert sources via curl/jq
- New Icinga2 config template defining User, NotificationCommand (host
+ service), and apply Notification rules — follows the PagerDuty
pattern with opt-in via vars.enable_incidentio
- Notification type mapping: PROBLEM/DOWN/CRITICAL/WARNING/UNKNOWN →
firing, RECOVERY/UP/OK → resolved, ACKNOWLEDGEMENT → firing with
metadata
- Deduplication keys: host-{name} for hosts, service-{host}-{service}
for services
- Deployed via Ansible: script copied to /etc/icinga2/scripts/,
config rendered to conf.d/; gated on icinga2_incidentio_token being
defined
92 lines
2.5 KiB
Bash
92 lines
2.5 KiB
Bash
#!/bin/bash
|
|
#
|
|
# incident.io alert notification script for Icinga2
|
|
#
|
|
# Sends host/service alerts to incident.io via their HTTP alert source API.
|
|
#
|
|
# Usage (called by Icinga2 NotificationCommand):
|
|
# incidentio-notification.sh \
|
|
# --endpoint-url <url> \
|
|
# --token <bearer-token> \
|
|
# --title <alert-title> \
|
|
# --description <alert-description> \
|
|
# --dedup-key <deduplication-key> \
|
|
# --status <icinga-notification-type> \
|
|
# [--host <hostname>] \
|
|
# [--service <servicename>]
|
|
|
|
set -euo pipefail
|
|
|
|
ENDPOINT_URL=""
|
|
TOKEN=""
|
|
TITLE=""
|
|
DESCRIPTION=""
|
|
DEDUP_KEY=""
|
|
NOTIF_STATUS=""
|
|
HOST=""
|
|
SERVICE=""
|
|
METADATA="{}"
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--endpoint-url) shift; ENDPOINT_URL="$1" ;;
|
|
--token) shift; TOKEN="$1" ;;
|
|
--title) shift; TITLE="$1" ;;
|
|
--description) shift; DESCRIPTION="$1" ;;
|
|
--dedup-key) shift; DEDUP_KEY="$1" ;;
|
|
--status) shift; NOTIF_STATUS="$1" ;;
|
|
--host) shift; HOST="$1" ;;
|
|
--service) shift; SERVICE="$1" ;;
|
|
*) echo "Unknown argument: $1" >&2; exit 1 ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# Validate required fields
|
|
if [ -z "$ENDPOINT_URL" ] || [ -z "$TOKEN" ] || [ -z "$TITLE" ] || [ -z "$DEDUP_KEY" ] || [ -z "$NOTIF_STATUS" ]; then
|
|
echo "Missing required arguments" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Map Icinga2 notification type to incident.io status
|
|
case "$NOTIF_STATUS" in
|
|
PROBLEM|DOWN|CRITICAL|WARNING|UNKNOWN)
|
|
INCIDENT_STATUS="firing"
|
|
;;
|
|
RECOVERY|UP|OK)
|
|
INCIDENT_STATUS="resolved"
|
|
;;
|
|
ACKNOWLEDGEMENT)
|
|
INCIDENT_STATUS="firing"
|
|
METADATA="$(echo "$METADATA" | jq -c '.acknowledged = true')"
|
|
;;
|
|
*)
|
|
# Default to firing for anything unrecognised
|
|
INCIDENT_STATUS="firing"
|
|
;;
|
|
esac
|
|
|
|
# Build metadata with host/service info
|
|
if [ -n "$HOST" ]; then
|
|
METADATA="$(echo "$METADATA" | jq -c --arg h "$HOST" '.host = $h')"
|
|
fi
|
|
if [ -n "$SERVICE" ]; then
|
|
METADATA="$(echo "$METADATA" | jq -c --arg s "$SERVICE" '.service = $s')"
|
|
fi
|
|
METADATA="$(echo "$METADATA" | jq -c --arg ns "$NOTIF_STATUS" '.icinga_notification_type = $ns')"
|
|
|
|
# Build JSON payload
|
|
PAYLOAD=$(jq -c -n \
|
|
--arg title "$TITLE" \
|
|
--arg description "$DESCRIPTION" \
|
|
--arg dedup_key "$DEDUP_KEY" \
|
|
--arg status "$INCIDENT_STATUS" \
|
|
--argjson metadata "$METADATA" \
|
|
'{title: $title, description: $description, deduplication_key: $dedup_key, status: $status, metadata: $metadata}'
|
|
)
|
|
|
|
# Send to incident.io
|
|
curl -s -S -X POST "$ENDPOINT_URL" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$PAYLOAD"
|