Ping-Check meldet den Systemstatus zusaetzlich per REST an die API
Laufen check_fds.sh und die API auf verschiedenen Rechnern, erreicht der
Legacy-Import die API nie: SystemController::index() liest MONITOR_STATUS_FILE
als lokale Datei, waehrend status.txt auf dem Ping-Host liegt. Der
LegacyStatusFileReader liefert dann stillschweigend ein leeres Array und der
System-Monitor zeigt dauerhaft "Keine Systeme gemeldet" - ohne Fehlermeldung,
die auf die Ursache hinweisen wuerde.
check_fds.sh meldet die Ping-Ergebnisse jetzt zusaetzlich per
POST /api/v1/systems/{id}/status (online -> ok, offline -> error) und schreibt
status.txt unveraendert weiter. Die Zugangsdaten stehen in monitor-api.conf
(Vorlage: monitor-api-sample.conf); fehlt die Datei, bleibt das Verhalten
unveraendert. Eine unerreichbare API bricht den Check nicht ab, sondern
protokolliert nur eine Warnung.
Die System-ID wird aus dem Hostnamen slugifiziert, weil der Router auf dem
rohen, nicht dekodierten Pfad matcht - "Nextcloud(intern)" landete sonst
prozentkodiert in der Datenbank. Der lesbare Name geht im Feld "name" mit.
Das README beschreibt den kombinierten Weg als "Weg 3" und weist bei Weg 1
darauf hin, dass der Legacy-Import eine lokale Datei erwartet.
Ausserdem zwei Fehler im selben Skript behoben:
- Pfade werden relativ zum Skript statt zum Arbeitsverzeichnis aufgeloest.
- Die letzte Zeile der hosts.conf wurde ohne abschliessenden Zeilenumbruch
stillschweigend verschluckt, ein zuletzt angehaengter Host also nie geprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
143bf922d3
commit
2a552342f5
4 changed files with 122 additions and 5 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -5,3 +5,5 @@ node_modules/
|
|||
__pycache__/
|
||||
deploy-webhook.log
|
||||
.phpunit.result.cache
|
||||
monitor-api.conf
|
||||
credentials.conf
|
||||
|
|
|
|||
26
README.md
26
README.md
|
|
@ -46,7 +46,8 @@ die dazugehörigen Klärungen in [Detailfragen.md](Detailfragen.md) und
|
|||
- `api/` — REST-API (PHP, SQLite), siehe [api/README.md](api/README.md)
|
||||
- `html/` — Frontend: `office.html` (Büro-Visualisierung), `js/`, `css/`
|
||||
- `tests/frontend/` — Node-Tests für die Frontend-Layoutlogik (`node --test`)
|
||||
- `check_fds.sh`, `mail_fds.py`, `hosts-sample.conf` — bestehende Ping-Überwachung
|
||||
- `check_fds.sh`, `mail_fds.py`, `hosts-sample.conf`, `monitor-api-sample.conf` — bestehende
|
||||
Ping-Überwachung (letztere: optionale Zugangsdaten für die Meldung per REST)
|
||||
- `docker-compose.yml` — komplette Entwicklungsumgebung (siehe unten)
|
||||
- `update.sh` — holt die neueste Version vom konfigurierten Git-Remote und aktualisiert die
|
||||
Docker-Compose-Umgebung (Abhängigkeiten, Images, Dienste, Tests)
|
||||
|
|
@ -104,6 +105,12 @@ kein System gemeldet wurde — dafür gibt es zwei unabhängige Wege:
|
|||
4. Die API liest `status.txt` laufend mit und zeigt die Einträge als Systeme
|
||||
(`source: "legacy"`) im System-Monitor an — ohne dass etwas neu gestartet werden muss.
|
||||
|
||||
> ⚠️ Dieser Import liest `MONITOR_STATUS_FILE` als **lokale Datei**. Läuft `check_fds.sh` auf
|
||||
> einem anderen Rechner als die API (oder liegt `status.txt` außerhalb des API-Containers —
|
||||
> der Mount in `docker-compose.yml` ist standardmäßig auskommentiert), erreicht sie die API
|
||||
> nie und der System-Monitor bleibt bei „Keine Systeme gemeldet". Fehlt die Datei, meldet die
|
||||
> API keinen Fehler, sondern liefert eine leere Liste. In dem Fall Weg 3 verwenden.
|
||||
|
||||
**Weg 2: Status direkt per REST-API melden**
|
||||
|
||||
Eigene Server/Skripte können ihren Status auch ohne `hosts.conf` melden:
|
||||
|
|
@ -121,4 +128,21 @@ Eigene Server/Skripte können ihren Status auch ohne `hosts.conf` melden:
|
|||
So gemeldete Systeme (`source: "api"`) haben Vorrang vor dem Legacy-Import aus `status.txt`
|
||||
und werden von ihm nicht überschrieben. Details zu Feldern/Auth: [API.md](API.md#systeme).
|
||||
|
||||
**Weg 3: Ping-Überwachung, die ihre Ergebnisse selbst per REST meldet**
|
||||
|
||||
Kombiniert beide Wege und ist der richtige Weg, wenn der Ping-Check auf einem anderen Rechner
|
||||
läuft als die API — dann fällt der Umweg über die Datei `status.txt` weg:
|
||||
|
||||
1. Wie in Weg 1 die `hosts.conf` pflegen und `check_fds.sh` per Cron laufen lassen.
|
||||
2. Wie in Weg 2 einen Agenten registrieren (Rolle `user`, damit er keinen Schreibtisch in der
|
||||
Büro-Visualisierung belegt).
|
||||
3. `monitor-api-sample.conf` nach `monitor-api.conf` neben `check_fds.sh` kopieren, dort
|
||||
`MONITOR_API_BASE` und `MONITOR_API_KEY` eintragen und die Datei auf `chmod 600` setzen.
|
||||
|
||||
`check_fds.sh` meldet dann nach jedem Ping zusätzlich per REST (`online` → `ok`,
|
||||
`offline` → `error`) und schreibt `status.txt` unverändert weiter für den alten Wandmonitor.
|
||||
Die System-ID entsteht dabei aus dem Hostnamen (`Nextcloud(intern)` → `nextcloud-intern`),
|
||||
der Originalname bleibt als Anzeigename erhalten. Ist die API nicht erreichbar, läuft die
|
||||
Ping-Überwachung normal weiter und protokolliert nur eine Warnung.
|
||||
|
||||
|
||||
|
|
|
|||
79
check_fds.sh
79
check_fds.sh
|
|
@ -1,11 +1,78 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Pfade relativ zum Skript aufloesen, nicht zum Arbeitsverzeichnis: der Cronjob startet
|
||||
# das Skript zwar mit "cd", ein Aufruf von aussen laese sonst aber die falsche hosts.conf
|
||||
# (oder gar keine).
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Pfad zur Textdatei mit Hostname-IP-Paaren (pro Zeile: hostname ip)
|
||||
HOST_FILE="hosts.conf"
|
||||
HOST_FILE="$SCRIPT_DIR/hosts.conf"
|
||||
# Pfad zum mail_fds.py-Skript
|
||||
MAIL_SCRIPT="mail_fds.py"
|
||||
MAIL_SCRIPT="$SCRIPT_DIR/mail_fds.py"
|
||||
# Pfad zur Statusdatei
|
||||
STATUS_FILE="/var/www/html/status.txt"
|
||||
# Zugangsdaten fuer die Statusmeldung per REST (siehe monitor-api-sample.conf)
|
||||
API_CONF="$SCRIPT_DIR/monitor-api.conf"
|
||||
|
||||
# Die Meldung per REST ist optional: fehlt monitor-api.conf oder ist sie leer, schreibt der
|
||||
# Check wie bisher nur status.txt und mailt bei Ausfall. Noetig ist sie dort, wo Ping-Check
|
||||
# und API auf verschiedenen Rechnern laufen - der Legacy-Import aus status.txt (F6) liest
|
||||
# eine lokale Datei und erreicht die API dann nicht.
|
||||
MONITOR_API_BASE=""
|
||||
MONITOR_API_KEY=""
|
||||
if [ -f "$API_CONF" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
. "$API_CONF"
|
||||
fi
|
||||
|
||||
# Erzeugt aus dem Hostnamen eine URL-sichere System-ID. Der Router der API matcht auf dem
|
||||
# rohen, nicht dekodierten Pfad (api/src/Http/Router.php) - eine prozentkodierte ID landete
|
||||
# also kodiert in der Datenbank. Der lesbare Originalname geht im Feld "name" mit.
|
||||
system_id() {
|
||||
local slug
|
||||
slug=$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]' \
|
||||
| sed -e 's/[^a-z0-9]\+/-/g' -e 's/^-//' -e 's/-$//')
|
||||
printf '%s' "${slug:-unbekannt}"
|
||||
}
|
||||
|
||||
json_escape() {
|
||||
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'
|
||||
}
|
||||
|
||||
# Meldet einen Host per POST /api/v1/systems/{id}/status. Fehler werden nur protokolliert:
|
||||
# eine unerreichbare API darf die Ping-Ueberwachung nicht anhalten.
|
||||
report_to_api() {
|
||||
local hostname="$1"
|
||||
local ip="$2"
|
||||
local status="$3"
|
||||
|
||||
if [ -z "$MONITOR_API_BASE" ] || [ -z "$MONITOR_API_KEY" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local api_status="error"
|
||||
if [ "$status" = "online" ]; then
|
||||
api_status="ok"
|
||||
fi
|
||||
|
||||
local payload
|
||||
payload=$(printf '{"status":"%s","name":"%s","type":"host","detail":"%s"}' \
|
||||
"$api_status" "$(json_escape "$hostname")" "$(json_escape "$ip")")
|
||||
|
||||
local code
|
||||
if ! code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 \
|
||||
-X POST "${MONITOR_API_BASE%/}/api/v1/systems/$(system_id "$hostname")/status" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: ${MONITOR_API_KEY}" \
|
||||
-d "$payload"); then
|
||||
echo " Warnung: API unter $MONITOR_API_BASE nicht erreichbar, $hostname nicht gemeldet."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$code" != "200" ]; then
|
||||
echo " Warnung: API antwortet mit HTTP $code auf die Meldung fuer $hostname."
|
||||
fi
|
||||
}
|
||||
|
||||
# Funktion zum Prüfen einer IP und Schreiben des Status
|
||||
check_ip() {
|
||||
|
|
@ -26,11 +93,13 @@ check_ip() {
|
|||
if [ "$success_count" -lt 2 ]; then
|
||||
status="offline"
|
||||
echo " Mehr als ein Ping fehlgeschlagen für $hostname ($ip). Führe $MAIL_SCRIPT aus."
|
||||
./"$MAIL_SCRIPT" --subject "Ping-Fehler bei $hostname $ip" --credentials credentials.conf
|
||||
"$MAIL_SCRIPT" --subject "Ping-Fehler bei $hostname $ip" --credentials "$SCRIPT_DIR/credentials.conf"
|
||||
else
|
||||
echo " $hostname ($ip) ist erreichbar."
|
||||
fi
|
||||
|
||||
report_to_api "$hostname" "$ip" "$status"
|
||||
|
||||
# Status in status.conf schreiben/aktualisieren
|
||||
local now=$(date +"%Y-%m-%d %H:%M")
|
||||
awk -v h="$hostname" -v i="$ip" -v s="$status" -v d="$now" '
|
||||
|
|
@ -64,7 +133,9 @@ fi
|
|||
# Statusdatei anlegen, falls nicht vorhanden
|
||||
touch "$STATUS_FILE"
|
||||
|
||||
while read -r line; do
|
||||
# "|| [ -n "$line" ]" nimmt auch eine letzte Zeile ohne abschliessenden Zeilenumbruch mit -
|
||||
# ohne sie verschluckt read den zuletzt angehaengten Host stillschweigend.
|
||||
while read -r line || [ -n "$line" ]; do
|
||||
case "$line" in
|
||||
\#*|"") continue ;;
|
||||
esac
|
||||
|
|
|
|||
20
monitor-api-sample.conf
Normal file
20
monitor-api-sample.conf
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Zugangsdaten, mit denen check_fds.sh die Ping-Ergebnisse zusaetzlich per REST an die
|
||||
# monitor-API meldet (POST /api/v1/systems/{id}/status, siehe API.md Abschnitt "Systeme").
|
||||
#
|
||||
# Noetig ist das, wenn check_fds.sh auf einem anderen Rechner laeuft als die API: der
|
||||
# Legacy-Import liest status.txt als lokale Datei und erreicht sie dann nicht.
|
||||
#
|
||||
# Diese Datei nach "monitor-api.conf" neben check_fds.sh kopieren und ausfuellen. Fehlt sie
|
||||
# oder bleibt ein Wert leer, meldet check_fds.sh wie bisher nur nach status.txt und per Mail.
|
||||
#
|
||||
# Der Key gehoert einem eigens registrierten Agenten der Rolle "user" - die bekommt nie einen
|
||||
# Schreibtisch in der Buero-Visualisierung (AgentRepository::register). Anlegen mit
|
||||
# register-agent.sh; der Key wird nur bei der Registrierung einmalig ausgegeben.
|
||||
#
|
||||
# Enthaelt ein Secret: chmod 600 monitor-api.conf
|
||||
|
||||
# Basis-URL der API, ohne abschliessenden Slash (Host-Port des api-Service)
|
||||
MONITOR_API_BASE="http://monitor.example.lan:8091"
|
||||
|
||||
# API-Key des registrierten Agenten
|
||||
MONITOR_API_KEY=""
|
||||
Loading…
Add table
Reference in a new issue