d525ef2e0a369b55911f296cce1b1549050545b1
29
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d525ef2e0a |
poe.sh: parallele Geräte-Prüfung + echte PoE-Erfolgskontrolle
Nach einem echten Import (46 Geräte, 8 Switche aus dem Altsystem) zeigten sich zwei Probleme in der Hintergrund-Prüfschleife: - Geräte wurden strikt sequentiell geprüft (eine einzige "while read"- Schleife) -- ein einzelnes ausgefallenes Gerät mit ebenfalls nicht erreichbarem Switch (bis zu 5s expect-Timeout je Verbindungsschritt) verzögerte die Prüfung aller nachfolgenden Geräte. Jede Geräte-Prüfung läuft jetzt als eigener Hintergrund-Job (& + wait), über Process Substitution statt einer Pipe, damit wait die Jobs auch tatsächlich erfasst (bei "cmd | while ...; done" liefe die Schleife sonst in einer eigenen Subshell). - disable_poe()/enable_poe() haben unabhängig vom tatsächlichen Ergebnis der SSH/expect-Sitzung immer wie ein Erfolg gewirkt -- lief die Verbindung in einen Timeout (Switch nicht erreichbar, falsche Zugangsdaten, falscher Port), endete das expect-Skript trotzdem mit Exit-Code 0, poe.sh loggte fälschlich "PoE deaktiviert"/"PoE aktiviert", obwohl am Switch nichts passiert war. Jeder kritische expect-Schritt hat jetzt einen eigenen timeout-Zweig mit explizitem "exit 1"; poe.sh wertet den Rückgabewert aus und loggt bei einem nicht erreichbaren/ablehnenden Switch stattdessen klar, dass die PoE-Aktion fehlgeschlagen ist. Gilt für die Prüfschleife, den manuellen Neustart (poe.sh restart <mac>) und damit auch den Dashboard-Neustart-Button. Live verifiziert: alle 46 Geräte innerhalb von ~2s geprüft (statt sequentiell), alle 43 offline erkannten Geräte mit Switch-Zuordnung zeigten korrekt die neue Fehlermeldung, da die realen Switch-IPs vom Test-Host aus nicht erreichbar sind -- vorher hätte das fälschlich als 43x "PoE deaktiviert/aktiviert" geloggt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
3b2a5fc76c |
Wartung: Online-Watchdog nach Neustart, Status-Reset, Zugangsdaten-Spalte
- Nach einem ausgelösten SSH-Neustart blieb der Job-Status bisher für immer auf "Neustart ausgelöst" stehen -- ergänzt um einen Ping- Watchdog (gleiche Invocation wie das bestehende Monitoring in poe.sh: "ping -c 1 -W 2"), der nach einer kurzen Schonfrist (15s) regelmäßig prüft, bis das Gerät wieder antwortet (Timeout 5min). Status wechselt dann sichtbar auf "wieder online" bzw. auf einen Fehler bei Zeitüberschreitung. - Ein abgeschlossener ERFOLGREICHER Job wird bei jedem (erneuten) Laden der Wartungsseite zurückgesetzt (wieder "Noch keine Aktion") -- ein Erfolg ist nur relevant, solange man ihn live mitverfolgt. Fehler bleiben bewusst bis zur nächsten Aktion sichtbar, um sie nicht durch einen einfachen Reload zu übersehen. - Clients-Tabelle zeigt jetzt wie die Switche-Tabelle eine "Zugangsdaten"-Spalte (Name + Username oder "— keine —"). Live gegen das dedizierte Testsystem verifiziert: zwei echte Neustarts, beide per uptime -s bestätigt (kein False-Positive-Ping gegen die noch nicht heruntergefahrene alte Instanz), Status korrekt von "wartet auf Online" auf "wieder online" gewechselt; Status-Reset beim Seitenaufruf ebenfalls live bestätigt (sichtbar vor, leer nach einem GET /maintenance). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
8772f7777b |
Wartung: SSH-Bulk-Update & -Neustart für Linux-Clients
Neue Seite "Wartung" (Geräte-Bereich, eigenes Rechtepaar maintenance.view/maintenance.edit), komplett getrennt vom PoE-Neustart auf dem Dashboard: - Dashboard-Neustart bleibt ausschließlich PoE-Reset über den Switch - Wartung läuft immer per SSH direkt auf dem Gerät, unabhängig von jeder Switch-Zuordnung -- nur Geräte mit SSH-Zugangsdaten der Kategorie "Linux-Client" erscheinen dort (Windows/PowerShell folgt als eigener, separater Schritt -- kein Testsystem dafür verfügbar) Backend: - _run_ssh_command()/_run_ssh_reboot(): nicht-interaktive SSH-Ausführung mit paramiko.RejectPolicy() gegen dieselbe known_hosts-Datei wie das interaktive Browser-Terminal -- ein Host muss vorher einmal per "Verbindung testen" bestätigt worden sein, da hier (anders als im Terminal) niemand eine "yes/no"-Rückfrage beantworten kann - _apt_upgrade_command(): "apt update && apt upgrade -y" nicht- interaktiv mit DEBIAN_FRONTEND=noninteractive und --force-confdef/--force-confold, damit ein Paket-Postinst-Skript nicht auf eine nie kommende Config-Rückfrage wartet - Reboot behandelt einen abrupten Verbindungsabbruch NACH dem Kommando als Erfolg (die Maschine fährt herunter, bevor sie antworten kann); nur ein Fehler VOR dem Reboot-Kommando zählt als echter Fehler - Job-Status lebt im Prozessspeicher (wie das SSH-Terminal), Live- Anzeige per Polling (/maintenance/status) Live gegen ein dediziertes Testsystem (getrennt vom gemeinsam genutzten App-Host, um dort kein echtes apt upgrade auszulösen) verifiziert: echtes "apt update && apt upgrade" inkl. Kernel-/systemd-/ netplan-Paketen lief vollständig durch, anschließender SSH-Neustart hat das System nachweislich neu gestartet (uptime nach dem Job bestätigt). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
d3cf78592f |
Fix: 'host-name'-Option kollidierte mit dem nativen Reservierungs-Hostname
Der Nutzer fragte zu Recht nach, ob eine Reservierung mit gleichzeitig gesetztem hostname-Feld (aus dem Namen abgeleitet, z.B. 'unraid') UND einem option-data-Override fuer 'host-name' (Code 12, z.B. 'test') so beabsichtigt ist. Laut Kea-Dokumentation beantwortet Kea die Host-Name- Anfrage eines Clients bei einer Reservierung automatisch mit deren eigenem hostname-Feld -- der zusaetzliche Options-Override fuer dieselbe Option war eine unbeabsichtigte Dopplung/Quelle fuer Widersprueche, keine zusaetzliche Funktion. 'host-name' aus den 56 verbleibenden Standard-Optionen entfernt (war eine von 57), neue Migration v3 loescht eine bereits geseedete/gesetzte host-name-Zeile samt Wert aus bestehenden Installationen nach. Live auf der Test-VM verifiziert: Option ist verschwunden, die 'unraid'-Reservierung enthaelt jetzt nur noch hw-address/ip-address/hostname ohne option-data, kea-dhcp4 -t weiterhin erfolgreich. |
||
|
|
255308f81b |
App-weite Warnung bei ungespeicherten Aenderungen + Options-UI-Fix + Cache-Busting
1. Generischer Ja/Nein-Dialog bei ungespeicherten Aenderungen (kein Opt-in pro Seite noetig): initUnsavedChangesGuard() erkennt automatisch jedes Formular mit echten Eingabefeldern, das seit dem Laden der Seite veraendert wurde, und fragt beim Klick auf einen Link (z.B. Sidebar- Navigation), ob zuerst gespeichert werden soll -- eigener Dialog (confirmSaveDiscard) statt des bestehenden confirmAction (dort ist "Abbrechen" = Bleiben, hier gibt es bewusst nur die zwei angefragten Optionen: speichern oder verwerfen, beide verlassen die Seite). "Ja, speichern" sendet das Formular ganz normal ab (echter POST) und merkt sich das eigentliche Ziel in sessionStorage, um danach automatisch dorthin weiterzuleiten. Nachtrag noch in dieser Session gefixt: ein normales Speichern ueber den Seiten-eigenen Button loeste zusaetzlich die native Browser-Warnung (beforeunload) aus, obwohl die Aenderung bereits gespeichert wurde -- navigatingAway-Flag wird jetzt bei jedem Submit eines beobachteten Formulars (eigener Button ODER eigener Ja/Nein-Dialog) gesetzt, die generische Browser-Warnung erscheint dadurch nur noch bei tatsaechlich ungefragter Navigation (Tab schliessen, Reload, Adresszeile). Live per Playwright in drei Szenarien verifiziert (direktes Speichern, Ja via eigenem Dialog, Nein via eigenem Dialog) -- kein Browser-Popup in den ersten beiden Faellen, korrektes Redirect zum urspruenglichen Ziel nach "Ja". 2. DHCP-Options-Dropdown (Reservierungs-Dialog) verschiebt ein neu ausgewaehltes Options-Feld jetzt direkt unter das Dropdown (in einen .poe-added-options-Container) statt es nur an seiner urspruenglichen Stelle in der bis zu 57 Eintraege langen Liste einzublenden -- lag dort oft ausserhalb des sichtbaren Modal-Ausschnitts und wirkte, als waere nichts passiert. Bereits gesetzte Overrides stehen von Anfang an im selben Container, weitere haengen sich beim Auswaehlen unten an. 3. Cache-Busting fuer app.js/style.css (asset_url()-Helper, haengt die Aenderungszeit der Datei als ?v=... an) -- ein im Browser gecachtes, veraltetes app.js konnte nach einem Update sonst den Eindruck erwecken, eine neue Funktion wuerde "nicht funktionieren", obwohl der Code auf dem Server laengst aktuell war. Alle drei live auf der Test-VM deployt und per Playwright verifiziert, keine Fehler im journalctl-Log. (Testartefakt aufgeraeumt: der echte Host-Hostname wurde durch die Playwright-Tests versehentlich auf "directsave-test"/"navsave-test" geaendert und wieder auf POETEST zurueckgesetzt.) |
||
|
|
1a0b55ed44 |
DHCP: manuelle Reservierungen, Options-Schutz+Dropdown-UI, Lease-Countdown-Fix
1. Manuelle Reservierungen (dhcp_manual_reservations) fuer Geraete, die nicht als Client in dieser App gepflegt werden -- bewusst eine eigene, explizite Aktion (MAC/IP/Name), damit kein externes Geraet unueberwacht automatisch eine feste IP bekommt. _dhcp_reservation_candidates fuehrt automatische (aus devices) und manuelle Reservierungen jetzt zusammen, case-insensitiv nach MAC dedupliziert (automatisch gewinnt bei Konflikt). Automatische Reservierungen sind in der Tabelle nicht loeschbar (Schloss-Symbol statt Button, sie entstehen/verschwinden mit den Client-Stammdaten), manuelle schon. Live verifiziert: Hinzufuegen, doppelte MAC ablehnen, ungueltige MAC ablehnen, generierte Kea-Config mit gemischten Auto-/manuellen Reservierungen besteht kea-dhcp4 -t. 2. Standard-DHCP-Optionen um 10 weitere verifizierte Optionen erweitert (u.a. host-name/12 -- Kea-Name mit Bindestrich, NICHT "hostname", live gegen echtes Kea geprueft) -- jetzt 57 insgesamt. Standard-Optionen sind nicht mehr loeschbar (Backend lehnt es ab, UI zeigt ein Schloss-Symbol statt Loeschen-Button) -- vorher liess sich eine vorbefuellte Options- Definition versehentlich entfernen. 3. Options-Tabellen (global UND pro Reservierung) zeigen jetzt nur noch tatsaechlich genutzte Options -- eigene immer, Standard-Optionen nur mit gesetztem Wert. Weitere Standard-Optionen kommen ueber ein Dropdown "+ Option hinzufuegen" dazu statt permanent alle 57 als leere Felder zu zeigen. Das neu eingeblendete Feld wird automatisch in den sichtbaren Bereich gescrollt und fokussiert (bei bis zu 57 moeglichen Optionen kann das Feld sonst weit unterhalb des sichtbaren Modal-Ausschnitts liegen und es wirkt so, als waere nichts passiert). 4. Lease-Countdown-Fix: die Ablaufzeit wird jetzt explizit als UTC ausgewiesen (Kea arbeitet intern in UTC-Epoch) und zusaetzlich als live tickender Countdown angezeigt (gleiches Prinzip wie der bestehende "Naechste Pruefung"-Timer). Vorher wirkte eine reine Absolutzeit auf der nicht selbst aktualisierenden Seite bei den kurzen Standard-Lease-Zeiten (600s) schnell "schon abgelaufen", sobald etwas Zeit vergangen war, bis man tatsaechlich hinschaut -- live im echten Betrieb genau als dieses Missverstaendnis beobachtet und anhand der rohen Kea-CSV verifiziert, dass die richtige Spalte (expire) korrekt gelesen wird. 5. UI-Feinschliff: "In Datei schreiben" bei den Reservierungen heisst jetzt "Speichern" und ist der primaere (orange) Button, "Reservierung hinzufuegen" sekundaer -- das Hinzufuegen legt nur einen Datensatz an, erst "Speichern" schreibt die tatsaechlich wirksame Kea-Config. Alles live auf der Test-VM deployt und verifiziert (Playwright fuer die Dropdown-Sichtbarkeit/Fokus-Interaktion, curl fuer die Backend-Validierung, kea-dhcp4 -t fuer die generierte Konfiguration), keine Fehler im journalctl-Log. |
||
|
|
9885a579ea |
DHCP: Subnetze deaktivierbar + 47 verifizierte Standard-Optionen
1. Subnetze koennen einzeln deaktiviert werden (enabled-Spalte), ohne sie loeschen zu muessen -- werden dann bei "In Datei schreiben" und "Aktivieren & (neu) starten" komplett uebersprungen. Bewusst nicht als "ungueltig" gewertet (kein Fehler/keine Warnung), da eine deaktivierte Zeile absichtlich kein echtes Netz braucht. Toggle-Button in der Subnetz-Tabelle, deaktivierte Zeilen abgeblendet mit "Deaktiviert"-Pill. 2. 47 kuratierte Standard-DHCP-Optionen vorbefuellt (analog den "Predefined Options" eines Windows-DHCP-Servers) -- Router/DNS-Server/ Domain-Name/Lease-Zeiten ausgenommen, dafuer gibt es bereits eigene Felder. Alle Namen live gegen eine echte Kea-2.4.1-Instanz verifiziert: jede der 49 Kandidaten-Optionen einzeln per kea-dhcp4 -t getestet, 47 akzeptiert (2 falsch geratene Namen verworfen: nis-domain-name statt nis-domain, nisplus-domain statt nisplus-domain-name). Wichtig fuer Kea-Kompatibilitaet: Standard-Optionen bekommen KEIN eigenes option-def in der generierten Konfiguration (neue is_standard- Spalte in dhcp_option_defs) -- Kea kennt sie bereits nativ, eine Neudefinition haette die eingebaute dupliziert. Nur echte eigene/ herstellerspezifische Options bekommen weiterhin ein option-def. Live verifiziert: option-def bleibt bei gesetztem Standard-Options-Wert leer, option-data enthaelt den Wert korrekt, kea-dhcp4 -t besteht, echter Dienstneustart mit der Config erfolgreich. Einmalige Migration (Guard wie bei den anderen Schema-Migrationen) -- ein vom Admin bewusst geloeschter Standard-Eintrag wird nach einem Neustart nicht stillschweigend wieder angelegt. Ausserdem in dieser Session zuvor gefixt (siehe vorherige Commits): der falsche Kea-Schluessel lease-file->name, der jeden Dienststart blockierte, sowie der 'Jetzt pruefen'-Button, der den Topbar-Countdown nur auf dem Dashboard aktualisierte. |
||
|
|
bf9b816fa2 |
DHCP: Mehrfach-Subnetze, aktive Leases-Anzeige, Reboot-Persistenz
1. Mehrere gleichzeitige DHCP-Subnetze statt einer einzelnen globalen Range
-- ein Host kann mehrere IPs/Interfaces mit jeweils eigenem Netz haben,
fuer die alle DHCP angeboten werden soll:
- Neue Tabelle dhcp_subnets (interface, range_start/end, optionales
gateway/dns je Zeile) statt der bisherigen dhcp_interface/_range_*/
_gateway/_dns-Settings-Keys. Domain, Lease-Zeiten und Ausgabepfad
bleiben global (Kea-weit gueltig).
- Einmalige Migration: eine bestehende globale Einzel-Range wird beim
ersten Start automatisch in eine erste Subnetz-Zeile ueberfuehrt,
statt eine funktionierende Konfiguration beim Upgrade zu verlieren
(live verifiziert: bestehende 192.168.80.220-230-Range korrekt
uebernommen).
- Neue Routen add/edit/delete_dhcp_subnet, jede mit derselben
Sicherheitsregel wie zuvor: es muss eine physische IP im gewuenschten
Bereich vorhanden sein (_dhcp_matching_network je Subnetz-Zeile),
sonst wird die Aktion abgelehnt. _detect_interface_network wurde dafuer
in eine neue _detect_interface_networks (alle IPv4-Adressen eines
Interfaces, nicht nur die erste -- ein Interface kann mehrere IPs
tragen) plus einen duennen Wrapper fuer die primaere Adresse aufgeteilt.
- _render_kea_config generiert jetzt einen eigenen subnet4-Block je
Subnetz (eigenes Gateway/DNS-option-data), _dhcp_reservation_candidates
ordnet jedes Geraet anhand seiner IP dem richtigen Subnetz zu.
- "In Datei schreiben" ueberspringt inzwischen ungueltig gewordene
Subnetze einzeln (mit Warnung, welche) statt die ganze Aktion
abzubrechen; "Aktivieren & (neu) starten" verweigert den Start, falls
kein einziges gueltiges Subnetz mehr existiert.
- Live auf der Test-VM verifiziert: Anlegen/Bearbeiten/Loeschen inkl.
Ablehnung ungueltiger Ranges, generierte Kea-Config mit zwei
subnet4-Bloecken korrekt (Interface, Subnet-CIDR, Pools je Zeile).
2. Aktive Leases direkt aus Kea sichtbar (settings_dhcp.html, neue Karte)
-- macht Clients OHNE eigene Reservierung sichtbar, die sich einfach
eine freie IP aus dem Pool genommen haben, statt nur die (unvollstaendige)
Reservierungsliste zu zeigen. Liest die memfile-Lease-CSV direkt
(kein Kea-Control-Agent noetig), reserved-Flag durch Abgleich mit den
bekannten Reservierungs-MACs. Live gegen eine echte (leere)
kea-leases4.csv verifiziert.
3. DHCP-Dienst uebersteht einen Host-Neustart jetzt korrekt im zuletzt
bewusst gewaehlten Zustand: "Stoppen" deaktiviert den Dienst zusaetzlich
(nicht nur systemctl stop), sonst wuerde systemd ihn nach einem Neustart
automatisch wieder hochfahren, obwohl der Admin ihn bewusst abgeschaltet
hat. Dieselbe Ergaenzung im automatischen Netzwerkaenderungs-Stop (siehe
vorheriger Commit) -- sonst koennte ein Host-Neustart vor der
Range-Pruefung den Dienst trotzdem mit einer ggf. falschen Konfiguration
wieder starten.
|
||
|
|
9660258940 |
Fix: DHCP-Range wurde nie gegen das tatsaechliche Netz geprueft
Auf der Test-VM liess sich der Dienst mit einer gespeicherten Range (192.168.81.203-212) starten, obwohl das erkannte Netz des Interfaces 192.168.80.0/24 war -- die Range gehoerte also zu einem komplett anderen Subnetz. _dhcp_config_is_complete() prophfte bisher nur, ob Range Start/ Ende ueberhaupt ausgefuellt waren, nie ob sie zum echten Netz passen. Neue Funktion _dhcp_matching_network(interface, start, end) validiert die Range jetzt an drei Stellen: beim Speichern (save_dhcp_config), beim Schreiben der Kea-Datei (write_dhcp_file) und beim Starten des Dienstes (dhcp_service_action=enable_restart) -- jede der drei Aktionen wird mit einer genauen Fehlermeldung abgelehnt, statt eine zum Netz nicht passende Range durchzulassen. Die Pruefung beruecksichtigt dabei ALLE IPv4-Adressen des Interfaces, nicht nur die erste -- ein Interface kann mehrere IPs/Subnetze gleichzeitig tragen (Alias-IPs). Dafuer wurde _detect_interface_network() in eine neue _detect_interface_networks() (Mehrzahl, alle Adressen) plus einen duennen Wrapper fuer die primaere/erste Adresse aufgeteilt -- alle bisherigen Aufrufer (Anzeige auf der DHCP-Seite, Host-Netzwerkeinstellungen) bleiben unveraendert auf der primaeren Adresse. Echte Mehrfach-Ranges gleichzeitig (mehrere Subnetze parallel, z.B. auf verschiedenen Interfaces) sind bewusst nicht Teil dieses Fixes -- laut Ruecksprache ein separater, groesserer Umbau (DB-Tabelle statt globaler Range, mehrere subnet4-Bloecke in der Kea-Config, Listen-UI) und als naechster Schritt vorgesehen. Live auf der Test-VM verifiziert: falsche Range wird beim Speichern, Schreiben und Starten korrekt abgelehnt, eine zum erkannten Netz passende Range weiterhin akzeptiert -- keine Fehler im journalctl-Log. |
||
|
|
3195df0fd3 |
Fix: nginx blockierte SSH-Terminal-WebSocket + DHCP-Stop bei Netzwerkaenderung
Auf der frisch installierten Test-VM zeigten sich zwei weitere reale Probleme: 1. "Verbindung testen" im Switch-Modal blieb dauerhaft auf "Getrennt" haengen, sobald ueber nginx (Port 80) statt direkt gegen Flask (Port 5000) zugegriffen wurde. Ursache: etc/nginx/sites-available/poe_manager reichte den "Upgrade"/"Connection"-Header fuer /ws/ssh_terminal nicht durch -- Flask/Werkzeug lehnte den WebSocket-Handshake dadurch mit 400 Bad Request ab, statt mit 101 Switching Protocols zu antworten. Live reproduziert und verifiziert (curl-Handshake direkt vs. durch nginx). Alle bisherigen Terminal-Tests dieser Session liefen ausschliesslich direkt gegen Flask, nie durch nginx, daher bis jetzt unentdeckt. Fix: eigener location /ws/ Block mit Upgrade-Map (Standard-nginx-Pattern) und grosszuegigen Timeouts fuer die lang offene Terminal-Verbindung. 2. Der Kea-DHCP-Server lief nach einer Aenderung der Host-Netzwerkkonfiguration unveraendert weiter, obwohl die konfigurierte Range nach einem IP-/Subnetzwechsel nicht mehr zum neuen Netz passen muss. Neue Funktion _stop_dhcp_service_if_active() stoppt Kea jetzt sowohl beim Anwenden als auch beim Auto-Rollback einer Netzwerkaenderung -- bewusst nur stoppen statt automatisch neu zu starten, die Range muss der Admin aktiv auf der DHCP-Seite pruefen und den Dienst dort bewusst wieder starten (gleiche Philosophie wie beim Rest der DHCP-Dienststeuerung). Beide Fixes live auf der Test-VM verifiziert (WebSocket-Handshake per curl, Netzwerk-Reapply ohne Fehler im journalctl-Log trotz nicht installiertem Kea). |
||
|
|
2b5d9d1b48 |
Netzwerkeinstellungen: netplan/systemd-networkd als drittes Backend + DHCP-Interface-Default-Fix
Auf einer echten, frisch installierten Ubuntu-24.04-VM (192.168.80.114, Standard-Setup, Netz per DHCP) zeigten sich zwei reale Bugs: 1. Systemeinstellungen > Netzwerkeinstellungen: 'Kein unterstütztes Backend erkannt' trotz laufendem Netz -- _detect_network_backend() kannte nur NetworkManager und dhcpcd, nicht netplan/systemd-networkd, den mit Abstand haeufigsten Fall auf einem normalen Ubuntu-Host. Neues drittes Backend 'netplan' ergaenzt: Erkennung ueber systemd-networkd + vorhandenes netplan-Binary, Moduserkennung ueber das 'dynamic'-Flag des Kernels auf der aktuellen Adresse, Anwenden ueber eine eigene Override-Datei (/etc/netplan/90-poe-manager.yaml, gewinnt alphabetisch gegen z.B. cloud-inits 50-*.yaml) plus Aufruf von netplan apply, Backup/Auto-Rollback wie bei den anderen Backends. Live verifiziert: Anwenden loeste echten DHCP-Lease-Renew aus, nach Ablauf der 45s-Bestaetigungsfrist wurde die Override-Datei automatisch wieder entfernt (Rollback funktioniert). 2. DHCP-Konfiguration: 'Keine IPv4-Adresse auf eth0 gefunden', obwohl das Interface-Dropdown korrekt 'enp1s0' zeigte -- DHCP_DEFAULTS hatte 'eth0' hart kodiert (Annahme aus einer aelteren Testumgebung), was auf Systemen mit Predictable Network Interface Names schlicht nicht existiert. _load_dhcp_settings() korrigiert das jetzt: liegt der gespeicherte/Default-Wert nicht unter den tatsaechlich vorhandenen Schnittstellen, wird automatisch die erste echte vorgeschlagen. Neue Abhaengigkeit PyYAML fuer das Schreiben der netplan-Override-Datei. |
||
|
|
4d7433e832 |
Fix: SSH-Terminal-Login (No auth methods), kaputtes DOM in Bearbeiten-Modals
Quelltext-Huerde wieder entfernt (auf Wunsch) - siehe vorherigen Commit,
hier nur der Revert von initSourceProtection() und der README-Erwaehnung.
SSH-Terminal-Login war komplett kaputt (von dir gemeldet + Screenshot):
- Root Cause: das Init-Payload vom Browser enthielt nie ein Passwort,
SSHClient.connect() bekam also weder Passwort noch Key noch Agent und
scheiterte sofort mit "No authentication methods available" - noch
bevor ueberhaupt eine interaktive Passwortabfrage moeglich gewesen
waere (die High-Level-API erledigt Host-Key-Pruefung UND
Authentifizierung in einem blockierenden Aufruf).
- Fix: Umstieg auf die Low-Level paramiko.Transport-API. Nach
Host-Key-Bestaetigung wird aktiv erfragt, welche Auth-Methoden der
Server anbietet (auth_none), und bei Bedarf interaktiv ueber das
Browser-Terminal nach Passwort/keyboard-interactive-Prompts gefragt
-- genau das Verhalten, das der bestehende Hinweistext im Modal schon
immer versprach, aber nie tatsaechlich implementiert war.
Host-Key-Verifikation dabei manuell nachgebaut (_verify_host_key_interactive)
inkl. hartem Ablehnen bei GEAENDERTEM (nicht nur unbekanntem) Host-Key,
wie ein echtes ssh-CLI bei einer moeglichen MITM-Situation.
- Waehrend der Live-Verifikation gegen ein echtes Geraet zwei weitere
Bugs gefunden und gefixt: ws.receive() wirft in diesem Setup
ConnectionClosed statt None zurueckzugeben (crashte
_terminal_read_line unbehandelt -> "Invalid frame header" beim
Client); _send_and_close() crashte ebenso, wenn der Client bereits weg
war. Beide jetzt defensiv abgefangen.
- Live gegen ein echtes Zielgeraet verifiziert (Host-Key-Bestaetigung,
Passwort-Prompt, erfolgreicher Login) sowie manuell von dir bestaetigt.
Kaputtes DOM in zwei Bearbeiten-Modals (von dir gemeldet: "Verbindung
testen" oeffnete beim Switch bearbeiten kein Fenster, obwohl es beim
Neuanlegen funktionierte):
- Root Cause: <div class="modal-overlay">...</div> stand direkt in
<tbody> (nur <tr> ist dort gueltig). Browser "foster-parenten"
ungueltigen Tbody-Inhalt aus der Tabelle heraus und zerreissen dabei
teils die Eltern-Kind-Beziehung zwischen <form> und seinen Buttons --
this.closest("form") lieferte dadurch null statt des Formulars.
Betroffen: editSwitchModal (switches.html), deviceOptionsModal
(settings_dhcp.html). Fix: beide Modal-Bloecke aus der Tabelle heraus
in eine eigene Schleife direkt danach verschoben (gleiches Muster wie
die bereits korrekten Neuanlegen-Modals).
- Per DOM-Inspektion verifiziert: this.closest("form") lieferte vorher
null, danach das korrekte Formular fuer alle Zeilen; End-to-End-Test
bestaetigt, dass sich das Terminal-Modal jetzt oeffnet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
6803929140 |
Hostname-Einstellung, DHCP-Range-Pflicht, Topbar-Ampel, Text-Straffung, Quelltext-Huerde
Hostname (Systemeinstellungen, neben Pruefintervall): - hostnamectl set-hostname ueber die App, Validierung (RFC-1123-artiges Label), kein Revert-Timer noetig (kappt die Erreichbarkeit nicht wie eine IP-Aenderung). Live getestet inkl. Validierung und Revert. DHCP: Range ist jetzt Pflicht, kein geratener Default mehr: - dhcp_range_start/end/dns starten leer (Platzhaltertext statt fake- echt aussehendem Default) - ein Zufalls-Range haette den Dienst sonst unbemerkt mit einer zum echten Netz nicht passenden Konfiguration starten lassen koennen. - write_dhcp_file und dhcp_service_action=enable_restart verweigern sich ohne eingetragene Range; _render_kea_config laesst "pools" ohne Range komplett weg statt einen kaputten Pool-String zu erzeugen. - Neues, separates dhcp_gateway-Feld (optional) fuer einen vom automatisch erkannten Gateway abweichenden Router fuer die Clients. Topbar-Ampel fuer den Kea-Dienst: - Gruener/roter Punkt neben dem Pruefintervall-Timer, nur sichtbar mit settings_dhcp.view (ein einzelner, kurzer systemctl-Aufruf pro Request, nicht die volle Status-Erkennung). Live verifiziert (rot wenn gestoppt, gruen wenn gestartet). Reservierungstabelle zeigt jetzt pro Client, welche eigene DHCP-Option greift (global oder Client-Override, mit Wert im Tooltip). Text-Straffung: die laengsten Hint-Texte und Code-Kommentare in Templates/app.py gekuerzt (u.a. groups.html, settings_dhcp.html, account.html, devices/switches/users/credentials.html, zwei grosse Migrations-/DHCP-Kommentarbloecke in app.py) - Kernaussagen erhalten, Redundanz entfernt. Quelltext-Huerde (KEINE echte Sicherheit, nur Abschreckung): Rechtsklick und DevTools-/Quelltext-Shortcuts per JS blockiert. Klar dokumentiert in Kommentar + README, dass der Browser HTML/CSS/JS immer vollstaendig ausliefert und das in Sekunden umgehbar ist - echte Absicherung bleiben ausschliesslich die serverseitigen Rechteprüfungen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
82edf7628b |
Neu: Netzwerkeinstellungen des Hosts unter Systemeinstellungen (IP/DNS/DHCP)
Bisher enthielt "Systemeinstellungen" nur das Pruefintervall. Jetzt zusaetzlich Verwaltung der Netzwerkkonfiguration DIESES Hosts (getrennt vom Kea-DHCP-*Server* fuer Clients): - Backend-Erkennung (NetworkManager vs. dhcpcd via systemctl is-active). Kein erkanntes Backend -> Seite bleibt rein lesend statt zu raten. - Status-Anzeige: Interface, IP/Prefix, Gateway, DNS, Modus (DHCP/Statisch). - Aenderung: Interface, Modus, bei Statisch IP/Prefix/Gateway, DNS unabhaengig von Modus setzbar (IP per DHCP + feste DNS moeglich). - Sicherheitsnetz analog "netplan try": Backup vor jeder Aenderung, automatisches Rollback nach 45s ohne explizite Bestaetigung (nur moeglich, wenn die Seite ueber die neue Config noch erreichbar ist) -- verhindert Aussperren durch einen Tippfehler bei IP/Gateway. - Bugfix waehrend der Implementierung gefunden: der Auto-Revert-Timer laeuft in einem Hintergrund-Thread ohne Request-Kontext: log_action() griff auf current_user zu und warf dort einen AttributeError (die Config wurde trotzdem korrekt zurueckgerollt, nur der Audit-Log-Eintrag fehlte und ein Fehler landete im Server-Log). Fix: log_action_system() ohne current_user-Abhaengigkeit fuer Code ausserhalb des Request- Kontexts. - Getestet: Backend-Erkennung + rein lesender Fallback live (WSL hat weder NetworkManager noch dhcpcd aktiv, korrekt erkannt), Rechte-Gating, Anwenden-/Rollback-Logik fuer beide Backends per gemocktem subprocess.run verifiziert (inkl. echtem dhcpcd.conf-Rewrite und vollständigem Anwenden-dann-Auto-Rollback-Durchlauf mit Audit-Log- Eintrag). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
7d7239e1af |
Fix: Benutzer-Löschen im Browser kaputt (JS), Gruppen-Rechtetabelle überarbeitet
Bugfix (von dir gemeldet, live auf Port 5000 gefunden): - initConfirmables() in app.js rief beim bestätigten Absenden form.requestSubmit() OHNE den ursprünglichen Submitter auf. Laut Spec wird dann KEIN Submit-Button-Name/Value mitgeschickt. users.html trug die Benutzer-ID als name/value des Löschen-Buttons selbst (statt eines verstecken Inputs wie überall sonst) — dadurch kam "delete_user" nie im Request an, der Klick tat scheinbar nichts. Fix: e.submitter beim ersten Klick merken und an requestSubmit(submitter) weiterreichen (behebt es grundsätzlich für alle Formulare dieser Art); zusätzlich users.html auf das robustere hidden-input-Muster umgestellt wie credentials/devices/groups. Mit echtem Playwright-Browserklick (nicht nur curl) verifiziert. Gruppen-Rechtetabelle, mehrere Korrekturrunden nach deinem Mockup: - Bereichsname + Kill-Switch-Kästchen jetzt eng nebeneinander in der Tabellen-Kopfzeile (nicht mehr an den Rand gestellt), R/W/E/D-Spalten in derselben Zeile statt einer zweiten. - Nur die von einem Bereich tatsächlich genutzten Spalten werden gezeigt (GROUP_ROW_TYPES) — Logs zeigt nur R, Einstellungen nur R/W/E, nur Geräte zeigt zusätzlich D. - Bugfix: D-Spalte bei Geräte verschwand durch zu schmale Flex-Breite der Spalte im Overflow, obwohl serverseitig korrekt gerendert — behoben durch flex:0 0 auto statt fester Breite. - Checkbox-Zentrierung robust per display:block+margin:auto statt sich auf native Checkbox-Ränder zu verlassen (waren leicht asymmetrisch). - Unterpunkte deutlich weiter eingerückt (34px) für klare Hierarchie. - Sichtbares Ausgrauen (nicht nur natives disabled) der Unterpunkte, solange der Bereich-Kill-Switch aus ist (JS setzt .permission-locked). - Legende jetzt UNTER der Rechtetabelle statt darüber. - Rechte lassen sich jetzt direkt beim Anlegen einer neuen Gruppe setzen (Modal zeigt dieselbe Rechtetabelle, add_group-Route verarbeitet mitgesendete permissions[] im selben Request) statt sie erst danach über die Gruppentabelle nachzupflegen. Alles inkl. Erstellen-mit-Rechten und Bearbeiten-Regression live per Playwright verifiziert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
8e4a874943 |
DHCP: Subnet/Netzmaske/Gateway immer aus System-Netzwerkkonfiguration ableiten
- Neue Helfer _list_network_interfaces() (echte Interfaces aus /sys/class/net) und _detect_interface_network() (IPv4/Prefix per "ip addr show", Gateway per "ip route show default") — Subnet/ Netzmaske/Router werden dadurch bei jeder Anzeige/Generierung live vom System gelesen statt manuell gepflegt zu werden. - dhcp_subnet/dhcp_netmask als manuelle Settings entfernt; Interface ist jetzt ein Dropdown mit den tatsächlich vorhandenen Interfaces statt Freitext, serverseitig zusätzlich gegen die echte Liste validiert. - _dhcp_reservation_candidates()/_render_kea_config() nehmen jetzt das erkannte Netz (ipaddress.IPv4Network) bzw. net_info entgegen statt Subnet/Netzmaske aus der Konfiguration zu lesen; Router kommt vom erkannten Gateway (Fallback: erster DNS-Eintrag, wie zuvor). - UI zeigt das erkannte Netz (IP/Prefix, Subnet, Gateway) read-only an; Schreiben/Vorschau werden blockiert bzw. liefern eine leere Reservierungsliste, wenn die Erkennung fehlschlägt, statt eine mit Sicherheit falsche Konfiguration zu erzeugen. - Live getestet: Erkennung liefert korrekt das tatsächliche WSL-NAT-Netz (172.25.64.0/20) samt Gateway; generierte Config besteht kea-dhcp4 -t; ein Testgerät mit IP im erkannten Netz erscheint korrekt als Reservierung, Geräte außerhalb werden weiterhin sauber übersprungen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
c3d69a9870 |
DHCP: Backend auf Kea umgestellt, eigene Options (global + pro Client), echte Install-/Dienststeuerung
- Backend-Wechsel von isc-dhcp-server (seit 2022 EOL) auf Kea DHCP (kea-dhcp4-server) — aktiv weiterentwickelt, bildet "globaler Wert, pro Client überschreibbar" nativ über Kea-Reservation-Option-Data ab. - Neue Tabellen dhcp_option_defs/dhcp_option_values: eigene/herstellerspezifische Options mit Code/Name/Typ/Beschreibung, Wert global sowie optional pro Client (device_mac="" für global, siehe Kommentar zur SQLite-NULL- UNIQUE-Falle). UI dafür: Optionen-Tabelle + "Neue Option"-Modal + Pro-Client-Overrides-Modal je Reservierung. - Kea-JSON-Generator (_render_kea_config): option-def für jede eigene Option, globale Werte im Top-Level option-data, Client-Overrides im option-data der jeweiligen Reservierung. - Reservierungen werden jetzt zusätzlich auf Zugehörigkeit zum konfigurierten Subnet gefiltert (_dhcp_reservation_candidates) — beim Live-Test gegen echtes Kea gefunden: Kea lehnt Reservierungen außerhalb ihres Subnets als Konfigurationsfehler ab, das muss also schon bei der Generierung berücksichtigt werden statt erst beim Laden zu crashen. - Neue, einzeln bestätigte Aktionen: "kea-dhcp4-server installieren" (apt-get), "Aktivieren & (neu) starten" sowie "Stoppen" (systemctl) — bewusst getrennt von "Konfiguration speichern"/"In Datei schreiben". - Live gegen eine echte, frisch installierte Kea-3.0.3-Instanz verifiziert: Installation erfolgreich, generierte Config besteht "kea-dhcp4 -t", Dienst übernimmt sie beim Neustart fehlerfrei (DHCP4_CONFIG_COMPLETE), globaler Options-Wert und Client-Override erscheinen korrekt getrennt. Danach wieder gestoppt; Paket bleibt installiert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
9eb9cfdda6 |
Neu: DHCP-Reservierungen aus Client-Stammdaten (Systemeinstellungen -> DHCP)
- Neue Unterseite unter Einstellungen (eigenes Rechtepaar
settings_dhcp.view/settings_dhcp.edit, in PERMISSIONS/NAV_ITEMS/
_nav_key_visible integriert, Kill-Switch über settings_group.view
greift wie bei den anderen Einstellungen-Unterpunkten).
- Rein lesende Installations-/Status-Erkennung (shutil.which("dhcpd"),
systemctl is-active isc-dhcp-server) — die App installiert/startet nie
selbst einen DHCP-Dienst, sondern zeigt bei fehlender Installation den
passenden manuellen Befehl an.
- Konfigurierbare Netzwerkparameter (Interface/Subnet/Netzmaske/Range/
DNS/Domain/Lease-Zeiten/Ausgabepfad), gespeichert als dhcp_*-Schlüssel
in der bestehenden settings-Tabelle.
- Reservierungen werden aus aktiven Geräten mit gültiger MAC+IP generiert
(Hostname aus Gerätename abgeleitet, Kollisionen automatisch
durchnummeriert, Geräte ohne MAC/IP werden übersprungen).
- "In Datei schreiben" (nur mit settings_dhcp.edit) schreibt eine
separate Include-Datei statt der aktiven dhcpd.conf; kein automatischer
Dienst-Reload/-Restart durch die App.
- Live getestet: Status-Erkennung, Config speichern, Reservierungs-
Generierung inkl. Namenskollisionen, Datei-Schreiben in sicheren
Testpfad, View-only-Gating (Formular ausgeblendet, POST blockiert),
Kill-Switch über settings_group.view.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
06db4c1382 |
Switche: optionaler SSH-Port statt fest 22
- Neue Spalte switches.ssh_port (nullable INTEGER), Migration für bestehende DBs in _ensure_schema(), Feld in create_db.py ergänzt. - Formular (Anlegen/Bearbeiten): optionales SSH-Port-Feld, Validierung 1-65535, leer -> NULL (= Standard 22 überall, SWITCH_DEFAULT_SSH_PORT). Switch-Liste zeigt den effektiven Port inkl. "(Standard)"-Hinweis. - generate_ips.py liefert den effektiven Port (Fallback 22) als eigenes Pipe-Feld an poe.sh; poe.sh übernimmt es in disable_poe/enable_poe und reicht es als "ssh -p <port>" an die expect-Skripte durch (Default weiterhin 22 falls Parameter fehlt). - Web-Terminal (Verbindungstest) sendet den im Formular eingetragenen Port statt hartkodiert 22. - Live getestet: gültiger/leerer/ungültiger Port beim Anlegen, korrekte Weitergabe durch generate_ips.py inkl. Feldreihenfolge, die poe.sh 'read' erwartet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
813b17d002 |
Rechtesystem: Löschen überall in Ändern falten, Gruppen-Tabelle transponieren
- "Ändern" deckt jetzt ausnahmslos überall Löschen mit ab (auch bei Clients) — es gibt kein eigenes *.delete-Recht mehr. Betroffen: devices/switches/credentials/users/groups. - "D" in der Rechtetabelle bedeutet ausschließlich Dashboard-Neustart (devices.restart, PoE-Neustart über das Dashboard-Popup) und existiert nur bei Clients. Automatische Neustarts bei Ausfall (poe.sh) bleiben davon komplett unabhängig. - Gruppen-Rechtetabelle transponiert: Kategorien jetzt als Zeilen, Rechte R(ead)/W(rite)/E(dit)/D(ashboard-Neustart) nebeneinander als Spalten statt untereinander. Deckt sich besser mit dem Legenden-Format und braucht weniger vertikalen Platz. - Neue, einmalig laufende Migration (_migrated_permission_delete_fold_v2) überführt bestehende *.delete-Grants verlustfrei in *.edit, bevor die veralteten Rechte-Zeilen entfernt werden. - Routen (delete_device/delete_switch/delete_credential/delete_user/ delete_group) und die zugehörigen can_delete-Template-Variablen prüfen jetzt einheitlich *.edit statt *.delete. - README-Rechtesystem-Abschnitt und Legende an das neue Tabellen-Layout angepasst. - Live getestet: Kill-Switch, alle 5 Delete-Foldings (mit/ohne Recht), devices.restart-Gating unabhängig von devices.edit, Eskalationsschutz (Admin-Löschschutz, Systemgruppen-Schutz) — alles bestätigt korrekt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
4b7403f476 |
Vollständig granulares, an der Navbar gespiegeltes Rechtesystem
Kompletter Umbau des Permission-Systems weg von groben is_admin-Gates hin zu
einem zweistufigen, an die Sidebar-Struktur gespiegelten Rechtebaum:
Geräte (devices_group.view)
├─ Clients Lesen/Schreiben/Ändern/Löschen (+ PoE-Neustart)
├─ Switche Lesen/Schreiben/Ändern/Löschen
└─ Zugangsdaten Lesen/Schreiben/Ändern/Löschen (jetzt eigene Rechte,
vorher an switches.* gekoppelt)
Logs (logs_group.view)
├─ Live Lesen
└─ Änderungen Lesen
Einstellungen (settings_group.view)
├─ Benutzer Lesen/Schreiben/Ändern/Löschen
├─ Gruppen Lesen/Schreiben/Ändern/Löschen
├─ Systemeinstellungen Lesen/Ändern
└─ Im-/Export Lesen (Export)/Ändern (Import)
- User.has_permission() ist jetzt hierarchisch: das "Bereich anzeigen"-Recht
einer Top-Level-Gruppe wirkt als Kill-Switch für alle Kind-Rechte
darunter, auch wenn ein Kind-Recht einzeln noch gesetzt ist. Mit
Testgruppe verifiziert (devices.view ohne devices_group.view -> /devices
liefert 302, "Geräte" verschwindet komplett aus der Sidebar; nach
Zurücksetzen sofort wieder 200).
- devices.toggle entfällt, ist jetzt Teil von devices.edit (Ändern).
- Neue eigenständige credentials.*-Rechte statt Kopplung an switches.*.
- Benutzer- und Gruppenverwaltung sind jetzt ebenfalls granular/delegierbar
(users.*/groups.*) statt fest is_admin-exklusiv — dafür neue,
fest einprogrammierte Eskalationsschranken: Admin-Konten anlegen/ändern/
löschen sowie Admin-Zuweisung bleiben unabhängig von delegierten Rechten
echten Admins vorbehalten (mit Testgruppe verifiziert: Anlegen als Admin,
Bearbeiten/Löschen bestehender Admin-Konten und Zuweisen zu "admin"
wurden alle korrekt blockiert, normale Benutzerverwaltung funktioniert).
- "Admin" (virtuell) und "Benutzer" (Standardgruppe, neues is_system-Flag)
sind jetzt echte Systemgruppen: weder umbenennbar noch in ihren Rechten
änderbar, auch nicht durch Admins über die UI — Mitgliedschaft bleibt frei
verwaltbar. Mit direktem POST verifiziert: Umbenennen/Löschen/Rechte-Reset
von "Benutzer" werden blockiert, Mitgliederverwaltung funktioniert weiter.
- groups.html zeigt den Baum jetzt als 3 Zeilen (Geräte/Logs/Einstellungen)
mit eingerückten Unterpunkten statt einer flachen Liste von Kategorien mit
wiederholtem Bereichsnamen im Label.
- Migration in _ensure_schema() (Altrechte übertragen, neue Bereichs-Rechte
für bestehende Gruppen nachtragen) läuft jetzt über einen Einmal-Guard in
der settings-Tabelle — lief anfangs bei jedem Neustart erneut und hat
damit den Kill-Switch-Mechanismus untergraben (ein deaktiviertes
Bereichs-Recht wäre bei jedem Neustart automatisch wieder gesetzt worden,
solange irgendein Kind-Recht noch aktiv war); im Test entdeckt und behoben.
- create_db.py synchronisiert (is_system-Spalte, neuer Rechtesatz für
Frischinstallationen).
- README: Rechtesystem-Abschnitt komplett neu beschrieben (Baum, Kill-Switch,
Systemgruppen, Eskalationsschutz).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
52b14b8ef7 |
Rechtesystem-Lücke schließen: Live-Log war nur @login_required statt admin-geschützt
Vollständiges Audit aller Routen gegen das Rechtesystem durchgeführt. Die Nav-Sichtbarkeit stufte "Live" (Live-Log) bereits korrekt als admin-only ein (_nav_key_visible: logs_live -> user.is_admin), die zugehörigen Routen /logs und /get_log prüften das aber nie tatsächlich — nur @login_required. Jeder eingeloggte Benutzer, unabhängig von seinen Gruppen-Rechten, konnte das Live-Log damit direkt per URL aufrufen, obwohl die Sidebar es korrekt ausblendete. - /logs: fehlende is_admin-Prüfung ergänzt (Flash + Redirect, konsistent zu activity_log()/users()/groups()/settings()). - /get_log: fehlende is_admin-Prüfung ergänzt (403, da per AJAX abgerufen). Alle anderen neu hinzugekommenen Seiten (Benutzer, Gruppen, Systemein- stellungen, Im-/Export, Änderungslog, Jetzt-prüfen-Trigger) waren bereits korrekt und bewusst exklusiv auf is_admin geprüft — dort gibt es keine sinnvolle granularere Rechte-Stufe unterhalb von Admin (Gruppenverwaltung steuert das Rechtesystem selbst, Systemeinstellungen/Import-Export/manuelle Prüfung wirken global). Zugangsdaten bleiben bewusst an switches.*-Rechte gekoppelt (bestehende, dokumentierte Design-Entscheidung). README um eine Übersicht ergänzt, welche Bereiche bewusst ohne granulare Rechte auskommen und warum. Mit Testbenutzer ohne jede Gruppenzugehörigkeit verifiziert: /logs liefert jetzt 302 (Redirect), /get_log liefert 403 statt beide zuvor 200. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
c4f682b5de |
UI-Fixes (Button-Wrap, Suchfeld-Icon, Log-Farben, Nav-Persistenz), manueller Check-Trigger, echter Live-Refresh
- section-head: Button ("+ Neue Zugangsdaten" etc.) rutscht bei langer
Beschreibung nicht mehr in die nächste Zeile — bleibt immer rechts oben,
der Beschreibungstext wickelt stattdessen innerhalb seiner eigenen Spalte.
- Suchfeld-Icon überlappte den Platzhaltertext: eine spätere, generische
Input-Regel mit gleicher Spezifität hat die padding-left-Regel des
Lupe-Icons überschrieben (reine Reihenfolge-im-Stylesheet-Sache) — Selektor
spezifischer gemacht.
- Live-Log: Neustart-bezogene Zeilen (manueller Neustart, automatischer
PoE-Restart bei Ausfall) werden jetzt orange markiert statt farblos.
- Aufgeklappte Nav-Gruppen bleiben über Seitenwechsel hinweg erhalten
(localStorage), zusätzlich zur automatischen Aufklappung der Gruppe der
aktuell aktiven Seite.
- Datei-Auswahl (Import) im Dark Mode gestylt (Text + Button), inkl.
color-scheme-bewusster Browser-Widgets.
- Manueller "Jetzt prüfen"-Trigger (Icon neben dem globalen Timer, nur
Admins): startet rpi-check.service neu -> frisches Logfile + sofortiger
Durchlauf, Countdown synchronisiert sich auf den manuellen Zeitpunkt.
- Dashboard und Live-Log aktualisieren sich jetzt per AJAX im Hintergrund
(kein voller Seiten-Reload mehr): neue Route /dashboard/tiles liefert das
Kachel-Fragment (_dashboard_tiles.html, von index.html eingebunden und vom
Live-Update nachgeladen), get_log() liefert den aktuellen Dateinamen als
Header mit, damit die Anzeige nach einem Service-Neustart aktuell bleibt.
- Root-Cause für "Intervall bleibt immer bei 300s": in der WSL-Testumgebung
lief poe_wrapper.py nur als manuell gestarteter Hintergrundprozess statt
als echter rpi-check.service — "systemctl restart" lief dadurch ins Leere.
Echten systemd-Service in WSL eingerichtet und Intervalländerung end-to-end
verifiziert (Log-Zeilenabstand folgt jetzt dem neu gesetzten Intervall).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
0fcb6c94cb |
Topbar auf globalen Prüf-Timer reduziert, Aktionen+Beschreibung über Tabellen, sortierbare Listen
- Topbar zeigt rechts jetzt ausschließlich den "Nächste Prüfung"-Countdown, konsistent auf jeder Seite (auch anonymes Dashboard) statt nur auf dem Dashboard. Neuer Context-Processor inject_check_timer()/get_last_run_at() liefert last_run/interval global, ohne dass jede Route das selbst berechnen muss. - "+ Neu ..."-Buttons (Devices, Switches, Zugangsdaten, Benutzer, Gruppen) aus der Topbar entfernt und stattdessen in einen .section-head direkt über der jeweiligen Tabelle verschoben, zusammen mit einer kurzen Beschreibung der Seite (bisher nur bei Zugangsdaten/Gruppen vorhanden, jetzt auch bei Geräte/Switche/Benutzer). - Live-Log: eigene lokale Timer-Pill entfernt (redundant zum globalen Timer), "Aktualisieren"-Button in denselben section-head verschoben. Dashboard: Suchfeld aus der Topbar in den Seiteninhalt verschoben, lokale Timer-Anzeige entfernt (übernimmt die globale Topbar-Pill), Reload-bei- Intervallende-Logik bleibt als separater, unsichtbarer Scheduler erhalten. - Neue generische Tabellen-Sortierung (app.js: initSortableTables): Klick auf eine Spaltenüberschrift mit data-sort-key sortiert die Zeilen anhand von data-sort-<key>-Attributen. Unterstützt auch Akkordeon-Tabellen mit mehreren <tbody> (Gruppen: Haupt- + Detail-Zeile bleiben als Einheit zusammen, die virtuelle "Admin"-Zeile bleibt über data-sort-pinned immer oben). Angewendet auf Geräte, Switche, Zugangsdaten, Benutzer, Gruppen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
37dac64abc |
Live-Log-Fix, Sidebar-Untermenüs für Geräte/Einstellungen, eigenes Konto
- Live-Log-Bug behoben: _latest_log_file() sortierte nach Datei-ctime statt
nach Dateiname — auf manchen Dateisystemen (u.a. unter WSL2 auf einem
gemounteten Windows-Laufwerk) unzuverlässig und lieferte nicht immer das
tatsächlich neueste Logfile. Sortiert jetzt wie der Rest des Codes über
den chronologisch sortierbaren Dateinamen (rpi-YYYYMMDDHHMMSS.log).
- Navbar umstrukturiert in aufklappbare Gruppen mit Unterpunkten:
- "Geräte": Clients (bisherige Devices-Seite), Switche, Zugangsdaten
- "Einstellungen": Benutzer, Gruppen, Systemeinstellungen (Prüfintervall),
Im-/Export
- "Logs": Live, Änderungen (vormals Live-Log/Änderungslog)
Sichtbarkeit gilt jetzt auch pro Unterpunkt: eine Gruppe erscheint nur,
wenn mindestens ein Unterpunkt für den Benutzer sichtbar ist, und zeigt
dann auch nur die sichtbaren Unterpunkte.
- Im-/Export als eigene Unterseite mit Export/Import nebeneinander
(.settings-grid).
- Neue Seite "Mein Konto" (/account, erreichbar über ein Zahnrad-Symbol
neben dem eigenen Namen in der Sidebar) ersetzt das bisherige Profil-Modal:
Profil/Passwort/Profilbild als volle Seite, dazu für Admins die
Navbar-Reihenfolge (aus den Systemeinstellungen hierher verschoben).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
a7a23b7c12 |
Audit-Log, Import/Export, eigenes Profil & anpassbare Navigation
- Änderungslog: audit_log-Tabelle + last_modified_by/at an Devices und Switches; log_action()/touch_record() in allen Verwaltungsrouten (Devices, Switches, Zugangsdaten, Benutzer, Gruppen, Settings) verdrahtet. Neue Admin-Seite "Änderungslog" unter /logs/aenderungen. PoE-Neustarts werden bewusst nicht geloggt. - Verschlüsseltes Import/Export für Devices/Switches/Zugangsdaten unter Settings, passphrasenbasiert (PBKDF2 + Fernet), für Umzug auf neue Umgebungen. Referenziert Zugangsdaten/Switche über Name/Hostname statt interner ID für stabilen Re-Import. - Eigenes Profil: Klick auf den Namen in der Sidebar öffnet ein Modal zum Ändern von Vor-/Nachname, eigenem Passwort (mit Prüfung des aktuellen Passworts) und Profilbild-Upload (Anzeige in Sidebar + Änderungslog). - Anpassbare Navigation: Reihenfolge der Sidebar-Punkte ist unter Settings per Auf-/Ab-Buttons konfigurierbar (settings.nav_order); "Devices"/ "Users"/"Settings" umbenannt zu "Geräte"/"Benutzer"/"Einstellungen"; "Live-Log" und "Änderungslog" zu aufklappbarer "Logs"-Gruppe zusammengefasst. Jeder Benutzer sieht weiterhin nur, wofür er berechtigt ist. - create_db.py mit allen Schema-Erweiterungen synchronisiert (audit_log, last_modified_by/at, avatar_filename) für Frischinstallationen. - venv-Umgebung im WSL neu aufgesetzt (war fälschlich unter dem Erstellungspfad venv-linux verankert und daher nicht aktivierbar). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
fa6bb2935f |
Zugangsdaten-Entitaet, Gruppen-Tabelle mit Aufklappansicht, Vor-/Nachname, Dashboard-Sektionen
- Zugangsdaten (SSH-Logins) als eigenstaendige, wiederverwendbare Entitaet statt direkt am Switch; inline Neuanlage beim Switch-Erstellen moeglich; automatische Migration bestehender Switch-Logins - Gruppen-Seite als Tabelle mit Aufklapp-Zeile fuer Rechte (Akkordeon), Admin als feste Systemzeile (Mitgliederverwaltung ueber is_admin), Standardgruppe 'Benutzer' mit allen Ansichtsrechten (devices.view, switches.view), automatische Zuordnung neuer/verwaister Benutzer - Users-Seite: Icon-Buttons statt Text, Bearbeiten+Passwortaenderung in einem Modal zusammengefuehrt, Gruppe/Admin-Zuweisung ueber eigenen Zuweisen-Button (wie Switch-Zuordnung bei Devices), Vor-/Nachname - Dashboard: einheitliche Kachelansicht mit/ohne Login, drei sortierte Abschnitte (Offline/Online/Deaktiviert), Kachel-Suchfilter, Bootstrap- artiges Grid (max. 6 Spalten), Aktivieren-Option im Popup fuer deaktivierte Geraete, Countdown serverseitig korrekt geseedet - Sidebar dauerhaft einklappbar (Desktop, persistent via localStorage) - Devices-Tabelle: Aktions-Buttons nebeneinander statt untereinander Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
08d8d1f738 |
Dashboard-Kacheln, Ansichtsrechte, Standardgruppe, Countdown-Fix, Deploy-Pfad
- Dashboard zeigt jetzt in beiden Zustaenden (mit/ohne Login) Kacheln statt Tabelle; ohne Login nur aktive Geraete + Online/Offline/Gesamt, eingeloggt alle Geraete + zusaetzliche Deaktiviert-Kachel - Sortierung ueberall: erst alle Nicht-Online-Geraete, dann Online, jeweils alphabetisch - Neue Rechte devices.view / switches.view; Standardgruppe 'Benutzer' wird automatisch angelegt (alle Ansichtsrechte) und jedem neuen Benutzer zugeordnet; bestehende Benutzer ohne Gruppe werden migriert - Gruppen-Seite zeigt zusaetzlich virtuelle 'Admin'-Karte (informativ) und markiert die Standardgruppe (nicht loeschbar) - 'Naechste Pruefung'-Countdown wird serverseitig aus dem tatsaechlichen letzten Log-Eintrag geseedet statt bei jedem Reload neu zu starten - Deployment-Doku korrigiert: Checkout getrennt von /srv/poe_manager, damit kein verschachteltes srv/poe_manager/srv/poe_manager entsteht Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
82bfeb17ed |
Initial commit: PoE Manager modern UI rebuild
- Neues, eigenständiges Frontend (Sidebar, zentriertes Logo in der Topbar, Dark/Light-Theme, Karten-Dashboard, Toasts/Modals statt Bootstrap) - Oeffentliches Kurz-Dashboard ohne Login (Status-Uebersicht) - Browser-SSH-Terminal (paramiko, plattformunabhaengig) zum Testen von Switch-Zugangsdaten inkl. interaktiver Host-Key-Bestaetigung - Granulares Rechtesystem mit Gruppen (Devices/Switches-Berechtigungen) - Aufgeraeumtes Backend mit konfigurierbaren Pfaden, auto-generierten Secrets statt hart codierter Werte im Original Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |