Quelltext des aktuellen Standes
<?php
declare(strict_types=1);
use OpenNIT\Monitoring\ZabbixHostTemplate;
/**
* Deckt die Vorlage ab, mit der Zabbix die Kennzahlen der Instanz abfragt.
*
* Eine Vorlage, die Zabbix beim Import abweist, ist schlimmer als keine – der
* Aufbau wird deshalb hier festgehalten: die Fassung, das eine Haupt-Element,
* die Bindung der abhängigen Elemente daran und das Dashboard mit den fünf
* Ticketzahlen.
*/
return static function (): void {
$yaml = static fn(string $url = 'https://doku.example.test'): string
=> ZabbixHostTemplate::yaml($url);
test('Der Kopf nennt eine Fassung, die jeder neuere Stand einspielt', function () use ($yaml) {
$text = $yaml();
assertTrue(str_contains($text, 'zabbix_export:'), 'Der Wurzelknoten fehlt');
// Zabbix spielt eine ältere Fassung in einen neueren Stand ein,
// umgekehrt nicht – deshalb die niedrigste noch gepflegte.
assertTrue(str_contains($text, " version: '6.0'"), 'Die Fassung fehlt oder ist zu hoch');
assertTrue(str_contains($text, ' templates:'), 'Der Abschnitt der Vorlagen fehlt');
assertTrue(str_contains($text, " template: 'OpenNIT by HTTP'"), 'Der Name der Vorlage fehlt');
});
test('Ein einziges Element holt die Daten, alle übrigen hängen daran', function () use ($yaml) {
$text = $yaml();
assertTrue(str_contains($text, ' type: HTTP_AGENT'), 'Das abrufende Element fehlt');
assertTrue(str_contains($text, ' key: opennit.metrics'), 'Der Schlüssel des Haupt-Elements fehlt');
assertTrue(
str_contains($text, " url: '{\$OPENNIT.URL}/api/ex/monitoring/metrics'"),
'Die Adresse des Endpunkts fehlt'
);
assertTrue(
str_contains($text, " value: 'Bearer {\$OPENNIT.TOKEN}'"),
'Die Kopfzeile mit dem Token fehlt'
);
// Jedes abhängige Element nennt dasselbe Haupt-Element.
$abhaengig = substr_count($text, ' type: DEPENDENT');
$bindungen = substr_count($text, ' key: opennit.metrics');
assertTrue($abhaengig > 20, 'Zu wenige abhängige Elemente: ' . $abhaengig);
assertSame($abhaengig, $bindungen, 'Nicht jedes abhängige Element hängt am Haupt-Element');
});
test('Die fünf Ticketzahlen sind vorhanden und stehen auf dem Dashboard', function () use ($yaml) {
$text = $yaml();
foreach (['new', 'open', 'waiting', 'solved', 'closed'] as $zustand) {
assertTrue(
str_contains($text, ' key: opennit.tickets.' . $zustand),
'Das Element für „' . $zustand . '" fehlt'
);
assertTrue(
str_contains($text, " key: 'opennit.tickets." . $zustand . "'"),
'Die Kachel für „' . $zustand . '" fehlt auf dem Dashboard'
);
}
assertTrue(str_contains($text, ' dashboards:'), 'Der Abschnitt der Dashboards fehlt');
assertTrue(str_contains($text, " name: 'OpenNIT – Tickets'"), 'Das Dashboard fehlt');
});
test('Die Kacheln liegen nebeneinander und passen ins Raster', function () use ($yaml) {
$text = $yaml();
// Zabbix rechnet mit 24 Spalten; sechs Kacheln zu vier Spalten füllen sie genau.
preg_match_all("/^ x: '(\\d+)'$/m", $text, $treffer);
$spalten = array_map('intval', $treffer[1]);
assertSame([0, 4, 8, 12, 16, 20], $spalten, 'Die Kacheln liegen nicht nebeneinander');
assertSame(6, substr_count($text, " width: '4'"), 'Nicht jede Kachel ist vier Spalten breit');
});
test('Jeder Auslöser nennt ein Element, das es gibt', function () use ($yaml) {
$text = $yaml();
preg_match_all("/\\/OpenNIT by HTTP\\/([a-z0-9._\\[\\]{}#]+)[,)]/", $text, $treffer);
assertTrue($treffer[1] !== [], 'Kein Auslöser gefunden');
foreach (array_unique($treffer[1]) as $key) {
// Element-Prototypen der Erkennung tragen eine Marke im Schlüssel.
$gesucht = str_contains($key, '{#')
? " key: '" . $key . "'"
: ' key: ' . $key;
assertTrue(
str_contains($text, $gesucht),
'Der Auslöser verweist auf ein Element, das die Vorlage nicht anlegt: ' . $key
);
}
});
test('Die Adresse der Instanz steht im Makro, der Token nicht in der Datei', function () use ($yaml) {
$text = $yaml('https://doku.example.test');
assertTrue(
str_contains($text, " - macro: '{\$OPENNIT.URL}'")
&& str_contains($text, " value: 'https://doku.example.test'"),
'Die Adresse fehlt im Makro'
);
// Der Token wird am Host gesetzt; eine Vorlage ohne Geheimnis lässt sich
// weitergeben, ohne dass jemand nachdenken muss.
assertTrue(
str_contains($text, " - macro: '{\$OPENNIT.TOKEN}'\n value: ''"),
'Das Token-Makro ist nicht leer'
);
});
test('Die Erkennung der geplanten Aufgaben ist vollständig', function () use ($yaml) {
$text = $yaml();
assertTrue(str_contains($text, ' discovery_rules:'), 'Der Abschnitt der Erkennung fehlt');
assertTrue(str_contains($text, ' key: opennit.tasks.discovery'), 'Die Regel fehlt');
assertTrue(str_contains($text, " - lld_macro: '{#TASK}'"), 'Die Marke der Aufgabe fehlt');
assertTrue(str_contains($text, ' item_prototypes:'), 'Die Element-Prototypen fehlen');
assertTrue(str_contains($text, ' trigger_prototypes:'), 'Der Auslöser-Prototyp fehlt');
});
test('Jede Kennung ist eindeutig', function () use ($yaml) {
$text = $yaml();
preg_match_all('/uuid: ([a-f0-9]{32})/', $text, $treffer);
$kennungen = $treffer[1];
assertTrue($kennungen !== [], 'Keine Kennung gefunden');
assertSame(
count($kennungen),
count(array_unique($kennungen)),
'Zwei Objekte tragen dieselbe Kennung – Zabbix weist den Import ab'
);
});
test('Dieselbe Eingabe ergibt dieselben Kennungen', function () use ($yaml) {
// Nur so aktualisiert ein erneuter Import die Vorlage, statt eine
// zweite daneben anzulegen.
preg_match_all('/uuid: ([a-f0-9]{32})/', $yaml(), $a);
preg_match_all('/uuid: ([a-f0-9]{32})/', $yaml('https://andere.example.test'), $b);
assertSame($a[1], $b[1], 'Die Kennungen hängen an der Adresse');
});
};