TP45 Schicht B1 Fix: Befehlspraefix nicht doppelt rendern
Erster Lauf nach dem Einbau ergab 144/145 -- und die eine Drift war mein Fehler, nicht der des Geraets: backup_lines() strippte mit l[1:] nur das fuehrende '/', nicht den ganzen Befehl. Das gerenderte Soll enthielt dadurch `/ip dhcp-server lease ip dhcp-server lease add ...`. Gefunden hat das die Compliance-Zahl selbst. Genau deshalb ist der NENNER die Abnahme und nicht der Zaehler: 140 -> 145 beweist, dass die neue Rule auf allen fuenf Geraeten auswertet; 145/145 beweist, dass das Soll stimmt. Ausserdem: seed --force fuer einen bewussten Neuschnitt (der Guard gegen versehentliches Re-Baseline bleibt). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -46,8 +46,9 @@ Drift mehr (genau der Grund, warum `ingest-core-firewall.py` manuell bleibt).
|
|||||||
python3 nautobot/tp45-leases.py check # Soll vs. Backup-Diff
|
python3 nautobot/tp45-leases.py check # Soll vs. Backup-Diff
|
||||||
python3 nautobot/tp45-leases.py seed # Dry-Run
|
python3 nautobot/tp45-leases.py seed # Dry-Run
|
||||||
python3 nautobot/tp45-leases.py seed --apply # B1
|
python3 nautobot/tp45-leases.py seed --apply # B1
|
||||||
python3 nautobot/tp45-leases.py move TP45-B2-v30 # Dry-Run, s. MOVES
|
python3 nautobot/tp45-leases.py seed --force --apply # Neuschnitt, ueberschreibt
|
||||||
python3 nautobot/tp45-leases.py move TP45-B2-v30 --apply # B2
|
python3 nautobot/tp45-leases.py move # Dry-Run, s. MOVES
|
||||||
|
python3 nautobot/tp45-leases.py move --apply # B2
|
||||||
|
|
||||||
Token: docs/nas-vlan20/stacks/210-nautobot.yml (gitignored), NAUTOBOT_SUPERUSER_API_TOKEN.
|
Token: docs/nas-vlan20/stacks/210-nautobot.yml (gitignored), NAUTOBOT_SUPERUSER_API_TOKEN.
|
||||||
Der Wert wird nie ausgegeben.
|
Der Wert wird nie ausgegeben.
|
||||||
@@ -164,7 +165,14 @@ def backup_lines():
|
|||||||
if dev == DEVICE:
|
if dev == DEVICE:
|
||||||
cfg = r.get("backup_config") or ""
|
cfg = r.get("backup_config") or ""
|
||||||
when = (r.get("backup_last_success_date") or "?")[:19]
|
when = (r.get("backup_last_success_date") or "?")[:19]
|
||||||
return ([l[1:] for l in cfg.splitlines() if l.startswith(PREFIX)], when)
|
# 🔴 len(PREFIX), NICHT l[1:]: das Argument-Teil ist ohne den ganzen Befehl
|
||||||
|
# zu speichern — genau wie firewall_filter, wo `add action=…` steht und
|
||||||
|
# das Template `/ip firewall filter ` davorsetzt. Ein blosses l[1:] liess
|
||||||
|
# `ip dhcp-server lease add …` stehen und erzeugte im gerenderten Soll
|
||||||
|
# den Befehl DOPPELT (`/ip dhcp-server lease ip dhcp-server lease add …`).
|
||||||
|
# Gefunden am 2026-09-21 an der ersten Compliance-Zahl nach dem Einbau:
|
||||||
|
# 144/145 statt 145/145.
|
||||||
|
return ([l[len(PREFIX):] for l in cfg.splitlines() if l.startswith(PREFIX)], when)
|
||||||
raise SystemExit("kein GC-Eintrag für " + DEVICE)
|
raise SystemExit("kein GC-Eintrag für " + DEVICE)
|
||||||
|
|
||||||
|
|
||||||
@@ -217,11 +225,13 @@ def main():
|
|||||||
return
|
return
|
||||||
|
|
||||||
if cmd == "seed":
|
if cmd == "seed":
|
||||||
if soll:
|
if soll and "--force" not in argv:
|
||||||
raise SystemExit("Soll ist NICHT leer (%d Zeilen) — `seed` ist ein Re-Baseline. "
|
raise SystemExit("Soll ist NICHT leer (%d Zeilen) — `seed` ist ein Re-Baseline. "
|
||||||
"Fuer eine geplante Aenderung `move` benutzen." % len(soll))
|
"Fuer eine geplante Aenderung `move` benutzen; fuer einen "
|
||||||
|
"bewussten Neuschnitt `--force`." % len(soll))
|
||||||
new, when = backup_lines()
|
new, when = backup_lines()
|
||||||
print("== seed aus Backup %s (%d Zeilen) ==" % (when, len(new)))
|
print("== seed aus Backup %s (%d Zeilen)%s =="
|
||||||
|
% (when, len(new), " [--force, ueberschreibt %d Zeilen]" % len(soll) if soll else ""))
|
||||||
else:
|
else:
|
||||||
if not soll:
|
if not soll:
|
||||||
raise SystemExit("Soll ist leer — erst `seed` laufen lassen (Schicht B1).")
|
raise SystemExit("Soll ist leer — erst `seed` laufen lassen (Schicht B1).")
|
||||||
|
|||||||
Reference in New Issue
Block a user