icinga2 Notification Email mutt
ONLINE

Icinga 2 + Director + Notifications = <3

Mit dem gestrigen Git-Checkout landete ein icinga2-module-director auf meinem System, mit dem das Erstellen und Deployen von notifications erstmals komplett funktionierte und eine syntaktisch korrekte Konfiguration ergab. Benachrichtigungen flexibel übers Webinterface zusammenklicken? Es funktioniert — ich zeige euch, wie!

time period

icinga2 director notification time periodKlar — im ersten Schritt sorgst du natürlich für ein ganz frisches git clone des Moduls. Beginnen wir nun also damit, dass wir uns (in Abhängigkeit vom Template generic-director-timeperiod) ein erstes time period-Objekt erstellen — ich nenne meins einfach always und setze als time range für jeden Tag der Woche die vollen 24 Stunden ein.

user

icinga2 director notifications userBenachrichtigungen brauchen natürlich auch einen User, der sie empfängt — abhängig von meinem Template generic-director-user (das selbstverständlich enable_notifications = true setzt!) erstelle ich nun also mich selbst — das ist selbsterklärend.
Im nächsten Schritt wird es nun schon spannender: es wird nämlich ein Script benötigt, das den Emailversand übernimmt…

Die Scripte

D die allseits bekannten mail-host-notification.sh und mail-service-notification.sh in Kombination mit ihren NotificationCommand-Definitionen sind so nicht in den Director übertragbar — dort gibt es (noch?) keinen ENV-Support. Ich habe mir also an dieser Stelle zwei eigene Scripte gehäkelt und auf Github gepackt — sie gewinnen ganz sicher keinen Schönheitswettbewerb, aber ihr dürft sie gerne nutzen:

$ cd /etc/icinga2/scripts
$ wget https://raw.githubusercontent.com/sysadmama/misc/master/icinga2/scripts/host-by-mail.sh
$ wget https://raw.githubusercontent.com/sysadmama/misc/master/icinga2/scripts/service-by-mail.sh
$ chmod +x *by-mail.sh
#!/bin/bash
## /etc/icinga2/scripts/host-by-mail.sh / 20160616
## Marianne Spiller <github@spiller.me>
## icinga2-2.4.10-1~ppa1~xenial1
 
Usage() {
  echo "host-by-mail notification script for Icinga 2 by spillerm <github@spiller.me> 2016/06/16"
  echo "Used by icinga2 director and command 'alarm-host'."
}
 
while getopts a:b:c:d:hl:o:r:s:t: opt
do
  case "$opt" in
    a) HOSTADDRESS=$OPTARG ;;
    b) NAUTHOR=$OPTARG ;;
    c) NCOMMENT=$OPTARG ;;
    d) DATE=$OPTARG ;;
    h) Usage
       exit 1 ;;
    l) HOSTDN=$OPTARG ;;
    o) HOSTOUTPUT=$OPTARG ;;
    r) RECIPIENT=$OPTARG ;;
    s) HOSTSTATE=$OPTARG ;;
    t) NTYPE=$OPTARG ;;
    ?) echo "ERROR: invalid option" >&2
       exit 1 ;;
  esac
done
 
shift $((OPTIND - 1))
 
notification_message=`cat <<EOF
*****  spiller.me VM Icinga 2 Host Monitoring  *****
 
==> $HOSTDN is $HOSTSTATE! <==
 
When?    $DATE
Host?    $HOSTDN
Address? $HOSTADDRESS
Info?    $HOSTOUTPUT
 
Comment by $NAUTHOR: $NCOMMENT
 
Have a look:
http://monitor.bafi.lan/icingaweb2/monitoring/host/show?host=$HOSTDN
 
EOF
`
 
/usr/bin/printf "%b" "$notification_message" | mail -s "$NTYPE alert for $HOSTDN - host state is $HOSTSTATE" $RECIPIENT
#!/bin/bash
## /etc/icinga2/scripts/service-by-mail.sh / 20160616
## Marianne Spiller <github@spiller.me>
## icinga2-2.4.10-1~ppa1~xenial1
 
Usage() {
  echo "service-by-mail notification script for Icinga 2 by spillerm <github@spiller.me> 2016/06/16"
  echo "Used by icinga2 director and command 'alarm-service'."
}
 
while getopts a:b:c:d:e:hl:o:r:s:t: opt
do
  case "$opt" in
    a) HOSTADDRESS=$OPTARG ;;
    b) NAUTHOR=$OPTARG ;;
    c) NCOMMENT=$OPTARG ;;
    d) DATE=$OPTARG ;;
    e) SERVICENAME=$OPTARG ;;
    h) Usage
       exit 1 ;;
    l) HOSTDN=$OPTARG ;;
    o) SERVICEOUTPUT=$OPTARG ;;
    r) RECIPIENT=$OPTARG ;;
    s) SERVICESTATE=$OPTARG ;;
    t) NTYPE=$OPTARG ;;
    ?) echo "ERROR: invalid option" >&2
       exit 1 ;;
  esac
