Import a NetBox source of truth — DCIM, IPAM, racks, cables, circuits, virtualization, tenancy, wireless, VPN and extras — keep it current with incremental sync and webhooks, reconcile drift against discovery, and write discovered truth back under governance.
Import a NetBox source of truth into Versus inventory — DCIM, IPAM, cabling and power, circuits, virtualization, tenancy, wireless, VPN, and the extras layer — then keep it current with incremental sync and webhooks, reconcile what NetBox documents against what Versus discovers, and, only when you opt in, write discovered truth back through a governed path.
Versus talks to NetBox in two distinct ways. IPAM Connections (see IPAM / DDI Integration) is a live read-through/allocate connector used by the Allocate VIP workflow step. NetBox Import — this page — is a full sync of NetBox objects into Versus's own inventory. The two coexist; a source added here never allocates addresses live.
Everything lives in the Versus Platform workspace under Integrations → Infrastructure (NetBox Import, NetBox Records, NetBox Drift), Inventory (Racks, Cabling, Cable Trace, Config Rendering), and IPAM / DDI → VLANs & VRFs.
Open Integrations → NetBox Import and click Add NetBox:
https://netbox.corp.example (Versus appends /api).Test calls NetBox's /api/status/ and records the NetBox version and object counts (sites, devices, interfaces, prefixes, IP addresses, VLANs, racks) on the source card. Connections are made directly from the Versus backend, not through a collector.
With GraphQL backfill ticked, the device pass of a full import runs as a single device_list query against NetBox's /graphql/ endpoint instead of paginated REST calls, mapped to the same shape the importer already consumes. Any GraphQL failure falls back to REST automatically, and incremental runs always use REST. The GraphQL button on a source previews the exact query Versus sends, one raw node as NetBox returns it, and the device rows it would produce — live when the source is reachable, otherwise a representative sample.
Sync now starts a progress-tracked import job — current step, per-type created/updated counts, and a log on the card. Every row is keyed on its NetBox id, so re-runs update in place rather than duplicating. The passes run in order:
cisco_nxos, an F5 VELOS becomes f5os); status, serial, primary IPv4, site, and rack position/face are mapped, and the full NetBox record (manufacturer, model, role, platform, tags, asset tag, URL) is preserved on the device.Parity-domain records are browsable in NetBox Records (one tab per domain, a searchable table per object type); devices land in Device Inventory, racks in Racks, prefixes and addresses in IPAM Networks / IP Addresses, and VLANs and VRFs in VLANs & VRFs.
NetBox tenancy is object ownership. It is imported as its own NetBox Tenant and Tenant Group records (NetBox Records → Tenancy) and is never mapped onto Versus's multi-tenant isolation — every imported row is stamped with the Versus tenant that owns the source.
Incremental on a source card pulls only objects whose NetBox last_updated is at or after the stored cursor — every list crawl is filtered server-side, so a run touches a handful of objects instead of the whole estate. The first incremental run (no cursor yet) is a full import; on success the cursor advances to the run's start time.
From the CLI, manage.py netbox_sync incrementally syncs every enabled source and is the cron hook; it respects NETBOX_SYNC_ENABLED, while --source <id> or --force runs regardless. Every run — full, incremental, or webhook — writes a sync-run audit row (mode, trigger, status, per-type counts, duration, error) available from the source's sync_runs API endpoint.
For near-real-time sync, point a NetBox event rule / webhook at:
POST https://<versus>/api/integrations/netbox/<source-id>/webhook/
The receiver stays disabled (HTTP 503) until NETBOX_WEBHOOK_SECRET is set on the Versus instance. Configure the same secret in NetBox so it signs the raw body as HMAC-SHA512 in the X-Hook-Signature header; a ?token=<secret> query parameter is accepted as a fallback. A valid call records a webhook sync-run (event and model), triggers an incremental sync of that source in the background, and returns 202; a bad signature returns 401 and an unknown or disabled source 404.
NetBox Drift compares NetBox's intent (preserved on each imported device) against what Versus actually discovers. Reconcile now runs the reconciler for one source or every enabled source and raises three kinds of finding:
| Kind | Meaning |
|---|---|
unreachable | Device is active in NetBox but Versus sees it as offline or unknown |
mismatch | An attribute differs — serial number (warning) or site (info) |
undocumented | An interface Versus discovered on a NetBox-imported device that NetBox has no record of (capped at 200 rows plus one overflow summary) |
Reconciliation is idempotent: a re-run refreshes findings in place and auto-resolves any open finding no longer observed. Filter by status, kind, or source, search by object or summary, and triage with Acknowledge, Resolve, or Ignore (a ticketed status with a ticket number is available via the API).
Inventory → Racks renders each rack's elevation with every device at its U position and face, sized by its NetBox U-height. Edit layout switches to authoring mode: create or edit racks, and place, move, or unrack devices from a palette of unracked devices. Placement is validated server-side — a device must fit within 1…U-height, and overlapping another device on the same face is rejected.
Inventory → Cabling edits the documented cable layer: label, type, color, status, length, and the A/B device and termination on each end. Inventory → Cable Trace walks that layer end to end from any device + endpoint: a cable landing on a patch-panel front port is passed through to its paired rear port and the walk continues on the next cable, up to 20 hops, returning the ordered segments, the panels crossed, both true endpoints, and whether the path completed or stopped at a dangling port, a loop, or the hop limit.
Inventory → Config Rendering mirrors NetBox's render-config pipeline. Pick a device (and optionally a template): Versus selects the active config contexts whose assignment matches the device's site, location, role, platform, tenant, or tags, deep-merges their data by ascending weight, and renders the template against the merged context plus a device fact dict — showing the applied contexts, merged JSON, and rendered output side by side. Templates render in a Jinja2 sandbox when Jinja2 is installed, falling back to Django's template engine otherwise; render errors are returned as text rather than failing the page.
Import is one-way until you opt in. Write-back pushes Versus-discovered truth to NetBox through a single fail-closed path with three gates, checked in order: the platform setting NETBOX_WRITEBACK_ENABLED, the source's writeback_enabled flag, and the source's writeback_scope allow-list. Three operations exist — create_interface, create_ip, and update_serial — and every successful write lands in the Versus audit log with actor, source, operation, and payload.
It runs from the NetBox — Write Back (governed) step in the workflow builder (category netbox: source, operation, JSON payload) or the source's writeback API action. A policy denial is a governed outcome: the step completes and reports which gate refused rather than erroring.
| Item | Detail |
|---|---|
| Pages | Integrations → NetBox Import, NetBox Records, NetBox Drift; Inventory → Racks, Cabling, Cable Trace, Config Rendering; IPAM / DDI → VLANs & VRFs |
| Auth | NetBox API token (encrypted at rest); direct from the backend, no collector |
| Import order | Sites → racks → devices → interfaces → IPAM → circuits, virtualization, tenancy, wireless, VPN, cabling & power, extras |
| Idempotency | Rows keyed on NetBox id; re-runs update in place |
| GraphQL | Optional per-source device backfill with REST fallback; GraphQL preview button |
| Incremental | last_updated cursor per source; Incremental button or manage.py netbox_sync (NETBOX_SYNC_ENABLED, --source, --force) |
| Webhook | POST /api/integrations/netbox/<id>/webhook/; HMAC-SHA512 X-Hook-Signature or ?token=; 503 until NETBOX_WEBHOOK_SECRET is set |
| Drift kinds | unreachable, mismatch, undocumented; statuses open, acknowledged, resolved, ticketed, ignored |
| Write-back gates | NETBOX_WRITEBACK_ENABLED → source writeback_enabled → op in writeback_scope; ops create_interface, create_ip, update_serial; audited |
| Cable trace | Through patch-panel front/rear ports, max 20 hops |
| Related | IPAM / DDI Integration, Device Management |