NetBox / Source of Truth
NetBox's Data Model: Sites, Devices, Interfaces, IP Addresses
What you'll learn
- NetBox's real device record shape: sites, roles, device types, platforms, primary IPs
- How custom fields attach to a device record
- The direct connection between NetBox's stored data and NAPALM's live-queried data
- Why a device record is structured, related data, not a flat inventory row
Listen to a guided explanation of this lesson.
Spoken narration isn't supported in this browser.
A device record, real and verified
{
"id": 1,
"name": "SW1",
"serial": "SW1-SN-001",
"asset_tag": null,
"site": { "id": 1, "name": "HQ", "slug": "hq" },
"device_role": { "id": 1, "name": "Switch", "slug": "switch" },
"device_type": {
"id": 1, "slug": "catalyst-3850",
"manufacturer": { "id": 1, "name": "Cisco", "slug": "cisco" }
},
"platform": { "id": 1, "name": "Cisco IOS", "slug": "cisco_ios" },
"primary_ip": { "id": 1, "address": "10.10.10.1/24" },
"custom_fields": {}
}Verified against nornir_netbox's real, installed source (Lesson 5) -- these exact fields (site, device_role, device_type.manufacturer, platform, primary_ip, custom_fields) are what a real inventory plugin actually reads.
Related records, not a flat row
A hosts.yaml row is flat: hostname, platform, maybe a group. A NetBox device record points at other records -- a site (itself a record), a manufacturer (itself a record), a platform (itself a record, with its own napalm_driver field, Lesson 5). Changing "HQ" the site once changes it everywhere it's referenced.
The connection to what NAPALM already taught
- Live queryasks the device right now
- vendor, model, serial_number, hostnamenormalized, from the device itself
- Answers: what IS this device, right now?
- Stored queryasks the source of truth
- manufacturer.name, device_type, serial, platformthe same concepts, stored and editable
- Answers: what is this device SUPPOSED to be?
Interfaces and IP addresses
# GET /api/dcim/interfaces/ (one record per physical/logical interface)
{ "id": 10, "device": { "id": 1, "name": "SW1" }, "name": "GigabitEthernet0/1", "enabled": true }
# GET /api/ipam/ip-addresses/ (one record per address, referencing an interface)
{ "id": 20, "address": "10.10.10.1/24", "assigned_object": { "id": 10, "name": "GigabitEthernet0/1" } }Verified against NetBox's documented REST schema, and confirmed executable via pynetbox against this module's own local mock backend (Lesson 3) -- real, verified output, not invented. Interfaces and IPs are their own records, each referencing the device/interface they belong to -- not embedded fields.
Custom fields: the escape hatch
For anything NetBox's built-in schema doesn't cover
custom_fields is a free-form dict on a device record -- the same escape-hatch idea as Nornir's own data: field (Phase 3.4) or NAPALM's optional_args. Site-specific metadata that isn't one of NetBox's built-in fields goes here.
Key takeaways
- A NetBox device record references other structured records (site, manufacturer, platform) -- verified against the real fields a Nornir inventory plugin actually reads.
- NetBox's stored data and NAPALM's get_facts() cover overlapping concepts (vendor, serial, model) but answer different questions: intended state vs. live state.
- Interfaces and IP addresses are their own record types, referencing what they belong to -- not flat embedded fields.
- custom_fields is NetBox's real, documented escape hatch for data outside its built-in schema -- the same idea as Nornir's data: field.