done
 
shift $((OPTIND - 1))
 
notification_message=`cat <<EOF
*****  spiller.me VM Icinga 2 Service Monitoring  *****
 
==> $SERVICENAME is $SERVICESTATE! <==
 
When?    $DATE
Service? $SERVICENAME
Host?    $HOSTDN
Address? $HOSTADDRESS
Info?    $SERVICEOUTPUT
 
Comment by $NAUTHOR: $NCOMMENT
 
Have a look:
http://monitor.bafi.lan/icingaweb2/monitoring/service/show?host=$HOSTDN&service=$SERVICENAME
 
EOF
`
 
/usr/bin/printf "%b" "$notification_message" | mail -s "$NTYPE alert for $SERVICENAME - service state is $SERVICESTATE" $RECIPIENT

Anhand der nun vorhandenen Scripte können zwei neue Kommando-Objekte vom Typ Notification Plugin Command erstellt werden.

Notification Plugin Command

Sowohl das command alarm-host als auch alarm-service werden nun innerhalb des Director angelegt: Objekte vom Typ Notification Plugin Command, die auf das jeweils korrespondierende Script im Filesystem verweisen. Als Argumente werden die im Script definierten Parameter übernommen, und als Wert erhalten diese den jeweils gewünschten Wert über die icinga runtime macros, der zur Laufzeit ermittelt wird. So bezeichnet -a beispielsweise die IP-Adresse des Hosts, und diese wird über das runtime macro $address$ übergeben. Betrachtet die Screenshots und häkelt euch eure ganz individuelle Benachrichtigungs-Lösung — ihr werdet schnell merken, wie umfangreich eure Möglichkeiten sind!

(Einschub: beim Erfassen der Parameter erhalte ich derzeit immer die rot hinterlegte Meldung »Trying to get invalid property „argument_name“« — was der Funktionalität jedoch keinen Abbruch zu tun scheint. Muss ich mal’n Bugreport aufmachen oder so. Einschub Ende.)

Notification

Nach all der Vorarbeit sind wir nun an dem Punkt angelangt, an dem wir die eigentliche Benachrichtigung erfassen können; im ersten Schritt werden zwei Templates (generic-host-alarm und generic-service-alarm) erstellt — ich definiere mir hier states und transition types, wie ich sie haben möchte. Und nun kann ich eine apply rule erfassen — wichtig ist hier, dass der Bereich »assignment rules« erst dann auftaucht, nachdem auf Store geklickt wurde! Über die »assignment rules« kann nun definiert werden, bei welchen Events der User informiert werden soll; die Auswahl »Host oder Service« unter »Apply to« ist hierbei zwingend erforderlich.

Fazit

