Files
bf-infra/nautobot
Christoph Emsenhuber dc639b0a55 ether3 ist Trunk, ap1 laeuft am Sideboard -- als offene Transaktion
Der Port trug keines der sieben VLANs, deshalb war ap1 nach dem Umpatchen tot.
Sieben set-Zeilen ueber gc-manual-plan.py, und der erste Deploy zeigte gleich zwei
bekannte Fallen von ihrer praktischen Seite:

Der Plan meldete Failed, und der Teilzustand war real -- sechs VLANs hatten ether3
bekommen, VLAN 40 nicht. Der Grund ist sauber: ether3 war dort UNTAGGED-Mitglied,
und ein Port kann in derselben VLAN nicht zugleich tagged und untagged sein.
Nachtrag deployt (untagged=ether2,ether4,ether5), diesmal mit --assert, und der
hat den Effekt am Geraet nachgewiesen statt dem Job zu glauben.

Ergebnis: ap1 antwortet in 447 us und traegt wieder 12 Clients (ap2: 16).

Die Aenderung bleibt bewusst UNCOMMITTED: sie steht am Geraet, nicht in der SoT,
und die Compliance meldet den Drift auf bridge-vlan. Genau so soll es sein,
solange offen ist, ob ap1 am Sideboard bleibt. Faellt die Entscheidung, wird
entweder das Template nachgezogen (commit) oder aus dem Snapshot zurueckgebaut.

Ein Bugfix im neuen Werkzeug faellt dabei gleich mit an: der Feature-Name steht
bei depth=1 nicht ausgeschrieben in rule.feature, dort kommt nur eine URL.
Verwendbar ist rule.display. Ohne das meldete status JEDEN Drift als "ausserhalb
des Scopes" -- also ausgerechnet die Zuordnung falsch, fuer die es gebaut wurde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 20:21:52 +02:00
..

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_vlans liest sich per REST als null, 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=1 ohne display → ein voll gepflegtes Device sieht leer aus.
  • LocationType.content_types muss ipam.vlangroup/ipam.vlan/ipam.prefix/dcim.controller enthalten, sonst 400 beim Anlegen.
  • parent_interface nur für virtuelle Interfaces — WLAN-VAPs können ihren Master nicht als Parent tragen.
  • WirelessNetwork hat kein VLAN-Feld; die VLAN-Bindung hängt an wireless/controller-managed-device-group-wireless-network-assignments und braucht zwingend einen Controller (bei uns logisch, controller_device leer — kein CAPsMAN).
  • RadioProfile.channel_width will Integer ([20,40,80]), nicht "20mhz".
  • IP↔Interface läuft über /ipam/ip-address-to-interface/.