Customized Mails in Icinga versenden – Teil 2

So,nach einer aufschlußreichen Diskussion zum Thema Umgebungsvariablen in Icinga – Ich hatte mir darüber noch nie wirklich einen Kopf gemacht, da “es” ja funktioniert hat – und der Bitte darum, ein “vollständiges Skript” zu veröffentlichen hier mal der entsprechende Entwurf für einen ansprechenden Ersatz der Standard-Mail-Benachrichtigung.
Das Grund-Layout stammt größtenteils von einem bestehenden Notification-Template wurde aber von mir nach Perl protiert und entsprechend umgebaut, bzw. angepasst.

Das Skript generiert eine HTML-Mail mit einem Link zum entsprechenden PNP4Nagios-Graphen.

Download

Die Integration in Icinga gestaltet sich ziemlich simpel.
Das Skript wird z.B. nach /usr/local/icinga/bin kopiert und ausführbar gemacht. Danach sollten die Abhängigkeiten zum Perl-Paket MAIL::Sender aufgelöst werden. Unter Debian geht das am einfachsten mit einem

apt-get install libmail-sender-perl

Sollte das Perl-Paket nicht in den Distribution-Quellen enthalten sein, kann man zur Not auch direkt CPAN bemühen

cpan Mail::Sender install

Danach fügt man entweder in eine bestehende commands.cfg oder am besten in eine “neue” notifications.cfg (Achtung, muss in der icinga.cfg unter Umständen eingefügt werden) folgenden Block ein

 define command {
 	command_name	notify-by-html-email
 	command_line	/usr/local/icinga/bin/icinga_mail.pl --debug 0 --smtphost 127.0.0.1 --icinga_url http://icinga.localdomain/icinga/ --pnp4nagios_url http://icinga.localdomain/pnp4nagios/ --originator "$ADMINEMAIL$" --recipient "$CONTACTEMAIL$" --notificationtype "$NOTIFICATIONTYPE$" --adminemail "$ADMINEMAIL$" --hostname "$HOSTNAME$" --hostalias "$HOSTALIAS$" --hostnotes "$HOSTNOTES$" --hoststate "$HOSTSTATE$" --hoststatetype "$HOSTSTATETYPE$" --hostattempt "$HOSTATTEMPT$" --maxhostattempt "$MAXHOSTATTEMPTS$" --hostduration "$HOSTDURATION$" --hostnotificationnumber "$HOSTNOTIFICATIONNUMBER$" --hostcheckcommand "$HOSTCHECKCOMMAND$" --hostlatency "$HOSTLATENCY$" --lasthostcheck "$LASTHOSTCHECK$" --lasthoststatechange "$LASTHOSTSTATECHANGE$" --lasthostup "$LASTHOSTUP$" --lasthostdown "$LASTHOSTDOWN$" --lasthostunreachable "$LASTHOSTUNREACHABLE$" --hostoutput "$HOSTOUTPUT$" --hostaddress "$HOSTADDRESS$" --hostnotesurl "$HOSTNOTESURL$" --servicedesc "$SERVICEDESC$" --servicestate "$SERVICESTATE$" --servicenotificationnumber "$SERVICENOTIFICATIONNUMBER$" --serviceoutput "$SERVICEOUTPUT$" --lastservicecheck "$LASTSERVICECHECK$" --lastservicestatechange "$LASTSERVICESTATECHANGE$" --lastserviceok "$LASTSERVICEOK$" --lastservicewarning "$LASTSERVICEWARNING$" --lastservicecritical "$LASTSERVICECRITICAL$" --lastserviceunknown "$LASTSERVICEINKNOWN$" --servicestatetype "$SERVICESTATETYPE$" --serviceattempt "$SERVICEATTEMPT$" --maxserviceattempts "$MAXSERVICEATTEMPTS$" --serviceduration "$SERVICEDURATION$" --servicecheckcommand "$SERVICECHECKCOMMAND$" --servicedisplayname "$SERVICEDISPLAYNAME$" --servicelatency "$SERVICELATENCY$" --servicepercentchange "$SERVICEPERCENTCHANGE$" --timet "$TIMET$" --processstarttime "$PROCESSSTARTTIME$" --totalhostsup "$TOTALHOSTSUP$" --totalhostsdown "$TOTALHOSTSDOWN$" --totalhostsunreachable "$TOTALHOSTSUNREACHABLE$" --totalservicesok "$TOTALSERVICESOK$" --totalserviceswarning "$TOTALSERVICESWARNING$" --totalservicescritical "$TOTALSERVICESCRITICAL$" --totalservicesunknown "$TOTALSERVICESUNKNOWN$" --totalhostproblemsunhandled "$TOTALHOSTPROBLEMSUNHANDLED$" --totalserviceproblemsunhandled "$TOTALSERVICEPROBLEMSUNHANDLED$" --notificationauthor "$NOTIFICATIONAUTHOR$" --notificationcomment "$NOTIFICATIONCOMMENT$"
}

Danach bekommt jeder “Contact” noch über host_notification_commands und service_notifications_commands das neue Notification-Template verpasst

...
host_notification_commands notify-by-html-email
service_notification_commands  notify-by-html-email
...

