# NetBox → Ansible inventory → local configuration diff

Configlane offline lab · 2026-09-07 · Python 3.10+ · standard library only

## Deutsch

Dieses Lab zeigt eine kleine, überprüfbare Übergabe vom geprüften Soll zu
Inventar und Konfigurationsausschnitten. Alle Geräte, IPs und Konfigurationen
sind erfunden. `fixture.json` wurde manuell vorbereitet; sie wurde **nicht aus
einer laufenden NetBox-Instanz exportiert**. `baseline/` enthält erfundene
Ausgangsausschnitte, keine Geräte-Backups.

Nach dem Entpacken im Verzeichnis `netbox-lab` ausführen:

```sh
python3 -B lab.py
python3 -B test_lab.py
```

Der erste Befehl erzeugt sechs Dateien unter `output/`. Der zweite prüft das
unveränderte Beispiel in temporären Verzeichnissen. Er vergleicht mit den
mitgelieferten Erwartungen und prüft gezielte Änderungen sowie Fehlerfälle.
Für einen weiteren Renderlauf ein neues Verzeichnis wählen:

```sh
python3 -B lab.py --output output/run-2
```

| Ergebnis | Erwartung |
| --- | --- |
| `output/inventory.ini` | Zwei Hosts; Gruppen nach Standort und Rolle; primäre IP ohne Präfixlänge |
| `output/candidate/sw-ber-01.cfg` | Bestehende VLANs 10 und 20 plus VLAN 30 `GUEST` |
| `output/diff/sw-ber-01.diff` | Genau die Ergänzung von VLAN 30 gegenüber `baseline/` |
| `output/candidate/sw-ham-01.cfg` | Bytegleich zum Hamburger Ausgangsausschnitt |
| `output/diff/sw-ham-01.diff` | Leer |
| `output/report.json` | `changed: ["sw-ber-01"]`, `unchanged: ["sw-ham-01"]` |

Wer Ansible bereits installiert hat, kann das Inventar zusätzlich auflisten.
Dieser Befehl kontaktiert keine Geräte:

```sh
ansible-inventory -i output/inventory.ini --list
```

Für ein eigenes Experiment `fixture.json` nach `fixture-experiment.json`
kopieren, dort nur den VLAN-Namen von `sw-ham-01` ändern und ausführen:

```sh
python3 -B lab.py --fixture fixture-experiment.json --output output/experiment
```

Der Berliner Kandidat muss gleich bleiben; Hamburg erhält jetzt ebenfalls
einen Diff. Die beigefügten Tests führen genau diese gezielte Variation aus.
Sie prüfen außerdem eine fehlende primäre IP, falsche Plattform, ungültige
VLANs, doppelte Gerätenamen, unsichere Namen und eine fehlende Freigabemarkierung.
Fehlerhafte Daten führen zu Exitcode 2, bevor ein Ausgabeverzeichnis entsteht.
Vorhandene Ausgaben bleiben erhalten. Ausgabeziele sind auf das lab-eigene
`output/` und das temporäre Systemverzeichnis begrenzt.

### Was an den Daten NetBox entspricht

`id`, `name`, `site.slug`, `role.slug`, `platform.slug` und
`primary_ip4.address` bilden einen ausgewählten Ausschnitt des Gerätemodells
ab. NetBox-Kontextdaten können frei definierte JSON-Werte tragen.
**`config_context.vlans` ist unser Lab-Schema**, keine eingebaute Liste von
VLAN-Zuweisungen eines Geräts. Die Einträge verwenden die VLAN-Felder `vid`
und `name`. `_lab` und die äußere `devices`-Liste gehören ebenfalls zum Lab;
dies ist weder ein vollständiges API-Response-Format noch ein NetBox-Importer.
Die Markierung `reviewed: true` ist nur ein lokales Beispiel für eine
Prüfvoraussetzung, kein signierter Review-Nachweis.

In einer echten Integration liest `netbox.netbox.nb_inventory` aus der
NetBox-API. Die dokumentierten Optionen `device_query_filters`, `group_by`
und `config_context: true` steuern Auswahl, Gruppen und Kontext-Hostvariablen.
Hier übernimmt eine feste Datei die Rolle der Quelle. Die erzeugten
Gruppennamen sind die Konvention dieses Labs, keine Garantie für die Ausgabe
jedes Plugin-Setups. Vor einer Integration den Vertrag mit den eingesetzten
NetBox- und Collection-Versionen prüfen; das Lab ruft das Plugin nicht auf.

### Aussage und Grenzen

