Auftrag war, den nicht abschaltbaren DTU-AP von ch1 wegzubekommen, indem man den Client per access-list an ap2 bindet. Transaktion TP17.1-dtu-pin-ap2 eroeffnet, fuenf reject-Regeln auf ap1s 2,4-GHz-Interfaces deployt. Der DTU flog um 14:38:48 von ap1 und kam bei ap2 nie an. Nach 2,5 Minuten zurueckgerollt, access-list ist wieder leer. Ursache ist Christophs Verdacht und protokollseitig belegbar: SetConfig.proto kennt channel_select (Feld 9). Der eigene AP des Geraets sendet auf ch1, und ein ESP hat ein Radio -- AP und STA teilen zwingend den Kanal. ap2 laeuft auf ch11, dort kann das Geraet gar nicht assoziieren. Die Sperre hat es also nicht umgeleitet, sondern ausgesperrt. Christophs Wiederverbindungsversuch ueber S-Miles scheiterte mit genau der Meldung, die er von Frequenz-Fehlanpassungen kennt. Damit ist meine Empfehlung "AP-Kanal verschieben, indem man den Client bindet" fuer dieses Geraet widerlegt und im Text durchgestrichen. Sie gilt weiter fuer frei scannende Geraete wie die Shellys. Zwei Merkregeln festgehalten: - Ein reject auf AP A ist keine Umleitung auf AP B, sondern ein Rausschmiss. Ob das Geraet woanders unterkommt, ist seine Entscheidung. Bei fixem Kanal: nirgends. - Vor einem Pin pruefen, ob der Client den Kanal des Ziel-APs ueberhaupt benutzen kann. Der Beleg lag vor: DTU-AP auf 2412, ap2 auf 2462. Signalstaerke ist kein Nachweis fuer Assoziationsfaehigkeit -- meine Abnahme war zu lasch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Transaktionen — Teständerungen mit Ablaufdatum
Hier liegen die Akten offener und geschlossener Config-Transaktionen. Werkzeug:
nautobot/gc-transaktion.py.
Wozu
Eine Änderung, die am Gerät steht, aber nicht in der SoT, ist Drift — und Drift sieht bisher immer gleich aus, egal ob er ein Versehen ist oder ein laufender Versuch. Wer testen wollte, hatte die Wahl zwischen „Compliance kaputt" und „gar nicht testen".
Eine Transaktion macht die Absicht sichtbar, ohne die Governance aufzuweichen: der Change geht
weiterhin ausschließlich über Golden Config (gc-manual-plan.py), und die Compliance meldet den
Drift weiterhin. Neu ist nur, dass status ihn zuordnen kann.
| SQL | hier |
|---|---|
BEGIN |
Snapshot des Scope-Abschnitts + Akte mit Gerät, Scope, Grund und Ablaufdatum |
| uncommitted | Change ist am Gerät wirksam und im Testumfeld sichtbar, aber nicht in der SoT |
COMMIT |
Template/Config-Context nachziehen → Compliance grün → Akte schließen |
ROLLBACK |
Rückbau-Vorschlag aus dem Snapshot, prüfen, deployen, Akte schließen |
Drei Regeln, die das Werkzeug erzwingt
--expiresist Pflicht. Eine offene Transaktion ohne Frist ist undokumentierter Drift mit besserem Gewissen.statusmarkiert überfällige Akten.- Der Scope ist eine ComplianceRule, kein Freibrief. Driftet etwas außerhalb des Scopes, meldet
statusdas ausdrücklich als nicht abgedeckt. - Eine offene Transaktion je Gerät — sonst ist beim Rollback nicht mehr entscheidbar, wohin zurück.
Zwei bewusste Grenzen
- Der Rollback pusht nicht selbst. Er schreibt einen Vorschlag aus dem Snapshot;
add-Zeilen aus einem/exportlegen neu an, statt zu ändern, und brauchen meist einset [find …]. Ein Rückbau, den niemand gelesen hat, ist genau die Sorte Automatik, die hier schon zweimal teuer war. - Der Snapshot enthält nur den Scope-Abschnitt. Ein voller
/exportenthält Firewall, Adressen, Benutzerliste und Skriptquellen — nichts davon wird für den Rückbau gebraucht, und diese Akten liegen im Git. Für den Ernstfall gibt es das binäre/system backupauf dem Gerät (--device-backup).
Dateien je Transaktion
| Datei | Inhalt |
|---|---|
<change-id>.json |
die Akte: Gerät, Scope, Grund, Fristen, Status |
<change-id>.snapshot.rsc |
der Scope-Abschnitt vor der Änderung |
<change-id>.commands.rsc |
was deployt wurde |
<change-id>.rollback.rsc |
erst nach rollback — der Vorschlag zum Prüfen |