From 62ccafbbd1e97bfa47903cea7d43abcedf25dc05 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 20 Sep 2026 23:56:49 +0200 Subject: [PATCH] Anmeldung fehlgeschlagen: sagen, woran es liegt Die Meldung nannte bisher nur die aufgerufene Adresse. Antwort, HTTP-Code und curls eigene Fehlermeldung wurden weggeworfen - also genau das, woran man es erkennt. Uebrig blieb Raten. Jetzt werden alle drei eingesammelt und ausgewertet: HTTP 400/401 Der Proxy Manager hat geantwortet und abgelehnt. Damit ist auch gesagt, dass Port, Netz und Proxy stimmen. Die Meldung der Schnittstelle steht dabei ("Invalid email or password"), dazu der Hinweis auf npm-reset, falls das Konto nie angelegt wurde. HTTP 000 Gar keine Antwort. Der Reihe nach wird geprueft und benannt: NPM_ENABLED=off, Container laeuft nicht, auf dem Port lauscht nichts, oder er antwortet nur nicht. HTTP 5xx Es hat etwas geantwortet, aber nicht wie erwartet. Dazu: ist die Antwort HTML statt JSON, wird das ausdruecklich gesagt und die erste Zeile gezeigt. Damit ist auf einen Blick erkennbar, dass ein HTTP-Proxy geantwortet hat und nicht der Proxy Manager - im Test "502 Proxy Error...". Beim Pruefen der Faelle ist ein Fehler aufgefallen: container_running benutzt RUNTIME ohne Absicherung. War die Runtime nicht erkannt, brach die Fehlerdiagnose unter "set -u" mit "RUNTIME ist nicht gesetzt" ab - ausgerechnet die Ausgabe, die helfen soll. Ohne erkannte Runtime lautet die Antwort jetzt schlicht "nein". Nebenbei korrigiert: NPM antwortet bei falschen Zugangsdaten mit 400, nicht mit 401 - der erste Entwurf fing den haeufigsten Fall nicht. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 37 +++++++++++ README_en.md | 36 +++++++++++ scripts/cmk-manage.sh | 144 ++++++++++++++++++++++++++++++++++++------ scripts/lib/common.sh | 9 ++- 4 files changed, 204 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index c9dc8c4..62e3529 100644 --- a/README.md +++ b/README.md @@ -1197,6 +1197,43 @@ neu anlegt. **Proxy-Hosts, Weiterleitungen und Zugriffslisten sind damit weg** – die Zertifikate bleiben. Das Kommando zeigt vorher genau das an und fragt nach. Die Proxy-Hosts lassen sich mit `proxy add` in einem Aufruf neu anlegen. +### 10.1.1 Wenn die Anmeldung fehlschlägt + +Die Meldung nennt inzwischen selbst, woran es liegt – sie zeigt den HTTP-Code, +die Antwort der Schnittstelle und, falls gar nichts antwortete, was curl +gemeldet hat: + +``` +[FEHLER] Anmeldung am Proxy Manager fehlgeschlagen. + Aufgerufen : http://127.0.0.1:81/api/tokens + Konto : admin@example.com + HTTP-Code : 400 + Antwort : Invalid email or password + + Woran es liegen kann + Der Proxy Manager hat geantwortet und die Anmeldung abgelehnt. + Der Weg dorthin stimmt also - Port, Netz und Proxy sind in Ordnung. +``` + +Das ist die halbe Miete: **hat es geantwortet, liegt es nicht am Netz.** +Die andere Richtung sieht so aus: + +| HTTP-Code | Bedeutung | Nächster Schritt | +|---|---|---| +| `400`/`401` | Der Proxy Manager lehnt ab | Konto/Kennwort in der `.env`, oder das Konto gibt es nicht → `npm-reset` | +| `000` | gar keine Antwort | Container aus? Port frei? – der Befehl prüft beides und sagt, welches zutrifft | +| `5xx` + HTML | etwas anderes antwortet | meist der HTTP-Proxy; die erste Zeile der HTML-Antwort wird mit angezeigt | + +Antwortet HTML statt JSON, steht es ausdrücklich da – samt erster Zeile, an der +man erkennt, wer da geantwortet hat: + +``` + Die Antwort ist HTML, kein JSON - sie stammt also nicht von der + Schnittstelle des Proxy Managers, sondern von etwas davor + (HTTP-Proxy, anderer Dienst auf dem Port). Erste Zeile: + 502 Proxy Error... +``` + ### 10.2 Proxy-Host anlegen – ohne Browser Die Weboberfläche lässt sich im Terminal-Browser nur mühsam bedienen; Formulare diff --git a/README_en.md b/README_en.md index a54ee3d..e6271d4 100644 --- a/README_en.md +++ b/README_en.md @@ -1196,6 +1196,42 @@ the account from `NPM_ADMIN_EMAIL`/`NPM_ADMIN_PASSWORD` on the next `up`. remain. The command shows exactly that beforehand and asks for confirmation. The proxy hosts can be recreated with `proxy add` in a single call. +### 10.1.1 When the login fails + +The message now names the cause itself – it shows the HTTP code, the API's +reply and, if nothing answered at all, what curl reported: + +``` +[FEHLER] Anmeldung am Proxy Manager fehlgeschlagen. + Aufgerufen : http://127.0.0.1:81/api/tokens + Konto : admin@example.com + HTTP-Code : 400 + Antwort : Invalid email or password + + Woran es liegen kann + Der Proxy Manager hat geantwortet und die Anmeldung abgelehnt. + Der Weg dorthin stimmt also - Port, Netz und Proxy sind in Ordnung. +``` + +That is half the battle: **if it answered, the network is not the problem.** +The other direction looks like this: + +| HTTP code | meaning | next step | +|---|---|---| +| `400`/`401` | the Proxy Manager refuses | account/password in `.env`, or the account does not exist → `npm-reset` | +| `000` | no answer at all | container down? port free? – the command checks both and says which applies | +| `5xx` + HTML | something else answered | usually the HTTP proxy; the first line of the HTML reply is shown | + +If HTML arrives instead of JSON, it says so explicitly – including the first +line, which reveals who answered: + +``` + Die Antwort ist HTML, kein JSON - sie stammt also nicht von der + Schnittstelle des Proxy Managers, sondern von etwas davor + (HTTP-Proxy, anderer Dienst auf dem Port). Erste Zeile: + 502 Proxy Error... +``` + ### 10.2 Creating a proxy host – without a browser The web interface is painful in a terminal browser, and forms with file uploads diff --git a/scripts/cmk-manage.sh b/scripts/cmk-manage.sh index cf99fb5..717dd4d 100755 --- a/scripts/cmk-manage.sh +++ b/scripts/cmk-manage.sh @@ -3769,31 +3769,135 @@ EOF fi return 1 fi - local body - body="$(curl -sS --max-time 20 --noproxy '*' -X POST "$base/api/tokens" \ + # Antwort, HTTP-Code und curls eigene Fehlermeldung getrennt + # einsammeln - ohne die drei laesst sich hinterher nicht sagen, WORAN + # es lag, und genau das ist hier der haeufigste Zeitfresser. + local body code cerr rc=0 + cerr="$(mktemp)" + body="$(curl -sS --max-time 20 --noproxy '*' -w '\n%{http_code}' \ + -X POST "$base/api/tokens" \ -H 'Content-Type: application/json' \ - -d "{\"identity\":\"$NPM_ADMIN_EMAIL\",\"secret\":\"$NPM_ADMIN_PASSWORD\"}" 2>/dev/null)" || true + -d "{\"identity\":\"$NPM_ADMIN_EMAIL\",\"secret\":\"$NPM_ADMIN_PASSWORD\"}" \ + 2>"$cerr")" || rc=$? + code="${body##*$'\n'}"; body="${body%$'\n'*}" + case "$code" in ''|*[!0-9]*) code=000 ;; esac + local tok; tok="$(json_str "$body" token)" - if [ -z "$tok" ]; then - err "Anmeldung am Proxy Manager fehlgeschlagen." - local m; m="$(json_str "$body" message)" - if [ -n "$m" ]; then printf ' Antwort: %s\n' "$m" >&2; fi - printf ' Geprueft wurde: %s\n' "$base/api/tokens" >&2 - # In Kundennetzen mit Zwangsproxy ist das die haeufigste Ursache - # fuer eine Fehlermeldung, die nach einem API-Problem aussieht. - if [ -n "${http_proxy:-}${HTTP_PROXY:-}${https_proxy:-}${HTTPS_PROXY:-}" ]; then - printf ' - In dieser Umgebung steht ein HTTP-Proxy. Nimmt no_proxy die lokalen - Adressen nicht aus, geht selbst diese Anfrage an ihn - dann meldet - er den Fehler, nicht der Proxy Manager. Nachsehen mit: - %s noproxy -' "$SELF" >&2 - fi - return 1 + if [ -n "$tok" ]; then + rm -f "$cerr" + printf '%s' "$tok" + return 0 fi - printf '%s' "$tok" + + err "Anmeldung am Proxy Manager fehlgeschlagen." + printf ' Aufgerufen : %s\n' "$base/api/tokens" >&2 + printf ' Konto : %s\n' "${NPM_ADMIN_EMAIL:-}" >&2 + printf ' HTTP-Code : %s\n' "$code" >&2 + local cmsg; cmsg="$(sed -n '1p' "$cerr" 2>/dev/null)" + if [ -n "$cmsg" ]; then printf ' curl sagt : %s\n' "$cmsg" >&2; fi + rm -f "$cerr" + # Der Proxy Manager verpackt seine Meldung in "error" - sie ist die + # nuetzlichste Zeile ueberhaupt und gehoert nach oben, nicht ans Ende. + local m; m="$(json_str "$body" message)" + if [ -n "$m" ]; then printf ' Antwort : %s\n' "$m" >&2; fi + + printf '\n %sWoran es liegen kann%s\n' "$C_BLD" "$C_RST" >&2 + + case "$code" in + 400|401|403) + # Es hat geantwortet - der Weg stimmt also, nur die Daten nicht. + printf ' Der Proxy Manager hat geantwortet und die Anmeldung abgelehnt. + Der Weg dorthin stimmt also - Port, Netz und Proxy sind in Ordnung.\n' >&2 + case "$m" in + *"fewer than"*|*"must NOT"*|*"required"*) + printf ' + Die Anfrage war unvollstaendig - meist ein leerer Wert in der .env: + NPM_ADMIN_EMAIL = %s + NPM_ADMIN_PASSWORD = %s + Setzen mit: %s config set NPM_ADMIN_PASSWORD \n' \ + "${NPM_ADMIN_EMAIL:-}" \ + "$([ -n "${NPM_ADMIN_PASSWORD:-}" ] && echo '' || echo '')" \ + "$SELF" >&2 ;; + *) + printf ' + Konto oder Kennwort stimmt nicht. Beide stehen in der .env: + %s config set NPM_ADMIN_EMAIL + %s config set NPM_ADMIN_PASSWORD + + Gibt es das Konto ueberhaupt? Seit Version 2.15 legt der Proxy + Manager keine Standardzugangsdaten an; das Konto entsteht nur beim + ERSTEN Start mit leerer Datenbank aus NPM_ADMIN_EMAIL/-PASSWORD. + War die Datenbank damals schon da, wurde es nie angelegt: + %s npm-reset (Datenbank beiseite, Konto entsteht neu) + Oder von Hand in der Oberflaeche: %s browser\n' \ + "$SELF" "$SELF" "$SELF" "$SELF" >&2 ;; + esac + ;; + 000) + printf ' Es kam ueberhaupt keine HTTP-Antwort.\n' >&2 + # Der Reihe nach das Naheliegende pruefen und BENENNEN + if ! npm_enabled; then + printf ' -> NPM_ENABLED=off - der Proxy Manager soll gar nicht laufen. + Einschalten: %s npm-enable on\n' "$SELF" >&2 + elif ! container_running "$NPM_CONTAINER_NAME"; then + printf ' -> Der Container "%s" laeuft nicht. + Starten: %s up\n' "$NPM_CONTAINER_NAME" "$SELF" >&2 + elif ! port_in_use "${NPM_ADMIN_PORT:-81}"; then + printf ' -> Auf Port %s lauscht nichts. + Der Container laeuft, aber die Oberflaeche ist dort nicht zu + erreichen. Nachsehen: %s logs + Port pruefen/aendern: %s npm-port\n' \ + "${NPM_ADMIN_PORT:-81}" "$SELF" "$SELF" >&2 + else + printf ' -> Port %s ist belegt, antwortet aber nicht auf diese Anfrage. + Vielleicht startet der Dienst noch: %s proxy restart\n' \ + "${NPM_ADMIN_PORT:-81}" "$SELF" >&2 + fi + case "$cmsg" in + *proxy*|*Proxy*) + printf ' -> curl nennt einen Proxy. Pruefen: %s noproxy\n' "$SELF" >&2 ;; + esac + ;; + 5??) + printf ' Es hat etwas geantwortet, aber mit einem Serverfehler. + Kommt die Antwort ueberhaupt vom Proxy Manager? Ein + HTTP-Proxy im Netz antwortet an dieser Stelle gern selbst: + %s noproxy\n' "$SELF" >&2 + ;; + *) + printf ' Unerwartete Antwort - erwartet wurde ein Feld "token".\n' >&2 + ;; + esac + + # Sieht die Antwort nach einer Webseite aus, kommt sie nicht von der + # Schnittstelle - das ist das sicherste Zeichen fuer einen Proxy + # oder einen fremden Dienst auf dem Port. + case "$body" in + '<'*|*'&2 ;; + '') + : ;; + *) + if [ -z "$m" ]; then + printf '\n Antwort (gekuerzt): %s\n' "$(printf '%s' "$body" | tr -d '\n' | cut -c1-120)" >&2 + fi ;; + esac + + if [ -n "${http_proxy:-}${https_proxy:-}${HTTPS_PROXY:-}" ]; then + printf ' + In dieser Umgebung steht ein HTTP-Proxy. Die eigenen Aufrufe gehen + zwar mit "--noproxy" daran vorbei, eigene Tests aber nicht: + %s noproxy\n' "$SELF" >&2 + fi + printf '\n' >&2 + return 1 } + + # npm_api METHODE PFAD [JSON] -> Antwort auf stdout, HTTP-Code via npm_code NPM_CODE_FILE="${TMPDIR:-/tmp}/.cmk-manage-npmcode.$$" trap 'rm -f "$NPM_CODE_FILE"' EXIT diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index a859d81..b7e478b 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -148,8 +148,13 @@ npm_enabled() { esac } -container_exists() { $RUNTIME container inspect "$1" >/dev/null 2>&1; } -container_running() { [ "$($RUNTIME container inspect -f '{{.State.Running}}' "$1" 2>/dev/null)" = "true" ]; } +# Ohne erkannte Runtime laesst sich nichts sagen - dann schlicht "nein" +# statt unter "set -u" mitten in einer Fehlerdiagnose abzubrechen. +container_exists() { [ -n "${RUNTIME:-}" ] && $RUNTIME container inspect "$1" >/dev/null 2>&1; } +container_running() { + [ -n "${RUNTIME:-}" ] || return 1 + [ "$($RUNTIME container inspect -f '{{.State.Running}}' "$1" 2>/dev/null)" = "true" ] +} require_cmk_running() { container_exists "$CMK_CONTAINER_NAME" \