Seite wählen

Modifier im Icinga-Director selbstgemacht

von | Apr 28, 2022 | Icinga

Ich bin sowohl als Consultant als auch als Ausbilder ein großer Fan von Hilfe zur Selbsthilfe. Der Blogpost wird also zum einen dem geneigten Leser hoffentlich helfen sich bei Bedarf seine eigenen Modifier für den Icinga-Director zu bauen, zum anderen will ich anhand des Beispiels auch beleuchten was ich so unter Hilfe zu Selbsthilfe verstehe. Daher will ich etwas weiter ausholen bevor der erste Code-Schnipsel kommt, wer also schon weiß was Modifier sind, wie man sie nutzt und warum man vielleicht Bedarf nach einem eigenen hat, darf gerne die Einleitung überspringen.

Modifier im Director ermöglichen es Daten aus der Import-Quelle anzupassen oder auch anzureichern, sprich es erlaubt der Monitoring-Administration auszubügeln was in der Datenquelle nicht passt oder auch einfach nicht für das geplante Regelwerk in Icinga 2 geeignet ist. Einfache Stringoperationen ermöglichen es bereits aus Hostnamen einen FQDN zu machen oder diesen aus möglicherweise getrenntem Hostnamen und Domäne zu kombinieren, komplexere Modifier machen beispielsweise einen DNS-Lookup um Icinga 2 zur Laufzeit vom DNS unabhängig zu machen. Bereits an den Beispielen sieht man hoffentlich, wie hilfreich diese Optionen sein können, und wenn damit dann Icinga 2 voll automatisiert mit Tausenden von Hosts befüllt wird, wird hoffentlich klar wie kritisch die Funktion ist. Nun gibt es natürlich trotzdem Bugs, einen hat Tom mit dem Release 1.9.1 gefixt und zwar dass bei Stringoperationen aus NULL-Werten ein leerer String wurde. Nachdem dieses Verhalten nun bereits länger so war, hat vielleicht der ein oder andere sich darauf verlassen, so dass es nun statt eines lang ersehnten Bug-Fix wie für mich, für diese Nutzer wie ein Bug erscheinen mag. Der Supportkunde der nun bei Patrick aufgeschlagen war, da dieser gerade wieder im Rahmen der Ausbildung das Operations-Team verstärkt, hatte zum Glück Verständnis für den Bug-Fix, aber trotzdem war nun sein Workflow kaputt. Als ein Beispiel wurde genannt, dass sie aktuell einen DNS-Lookup als Modifier nutzen, der gegebenenfalls wenn ein Name nicht auflösbar ist einen NULL-Wert zurückgibt, im nächsten Schritt wurde daraus ein leerer String und dann wurde der leere String durch einen regulären Ausdruck zum String „Unknown“. Von Patrick um eine kurze Einschätzung gebeten, sagte ich ihm er soll mal schauen ob der Modifier statt einem NULL-Wert direkt einen leeren String zurückgeben kann oder ein anderer Modifier genutzt werden kann um NULL-Werte zu befüllen. Nachdem diese Suche erfolglos geblieben war, hat er das Ticket in Richtung Icinga eskaliert, da das Kundenproblem nicht ohne Software-Änderung zu lösen war.

Nun hätten wir es darauf beruhen lassen können, da ich aber bei meinen Auszubildenden den Drang fördere, eine Lösung zu suchen statt das Problem nur jemand anders zuzuschieben und Patrick auch von Natur aus nicht zufrieden ist wenn er ungelöste Probleme vor sich hat, kam er erneut auf mich zu. Mit meiner Antwort, dass so ein Modifier in etwa 10 Minuten geschrieben sei, und dass er dies doch übernehmen könne, war er natürlich nicht ganz zufrieden bis ich ihm dafür meine Unterstützung angeboten habe. Da ich hier schon entsprechendes beigetragen habe, konnte ich ihm direkt sagen was zu tun ist und es kam dabei der Commit 4692b28 für den Director heraus. Dieser fügt einen Modifier hinzu der es erlaubt NULL-Werte direkt durch einen angegebenen String zu ersetzen, heißt der Kunde kann wieder seinen Workflow bauen und dieser dürfte sogar einfacher sein.

Modifier: Replace null value with String

Wenn man sich den Commit nun anschaut sind es nur zwei veränderte Dateien, zum einen der neu erstellte Modifier und zum anderen ist eine Registrierung notwendig. Der Modifier selbst besteht quasi aus einem Rumpf aus Namespace, verwendeten Klassen und seiner eigenen Klasse als Implementierung der Basisklasse sowie drei Funktionen in der Datei library/Director/PropertyModifier/PropertyModifierReplaceNull.php. Die Funktion getName() erlaubt es eine Beschreibung für das Auswahlfeld der Modifier zurückzugeben, addSettingsFormFields(QuickForm $form) erlaubt es zusätzliche, für den Modifier benötigte Eingabefelder zu definieren und transform($value) ist dann die eigentliche Modifikation, also bei einem NULL-Wert den eingegebenen String zurückzugeben ansonsten den ursprünglichen Wert. Entstanden ist das Ganze durch Kopieren und Anpassen eines ähnlichen Modifiers in 5 Minuten Arbeitszeit und 30 Minuten Erklärung.

<?php

namespace Icinga\Module\Director\PropertyModifier;

