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!

Update 19. Juni 2017: Die Scripte dieses Artikels entstanden aus der Not heraus, dass der Icinga Director nicht mit ENV-Variablen umgehen kann. Die Resonanz darauf hat mich mehr als überrascht: wahnsinnig viele Leute zeigten sich wahnsinnig interessiert an meiner Art, Notifications zu erstellen.
Nachdem ich nun also den Umgang mit GIT ansatzweise kapiert habe, habe ich den ersten Pull Request meines Lebens gestellt, und ab der bald verfügbaren 2.7.0 von Icinga 2 werden meine Scripte der neue Default sein. Deshalb friere ich den vorliegenden Artikel an dieser Stelle ein und bitte euch, Fragen und Diskussionen über die offiziellen Kanäle zu führen 🙂

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 Immerzu 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. Dass dieser auch nicht zwingend benötigt wird, zeige ich euch anhand der folgenden Scripte, die ich mir gehäkelt habe — 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

Notification Plugin Command

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

object NotificationCommand "Service Alarm By Email" {
    import "plugin-notification-command"
    command = [ "/etc/icinga2/scripts/service-by-mail.sh" ]
arguments += {
        "-4" = {
            required = true
            value = "$address$"
        }
        "-6" = "$address6$"
        "-b" = "$notification.author$"
        "-c" = "$notification.comment$"
        "-d" = {
            required = true
            value = "$icinga.long_date_time$"
        }
        "-e" = {
            required = true
            value = "$service.name$"
        }
        "-f" = "$notification_from$"
        "-i" = "$icingaweb2url$"
        "-l" = {
            required = true
            value = "$host.name$"
        }
        "-n" = {
            required = true
            value = "$host.display_name$"
        }
        "-o" = {
            required = true
            value = "$service.output$"
        }
        "-r" = {
            required = true
            value = "$user.email$"
        }
        "-s" = {
            required = true
            value = "$service.state$"
        }
        "-t" = "$notification.type$"
        "-u" = {
            required = true
            value = "$service.display_name$"
        }
        "-v" = "$notification_logtosyslog$"
    }
}
object NotificationCommand "Host Alarm By Email" {
    import "plugin-notification-command"
    command = [ "/etc/icinga2/scripts/host-by-mail.sh" ]
    arguments += {
        "-4" = {
            required = true
            value = "$address$"
        }
        "-6" = "$address6$"
        "-b" = "$notification.author$"
        "-c" = "$notification.comment$"
        "-d" = {
            required = true
            value = "$icinga.long_date_time$"
        }
        "-f" = "$notification_from$"
        "-i" = "$icingaweb2url$"
        "-l" = {
            required = true
            value = "$host.name$"
        }
        "-n" = {
            required = true
            value = "$host.display_name$"
        }
        "-o" = {
            required = true
            value = "$host.output$"
        }
        "-r" = {
            required = true
            value = "$user.email$"
        }
        "-s" = {
            required = true
            value = "$host.state$"
        }
        "-t" = {
            required = true
            value = "$notification.type$"
        }
        "-v" = "$notification_logtosyslog$"
    }
}

Sowohl das command Host Alarm By Email als auch Service Alarm By Email 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 -4 beispielsweise die IPv4-Adresse des Hosts, und diese wird über das runtime macro $address$ übergeben. 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.) → Der Bug ist inzwischen behoben.

Notification Object

icinga2 notification objectNach 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 Service Alarm By Email und Generic Host Alarm By Email) 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 »Assign where« erst dann auftaucht, nachdem auf Store geklickt wurde! Über »Assign where« kann nun definiert werden, bei welchen Events der User informiert werden soll; die Auswahl »Host« oder »Service« unter »Apply to« ist hierbei zwingend erforderlich.

icinga director notifications data fieldsDie inzwischen massiv erweiterte Version des Scripts gibt nun auch die Möglichkeit, einen From:-Header zu definieren — legt man sich ein Datenfeld im Director an, ist auch das bequem über das Webinterface steuerbar. Wird für $icingaweb2url ein String hinterlegt, erweitert sich die Ausgabe der Email um den passenden Link. Das Script fängt nun ab, wenn keine Kommentare vorhanden sind, und blendet die Zeile nur noch im Bedarfsfall ein. Und per Log To Syslog lässt sich eine Debug-Ausgabe ins syslog realisieren, wenn man sie denn haben möchte.

Fazit

