homelab-codex-ws/scripts/npm
oskar 5daae77e2f feat(scripts): npm_api.py — CLI do zarzadzania npm PIHA+VPS przez REST API
token/list-hosts/list-certs/set-cert/create-host, dry-run domyslny dla
zmian (--apply wymagane), stdlib urllib (zero-dep). Adresy npm@VPS
przez Tailscale (100.95.58.48:81), NIE public IP.

+ docs/backlog.md: npm@VPS admin panel :81 publicznie osiagalny —
brak override ograniczajacego bind do mesh/localhost.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 14:57:42 +02:00
..
env.example feat(scripts): npm_api.py — CLI do zarzadzania npm PIHA+VPS przez REST API 2026-07-10 14:57:42 +02:00
npm_api.py feat(scripts): npm_api.py — CLI do zarzadzania npm PIHA+VPS przez REST API 2026-07-10 14:57:42 +02:00
README.md feat(scripts): npm_api.py — CLI do zarzadzania npm PIHA+VPS przez REST API 2026-07-10 14:57:42 +02:00

npm_api.py — sterowanie Nginx Proxy Manager przez REST API

CLI do zarzadzania dwoma instancjami NPM (PIHA, VPS) bez klikania w web UI. Uzywa tego samego REST API co panel admina (/api/tokens, /api/nginx/*).

Dlaczego stdlib (urllib), nie requests

Skrypt uzywa wylacznie biblioteki standardowej Pythona (3.11+) — zero zaleznosci do zainstalowania. To narzedzie CLI uruchamiane doraznie z roznych miejsc (SATURN, laptop operatora), nie serwis z wlasnym obrazem Docker — pip install przed kazdym uzyciem byloby tarciem bez korzysci. Zapotrzebowanie na API jest proste (JWT bearer, JSON), wiec urllib.request w zupelnosci wystarcza.

Konfiguracja

cp scripts/npm/env.example scripts/npm/.env
# wypelnij NPM_PIHA_USER/PASS i NPM_VPS_USER/PASS realnymi danymi

.env jest gitignored (wzorzec *.env w .gitignore) — nigdy nie trafia do repo.

Adresy domyslne (nadpisywalne w .env przez NPM_PIHA_URL/NPM_VPS_URL):

Instancja URL Uwaga
piha http://192.168.31.5:81 LAN
vps http://100.95.58.48:81 Tailscale mesh, NIE publiczny IP 135.181.153.108:81

Uzycie

python3 scripts/npm/npm_api.py --npm piha|vps <komenda> [opcje]

Komendy

  • token — loguje sie i pokazuje status + czas wygasniecia tokenu (test poswiadczen).
  • list-hosts — tabela proxy hostow (id, domeny, forward, cert, ssl_forced, enabled).
  • list-certs — tabela certyfikatow (id, provider, nice_name, domeny, expires_on).
  • set-cert HOST_ID CERT_ID [--apply] — podpina certyfikat pod host. Dry-run domyslnie, realna zmiana tylko z --apply. NPM przeladowuje nginx sam po PUT.
  • create-host --domain ... --forward-host ... --forward-port ... [opcje] [--apply] — tworzy nowy proxy host. Dry-run domyslnie, realna zmiana tylko z --apply.

create-host opcje: --domain (powtarzalne), --forward-host, --forward-port, --forward-scheme http|https (domyslnie http), --cert-id (domyslnie 0 = brak), --ssl-forced/--no-ssl-forced (domyslnie: true jesli podano --cert-id), --http2-support/--no-http2-support, --block-exploits/--no-block-exploits (domyslnie true), --websocket/--no-websocket (domyslnie false), --access-list-id, --advanced-config.

Przyklady

Faza 2 okit.pl — przepiecie certow proxy hostow na wildcard

Zamiast bulk-SQL + recznego sed na .conf (patrz docs/sessions/2026-07-07-okit-wildcard.md), API robi reload samo:

# 1. znajdz ID wildcard certu
python3 scripts/npm/npm_api.py --npm piha list-certs

# 2. znajdz ID hosta ktory ma dostac nowy cert
python3 scripts/npm/npm_api.py --npm piha list-hosts

# 3. podejrzyj zmiane (dry-run)
python3 scripts/npm/npm_api.py --npm piha set-cert 11 5

# 4. wykonaj
python3 scripts/npm/npm_api.py --npm piha set-cert 11 5 --apply

Deploy Gokapi — vhost share.okit.pl na npm@VPS

# dry-run
python3 scripts/npm/npm_api.py --npm vps create-host \
  --domain share.okit.pl \
  --forward-host 127.0.0.1 --forward-port 8080 \
  --cert-id 5 --ssl-forced --http2-support --block-exploits

# apply
python3 scripts/npm/npm_api.py --npm vps create-host \
  --domain share.okit.pl \
  --forward-host 127.0.0.1 --forward-port 8080 \
  --cert-id 5 --ssl-forced --http2-support --block-exploits \
  --apply

Obsluga bledow

Bledy autentykacji, brakujace hosty/certy i bledy API zwracane sa z czytelnym komunikatem na stderr (kod wyjscia 1) — np.:

Error: PUT /nginx/proxy-hosts/11 -> HTTP 404: Proxy host not found

Referencje API

Oficjalny swagger jest niekompletny; zweryfikowano bezposrednio ze zrodla (GET /api/schema na dzialacej instancji NPM 2.14, OpenAPI 3.1) oraz github.com/DenAV/nginx-proxy-manager-ansible.