Drucker an IP-Steckdose per Icinga 2 resetten

Diesen Beitrag schrieb ich 6 Jahre und 3 Wochen zuvor; die nachfolgenden Ausführungen müssen heute weder genau so nach wie vor funktionieren, noch meiner heutigen Meinung entsprechen. Behalte das beim Lesen (und vor allem: beim Nachmachen!) bitte stets im Hinterkopf.

Geschätzte Lesezeit: 2 Minuten

Wie faul kann man sein? Die Ausgangssituation ist ein älterer Drucker, der sich softwareseitig immer wieder mal aufhängt, sprich: er ist dann zwar an, doch er ist per Netzwerk nicht erreichbar und macht auch sonst nichts mehr. Das einzige, was in dieser Situation hilft: erst ausschalten, dann anschalten.

Oder richtiger: erst hinlaufen, dann ausschalten, dann einschalten – Nervkram also. Die Idee lag daher in der Beschaffung einer IP-Steckdose, genauer einer EnerGenie EG-PMS2-LAN: einer 6fachen Überspannungsschutz-Steckdosenleiste mit LAN-Schnittstelle, die es ermöglicht, vier der Steckplätze aus der Ferne zu kontrollieren. Das ist erfreulich kostengünstig, konfiguriert ist sie auch schnell, und übers Webinterface lässt sie sich rasch bedienen – aber wer möchte das schon? Das muss doch auch eleganter gehen? Daher installierte ich auf meinem Monitoring-Host das Tool egcfg, das ich auf GitHub aufstöberte: es dient genau dazu, die vier Steckplätze anzusteuern.

$ git clone https://github.com/unterwulf/egctl.git
$ cd egctl
$ make && make install

Zum Funktionieren benötigt das Tool – es heißt übrigens /usr/local/bin/egctl – noch ein Konfigfile egtab, welches in /etc abgelegt werden will. Hier sind IP-Adresse und Passwort der Steckdosenleiste zu hinterlegen.

# Name    Protocol IP              Port    Password
# ------- -------- --------------- ------- --------
egpms     pms20    a.b.c.d         5000    einpasswort

Über die Konsole kann das Gerät nun bereits angesteuert werden. Soll also beispielsweise der vierte Steckplatz eingeschaltet werden und die übrigen drei unverändert bleiben, so wäre hierzu folgender Aufruf nötig:

$ /usr/local/bin/egctl egpms left left left on

Was also soll konkret passieren, wenn der Drucker mal wieder rumspinnt? Steckdose #4 abschalten… Paar Sekunden warten… Und Steckdose #4 dann wieder einschalten. Das passt alles in ein kleines Shell-Script namens Reset_Printer.sh – ich hab’s noch durch ein paar Debug-Meldungen aufgeblasen und dann in /etc/icinga2/scripts abgelegt.

#!/usr/bin/env bash

PROG="$( basename $0 )"
DEVICE="egpms"
SOCKET="4"
STATE="$1"

if [ $STATE -gt 0 ] ; then
  logger "$PROG: Resetting socket $SOCKET on poweroutlet $DEVICE:"
  /usr/local/bin/egctl $DEVICE left left left off
  if [ "$?" == "0" ] ; then
    logger "$PROG: Turned $SOCKET on $DEVICE OFF; waiting 5 seconds and turning ON again."
    sleep 5
    /usr/local/bin/egctl $DEVICE left left left on
    if [ "$?" == "0" ] ; then
      logger "$PROG: Turned $SOCKET on $DEVICE ON again; all done."
    else
      logger "$PROG: Not successful. Please investigate."
    fi
  else
    logger "$PROG: Not successful. Please investigate."
  fi
else
  logger "$PROG: Host state is $STATE, nothing to do."
fi