Kein Netzwerkzugriff, kein SSH, keine NetBox-Verbindung, keine Zugangsdaten
und keine Geräteänderung. Es werden nur lokale Dateien erzeugt. Die
Konfiguration enthält ausschließlich Hostname und VLAN-Definitionen. Ein
Textdiff dieser Ausschnitte ist kein Geräte-Check-Mode und kein Nachweis
funktionierenden Gastzugangs. Ports, Trunks, Routing, DHCP, ACLs,
Lizenzanforderungen, Anwendungstests und vollständige Rollback-Konfiguration
sind nicht Teil des Beispiels. Die Baseline muss dieselben Gerätenamen wie
die Fixture enthalten; der Generator inventarisiert keine hinzugefügten oder
entfernten Geräte automatisch. Eigene Versuche in einer Kopie durchführen,
damit die unveränderten Erwartungen unter `expected/` nachprüfbar bleiben.

## English

This lab demonstrates a small, inspectable handover from reviewed intent to
inventory and configuration snippets. Every device, IP and configuration is
fictional. `fixture.json` was prepared by hand; it was **not exported from a
running NetBox instance**. `baseline/` contains fictional snippets, not device
backups.

After extracting, run these commands inside the `netbox-lab` directory:

```sh
python3 -B lab.py
python3 -B test_lab.py
```

The first command writes six files in `output/`. The second checks the original
example in temporary directories against the supplied `expected/` files. It
also tests targeted changes and invalid inputs. For another rendering run:

```sh
python3 -B lab.py --output output/run-2
```

Expected results: `inventory.ini` has two hosts with primary IP addresses and
site/role groups. `candidate/sw-ber-01.cfg` adds VLAN 30 named `GUEST` to VLANs
10 and 20; its diff contains that addition. The Hamburg candidate matches its
baseline byte for byte and `diff/sw-ham-01.diff` is empty. `report.json` lists
`sw-ber-01` as changed and `sw-ham-01` as unchanged.

If Ansible is already installed, list the inventory without contacting devices:

```sh
ansible-inventory -i output/inventory.ini --list
```

For an experiment, copy `fixture.json` to `fixture-experiment.json`, change
only the VLAN name on `sw-ham-01`, then run:

```sh
python3 -B lab.py --fixture fixture-experiment.json --output output/experiment
```

Berlin's candidate must stay identical; Hamburg now has a diff too. The tests
exercise this variation, missing primary IPs, an unsupported platform,
malformed VLANs, duplicate device names, unsafe names and an unreviewed fixture.
Invalid data exits with code 2 before creating output. Existing output is
preserved. Output paths are limited to this lab's `output/` directory or the
system temporary directory.

`id`, `name`, `site.slug`, `role.slug`, `platform.slug` and
`primary_ip4.address` represent a selected subset of device fields. NetBox
context data can carry arbitrary JSON. **`config_context.vlans` is our lab
schema**, not a built-in device VLAN-assignment list. Its entries use the VLAN
fields `vid` and `name`. `_lab` and the outer `devices` list are lab-specific;
this is neither a full API response nor a NetBox importer. `reviewed: true`
illustrates a local review prerequisite; it is not a signed approval record.

In a real integration, `netbox.netbox.nb_inventory` reads from the NetBox API.
Its documented `device_query_filters`, `group_by` and `config_context: true`
options control selection, groups and context host variables. This lab uses
a fixed file instead. Its group names are a lab convention, not a guarantee
for every plugin setup. Verify the contract against your deployed NetBox and
collection versions; the lab never invokes the plugin.

There is no network access, SSH, NetBox connection, credential or device write.
The script only creates local files. The configuration covers hostnames and
VLAN definitions. A text diff of these snippets is neither device check mode
nor proof of working guest access. Ports, trunks, routing, DHCP, ACLs, licensing,
application checks and complete rollback configurations are outside this lab.
The fixture must contain the same device names as the baseline; device
additions/removals are not discovered automatically. Experiment in a copy to
preserve the supplied reference expectations.

## Primary sources / Primärquellen

Opened and checked on 2026-09-07. The fixture and renderer are independently
written examples; the documentation supports the field concepts and handover.

- [NetBox introduction: desired state and human review](https://netboxlabs.com/docs/netbox/introduction/)
- [NetBox device fields and primary addresses](https://netboxlabs.com/docs/netbox/models/dcim/device/)
- [NetBox context data](https://netboxlabs.com/docs/netbox/features/context-data/)
- [NetBox VLAN fields](https://netboxlabs.com/docs/netbox/models/ipam/vlan/)
- [Ansible NetBox inventory plugin](https://docs.ansible.com/ansible/latest/collections/netbox/netbox/nb_inventory_inventory.html)
- [Ansible inventory formats, hosts and groups](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html)

The ZIP contains the Python sources, this bilingual README, the fixture,
baselines, expected results and tests. It includes no generated `output/`,
credentials or dependencies.