Nach dem anschließenden Reload der Icinga-Config werden dann Mails mit dem “neuen” Template verschickt.

UPDATE

Wie es halt immer so ist … Eine Software wird nie fertig :-)
Damit die PNP4Nagios-Graphen auch ausserhalb des Unternehmens funktionieren, dürfen diese nicht nur verlinkt werden, sondern müssen base64-codiert mitgeschickt werden.
Ich habe das Skript um einen Wget-Call erweitert und den base64-Code im IMG-Tag eingebaut:

<img src="data:image/png;base64, iVBORw0KGgoAAAANSU...MyBzOjAuMDEgcjowLjEzCg==" alt="pnp4nagios: hostname service" />

Dazu die Datei icinga_mail_base64.pl herunterladen und in icinga_mail.pl umbenennen.

Download – pnp4nagios über base64

Für den Wget-Call habe ich versucht die allgemeingültigsten Parameter –no-proxy –no-check-certificate zu verwenden. Wer über einen Proxy oder mit einem gültigen Zertifikat auf Icinga zugreift, muss das in der Zeile 716

# get pnp4nagios images as base64
my $base64image = `wget --no-proxy --no-check-certificate -O - '$pnp4nagios_url/image?host=$icinga_hostname&srv=$icinga_servicedesc&view=1&source=0' 2> /dev/null | base64`;

entsprechen anpassen.

UPDATE 2

Das ganze ist jetzt auch Google Code Project verfügbar:

Issues und Bugs bitte dort einkippen.

Customized Mails in Icinga versenden

Die mit Icinga mitgelieferten E-Mail-Benachrichtigungen erfüllen zwar ihren Zweck, sind aber alles andere als hübsch anzuschauen. Vor allem, wenn Gruppierungen benachrichtigt werden sollen, die mit dem ganzen Tech-Quatsch nichts am Hut haben.

Glücklicherweise kann man auch an dieser Stelle ziemlich simpel per Skript ansetzen. An dieser Stelle möchte ich nur eine kleine Hilfestellung für eine eigene Umsetzung geben.

Zuerst muss in einer der Icinga-Konfigurationsdateien das “command” bekannt gemacht werden:

define command {
	command_name	notify-by-html-email
	command_line	/usr/local/icinga/bin/icinga_mail.pl
}

Dann muss dieses “command” an den entsprechenden User vererbt werden:

# contact user1
define contact {
	 contact_name 	user1
	 alias 	User 1
	 host_notifications_enabled 	1
	 service_notifications_enabled 	1
	 host_notification_period 	24x7
	 service_notification_period 	24x7
	 host_notification_options 	d,u,r,f,s
	 service_notification_options 	w,u,c,r,f,s
	 host_notification_commands 	notify-by-html-email
	 service_notification_commands 	notify-by-html-email
	 email 	yourmail@localdomain.td
	 can_submit_commands 	0
	 retain_status_information 	0
	 retain_nonstatus_information 	0
}

Anschließend packt man folgendes Skript in das oben angegeben Verzeichnis.

#!/usr/bin/perl
#
# sudo apt-get install libmail-sender-perl
#
use warnings;
use strict;
use Mail::Sender;
 
# define your mail server
my $mailServer = "127.0.0.1";
 
# set from address
my $originator = "icinga\@localdomain.td";
 
# recipient (e.g. root\@localhost) -> 
my $recipient = $ENV{ICINGA_CONTACTEMAIL};
 
# get icinga notification type
my $icinga_notificationtype = $ENV{ICINGA_NOTIFICATIONTYPE};
 
my $subject = "$icinga_notificationtype: $ENV{ICINGA_HOSTNAME}->$ENV{ICINGA_SERVICEDESC} is $ENV{ICINGA_SERVICESTATE}";
 
my $messageBody = "< !DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
</head>
<body bgcolor=\"#ffffff\" text=\"#000000\">
Hello,<br />
<br />
the following information has been generated:<br />
<br />
$ENV{ICINGA_HOSTNAME}->$ENV{SERVICEDISPLAYNAME} is <b>$ENV{ICINGA_SERVICESTATE}</b> since $ENV{ICINGA_SERVICEDURATION}
<br />
Output: $ENV{ICINGA_SERVICEOUTPUT}
<br />
</body>
</html>";
 
# send mail
sendMail($messageBody);
 
 
sub sendMail {
  my $messageBody = $_[0];
  my $sender = new Mail::Sender {
  	smtp		=>	$mailServer,
  	from		=>	$originator,
  	on_errors	=>	undef
  } or die "Can't create the Mail::Sender object: $Mail::Sender::Error\n";
 
  $sender->Open({
  	to	=>	$recipient,
  	subject		=>	$subject,
  	ctype		=>	"text/html",
  	encoding	=>	"UTF-8"
  }) or die $Mail::Sender::Error . "\n";
  $sender->SendEx($messageBody);
  $sender->Close();
}

Voila … Ab sofort werden selbstgebastelte Mails an die User verschickt. Den eigenen Gestaltungswünschen sind jetzt keine Grenzen mehr gesetzt. Einfach den oben angeführten HTML-Code entsprechend anpassen oder austauschen. Die möglichen Variablen kann man der Dokumentation hier http://docs.icinga.org/1.6/en/macrolist.html entnehmen.