NetBox feature-parity analysis¶
Purpose. Danbyte wants NetBox operators to migrate easily. That does not mean copying NetBox 1:1 — it means supporting the same ideas so a NetBox export lands somewhere without losing data or a workflow people depend on. This document maps NetBox v4.6.1's data model against Danbyte's and turns the gaps into a prioritized roadmap.
Method. Compared the full NetBox v4.6.1 schema (245 tables across
dcim,ipam,circuits,virtualization,tenancy,vpn,wireless,extras,core) against Danbyte's models inapi/models.py,core/,customization/,audit/,integrations/, andmonitoring/. Established 2026-07-02.
How to read this¶
- Status — ✅ have (parity) · 🟡 partial / concept covered differently / denormalized · ❌ missing.
- Migration priority rates how much a real NetBox export would hurt without it — i.e. would a populated NetBox instance carry rows we'd have to drop — not general feature desirability. A niche model that's rarely populated is Low even if it's "missing."
- Zero-pre-filled-data. Per
CLAUDE.md, Danbyte ships models, never data. Many NetBox "models" are thin catalogs or attributes that belong incustom_fields(JSONB) or a user-created tag, not a new table. Each section calls those out. A new model earns its keep only when other rows FK at it or behaviour hangs off it.
Executive summary¶
Danbyte is closer to NetBox than the table count suggests. The IPAM spine is at near-complete parity, and the DCIM, virtualization, wireless, and tenancy/extras cores are solid. The gaps cluster in one recurring shape: the termination / relationship layer. Danbyte tends to model the head object well (Circuit, Tunnel, Device, DeviceType) but flatten or omit the join that attaches it to the rest of the graph (circuit terminations, tunnel terminations, device component templates, console/power ports). Those are the migration blockers, because that's exactly the data a live NetBox instance is full of.
| Domain | Parity | Biggest gap |
|---|---|---|
| IPAM | ✅ Near-complete | Only asnrange + VLAN-translation (both Low, custom-field candidates) |
| DCIM | 🟡 Strong core, structural holes | Component templates on device types; console + device power ports; modular/chassis family |
| Circuits | 🟡 Head without terminations | CircuitTermination flattened to two Site FKs; no ProviderNetwork |
| VPN | 🟡 Objects without terminations | Tunnel has no TunnelTermination; no L2VPN family |
| Wireless | ✅ Core present | WirelessLink (PtP) missing |
| Virtualization | ✅ Full spine | VMInterface lacks VLAN/VRF (fields already exist on Interface); VirtualDisk |
| Tenancy | ✅ Core present | No TenantGroup / nested ContactGroup hierarchy |
| Extras / Core | 🟡 Mostly covered or divergent | ConfigTemplate binding, DataSource git-sync, CustomLink, ImageAttachment |
Crucially, several whole subsystems exist in Danbyte that NetBox doesn't have at all — native monitoring/alerting, config-drift/automation, SNMP discovery, delegated RBAC, per-tenant human IDs. Parity is not a one-way street; see Where Danbyte is ahead.
Prioritized roadmap — what we need to do¶
Grouped by migration impact. Each item links to the detailed rationale in its domain section below.
Tier 1 shipped (2026-07-02)
All four Tier-1 items below are implemented: CircuitTermination +
ProviderNetwork, TunnelTermination, console + device-power components
(with the new CableTermination endpoint arms), and the device-type
component-template layer with materialisation on device create. The
per-domain tables further down predate this and still show those rows as
gaps — read them with that in mind.
Tier 2 shipped (2026-07-03)
All five Tier-2 items below are implemented: L2VPN + L2VPNTermination,
VirtualChassis (+ Device.virtual_chassis / vc_position /
vc_priority), VMInterface L2/L3 parity (mode / untagged vlan /
tagged_vlans / vrf), TenantGroup + nested ContactGroup, and the
ConfigTemplate binding (a config_template FK on Device / DeviceRole /
Platform over ExportTemplate, resolved device → role → platform by
/api/devices/<id>/render/). The coverage rows for these models further
down have been updated to ✅; surrounding prose may still describe the
pre-Tier-2 state.
Tier 1 — Migration blockers (build first)¶
These silently drop data a typical NetBox export contains, or leave a head object unusable.
CircuitTermination+ProviderNetwork(Circuits). Today a circuit's ends are two nullableSiteFKs — port/upstream speed,xconnect_id,pp_info, cable tracing, and any provider-cloud endpoint are unrepresentable. Promote to a real termination model; addProviderNetworkso the far end can be a carrier cloud, not only a Site.TunnelTermination(VPN). ATunnelcurrently can't attach to anything — no interface, no IP. Every imported tunnel is orphaned. The sockets (Interface,VMInterface,IPAddress) already exist; this is a small model.- Console + device-power components (DCIM):
ConsolePort,ConsoleServerPort,PowerPort(device inlet),PowerOutlet(PDU outlet) — and extendCableTerminationto terminate on them. Danbyte has the upstream power half (PowerPanel→PowerFeed) but nothing at the device, so the power and console-cabling stories are half-built. - Device-type component templates (DCIM):
InterfaceTemplate,ConsolePortTemplate,PowerPortTemplate,PowerOutletTemplate,FrontPortTemplate,RearPortTemplate(+ console-server). A NetBox export is near-universally populated from the community devicetype-library; without a home for these, aDeviceTypecan't auto-stamp components onto new devices.
Tier 2 — High-value fidelity (build next)¶
L2VPN+L2VPNTermination(VPN). EVPN/VXLAN/VPWS overlay — a hard blocker for service-provider NetBox instances (Med for enterprise).RouteTargetalready exists, so the import/export-target M2M is ready to wire.VirtualChassis(DCIM). Switch stacks (StackWise/VC) are common; note Danbyte'sClusteris the VM host-group, not this. Small model + 3 fields onDevice.VMInterfaceL2/L3 parity (Virtualization). Addmode/untagged_vlan/tagged_vlans/vrf— the field definitions already exist verbatim on the deviceInterface. Best ROI in the whole set.TenantGroup+ nestedContactGroup(Tenancy). Add a self-FKparentso tenant/contact hierarchies import losslessly.ConfigTemplatebinding (Extras). Package the pieces that already exist (ExportTemplate+ConfigContext+DeviceConfigState.template) into a first-class per-device/role/platform golden-config render. Makes Danbyte's IaC loop bidirectional.
Tier 3 — Nice-to-have / lossless-import extras¶
CustomLinkandImageAttachment— small, user-authored, commonly populated in real installs (Grafana links, rack photos).VirtualDisk(multi-disk VMs) andWirelessLink(PtP backhaul).DataSource/DataFile— git/S3 sync for config-contexts & templates (GitOps). Workflow gap more than a data gap.- Generic persisted
JobandSavedFilter— operability + a landing spot for NetBox job history / saved filters. CustomFieldChoiceSet— reusable, empty-by-default choice lists (import NetBox choice sets cleanly without shipping seeded values).- Modular/chassis family —
DeviceBay,Module/ModuleBay/ModuleType,InventoryItem. Only populated on chassis/blade shops; higher build cost. - Small self-FKs:
IPAddress.nat_inside/outside, Provider↔ASN,ProviderAccount.
Deliberately skip (use tags / custom fields instead)¶
sitegroup, racktype, cablebundle, virtualdevicecontext,
inventoryitemrole, moduletypeprofile, asnrange, vlantranslationpolicy/rule,
the virtualcircuit* family, circuitgroup, script, an eventrule condition
DSL, configrevision, tableconfig, dashboard, notification/subscription,
objecttype, managedfile. These are thin catalogs, UI/config state with no
migratable row-data, or intentional architecture divergences — none earns a table
under zero-pre-filled-data.
The rest of this document is the detailed per-domain analysis the roadmap is drawn from. Each domain ends with its own coverage table and rationale.
DCIM¶
NetBox → Danbyte data-model gap analysis for the DCIM (device / rack / cabling / power) domain. Danbyte models confirmed by reading api/models.py and core/models.py. "Migration priority" rates how important a gap is for a NetBox user exporting a populated instance and expecting the data to land somewhere — not general feature desirability.
Danbyte already has a genuinely deep DCIM core: Site, Region, Location, Manufacturer, DeviceType, Device, DeviceRole, Platform, Interface (with LAG / bridge / parent-subinterface / 802.1Q access+trunk tagged_vlans M2M / per-interface VRF), first-class MACAddress, FrontPort / RearPort (patch-panel pass-through), Cable + CableTermination, Rack, RackRole, PowerPanel, PowerFeed. What it lacks is (a) the entire component-template layer on device types, (b) console and device-level power components, and © the modular-hardware / chassis family (device bays, modules, inventory items, virtual chassis).
Coverage table¶
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
site |
Site |
✅ have | High | Rich: region FK, gateway policy, VRF M2M, custom fields, tags. |
sitegroup |
— (use Region or a tag) |
❌ missing | Low | Non-geographic parallel grouping of sites. Danbyte only has geographic Region. A NetBox export may populate it, but it maps cleanly onto a tag or a second Region tree — no new model needed under the zero-pre-filled-data rule. |
region |
Region |
✅ have | High | Self-nesting tree, cycle-guarded. Parity. |
location |
Location |
✅ have | High | Self-nesting tree within a site; racks/devices/prefixes hang off it. Also absorbs legacy rackgroup (see below). |
rackgroup |
Location |
🟡 partial | Med | NetBox v4 already folded rackgroup into location; a v4.6 export won't emit rackgroup rows as a separate populated table for new data, but legacy dumps might. Map rack-group hierarchy → Location. No separate model warranted. |
rackrole |
RackRole |
✅ have | Med | Colored catalog. Parity. |
rack |
Rack |
✅ have | High | width / u_height / starting_unit / desc_units / role / status / facility_id. Dimensions are inline (see racktype). |
racktype |
— (inline on Rack) |
❌ missing | Low-Med | v4.0 reusable rack "model" (vendor, form factor, dims) that a Rack references. Danbyte carries the dims directly on Rack, which is sufficient for parity — migration just denormalises the racktype's fields onto each rack. Only recently populated in the wild. |
rackreservation |
— | ❌ missing | Low-Med | Reserves specific U ranges of a rack (for a user, with a note) without placing a device. Some ops teams use it heavily, many not at all. Populated-but-optional. |
manufacturer |
Manufacturer |
✅ have | High | Parity. |
devicetype |
DeviceType |
🟡 partial | High | Fields parity (u_height, rack_width/half-U, part_number, front/rear image). But zero component templates — see gap 1. The type itself migrates; its child *template rows do not. |
devicerole |
DeviceRole |
✅ have | High | Colored, shared by Device + VM. Parity. |
platform |
Platform |
✅ have | Med | Parity (manufacturer FK). |
device |
Device |
✅ have | High | Very rich: rack placement (position/face/rack_side half-U), airflow, geolocation, primary/secondary/oob IP, cluster, location, status, serial, asset_tag. |
interface |
Interface |
✅ have | High | LAG / bridge / parent subinterface, access+trunk mode, tagged_vlans M2M (covers the interface_tagged_vlans join table), per-interface VRF, MTU, speed. Strong parity. |
interfacetemplate |
— | ❌ missing | High | Per-device-type interface template. See gap 1. Populated on nearly every NetBox instance via the community devicetype-library. |
macaddress |
MACAddress |
✅ have | Med | First-class, interface-assigned, tenant-scoped. Parity (NetBox made MAC first-class in v4.2). |
frontport |
FrontPort |
✅ have | Med | Maps to a RearPort position. Parity. |
frontporttemplate |
— | ❌ missing | Med | See gap 1. |
rearport |
RearPort |
✅ have | Med | positions strands. Parity. |
rearporttemplate |
— | ❌ missing | Med | See gap 1. |
consoleport |
— | ❌ missing | High | Device console (management) port. See gap 2. Populated on virtually every switch/router. |
consoleporttemplate |
— | ❌ missing | High | See gaps 1 + 2. |
consoleserverport |
— | ❌ missing | Med | The other end — a terminal-server port. Populated where console servers exist. |
consoleserverporttemplate |
— | ❌ missing | Med | See gaps 1 + 2. |
powerport |
— | ❌ missing | High | Device power inlet (the device's own power draw / connection). Distinct from site-level PowerFeed. See gap 3. |
powerporttemplate |
— | ❌ missing | High | See gaps 1 + 3. |
poweroutlet |
— | ❌ missing | High | Device power outlet (a PDU's outlets, feeding downstream power ports). See gap 3. |
poweroutlettemplate |
— | ❌ missing | High | See gaps 1 + 3. |
powerpanel |
PowerPanel |
✅ have | Med | Site-level distribution panel. Parity. |
powerfeed |
PowerFeed |
✅ have | Med | Panel → rack feed, electrical characteristics, max_utilization. Parity. Note: Danbyte models power upstream of the rack (panel→feed→rack) but not at the device (port/outlet). See gap 3. |
devicebay |
— | ❌ missing | Med | Chassis bay holding a child device (blade/FEX). See gap 4. |
devicebaytemplate |
— | ❌ missing | Med | See gaps 1 + 4. |
module |
— | ❌ missing | Med | Installed module (line card, transceiver-as-module) in a modulebay. See gap 5. |
modulebay |
— | ❌ missing | Med | Slot on a device/module that holds a module. See gap 5. |
modulebaytemplate |
— | ❌ missing | Med | See gaps 1 + 5. |
moduletype |
— | ❌ missing | Med | Template for a module (like DeviceType, but for line cards). See gap 5. |
moduletypeprofile |
— | ❌ missing | Low | v4.3 schema/profile describing a module type's attributes. Rarely populated; skip until modules land. |
inventoryitem |
— | ❌ missing | Med | Non-connected physical parts (PSU, fan, SFP, CPU). See gap 6. |
inventoryitemrole |
— (could be a tag) | ❌ missing | Low-Med | Catalog of inventory-item roles. Ties to inventoryitem; could start as a tag. |
inventoryitemtemplate |
— | ❌ missing | Low-Med | See gaps 1 + 6. |
virtualchassis |
VirtualChassis |
✅ have | Med-High | Shipped 2026-07-03 (Tier 2): name / domain / master FK plus Device.virtual_chassis + vc_position (unique per chassis) + vc_priority. Master must be a member; deleting a stack releases members. Danbyte's Cluster is the VM-host analogue, not this. |
virtualdevicecontext |
— (or custom field) | ❌ missing | Low | Cisco Nexus VDC / Juniper logical-system partitioning. Rarely populated. Candidate for custom fields rather than a model. See gap 8. |
cable |
Cable |
✅ have | High | type / status / length / color / label. Parity. |
cabletermination |
CableTermination |
🟡 partial | High | Danbyte terminates on interface / front_port / rear_port only. NetBox also terminates cables on console ports, console-server ports, power ports, power outlets, and power feeds. Once gaps 2–3 land, this needs the extra FK targets + check-constraint arms. |
cablepath |
— (computed trace) | ❌ missing | Low | Internal denormalised trace NetBox recomputes; not user-authored data. Danbyte can trace live via CableTermination. Don't migrate; recompute if ever needed. |
cablebundle |
— | ❌ missing | Low | Newer bundling grouping of cables. Sparsely populated; a tag or custom field could stand in. |
M2M/join tables (interface_tagged_vlans, interface_bridge, etc.) are intentionally skipped — the only load-bearing one, interface↔tagged VLANs, is already covered by Danbyte's Interface.tagged_vlans M2M.
The biggest gaps, explained¶
Gap 1 — Component templates on device types (the structural hole)¶
The idea: In NetBox a DeviceType owns a set of component templates — InterfaceTemplate, ConsolePortTemplate, ConsoleServerPortTemplate, PowerPortTemplate, PowerOutletTemplate, FrontPortTemplate, RearPortTemplate, DeviceBayTemplate, ModuleBayTemplate, InventoryItemTemplate. Each template FKs back to the device type. When you instantiate a Device of that type, NetBox copies every template into a concrete component on the device (Interface, ConsolePort, …). So a "Cisco C9300-48P" type carries 48 interface templates + 2 power-port templates + 1 console-port template, and every device you stamp out is pre-wired.
Danbyte today: DeviceType has no child components at all. Interfaces / front ports / rear ports exist only as ad-hoc per-Device rows created by hand. There is no template → instance materialisation anywhere.
Migration parity: Medium-High as data, High as workflow. The community netbox-community/devicetype-library is near-universal, so a real NetBox export will contain these template rows — they are populated data, so a faithful importer needs a home for them. But note the distinction: the materialised device components (the actual interfaces/ports on existing devices) migrate fine as long as the target component model exists (gaps 2–6). The templates themselves matter most for the ongoing workflow of adding new devices post-migration. A pragmatic first cut: import the materialised components (high value, low model cost since Interface/FrontPort/RearPort already exist) and treat templates as a fast-follow that unlocks "add device → auto-create components."
Gap 2 — Console ports (consoleport / consoleserverport)¶
The idea: A ConsolePort is a device's serial/management console jack; a ConsoleServerPort is the terminal-server side it patches to. Both are cable-terminable components (they FK a device and can be a CableTermination endpoint), forming the out-of-band management path.
Danbyte today: Nothing. There is no console component and CableTermination can't terminate on one.
Migration parity: High. Almost every managed switch/router in a NetBox instance has a console port populated, and console-server deployments populate the server side too. This is core existing physical-inventory data, not a nice-to-have. Requires a new ConsolePort (and ConsoleServerPort) model FK'd to Device, plus a new arm on CableTermination's exactly-one-point check constraint.
Gap 3 — Device-level power (powerport / poweroutlet)¶
The idea: NetBox splits power into two layers. Upstream: PowerPanel → PowerFeed (site/rack electrical). At the device: a PowerPort is the device's power inlet (its draw), and a PowerOutlet is an outlet on a PDU device that downstream power ports plug into. A rack PDU is a Device whose PowerPort connects to a PowerFeed and whose many PowerOutlets feed server PowerPorts — a full power chain traceable through cables.
Danbyte today: It has the upstream half (PowerPanel, PowerFeed) but not the device half. So you can say "this feed delivers to this rack," but you cannot model "this server draws 2×750W from these two PDU outlets," and you cannot cable power.
Migration parity: High for power-conscious DC instances (they populate PDU outlets and server power ports densely), Medium for network-only instances. Because Danbyte already has the panel/feed half, this is an asymmetric gap that's very visible: the power story is half-built. Needs PowerPort + PowerOutlet models plus CableTermination arms (outlets/ports/feeds all become cable endpoints).
Gap 4 — Device bays (devicebay) — ✅ SHIPPED 2026-07¶
The idea: A DeviceBay is a slot in a parent chassis Device that holds a child Device — blade servers in a blade chassis, FEX in a parent switch. It's how NetBox nests a device inside another device (distinct from modules, which aren't independent devices).
Danbyte today: No parent/child device nesting exists.
Migration parity: Medium. Only populated where blade/chassis gear exists, but where it does it's essential structural data. Needs a DeviceBay (parent Device FK + installed-child Device FK) and its template.
Gap 5 — Modules (module / modulebay / moduletype) — ✅ SHIPPED 2026-07 (M1: interface templates)¶
The idea: Modular hardware. A ModuleBay is a slot; a ModuleType is a template (like DeviceType, but for a line card / supervisor / transceiver-module); a Module is an installed instance of a ModuleType in a ModuleBay. Modules can themselves carry components (a line card's ports), so a chassis's interfaces can be attributed to the specific card providing them.
Danbyte today: Nothing — all ports live flat on the Device.
Migration parity: Medium. A relatively newer NetBox subsystem; population varies (heavy for chassis-switch shops, absent elsewhere). Where absent, the flat Danbyte model already suffices. Where present, migration would otherwise flatten module-scoped components onto the device (lossy but not blocking). A four-model family (ModuleType, ModuleBay, Module, ModuleBayTemplate), so higher build cost — reasonable to defer behind gaps 1–3.
Gap 6 — Inventory items (inventoryitem / inventoryitemrole) — ✅ SHIPPED 2026-07 (roles = tags)¶
The idea: InventoryItem records physical parts that aren't cable-connected components — PSUs, fans, CPUs, discrete SFPs, memory. They're a self-nesting tree on a device (a card containing sub-parts), each with serial / part-id / manufacturer and an optional InventoryItemRole catalog.
Danbyte today: Nothing. There's no place for a serial-tracked sub-part.
Migration parity: Medium. Populated by asset-tracking-focused and automation-fed (NAPALM/discovery) instances, empty in many others. A single InventoryItem model (self-FK tree + device FK + optional role) covers most of it; inventoryitemrole could initially be a tag under the zero-pre-filled-data rule.
Gap 7 — Virtual chassis (virtualchassis)¶
The idea: A VirtualChassis groups several physical Devices (stack members, each with a position + priority) into one logical switch — a Juniper VC / Cisco StackWise stack. Members share a control plane and are often managed as one.
Danbyte today: No equivalent. Important: Danbyte's Cluster is not this — Cluster is the virtualization host-group for VMs. Physical switch stacking has no home.
Migration parity: Medium-High. Access-layer switch stacks are common, so many NetBox instances populate this. Modelled as a small VirtualChassis (name + master Device FK) plus two fields on Device (virtual_chassis FK, vc_position, vc_priority) — low build cost for the parity it buys.
Gap 8 — Virtual device contexts (virtualdevicecontext)¶
The idea: A VirtualDeviceContext (VDC) partitions one physical device into multiple logical devices (Nexus VDCs, Juniper logical systems), each able to own interfaces and a primary IP.
Danbyte today: Nothing.
Migration parity: Low. Rarely populated (niche hardware feature). Strong candidate to not become a model — under Danbyte's zero-pre-filled-data philosophy a VDC could be expressed as a custom field / tag on interfaces, or deferred indefinitely. Only build it if a migrating customer actually has VDCs.
Philosophy note (zero-pre-filled-data)¶
Several NetBox "models" are really catalogs or groupings and, per CLAUDE.md, should lean on tags / custom fields rather than new tables unless behaviour depends on them:
sitegroup→ a tag or a secondRegiontree (no behaviour attached).inventoryitemrole→ start as a tag; promote to a model only if coloring/roll-ups are needed.virtualdevicecontext→ custom fields on interfaces before a dedicated model.cablebundle→ a tag on cables.racktype/moduletypeprofile→ templates/denormalisation, not user-seeded catalogs.
Conversely, the genuinely structural gaps (console ports, device power ports/outlets, device bays, modules, virtual chassis, and the component-template layer) cannot be tags/custom fields — they carry FKs, cable terminations, and instantiation behaviour, so they need real models.
Summary + HIGH-priority list¶
Danbyte's DCIM core is already strong on the IPAM-adjacent layer — sites/regions/locations, device types, devices, a feature-rich Interface, MAC-as-object, patch-panel front/rear ports, cabling, racks, and the upstream half of power (panel→feed). The parity gaps cluster in three areas: (1) the component-template layer on device types is entirely absent, so device types can't auto-stamp components; (2) console and device-level power components (ports/outlets) don't exist, leaving cabling and the power chain half-modelled; and (3) the modular / chassis family (device bays, modules, inventory items, virtual chassis) is missing, so blade/stack/line-card hardware can't be represented. CableTermination will also need new endpoint types once console/power components land.
HIGH-priority missing models for migration parity:
consoleportconsoleserverportpowerport(device power inlet)poweroutlet(PDU outlet)- Component-template layer:
interfacetemplate,consoleporttemplate,consoleserverporttemplate,powerporttemplate,poweroutlettemplate,frontporttemplate,rearporttemplate(populated ~universally via the community devicetype-library) virtualchassis(borderline High — common switch stacks; note DanbyteClusterdoes not cover it)- Extend
CableTerminationto terminate on console ports, power ports, power outlets, and power feeds
IPAM¶
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
aggregate |
Aggregate |
✅ | High | FK → RIR, prefix CIDR, date_added. utilisation_pct computed. Full parity. |
asn |
ASN |
✅ | High | 32-bit asn, FK → RIR, M2M → Site. Parity. NetBox also links ASNs to Providers via provider_asns M2M — Danbyte has no Provider↔ASN link (see Circuits). |
asnrange |
— | ❌ | Low | No ASNRange. NetBox models a named span (start–end, FK→RIR) that auto-suggests the next free ASN. Pure provisioning convenience; individual ASN rows still carry the real data. |
fhrpgroup |
FHRPGroup |
✅ | Med | protocol/group_id/auth, optional virtual_ip FK. Parity. |
fhrpgroupassignment |
FHRPGroupAssignment |
✅ | Med | FK → FHRPGroup, and to Interface or VMInterface (NetBox uses a generic FK to any interface type — Danbyte's two explicit FKs cover the same real targets). |
ipaddress |
IPAddress |
✅ | High | Rich: VRF, prefix, site, status, role, NAT-less but assigned_device/assigned_interface/assigned_vm/assigned_vm_interface. No nat_inside/nat_outside self-FK — NetBox 1:1 NAT mapping is absent (🟡 sub-gap, Med). |
iprange |
IPRange |
✅ | High | start_address/end_address, VRF, status, role, size/family computed. Parity. |
prefix |
Prefix |
✅ | High | VRF, status, vlan, site, location; utilisation_pct, is_enumerable. NetBox is_pool/mark_utilized booleans not present (🟡, Low — custom-field candidates). |
rir |
RIR |
✅ | High | is_private flag present. Parity. |
role (IP/prefix role) |
IPRole |
✅ | High | Subclass of _LabeledChoice (name/slug/color/weight). Parity. |
routetarget |
RouteTarget |
✅ | High | name (RT string), tenant-scoped. Parity. |
service |
Service |
✅ | Med | name/protocol/ports(JSON), attached to Device or VM, optional ip_address. Plus Danbyte's monitoring-check hook. Parity+. |
servicetemplate |
ServiceTemplate |
✅ | Med | name/slug/protocol/ports. Parity. |
vlan |
VLAN |
✅ | High | vid, name, tenant, site, group FK, status, role. Parity. |
vlangroup |
VLANGroup |
✅ | High | Scope to site or cluster, VID range. NetBox 4.x allows a broader scope set (region/location/rack/cluster-group) via generic FK — Danbyte covers the two common scopes (🟡, Low). |
vlantranslationpolicy |
— | ❌ | Low | No model. A named container of translation rules, referenced from an interface. |
vlantranslationrule |
— | ❌ | Low | No model. (policy, local_vid → remote_vid). Q-in-Q / carrier-edge feature; rarely populated in a typical export. |
vrf |
VRF |
✅ | High | rd, enforce_unique, import_targets + export_targets M2M → RouteTarget both present (models.py L173/180). Full L3VPN parity. |
IPAM key gaps and their idea / FK interconnection¶
-
ASN range (
asnrange) — idea: a named, RIR-scoped[start, end]span from which individual ASNs are allocated, mirroring howIPRangesits overIPAddress. FK shape is trivial:tenant,rirFK, two integer bounds. It exists purely so the UI can offer "next available ASN." Migration parity: low — a NetBox export rarely hasasnrangepopulated (most orgs manage a handful of ASNs directly), and the childASNrows migrate fine without it. Nice-to-have, not a migration blocker. -
VLAN translation policy + rule — idea: on a service-provider edge you re-map a customer's local VLAN ID to a different VID on your side.
VLANTranslationPolicyis a named bag;VLANTranslationRuleholds(policy FK, local_vid, remote_vid)unique per policy; anInterfacepoints at the policy viaqinq_svlan/vlan_translation_policyFK. Migration parity: low — only carrier / metro-E deployments use it; the vast majority of NetBox exports have zero rows. If a migrating org needs it, the translation map is a strong custom-field / JSONB candidate onInterfacerather than two new tables (aligns with zero-pre-filled- data: no new model earns its keep for a feature most tenants never touch). -
IP NAT mapping (sub-gap on
ipaddress) — NetBox'snat_inside/nat_outsideself-referential FK pair onIPAddressis absent. Idea: a 1:1 (or 1:many) link between an inside and outside address. Migration parity: medium — real, and it is present in exports where NAT is documented, but it's a single self-FK, cheap to add later. Could be acustom_fieldsreference short-term, but a proper self-FK is the clean answer if NAT docs matter to the migrating org.
Verdict: Danbyte's IPAM is at near-complete parity. The only true model-level holes are asnrange and the
VLAN-translation pair — all three are low-priority, low-population, and two of them are better served by
custom fields than new tables.
Circuits¶
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
provider |
Provider |
✅ | High | name/slug/account/portal/NOC contacts. Parity for the core record. |
circuittype |
CircuitType |
✅ | High | name/slug/color, user-defined (zero pre-fill). Parity. |
circuit |
Circuit |
🟡 | High | cid, provider, type, status, install/termination dates, commit_rate_kbps. But terminations are denormalized — see below. |
circuittermination |
(folded into Circuit.termination_a_site / termination_z_site) |
🟡 | High | Danbyte stores only two nullable Site FKs on the Circuit itself. No standalone termination model. Loses: per-side port_speed/upstream_speed, xconnect_id, pp_info, patch-panel/interface attachment, cable-tracing, and termination to a ProviderNetwork instead of a site. See prose. |
provideraccount |
(folded into Provider.account — single string field) |
🟡 | Med | NetBox 4.x promoted account to its own model (a provider can have many accounts, each circuit references one). Danbyte has one free-text account on Provider. |
providernetwork |
— | ❌ | High | No model. The "far end" of a circuit that isn't your own site (provider cloud, IX fabric, another carrier). Without it, a circuit's Z-side to a provider cloud cannot be represented. |
circuitgroup |
— | ❌ | Low | Named grouping of circuits (e.g. for diversity/redundancy tracking). |
circuitgroupassignment |
— | ❌ | Low | M2M-with-priority join of Circuit↔CircuitGroup (priority: primary/secondary/tertiary). |
virtualcircuit |
— | ❌ | Low | Overlay circuit riding physical circuits (EVPN/pseudowire era feature, NetBox 4.1+). |
virtualcircuittermination |
— | ❌ | Low | Endpoint of a virtual circuit, bound to an interface. |
virtualcircuittype |
— | ❌ | Low | User-defined classification for virtual circuits. |
(NetBox provider_asns M2M) |
— | ❌ | Med | No Provider↔ASN link. NetBox associates a provider's public ASNs; Danbyte's ASN has no providers relation. |
Circuits key gaps and their idea / FK interconnection¶
-
Circuit terminations (
circuittermination) — the critical structural gap. In NetBox aCircuitowns twoCircuitTerminationrows (term_side= A / Z). Each termination is a first-class object that: (1) FKs to either aSiteor aProviderNetwork(termination_typegeneric FK) — so one end can be your DC and the other a carrier cloud; (2) carriesport_speed,upstream_speed,xconnect_id,pp_info,description; and (3) is a cable termination endpoint — you can patch it into a device interface / patch panel and trace the physical path. Danbyte instead flattens this to twoSiteFKs directly onCircuit(termination_a_site,termination_z_site, bothSET_NULL). The model comment even says "kept on the circuit for a simple, immediately-useful model." Consequences for migration: a NetBox export's termination speeds, cross-connect IDs, patch-panel info, and any Z-side terminating on a provider network are dropped or unrepresentable. This is the single highest-value circuits gap. Migration parity: HIGH —circuitterminationis almost always populated in a NetBox export (it's how a circuit becomes useful), and the flattened site FKs can't hold the port-speed / xconnect / provider-network data. Recommend promoting to a realCircuitTerminationmodel (circuitFK,term_side,siteFK orprovider_networkFK, speeds, xconnect_id, pp_info) and, if physical tracing is wanted, wiring it into the existingCableTerminationmachinery. -
Provider networks (
providernetwork). Idea: represents the far side of a circuit that you don't own — an ISP's cloud, an internet exchange fabric, another carrier's network. FK:provider+ name. It exists so a circuit termination has something to point at when the Z end isn't a Site. It is therefore tightly coupled to the termination gap above — fixing terminations properly requires this model to exist. Migration parity: HIGH for any org with internet/transit circuits (the Z side is a provider cloud, not a site). Not a custom-field candidate — it's a referenced entity with its own identity. -
Provider accounts (
provideraccount). Idea: NetBox 4.x split "account" off Provider into its own model so one provider can hold multiple billing accounts, and each circuit references a specific one (Circuit.provider_accountFK). Danbyte keeps a singleaccountstring onProvider. Migration parity: medium — exports from NetBox ≥3.5 will have provider-account rows, but most orgs have exactly one account per provider, so the single string covers the common case. Promote to a model only if multi-account providers appear in the source data; otherwise the current field (or acustom_fieldsentry for extra accounts) is adequate. -
Circuit groups + assignments (
circuitgroup/circuitgroupassignment). Idea: group circuits for redundancy/diversity reporting; the assignment join carries apriority(primary/secondary/tertiary). FK shape:CircuitGroupAssignment(circuit FK, group FK, priority). Migration parity: low — newer (4.1+) and lightly used; many exports have none. The grouping itself is a reasonable tag use (aredundancy-group:xxxtag), though the per-memberprioritydoesn't fit a tag cleanly. Low priority. -
Virtual circuit set (
virtualcircuit,virtualcircuittermination,virtualcircuittype). Idea: an overlay service (EVPN / pseudowire / VXLAN tunnel-style) that rides one or more physical circuits; terminations bind to device interfaces rather than sites. Introduced in NetBox 4.¼.2. Migration parity: low — very few deployments populate these yet; a typical NetBox export will have them empty. Defer until a migrating org actually has virtual-circuit data. -
Provider ↔ ASN (
provider_asns). NetBox links a provider's public ASNs via M2M. Danbyte'sASNalready has an M2M toSitebut none toProvider. Migration parity: medium — populated when providers' ASNs are documented. Cheap to add (one M2M onASNorProvider); until then it's expressible via a custom field or tag.
Verdict: Circuits is where the real gaps are. Circuit/CircuitType/Provider exist, but the termination
model is flattened into two Site FKs, which — together with the missing ProviderNetwork — is the dominant
parity problem: it silently drops port speeds, cross-connect IDs, and any provider-cloud endpoint that a NetBox
export will contain. The virtual-circuit and circuit-group families are low-priority (new, rarely populated).
Zero-pre-filled-data alignment notes¶
Per CLAUDE.md, prefer custom fields / tags over new models where the NetBox concept is thin or rarely populated:
asnrange,vlantranslationpolicy/rule,virtualcircuit*— low-population, specialized. Where an org does need translation maps, a JSONBcustom_fieldsmap onInterfacebeats two new tables.circuitgroupmembership maps naturally onto tags (redundancy:site-a-diverse); only the per-assignmentpriorityargues for a model.provideraccount— single account already covered byProvider.account; extra accounts fit a custom field unless multi-account is common in the source.providernetworkandcircuitterminationare the exceptions — they are referenced entities with identity and FKs pointing at them, not attributes. These earn real models; a custom field cannot serve as an FK target.
HIGH-priority missing / deficient models (migration blockers)¶
CircuitTermination— currently flattened toCircuit.termination_a_site/z_site(two Site FKs). Loses port speeds, upstream speed, xconnect_id, pp_info, cable tracing, and provider-network endpoints.ProviderNetwork— no model; without it a circuit's far end can only be a Site, so transit/internet circuits (Z = provider cloud) can't be represented. Prerequisite for fixing terminations.
(Medium: ProviderAccount, Provider↔ASN link, IPAddress NAT self-FK. Everything else is Low.)
VPN¶
Danbyte has: TunnelGroup, IPSecProfile, Tunnel. It does not have any tunnel-termination
model, any of the four IKE/IPSec proposal+policy models, or any L2VPN model.
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
tunnelgroup |
TunnelGroup |
✅ | — | Tenant-scoped, slug-unique. Direct match. |
tunnel |
Tunnel |
🟡 | — | Present with encapsulation, tunnel_id, group, status, and an ipsec_profile FK. But it has no terminations (see below), so a Danbyte tunnel is a floating object — it is not attached to any interface, VM interface, or IP. |
tunneltermination |
(none) | ❌ | High | NetBox binds each tunnel end to a device Interface or a vminterface (GenericForeignKey termination), with a role (peer/hub/spoke) and an outside_ip. Without this, imported tunnels lose both endpoints. This is the single biggest VPN gap. |
ipsecprofile |
IPSecProfile |
🟡 | Med | Danbyte flattens the whole crypto stack into one record: ike_version, encryption, authentication, dh_group, pfs_group, sa_lifetime. NetBox instead composes a profile from an ipsecpolicy + an ikepolicy + a mode. The idea is covered; the shape is a lossy denormalization (see chain discussion). |
ikepolicy |
(folded into IPSecProfile) |
🟡 | Med | NetBox: an IKE policy = a version + mode (main/aggressive) + an ordered set of ikeproposals + optional preshared key. Danbyte captures ike_version only; no mode, no PSK, no proposal ordering. |
ikeproposal |
(folded into IPSecProfile) |
🟡 | Med | NetBox Phase-1 proposal = authentication_method + encryption_algorithm + authentication_algorithm + group (DH) + sa_lifetime. Danbyte collapses this to single encryption/authentication/dh_group fields — only one proposal per profile, no auth-method (PSK vs certs). |
ipsecpolicy |
(folded into IPSecProfile) |
🟡 | Med | NetBox IPSec policy = ordered ipsecproposals + a PFS group. Danbyte has pfs_group but no proposal set. |
ipsecproposal |
(folded into IPSecProfile) |
🟡 | Med | NetBox Phase-2 proposal = encryption + auth + sa_lifetime_seconds + sa_lifetime_data. Danbyte has sa_lifetime (seconds only), no data-based lifetime, one proposal only. |
l2vpn |
L2VPN |
✅ | High (for service providers) / Med (enterprise) | Shipped 2026-07-03 (Tier 2): type (vxlan, vxlan-evpn, mpls-evpn, pbb-evpn, vpws, vpls, epl, evpl, spb, trill), identifier (VNI/VC-ID), import_targets/export_targets M2M → RouteTarget, status, tags + custom fields. |
l2vpntermination |
L2VPNTermination |
✅ | High (SP) / Med | Shipped 2026-07-03 (Tier 2): attaches an L2VPN to a VLAN, an Interface, or a VMInterface — exactly one, check-constrained (explicit FKs instead of NetBox's GFK); each endpoint terminates at most one L2VPN. |
Key VPN gaps — the idea and the FK interconnection¶
The IKE/IPSec proposal → policy → profile chain. NetBox models crypto as a four-level composition so that the reusable primitives (proposals) can be mixed into multiple policies, and policies into multiple profiles:
ikeproposal ─┐ ipsecproposal ─┐
├─(M2M, ordered)→ ikepolicy ├─(M2M, ordered)→ ipsecpolicy
┘ │ ┘ │
└──────→ ipsecprofile ←─────────────────────┘
│
tunnel.ipsec_profile
Danbyte's IPSecProfile is a deliberate flattening of that entire tree into one row (its own
docstring says "flattens the common IKE + IPSec policy parameters into one named record"). For the
common single-proposal, IKEv2-PSK site-to-site tunnel this is genuinely nicer UX. The migration
cost is real but bounded: a NetBox profile with one IKE proposal and one IPSec proposal maps
cleanly onto Danbyte's fields; a profile that offers multiple proposals (a negotiation set) or
uses certificate auth cannot round-trip — you lose all but the first proposal and the auth-method
distinction. Recommendation: keep the flat IPSecProfile as the default UX, but add optional
ike_proposals/ipsec_proposals JSONB arrays (or child rows) to preserve multi-proposal sets on
import. Don't build the full 4-model NetBox tree unless SP customers demand it — it fights the
"one named record" ergonomics. Parity importance: Med — most enterprise tunnels are single-proposal.
Tunnel terminations (❌ High). This is the concrete blocker. In NetBox a tunnel is inert until
it has tunneltermination rows binding each end to an Interface or vminterface, tagging the
role (peer / hub / spoke), and recording the outside_ip (the underlay/public IP) — the tunnel's
inside IPs then attach to the terminating interface normally. Danbyte's Tunnel has an
ipsec_profile FK but no way to say where the tunnel lands. Danbyte already has all the sockets
this needs (Interface, VMInterface, IPAddress with assigned_interface/assigned_vm_interface),
so the fix is a small TunnelTermination model with a tunnel FK + a nullable interface/
vm_interface pair (mirroring the existing CableTermination GFK-avoidance pattern in this codebase)
+ role + outside_ip FK to IPAddress. This is the highest-value VPN addition.
L2VPN + terminations (❌ High for SPs). This is the EVPN/VXLAN/VPWS/VPLS overlay layer — the
reason a service provider runs NetBox at all. RouteTarget already exists in Danbyte, so the import/
export-target M2M is ready to wire; what's missing is the L2VPN object (type + VNI/VC identifier +
RT M2M) and L2VPNTermination (attach to VLAN / Interface / VMInterface). For an enterprise-only
deployment this is Med; for anyone migrating an SP NetBox instance it is a hard blocker and ranks
High.
Wireless¶
Danbyte has: WirelessLANGroup, WirelessLAN. It does not have wirelesslink.
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
wirelesslangroup |
WirelessLANGroup |
✅ | — | Tenant-scoped, slug-unique, self-documented "zero pre-filled data". Direct match. NetBox's group is self-nesting (tree); Danbyte's is flat — minor gap. |
wirelesslan |
WirelessLAN |
🟡 | Low | Strong coverage: ssid, group, status, vlan, auth_type, auth_cipher, description, comments. NetBox adds auth_psk (the pre-shared key secret) and a scope GFK (region/site/location the SSID applies to). Danbyte lacks both, but the core object is here. |
wirelesslink |
(none) | ❌ | Med | A point-to-point wireless link between two device interfaces (interface_a/interface_b), with ssid, status, distance, and auth_*. It is the wireless analogue of a Cable between radios (PtP backhaul / bridge). Danbyte models wired links via Cable/CableTermination but has no wireless-link peer. |
Key Wireless gaps¶
Wireless links (❌ Med). NetBox's wirelesslan (an SSID/broadcast domain) and wirelesslink
(a PtP radio link between two interfaces) are two different concepts; Danbyte implemented the first
and skipped the second. A WirelessLink would sit alongside Cable — two Interface FKs
(interface_a, interface_b) plus ssid/status/distance/auth_*. Parity importance Med:
WISPs and campus backhaul users rely on it, but the average IPAM user tracks SSIDs, not radio links.
Cheap to add and structurally identical to the existing Cable two-ended pattern.
Secondary gaps (Low): auth_psk on WirelessLAN — hold to Danbyte's secrets-at-rest handling
(it already encrypts secrets per commit 30b49be); and the scope GFK (which site/region an SSID
covers) — probably better expressed as a site/region FK than a GFK given Danbyte's style.
Virtualization¶
Danbyte has: ClusterType, ClusterGroup, Cluster, VirtualMachine, VMInterface. It does
not have virtualdisk or virtualmachinetype.
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
clustertype |
ClusterType |
✅ | — | Tenant-scoped, slug-unique. Direct match. |
clustergroup |
ClusterGroup |
✅ | — | Direct match. |
cluster |
Cluster |
✅ | — | tenant, type, group, site, status, description. NetBox 4.x also allows a cluster scope (site or location) and a set of member host devices via a device.cluster back-ref; Danbyte pins VM→host via VirtualMachine.device instead, and scopes cluster to site only. Functionally equivalent. |
virtualmachine |
VirtualMachine |
✅ | — | Rich: cluster, role, platform, host device, site, status, vcpus, memory_mb, disk_gb, primary_ip. Monitorable. Matches NetBox well. Missing primary_ip6 split (Danbyte uses one primary_ip), no serial. Minor. |
vminterface |
VMInterface |
✅ | Med | Has vm, name, enabled, mac_address, mtu, description, and IPs attach via IPAddress.assigned_vm_interface. Shipped 2026-07-03 (Tier 2): now also carries the device-Interface L2/L3 context — mode (access / tagged / tagged-all), untagged vlan, tagged_vlans M2M, vrf. Remaining minor gap: no parent/bridge nesting. |
vminterface_tagged_vlans (M2M) |
VMInterface.tagged_vlans |
✅ | Med | Shipped 2026-07-03 (Tier 2) as part of the VMInterface L2/L3 parity work above. |
virtualmachinetype |
(none) | ❌ | Low | NetBox 4.6 added VM "types" (manufacturer + model template for VMs, mirroring DeviceType). Danbyte has no VM-type object; VM sizing is entered directly on the VM. Marginal — introduced late in NetBox and lightly used. |
virtualdisk |
(none) | ❌ | Med | NetBox breaks VM storage into named disks (name, size per disk) as child rows, superseding the single disk scalar. Danbyte keeps only a single disk_gb integer on the VM. Multi-disk VMs flatten to one number on import — lossy but not blocking. |
Key Virtualization gaps¶
VMInterface parity with device Interface (❌ Med — the headline VM gap). Danbyte's VMInterface
is intentionally minimal (name, enabled, mac_address, mtu, description). A real VM NIC in
NetBox carries L2/L3 context: mode (access/tagged), untagged_vlan, tagged_vlans (M2M),
vrf, and parent. Danbyte already defines all of these on the device Interface (lines 936–986)
— the fields and choice sets exist and could be lifted onto VMInterface almost verbatim. Until
then, a NetBox VM interface that trunks VLANs or lives in a VRF loses that data on import. Parity
importance Med: VLAN-tagged VM interfaces are common in virtualized DCs. Because the exact same
field definitions already exist on Interface, this is a low-effort, high-value alignment — arguably
the best ROI item in the whole virtualization set.
Virtual disks (❌ Med). NetBox moved from a single disk scalar to child virtualdisk rows so
a VM can list several named disks with individual sizes; VirtualMachine.disk becomes the derived
sum. Danbyte still has the flat disk_gb. Importing a multi-disk VM collapses all disks to one
total — data loss, not a blocker. Add a VirtualDisk(vm FK, name, size_gb) child model and keep
disk_gb as a computed rollup if/when this matters.
VM & cluster typing (❌ Low for VM type / ✅ for cluster type). Cluster typing is fully covered by
ClusterType. VM typing (virtualmachinetype) is a newer, lightly-adopted NetBox concept and can
stay out — matching Danbyte's "zero pre-filled data" stance, users size VMs directly rather than from
a shipped template library.
"Zero pre-filled data" alignment¶
Every Danbyte model above is tenant-scoped and ships empty — ClusterType, TunnelGroup,
WirelessLANGroup all carry explicit "zero pre-filled data" docstrings, and none seed default rows.
Any new model recommended here must follow suit: no shipped IKE proposals, no default L2VPN types,
no starter SSIDs. The one nuance is enum choice-lists baked into model fields (e.g. IPSecProfile's
ENCRYPTION_CHOICES, Tunnel's ENCAP_CHOICES, WirelessLAN's AUTH_TYPE_CHOICES). These are
protocol constants, not user data, so they're an acceptable exception under CLAUDE.md's "almost
always it should be custom_fields or a user-created object" rule — but a new l2vpn.type or
virtualdisk should lean on custom_fields for anything site-specific rather than growing hardcoded
choice lists.
Summary¶
Danbyte already has solid bones in all three domains: Wireless (LAN + group) and Virtualization
(the full cluster→VM→interface spine) are largely at parity, and the VPN side has TunnelGroup,
Tunnel, and a pragmatically-flattened IPSecProfile. The gaps are concentrated in the
relationship/termination layer and in service-provider overlay modeling, not in the core
objects. The most damaging omission is that Danbyte tunnels have no terminations — a Tunnel
today cannot attach to any interface or IP — followed by the absence of the entire L2VPN
(EVPN/VXLAN/VPWS) family for SP migrations. Everything else (VMInterface VLAN/VRF parity, virtual
disks, wireless links) is real but non-blocking data-fidelity loss.
HIGH-priority missing models (must-add for credible NetBox migration parity):
1. TunnelTermination — binds a tunnel end to an Interface/VMInterface + role + outside_ip. Without it every imported tunnel is orphaned. (Sockets already exist; small model.)
2. L2VPN — overlay service (type/VNI + import/export RouteTarget M2M; RouteTarget already exists). Hard blocker for service-provider NetBox instances.
3. L2VPNTermination — attaches an L2VPN to a VLAN/Interface/VMInterface; the piece that makes an L2VPN carry traffic.
Med-priority (data-fidelity, add next): VMInterface L2/L3 parity (mode/untagged_vlan/
tagged_vlans/vrf, all already defined on device Interface); optional multi-proposal preservation
on IPSecProfile; VirtualDisk; WirelessLink.
Low / skip: virtualmachinetype, wirelesslan.auth_psk (route through existing secrets-at-rest),
nested wireless-group tree.
Tenancy¶
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
tenant |
core.Tenant |
✅ | High | Danbyte's Tenant is a hard isolation boundary (every domain row is tenant-scoped, RBAC enforces it), where NetBox tenant is a soft ownership label many objects optionally FK to. Migration is a mapping decision, not a schema gap — see prose. color, description, slug, prefs present. |
tenantgroup |
core.TenantGroup |
✅ | Med–High | Shipped 2026-07-03 (Tier 2): org-scoped self-nesting tree (parent self-FK, cycle-guarded) + Tenant.group FK. NetBox tenant-group hierarchies now land losslessly. |
contact |
api.Contact |
✅ | High | Full: name, title, phone, email, address, link, comments, group, tags, custom fields. |
contactgroup |
api.ContactGroup |
✅ | Med | Shipped 2026-07-03 (Tier 2): gained a parent self-FK (cycle-guarded), so NetBox's nested contact-group trees import losslessly. |
contactrole |
api.ContactRole |
✅ | Med | name/slug/description, tenant-scoped. Parity. |
contactassignment |
api.ContactAssignment |
✅ | High | Generic object→contact link with a role. Confirm the assignable-object registry covers the same object types NetBox allows (site, device, prefix, circuit, etc.). |
TenantGroup / ContactGroup nesting — the gap and the idea. NetBox models
both tenantgroup and contactgroup as MPTT trees so you can roll tenants up
(region → business-unit → customer) and filter/permission on a whole subtree.
Danbyte has a two-level Organization → Tenant spine and flat
ContactGroup. For migration parity the cheapest faithful move is to add a
nullable self-referential parent FK to ContactGroup (and, if we want tenant
grouping without abusing Organization, either a TenantGroup model or a
parent/group FK on Tenant). This is low-risk — it's structural, not
seeded data, so it respects zero-pre-filled-data. Rate Med–High: NetBox
installs that lean on tenant/contact hierarchies will have real rows here, and
there is no lossless place to put them today.
Extras / Customization¶
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
customfield |
customization.CustomField |
✅ | High | Tenant-scoped, typed (text/textarea/integer/decimal/boolean/date/url/select/multiselect), applies_to, required, default, weight, group. Solid parity. Gaps vs NetBox: no per-field validation_regex/min/max, no filter_logic, no object/multi-object reference field type (NetBox can make a CF that points at another object). |
customfieldchoiceset |
— (choices inline on CustomField.choices) |
🟡 | Med | Danbyte stores choices as a JSON list on each field. NetBox factors them into a reusable customfieldchoiceset shared across fields (+ base-set presets like IATA airport codes). See prose — a reusable choice-set object is defensible even under zero-pre-filled-data, but it is a convenience, not a data-loss gap. |
customfieldgroup* |
customization.CustomFieldGroup |
✅ | — | Danbyte is actually ahead here — a first-class group object (name/slug/description/weight/collapsed) vs NetBox's free-text group_name string. (*NetBox has no customfieldgroup model; noted for contrast.) |
tag |
core.Tag |
✅ | High | Color-aware, luminance-picked text color. NetBox tag also has object_types scoping (restrict a tag to certain models) and a weight — Danbyte's tag is global-per-install and unscoped. Minor. |
bookmark |
core.Bookmark |
✅ | Low | Per-user saved SPA path. Parity (Danbyte stores the full path+query, arguably richer). |
journalentry |
audit.JournalEntry |
✅ | High | Free-form dated notes on any object, with kind (info/success/warning/danger), author denormalized. Parity. |
configcontext |
api.ConfigContext |
✅ | Med | JSON blob merged onto devices/VMs by criteria (regions/sites/device_roles/platforms), weight-ordered. Good parity. Missing NetBox criteria dimensions: cluster/cluster-group, tenant/tenant-group, location, tag-based matching. |
configcontextprofile |
— | ❌ | Low | New in recent NetBox — a schema/validation profile for config-context data. Niche; skip until asked. |
configtemplate |
api.ExportTemplate + config_template bindings |
✅ | Med–High | Shipped 2026-07-03 (Tier 2) as a binding over ExportTemplate rather than a separate model: Device / DeviceRole / Platform each gained a config_template FK, resolved device → role → platform (NetBox's order). GET /api/devices/<id>/render/ falls back to the resolved binding and the device Config tab preselects it. |
exporttemplate |
api.ExportTemplate |
✅ | Med | Jinja2 per-object-type render to a file (mime/extension/as_attachment), sandboxed. Parity. |
webhook |
integrations.Webhook |
✅ | High | object_types, create/update/delete triggers, HMAC signing secret (encrypted at rest), extra headers, SSL verify. Strong parity — arguably ahead (secret encryption). |
eventrule |
— (partly folded into Webhook + AutomationTarget.auto_on_change) |
🟡 | Med | NetBox split the old webhook trigger logic into eventrule (the condition/what-fires) + an action (webhook or script). Danbyte keeps the trigger config on the Webhook (object_types/on_create/update/delete) and has AutomationTarget.auto_on_change. No general condition language (NetBox eventrule supports a conditions JSON DSL) and no "run a script" action. |
script |
— | ❌ | Low–Med | NetBox custom Python scripts (user automation run in-app). Danbyte deliberately pushes automation out to runners (AutomationTarget → AWX/webhook), so an in-process script runner is a philosophy difference, not a hole. Migration: scripts don't carry portable "data", so low data-loss risk. |
customlink |
— | ❌ | Med | NetBox lets admins add templated hyperlinks (Jinja over the object) onto any detail page — e.g. "Open in Grafana", "Ping via NMS". No Danbyte equivalent. Cheap, high-utility, and fits zero-pre-filled-data (user-authored). Real NetBox installs commonly have several. |
imageattachment |
— | ❌ | Med | Arbitrary image uploads pinned to any object (rack photos, site diagrams, cabling pics). Danbyte only has DeviceType.front/rear_image. A NetBox export with image attachments would lose them. Generic-FK + file upload. |
savedfilter |
— | ❌ | Med | NetBox stores named, shareable filter querysets. Danbyte has Bookmark (a saved URL with query string) which partially covers the use case per-user, but not shared/named org-level filters or the structured filter payload. |
tableconfig |
— (localStorage columns/stripes) | ❌ | Low | NetBox persists per-user table column layouts server-side. Danbyte does this client-side (danbyte-stripes, column menus in localStorage). Fine for now; server-side sync is a nice-to-have. |
dashboard |
— (fixed dashboard + Bookmark) |
🟡 | Low | NetBox stores a per-user configurable widget dashboard. Danbyte ships a fixed dashboard surfacing bookmarks/jobs. Not migration-critical (layout config, not data). |
notification / notificationgroup / subscription |
monitoring.NotificationChannel (alerting only) |
🟡 | Low | NetBox's are in-app user notifications + object subscriptions ("watch this device"). Danbyte's NotificationChannel is outbound alert routing (Slack/email/PagerDuty), a different axis. No per-user "subscribe to object" bell. Low data-loss risk. |
CustomFieldChoiceSet — reusable choice lists vs. zero-pre-filled-data.
NetBox factors select/multiselect options into a shared customfieldchoiceset
so "Environment = prod/staging/dev" is defined once and reused by many fields,
and ships optional base-sets (IATA codes, etc.). Danbyte stores choices as a
JSON list on each CustomField. The tension with CLAUDE.md is only about the
shipped base-sets — those violate zero-pre-filled-data and should stay out.
The reuse idea itself is compatible: a tenant-created, empty-by-default
CustomFieldChoiceSet that fields point at is still user-defined data. Verdict:
Med — worth adding for ergonomics and to import NetBox choice sets cleanly,
but not a data-loss blocker (choices survive the migration inline either way).
ConfigTemplate — Jinja device-config rendering. This is the most
substantive Extras gap. NetBox configtemplate renders a device's intended
running-config from Jinja (context = the device + its merged config-contexts),
bindable at device/role/platform level and pushable via NAPALM. Danbyte already
has all the pieces: ExportTemplate is sandboxed Jinja keyed by object type,
ConfigContext supplies the merged data, and integrations.DeviceConfigState
literally has a template = FK(ExportTemplate) for intended-vs-actual drift.
What's missing is the first-class binding (a template attached to a device
role/platform that auto-selects per device) and the render endpoint that feeds
config exactly like NetBox's. Rate Med–High: NetBox users who do
golden-config will expect this, and it's mostly wiring existing parts rather
than new infrastructure. Because Danbyte's drift loop is read-side (a runner
POSTs actual config back) it's actually a natural home for intended-config
rendering — closing this gap makes Danbyte's IaC loop bidirectional.
EventRule / Script — the automation seam. NetBox 4.x refactored automation
into eventrule (condition) → action (webhook or script). Danbyte made a
deliberate architectural choice: triggers live on the Webhook itself, and
heavier automation is delegated to external runners via AutomationTarget
(AWX/AAP or signed webhook) with optional auto_on_change. So Danbyte covers
the webhook half of eventrule well; it lacks (a) a condition DSL to gate
firing on field values, and (b) any in-process script action. Neither
carries migratable row-data of consequence, so both are Low–Med for parity —
but a small conditions JSON matcher on Webhook/AutomationTarget would close
most of the practical eventrule gap cheaply.
CustomLink & ImageAttachment — small, user-authored, commonly populated. Both are pure zero-pre-filled-data fits (admins/users author them) and both hold real rows in typical NetBox installs, so they matter for lossless migration even though each is architecturally trivial. CustomLink = a templated URL per object type (Jinja over the object). ImageAttachment = generic-FK file upload. Recommend both at Med.
Core / Data sources¶
| NetBox model | Danbyte equivalent | Status | Migration priority | Notes |
|---|---|---|---|---|
objectchange |
audit.ChangeLogEntry |
✅ | High | Append-only change log with field-level changes diff plus full pre_change/post_change snapshots (explicitly "NetBox-style"), request_id grouping, user denormalized, tenant-scoped, retention via DeploymentSettings.changelog_retention_days. Strong parity, possibly ahead. |
job |
— (RQ + /jobs page, DeployRun for deploys) |
🟡 | Med | NetBox persists a job row per background task (status/started/completed/data/error) as first-class, queryable history. Danbyte runs RQ and surfaces live queues on /jobs, and DeployRun records automation dispatches, but there is no generic persisted Job table covering all task types (discovery sweeps, SNMP polls, exports). A NetBox job history import has no home. |
datasource |
— | ❌ | Med–High | NetBox syncs remote git / S3 / local repos to pull in config-contexts, export/config templates, and scripts. Danbyte has no external-content sync at all. This is the biggest Core gap by capability. See prose. |
datafile |
— | ❌ | Med | The synced file records under a datasource. Only meaningful alongside datasource. |
autosyncrecord |
— | ❌ | Low | Bookkeeping for datasource auto-sync; only with datasource. |
managedfile |
— | ❌ | Low | Tracks files managed on disk (scripts/templates). Only relevant with the script/datasource machinery. |
configrevision |
core.DeploymentSettings (no history) |
🟡 | Low | NetBox versions its app config; Danbyte keeps a single mutable DeploymentSettings singleton with no revision history. Config isn't user "data" to migrate — Low. |
objecttype |
— (registry in code, not a table) | 🟡 | Low | NetBox has a ObjectType proxy over ContentType for its object-type registry. Danbyte uses in-code registries (RBAC object-type slugs, CUSTOMIZABLE_MODELS, STATUSABLE_MODELS). Functionally covered; no migratable rows. |
DataSource / DataFile — external content sync (the real Core gap). NetBox
datasource connects a git repo, S3 bucket, or local path and syncs its
files in, which then back config-contexts, config/export templates, and
scripts (GitOps for your source-of-truth data). Danbyte has nothing here:
ConfigContext data and ExportTemplate code are edited in-app only. For
migration parity this is Med–High by capability but Low by data-loss —
a NetBox export ships the rendered config-contexts/templates as rows (which
Danbyte can import), not the upstream repo binding, so nothing is strictly lost;
the workflow (GitOps sync) is what's missing. Given Danbyte already leans on
external runners for push automation, a DataSource that pulls
ConfigContext/ExportTemplate content from git would round out the IaC story and
should be considered once the ConfigTemplate binding lands.
Job history. Worth a persisted, generic Job model (tenant-scoped: kind,
status, started/finished, params, result/error, initiating user) so discovery
sweeps, SNMP polls, exports, and deploys share one auditable history surface
instead of only live RQ introspection + the deploy-specific DeployRun. Rate
Med — improves operability and gives NetBox job-history imports a landing
spot.
Where Danbyte is AHEAD of NetBox¶
- Monitoring / check engine (whole subsystem NetBox lacks).
monitoring/ships a multi-protocol status/health engine —CheckTemplate(ICMP/TCP/UDP/HTTP/SNMP/SSH/Telnet/exec with rise/fall/degraded thresholds),CheckAssignmentwith prefix-tree inheritance,CheckResulttime-series,CheckStateroll-ups,StateTransitionhistory, plus a full alerting stack:AlertRule,Alert(dedup/ack/escalate/flap),Silence(maintenance windows), andNotificationChannel(Slack/Teams/Discord/ PagerDuty/email/webhook). NetBox has no native monitoring — users bolt on Prometheus/LibreNMS. This is a category Danbyte owns outright. - Config backup / drift / automation (read-side IaC).
integrations/hasAutomationTarget(AWX/AAP or signed webhook dispatch),DeployRun(dispatch history with retry chains), andDeviceConfigState/DeviceConfigSnapshot(intended-vs-actual drift with a transition event log). NetBox renders intended config but has no built-in drift-ingest / assurance loop. - SNMP discovery & interface telemetry.
SnmpProfile,SnmpProfileBinding(device→role→type→tenant resolution),DeviceSnmp(observed sys/if/LLDP/ARP facts kept separate from intent), andSnmpInterfaceSample(HC-counter utilisation series). NetBox has no native poller. - RBAC with tenant/site delegation.
auth_api.ObjectPermission+ApiToken, plusDeploymentSettings.allow_site_editor_delegationand expiring public share links — a delegation model finer-grained than NetBox's object permissions for the MSP/multi-tenant case. - Per-tenant human IDs (
numid). Every object carries a per-tenant sequential number alongside its UUID (NetBox has only global integer PKs), built explicitly as a NetBox-migration affordance (a cable tagged "27" → cable #27). - First-class
CustomFieldGroup(vs NetBox's free-text group name) and encrypted-at-rest secrets on webhooks/automation/SNMP/SMTP.
Bottom line — HIGH-priority missing models for migration parity¶
Ranked for a lossless NetBox import + workflow continuity:
- TenantGroup / nested ContactGroup — add hierarchy (self-FK) so tenant & contact group trees import losslessly. (Med–High)
- ConfigTemplate binding — package the existing ExportTemplate + ConfigContext
- DeviceConfigState pieces into a first-class per-device/role/platform config render, matching NetBox golden-config expectations. (Med–High)
- DataSource / DataFile — git/S3 sync for config-contexts & templates; the marquee Core capability Danbyte lacks (workflow gap more than data gap). (Med–High)
- CustomLink and ImageAttachment — small, user-authored, and actually populated in real NetBox installs, so needed for a lossless import. (Med)
- Generic persisted Job and SavedFilter — operability + a landing spot for NetBox job history / saved filters. (Med)
- CustomFieldChoiceSet — reusable (empty-by-default) choice lists; import NetBox choice sets cleanly without shipping seeded values. (Med)
Everything else (script, eventrule condition DSL, configrevision, tableconfig,
dashboard, notification/subscription, objecttype, managedfile) is either an
intentional architecture divergence or config/UI state that carries no
migratable row-data — Low priority. Crucially, most of NetBox's long Extras list
maps onto Danbyte's existing custom_fields JSONB + user-created Tag/Status
objects rather than warranting new models, which is the right call under the
zero-pre-filled-data constraint.