icinga2 director notification die erste EmailMein 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. UnterschriftAber 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. Bastien

    Thank you for this tutorial. I don’t understand how to import the icinga command into the director. I add my notification command to the file „commands.conf“ but it doesn’t appear in the commands.
    I try to add the command through the interface but it does not allow to provide arguments.
    Please help

    • Hi Bastien,

      when you add entries to commands.conf, Director does not know about them; so you have to re-run the Director kickstart. I would suggest you to add the command and its arguments via Director: first add the command itself and store it, and then add arguments and data fields as needed (once stored, there appears a tab for them).

      HTH,
      Marianne

      • Bastien

        Hi Marianne,
        Danke for your answer.
        I didn’t notice that the Arguments tab appear after the command is stored.
        In your example did you use custom field ? or you only used inherited field ?

  2. Vielen Dank für das HowTo, hat prima geklappt.
    Ich musste ein wenig nach den Timeperiods suchen und habe sie gefunden, bevor ich Mictus Kommentar und Deine Antwort gesehen habe

    Gerne mehr davon!

  3. HUHU erstmal danke für deine Arbeit deine Tutorials haben mir bisher sehr weitergeholfen!!

    die PUnkte „K““B““D“ haben soweit gut geklappt…. leider verstehe ich nicht was danach zu tun ist

    habe die scripte kopiert und jetzt?

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

    verstehe ich nicht ganz wie das gehen soll Wäre hammer wenn du mir weiter helfen könntest bestimmt hängen da andere auch fest!

  4. Claudia Bühler

    Hallo,
    ich bin ein absoluter Neuling bei Icinga2 und Director. Daher meine Frage: wie bekomme ich es hin, dass ich bei „Add new Icinga Notification“ unter „Assign where“ „host.vars.notification“ angeben kann?
    Grüße, Claudia

    • Hi,
      in meinem Beispiel ist das eine Host-Variable, die halt irgendwo gesetzt werden muss; ich hab im Director ein entsprechendes Data Field angelegt, es meinen Host-Templates zugeordnet und den gewünschten Wert vergeben

      Cheers,
      Marianne

  5. Pingback: Siegfried Eichhorn

  6. neeraj kori

    Hi ,

    Nice work !! , To configure mail notification with icinga2 with the help of icinga director.
    I configured the notification with the process mentioned on the past.

    It works fine for host notification. i.e host up and host down
    But it is not working for the services. i.e server status,like critical unknow.

    Could you please suggest me . How can i make it right.

    Regards,
    Neeraj

  7. Hi Marianne,

    wie oder wo ist denn bitte das Time-Zone Fenster (Dein erstes Bild)?
    Ich scheine Blind zu sein. Habe alles angeklickt – aber nirgends finde ich es.
    Habe auch komplett neu gecloned. Gibt es dieses Feature vielleicht gar nicht mehr?

    Kurzum: Wo kann ich die Timezone in Director einstellen.
    Danke im Voraus!

    Mictu

    • Ja, die Timezones haben ein wenig den Ort gewechselt

      Icinga Director → Notifications → Timeperiods → Add

      Hilft dir das weiter?

      • Ja – herzlichen Dank! Auch überhaupt für Deine Webseite und die Arbeit, die Du da rein gesteckt hast.
        Sie hat mir sehr als Einsteiger geholfen. Topp Arbeit! *_Thump_Up_*

      • Die Timeperiods sind aber zickig (geworden?).
        Ich kann kein Objekt mit Zeiten anlegen, so wie in Deinem Bild.
        Ich kann es nur in einem Template anlegen.
        Wenn ich dann ein Object mit einem Import auf diese Vorlage anlegen will,
        knallt es. Denn aus irgendeinem Grund macht er dann anscheinend zwei Imports (sieht man in der Configübersicht).
        U. A. will er dann auch „legacy-timeperiod“ importieren, wobei ich überhaupt nicht verstehe, wo dieser Wert herkommt.

        Frage: Du schreibst was von „generic-director-timeperiod“. Wo hast Du den wie angelegt?
        Danke, wenn DU Dir hierfür noch ein paar Minuten Antwortzeit erübrigen könntest!

        • Der erste Schritt ist immer, (mindestens) ein Template anzulegen; also Add → Object type »Timeperiod template« → Name »test-template« → Update method »LegacyTimePeriod« → Imports »Gar nix« → und speichern.

          Im nächsten Schritt definierst du dir ein konkretes Objekt:
          Add Object type »Timeperiod object« → Name »workhours« → Imports »test-template« → und speichern.

          Und jetzt, da das Objekt erstellt und gepeichert ist, erscheinen oben die Reiter Preview sowie History und Ranges – über Ranges landest du dann in der Eingabemaske für die Zeiten, vergleichbar mit meinem ersten Screenshot.

          Im letzten Dreivierteljahr hat sich wahnsinnig viel getan beim Director; im Grunde genommen ist der Weg jetzt zwar vielleicht etwas umständlicher, dafür ist es aber der saubere

          Sag mal ob\’s geklappt hat!

          • Yup. Hat geklappt. Ich hatte noch einen Fehler mit den Zonen, den Du schon weiter unten glücklicherweise beantwortet hast.

            Jetzt habe ich noch einen Knoten im Gehirn mit „Assign where“.
            Ich verstehe im Moment noch nicht so genau, wofür das da ist.
            Hatte jetzt einen Filter für bestimmte Host.name angelegt. Dachte, dass diese Regel dann nur für diese Hostnamen gilt. Jetzt meckert der Check aber bei den Hosts, die nicht darauf passen.

            Dein „Expression“ Eintrag verstehe ich nicht.
            Hmm…

  8. 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…

  9. Thanks! very helpful howto

  10. 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

  11. 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

  12. 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!

  13. This Article was mentioned on unixe.de

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

  15. @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

Kommentarfunktion ist deaktiviert.