use Icinga\Module\Director\Hook\PropertyModifierHook;
use Icinga\Module\Director\Web\Form\QuickForm;

class PropertyModifierReplaceNull extends PropertyModifierHook
{

    public function getName()
    {
        return 'Replace null value with String';
    }

    public static function addSettingsFormFields(QuickForm $form)
    {
        $form->addElement('text', 'string', array(
            'label'       => 'Replacement String',
            'description' => $form->translate('Your replacement string'),
            'required'    => true,
        ));
    }

    public function transform($value)
    {
        if ($value === null) {
            return $this->getSetting('string');
        } else {
	    return $value;
	}  
    }
}

Zusätzlich muss der Modifier noch in register-hooks.php registriert werden, dazu benötigt es zwei Einträge. Zum einen muss der Modifier an sich bekannt gemacht werden und zum anderen dann noch als Umsetzung des Hook angeboten werden was der Director über eine Iteration durch ein mehrdimensionales Array löst, so dass der Modifier nur an entsprechender Stelle dem Array hinzugefügt werden muss. Dabei der Ordnung halber an die alphabetische Reihe gehalten und schon ist es auch hübsch. Dafür nehmen wir mal 1 Minute Arbeitszeit und 5 Minuten erklären an.

...
use Icinga\Module\Director\PropertyModifier\PropertyModifierReplaceNull;
...
        PropertyModifierReplaceNull::class,
...

Noch mal den Git-Workflow erklärt, den Commit in Patrick’s Fork gepusht, auf seinem Testsystem ausgecheckt, getestet und für gut befunden, Pull-Request erstellt, macht weitere 5 Minuten Arbeitszeit und 5 Minuten Erklärung, wobei ich mir diese hier spare und stattdessen auf einen älteren Blogpost verweise, den zusammen mit Kollegen geschrieben hatte. In Summe macht das in etwa eine Stunde aufgewandte Zeit, aber ich habe nun einen Auszubildenden, der beim nächsten Mal ein ähnliches Problem besser verstehen wird, es direkt lösen kann und als Bonus neben dem Erfolgserlebnis auch als Contributor beim Director auftaucht. Patrick hat sein Wissen erweitert, den Icinga-Kollegen Arbeit abgenommen und dem Kunden ohne lange Wartezeit eine Lösung geliefert, von der auch andere zukünftig profitieren werden. Beim nächsten Mal sind es dann vermutlich wirklich 10 Minuten Arbeit für Patrick! 😉

Was aber nun wenn man einen so speziellen Modifier benötigt, dass es keinen Sinn macht diesen dem Director und damit der Allgemeinheit zur Verfügung zu stellen? Durch den modularen Aufbau von Icinga Web 2 lassen sich Modifier als Hook auch aus einem eigenen Modul anbieten. Heißt wenn der Modifier speziell für eine bestimmte Import-Quelle benötigt wird, kann der Modifier im gleichen Modul eingebaut werden. Ist er dagegen nur für die eigene Umgebung relevant kann man ihn in ein separates Modul packen oder vielleicht mit in das Modul für das Theme des Unternehmens. Dafür müssten nur ein paar Kleinigkeiten angepasst werden. Der Modifier wäre dann im Modul an der Stelle library/MODULENAME/ProvidedHook/Director/PropertyModifier/ abzulegen, dementsprechend wäre der Namespace Icinga\Module\MODULENAME\ProvidedHook\Director\PropertyModifier und statt einer register-hooks.php erstellt man eine run.php mit folgendem Inhalt:

<?php

use Icinga\Module\MODULENAME\ProvidedHook\Director\PropertyModifier\PropertyModifierMODIFIERNAME;

$this->provideHook('director/PropertyModifier', PropertyModifierMODIFIERNAME::class);

Ich hoffe das Beispiel und die Erklärungen helfen demjenigen, der einen eigenen Modifier braucht, und ich konnte auch zeigen warum ich so ein großer Fan von Hilfe zur Selbsthilfe bin. Wer noch gar nichts mit den Import-Möglichkeiten des Directors anfangen kann, ist in der überarbeiteten Schulung Icinga 2 Advanced willkommen. Das Kapitel zu Import kommt aus meiner Feder und erklärt ausführlich und anhand von Übungen wie man Daten mittels SQL aus einer Datenbank importiert und mit dem Inhalt einer CSV-Datei ergänzt um Hosts anzulegen und aus einem LDAP-Verzeichnisdienst Benutzer und Gruppen zieht. Wer dagegen jemanden kennt, der ein bisschen Hilfe zur Selbsthilfe bekommen will, wir haben noch Ausbildungsplätze bei uns im Professional Services frei! Ich verspreche aber auch allen anderen Kollegen zu helfen, wenn sich jemand für eine der anderen Stellen interessiert! 😉

Das Beitragsbild kombiniert den Director von rones auf Openclipart mit dem Icinga-Logo.

Dirk Götz
Dirk Götz
Principal Consultant

Dirk ist Red Hat Spezialist und arbeitet bei NETWAYS im Bereich Consulting für Icinga, Puppet, Ansible, Foreman und andere Systems-Management-Lösungen. Früher war er bei einem Träger der gesetzlichen Rentenversicherung als Senior Administrator beschäftigt und auch für die Ausbildung der Azubis verantwortlich wie nun bei NETWAYS.

0 Kommentare

Einen Kommentar abschicken

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

Mehr Beiträge zum Thema Icinga