Der dritte Access-Point laeuft: 10.40.99.13 auf vlan99, Uplink ether1 -> core ether21, reiner CAP unter crs326-core, Kanaele 5180/ax/Ce/I und 2437/ax (ch6) -- am Geraet nachgemessen, nicht aus dem Plan abgeschrieben. Der Kanalplan stammt aus TP25 vom 2026-08-24; mein erster Entwurf hatte ihn neu erfunden und waere bei ch1 statt ch6 gelandet. Lehre: den TP-Body lesen, nicht nur den Quick-Index. ap1 hat bewusst KEINE Provisioning-Regel mehr: es steht bis zu seinem Umzug ans Sideboard direkt neben ap3 und wuerde auf 5180 kollidieren. Geraet bleibt erreichbar, die Objekte ch-*-ap1 / cfg-main-*-ap1 bleiben fuer den Umzug stehen. Bring-up in zwei Phasen ueber ein Patchkabel ap3 ether2 -> core ether22, weil ueber ether1 nichts ging (s.u.). Loop-Schutz: ether21 war waehrend Phase 1 abgeschaltet und wurde im selben Befehl gegen ether22 getauscht. RouterOS 7.20.8 -> 7.24.1 plus RouterBOOT (zwei Reboots, TP27-Kriterium erfuellt). Die anderen vier stehen auf 7.24 -- die Angleichung ist ein eigener Durchgang, der Core-Reboot ist ein Standort-Ausfall. Nautobot: DeviceType "cAP ax", Device ap3 mit 16 Interfaces, primary_ip4, secrets_group, ConfigContext 5g=ch36 2g=ch6 extra_ports=[]. Nebenkorrektur: ap1 stand auf "Wohnzimmer Sideboard", steht physisch aber in Technik UG (User-Bestaetigung). Sechs Funde, alle als Gotcha in CLAUDE.md und im Handoff: - ether1 ist am Werksgeraet WAN: Discovery aus, Input-TCP verworfen, ICMP aber erlaubt. Es pingt, und das liest sich wie "erreichbar". MikroMCP hilft nicht -- Port 80 ist zu. - pvid ist Ingress, tagged/untagged ist Egress. Ein Lease hing ewig auf "offered", weil der ACK getaggt rausging und ein Werksgeraet das nicht versteht. - `cap enabled=yes` reicht nicht: jedes Master-Radio braucht configuration.manager=capsman, sonst bietet der CAP seine Radios gar nicht an -- state=Ok, radio-Tabelle leer. - Ein Geraet ohne secrets_group erzeugt eine LUECKE, keine Fehlermeldung: Backup scheitert still, keine Compliance-Eintraege, Zahl bleibt unauffaellig bei 104/104. Eine gleichbleibende Compliance-Zahl nach dem Hinzufuegen eines Geraets ist ein BEFUND. - CAPsMAN verteilt keine Login-Passwoerter, nur WLAN-PSKs. Der Geraete-Login ist eine lokale DB pro Geraet; das einheitliche Admin-PW ist eine Konvention von Hand. - Firewall-Regelnummern aus `print where` sind Handles, keine Positionen. Beweis ist der Zaehler, nicht die Zahl. Abnahme: 3 CAPs state=Ok, VAP-Satz vollstaendig und running, 20 IOT-Clients auf ap3 mit 0 % Ping-Verlust ueber VLAN30 (bewusst nicht ueber die Registration-Table abgenommen), Compliance 130/130 / 0 Drifts, Core-Temp-Pfad restlos abgeraeumt. Offen: TP25-Messrunde (braucht Rundgang), PW-Rotation TP30, MikroMCP-Neustart. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nautobot-Tooling
ingest-baseline.py
Idempotenter Basisdaten-Ingest (Locations, Rollen, Device-Types, Devices, VLANs/Prefixes, ap1-Interfaces + IPs, WLAN-Modelle). Bildet den Ist-Zustand ab, nicht den Zielzustand.
export NAUTOBOT_TOKEN=... # aus docs/nas-vlan20/stacks/210-nautobot.yml (gitignored)
python3 nautobot/ingest-baseline.py # Dry-Run
python3 nautobot/ingest-baseline.py --apply # schreiben
API-Fallen (teuer gelernt)
tagged_vlansliest sich per REST alsnull, obwohl korrekt gespeichert. Verifikation nur über GraphQL:POST /api/graphql/mit{interfaces(device:"ap1"){name mode untagged_vlan{vid} tagged_vlans{vid}}}.- Relationen kommen ohne
?depth=1ohnedisplay→ ein voll gepflegtes Device sieht leer aus. LocationType.content_typesmussipam.vlangroup/ipam.vlan/ipam.prefix/dcim.controllerenthalten, sonst 400 beim Anlegen.parent_interfacenur für virtuelle Interfaces — WLAN-VAPs können ihren Master nicht als Parent tragen.WirelessNetworkhat kein VLAN-Feld; die VLAN-Bindung hängt anwireless/controller-managed-device-group-wireless-network-assignmentsund braucht zwingend einenController(bei uns logisch,controller_deviceleer — kein CAPsMAN).RadioProfile.channel_widthwill Integer ([20,40,80]), nicht"20mhz".- IP↔Interface läuft über
/ipam/ip-address-to-interface/.
ingest-wifi-access-list-rule.py
Legt ComplianceFeature + ComplianceRule wifi-access-list an (Plattform RouterOS,
match_config=/interface wifi access-list). Idempotent, Dry-Run ist Standard.
export NAUTOBOT_TOKEN=...
python3 nautobot/ingest-wifi-access-list-rule.py --apply
Warum es die Rule braucht: ohne sie erzeugen Eintraege in der access-list keinen Drift
und lassen sich nicht als Config-Transaktion fuehren -- gc-transaktion.py verlangt eine
ComplianceRule als --scope. docs/tp25-pin-s22.sh schreibt dort bei jedem Messrundgang, und
TP25 Fund E (signal-range-Boden) landet dauerhaft dort.
Der Soll-Zustand ist leer und steht als Kommentarblock [6c] im Template. Waehrend eines
Messlaufs ist der Drift erwartet und gehoert als offene Transaktion gefuehrt.