Mein Hirn brauchte eine Weile, um hier durchzusteigen; im Nachhinein finde ich es eigentlich sehr logisch und einfach Nun können die Testläufe beginnen — testet ausgiebig, denn gerade bei Benachrichtigungen möchte man keine bösen Überraschungen erleben. Noch spannender wird die Sache, wenn alternative Benachrichtigungen hinzukommen — Jabber, HipChat, Telegram, SMS — damit möchte ich auch noch ein wenig rumbasteln. Aber für heute freue ich mich einfach, dass das Erfassen der User und ihrer Benachrichtigung nun über den Director funktioniert — und mir die Arbeit in Zukunft signifikant erleichtern wird.

  1. Sehr gutes Howto!
    Ich hatte anfangs auch viele Probleme, mittlerweile sind die letzten Hürden aber eingekreist. Zum Glück läuft das System noch nicht live…
    Da es leider noch keinen vernünftigen Android-Client für Benachrichtigungen gibt – und ich auch keine Mails geschickt bekomen möchte, habe ich mir anhand dieser Anleitung
    http://www.jens.bruntt.dk/jbrt-a58a9m/
    einen PushService installiert, was auch relativ gut funktionierte; der Einfachheit halber wurde der curl-Aufruf in dein Script reinkopiert.
    Ein Problem gibt es aber noch (eigentlich sind es zwei…):
    -) Ich verstehe den Zusammenhang zwischen den Argumenten beim Kommando nicht (-a – $host.address$)
    -) Für Host-Benachrictigungen funktioniert das mit dem Push (und Mail) einigermaßen gut; nicht aber bei den Services. Hier kommen nur leere Push-Benachrichtigungen (und Mails) an; die Skripte werden aber korrekt aufgerufen.
    Hast Du eine Idee, woran das liegen könnte?

    Grüße aus Saarbrücken,

    Andreas

    • Hi Andreas,

      also 1.) verstehe ich nicht so ganz; das -a übergibt halt $address$ (und nicht $host.address$, übrigens), weil ich mir das so ausgedacht hab; du kannst das ja scripten, wie du möchtest, und die Adresse mit sonstwas != a übergeben

      Und zu 2.) Nein, da habe ich keine Idee — außer die, dass das Script denn wohl doch nicht so korrekt aufgerufen (bzw. nicht fehlerfrei ausgeführt) wurde. Vielleicht was verwurschtelt/ vergessen bei der Parameterübergabe? Zu Debugging-Zwecken kannst du dir das Script ja dahingehend anpassen, dass es seine Argumente und Kram in ein Text-File (oder per logger ganz faul ins syslog) bläst — meist sieht man dann ja recht schnell, wo es hakt.

      Viele Grüße ebenfalls aus Saarbrücken
      Marianne

      • Ok, 1) habe ich verstanden – ich habe gesehen, dass ich – warum auch immer – nur einen Teil des Skriptes hatte; da waren keine Variablen-Zuweisungen drin.
        Vollends verwirrt hat mich heute morgen allerdings mein Handy, auf dem mit einem Mal eine KORREKTE Pusch-Nachricht auf mich wartete; und zwar die von der geplanten Downtime des localhost, die in icinga2 vorkonfiguriert ist. Wie der Server das geschafft hat, ist mir schleierhaft; da ich ausgerechnet das nicht konfiguriert hatte (zumindest nicht wissentlich).
        Die große Frage, deren Beantwortung ich den ganzen Morgen schon hinterher suche ist, was da passiert ist bzw. wieso der localhost richtig schicken kann, meine im director konfigurierten aber nicht. Das Skript passt, sonst hätte ich ja heute Nacht nix bekommen….
        Debug im icinga2 habe ich aktiviert; mal sehen, was da heute nacht passiert….
        Der Aufruf sieht für mich eigentlich i.O. aus (auch wenn es nicht funktioniert…):

        /etc/icinga2/scripts/mail-service-notification.sh‘ ‚HOSTDISPLAYNAME‘ ‚magellan.agit.home‘
        ‚USEREMAIL‘ ‚andreas@mydomain.de‘
        ‚SERVICESTATE‘ ‚CRITICAL‘
        ‚SERVICEOUTPUT‘ ‚NTP CRITICAL: Offset unknown‘
        ‚SERVICEDISPLAYNAME‘ ‚check_ssh_ntp‘
        ‚SERVICEDESC‘ ‚check_ssh_ntp‘
        ‚PUSHOVERMESSAGE‘ ‚PROBLEM magellan.agit.home UP 2017-01-04 13:32:42 +0100‘
        ‚NOTIFICATIONTYPE‘ ‚PROBLEM‘
        ‚NOTIFICATIONCOMMENT‘ “
        ‚NOTIFICATIONAUTHORNAME‘ “
        ‚LONGDATETIME‘ ‚2017-01-04 13:32:42 +0100‘
        ‚-a‘ ‚192.168.100.21‘
        ‚HOSTALIAS‘ ‚magellan.agit.home‘
        ‚HOSTADDRESS‘ ‚192.168.100.21‘
        ‚-s‘ ‚CRITICAL‘ ‚-r‘ ‚andreas@mydomain.de‘
        ‚-o‘ ‚NTP CRITICAL: Offset unknown‘
        ‚-l‘ ‚magellan‘ ‚-e‘ ‚check_ssh_ntp‘
        ‚-c‘ “
        ‚-b‘ “)
        terminated with exit code 0

        Im Service-Kommando habe ich die die „langen“ und die „kurzen“ Variablen mal definiert; daher wird das alles doppelt übergeben…

        • Eureka….
          Das Problem war eigentlich relativ simpel – und daher nicht wirklich offensichtlich. Im Template benutze ich etwas derart

          message=`cat < $HOSTDN is $HOSTSTATE! <==

          ; das Skript hat sich an den "*" gestört. Dadurch waren sämtliche Vairablen weg und somit kamen leere Mails an.
          Somit also auch kein "Problem" vom Icinga2…

  2. Thanks! very helpful howto

  3. Hallo,
    danke für Deine Notification Scripte. Hat mich mit meiner Arbeit weiter gebracht.
    Aber habe weiter Frage zu Variablen in Deinem Script.
    -b notification.author und
    -c notification.comment
    Bei mir funktioniert Dein Script nur bei „Custom Notification“.
    Beide Variable bekommen Ihren Inhalt und Alarmierung gehts raus.
    Bei Downtime und Host/Service Alarmierungen fehlen dieser Inhalte später im Mail und SMS Nachricht.
    Debug eingeschaltet:
    ./host-by-mail.sh‘ ‚-a‘ ‚10.10.10.10‘ ‚-b‘ “ ‚-c‘ “ ‚-d‘ ‚2016-08-14 08:23:52‘ ‚-l‘ ‚SERVER01’……

    Da ich auch Dein Script auch als SMS-Versender benutzen wollte, kann ich die Variable „author“ als VERSENDER auch nicht benutzen.
    Auch in Deinem Beispiel Mail-Alarmierung fehlen beide Inhalte (Comment by : ).
    Ist es hier so gewollt oder nur bei mir Konfiguration falsch ist?

    • Hi,

      spontan kann ich dazu nur sagen: also bei mir funktioniert alles.
      Ich kann es mir derzeit nicht näher anschauen, weil ich mit einem Bein im Urlaub bin; wenn ich zurück bin, schau ich es mir nochmal genauer an.

      Viele Grüße!

      • Hallo,
        dieser Woche kamen mehrere Icinga2 Updates mit DB Schema Upgrade.
        Danach war alles OK.
        Notification Runtime Macros ( notification.author und notification.comment) haben ihren Inhalt bekommen und SMS und Mail Alarmierung funktioniert.

        Danke noch mal für Deine Scripte und hoffe das Du Dein Urlaub geniesst.
        MfG

  4. Dimitris

    Hallo.
    Obwohl du es sehr gut beschreibst, kann ich ech leider nicht zum lauf bringen.
    Ich kriege bei Generic Notification Template keinen Command in „Notification Command“… nur „-please choose-„.
    Command habe ich schon gemacht und sehe nicht wo der Fehler ist.
    Hast du mir vielleicht eine Ahnung was da schief gegangen ist?

    • Ist denn dein Command auch ganz sicher vom Typ Notification Plugin Command? Welche Version vom Director verwendest du?

      • Dimitris

        Ja. Der ist.
        Inzwischen bin ich ein stueckhen weiter, aber.. lass mich erkleren.
        Die Director version ist 1.1.0
        1. Ich erstelle ein Command Template (alarm-host-template) (Notification Plugin Command)
        2. Ich erstelle ein Command (alarm-host) der auch den Command (/etc/icinga2/scripts/host-by-mail.sh) hat.
        Imports -> alarm-host-template
        3. Alle Argumente sind im Command.
        4. In Director Notifications ich erstelle ein Notification Template (generic-host-alarm) mit
        5. Ich erstelle eine Notification (Apply to Hosts) mit Rules (assign where name = servername)
        Imports -> generic-host-alarm
        Habe auch alle States & Transition Types configuriert.

        Nun kriege ich error…
        Error: Validation failed for object ‚alarm-host‘ of type ‚NotificationCommand‘; Attribute ‚zone‘: Object ‚director-global‘ of type ‚Zone‘ does not exist.

        • Dimitris

          Das passiert nur wenn ich den Command Aktiviere.

          Da muss was fehlen. oder?

        • Dann erweitere deine /etc/icinga2/zones.conf mal um die benötigte Zone (steht IIRC auch im RTFM auf der Github-Seite):

          object Zone "director-global" {
                  global = true
          }

          Dienst durchstarten und nochmal probieren

  5. Hey, vielen Dank für die Icinga2 & Icinga Director Anleitungen. Habe ein paar Tage versucht die Notificatios zum laufen zu bekommen und war auch schon an einem eigenen Script dran – ein vorgefertiges Script zu nehmen ist aber einfacher Vielen Dank für die Arbeit und Dokumentation!

  6. This Article was mentioned on unixe.de

  7. Vielen Dank für die Skripte – haben mir sehr weiter geholfen!

  8. @sys_adm_ama Das muss ich unbedingt ausprobieren.

    via twitter.com

    • Sehr cool! Vielen Dank!
      Ich habe jetzt erfolgreich Mails versendet… Aber ich bekomme es nicht hin „unterhalb“ eines Hosts an verschiedene Empfänger zu senden, also z.B. soll der DB Check an die DBAler gesendet werden, der Filesystem-Check an die Unixer….
      Ich unertscheide die Richtung, die die Mail nehmen soll mittels einer Uservariable „TEAM“, sowohl beim Hostobjekt, als auch beim Serviceobjekt. das wird auch prima angezeigt, allerdings zieht die asignment Rule nur die Variablen des Hosts, obwohl ich in der Auswahlbox „Apply to“ „Service“ ausgewählt habe. Irgendeine Idee würde mir den verlorenen sonnigen Tag zurückbringen..
      danke schon mal für´s Lesen!
      VG, Rainer Gockeln

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.