Ist ein EventCommand hinterlegt, so wird es bei Statusänderung des Hosts ausgeführt – und zwar bei jeder Statusänderung. Deshalb fange ich seitens des Scripts ab, welchen Status mein Host hat, dieser wird nämlich als Argument mit übergeben; und das Script soll nur dann ausgeführt werden, wenn der Drucker ungleich UP (was einer $host.state_id$ > 0 entspricht) gelistet wird. Ich habe auch kurzfristig mit command = "test $host.state_id$ -eq 0 || /etc/icinga2/scripts/Reset_Printer.sh" und ähnlichen Scherzen experimentiert, erhielt aber in den Logfiles die lapidare Meldung no such file or directory, und im Director lässt sich sowas überhaupt nicht anlegen, weil er ein Array draus macht. Aber egal, kann sein, dass es irgendwie geht, ich hab mich nicht wirklich lange damit beschäftigt. Brrr, okay, mein Script muss ich noch als EventCommand in Icinga 2 erfassen – ich hab das über den Director gemacht, aber geht natürlich auch so.

object EventCommand "event_reset_printer" {
    import "plugin-event-command"

    command = [ "/etc/icinga2/scripts/Reset_Printer.sh" ]
    arguments += {
        "-state" = {
            required = true
            skip_key = true
            value = "$host.state_id$"
        }
    }
}

Zuletzt muss man dem Host nun natürlich diesen Event-Handler verpassen. Das wiederum geht über den Director nicht (dort kann man Services einen Handler zuweisen, aber eben nicht Hosts), weshalb ich den Drucker in Form einer Konfigdatei nach /etc/icinga2/conf.d geschmissen hab.

object Host "printer" {
  import "Old Printer"

  display_name = "printer"
  address = "w.x.y.z"
  enable_event_handler = true
  event_command = "event_reset_printer"
}

Grundsätzlich war’s das auch schon. Im Debug-Log lässt sich prima beobachten, ob und wann der Event Handler auf die Reise geschickt wurde, und die Debug-Meldungen des Scripts sorgen für Ausgabe in /var/log/syslog.

$ icinga2 feature enable debuglog
$ service icinga2 restart
$ multitail /var/log/icinga2/debug.log /var/log/syslog
[2018-03-23 09:34:11 +0100] notice/Checkable: State Change: Checkable 'printer' soft state change from UP to DOWN detected.
[2018-03-23 09:34:11 +0100] notice/Checkable: Executing event handler 'event_reset_printer' for service 'printer'
[2018-03-23 09:34:11 +0100] debug/DbEvents: add eventhandler history for 'printer'
--
Mar 23 09:34:11 monitor nagios: Reset_Printer.sh: Resetting socket 4 on poweroutlet egpms:
Mar 23 09:34:12 monitor nagios: Reset_Printer.sh: Turned 4 on egpms OFF; waiting 5 seconds and turning ON again.
Mar 23 09:34:17 monitor nagios: Reset_Printer.sh: Turned 4 on egpms ON again; all done.

Mir sind die Syslog-Meldungen tatsächlich wichtig, da in Icinga Web 2 nicht ersichtlich ist, ob der Event Handler zuschlug und was er gegebenenfalls gemacht hat – an dieser Stelle ist man vollständig auf Logfiles angewiesen. Kurzum: es funktioniert. Der als DOWN erkannte Drucker wird hart resettet und funktioniert anschließend wieder; da der nächste state change von DOWN nach UP geht, wird das Script dann nicht erneut ausgeführt – wer will sich schon in eine Endlosschleife katapultieren? Jedenfalls ist das eine durchaus nicht uncoole Sache, und mir fallen da spontan noch ein paar Anwendungsbeispiele zu ein…

Alle Bilder dieser Seite: © Marianne Spiller – Alle Rechte vorbehalten
Hintergrundbild: Generic Screenshot, 2018, 1500x 690px, Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten

Eure Gedanken zu „Drucker an IP-Steckdose per Icinga 2 resetten“

Ich freue mich über jeden Kommentar, es sei denn, er ist blöd. Deshalb behalte ich mir auch vor, die richtig blöden kurzerhand wieder zu löschen. Die Kommentarfunktion ist über GitHub realisiert, weshalb ihr euch zunächst dort einloggen und „utterances“ bestätigen müsst. Die Kommentare selbst werden im Issue-Tracker und mit dem Label „✨💬✨ comment“ erfasst – jeder Blogartikel ist ein eigenes Issue. Über GitHub könnt ihr eure Kommentare somit jederzeit bearbeiten oder löschen.