Default VRF per Device/Site/Location/Rack/Tenant #607

Closed
opened 2026-04-05 16:52:00 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @patrickpreuss on 1/12/2026

NetBox version

v4.5.0

Feature type

Data model extension

Proposed functionality

Introduce an inherited “Default VRF” capability that can be configured on Tenant, Site, Location, Rack, and Device and is used to auto-populate the VRF for newly created IPAM objects only when the user/API client does not explicitly specify a VRF.

  1. Data model changes

Add a nullable foreign key field default_vrf → ipam.VRF on:

tenancy.Tenant

dcim.Site

dcim.Location

dcim.Rack

dcim.Device

Field properties:

optional (null=True, blank=True)

deletion behavior: prefer on_delete=PROTECT (prevents deleting a VRF still referenced as a default), though SET_NULL would be acceptable if the project prefers permissive deletes.

  1. VRF resolution / inheritance rules

Implement a single canonical resolver used by UI + API:

Precedence order

Device.default_vrf

Rack.default_vrf

Location.default_vrf

Site.default_vrf

Tenant.default_vrf

Fallback behavior

If a device has no rack, the resolver should fall back to Location/Site automatically.

The resolver should also return the source object (e.g., “inherited from Site ‘Berlin’”) for UI display.

  1. Where defaults apply (workflows)

Apply defaulting on create for these IPAM objects:

IP Address (ipam.IPAddress)

Prefix (ipam.Prefix)

IP Range (ipam.IPRange)

  1. UI behavior (“auto-set unless override”)

Update create/edit UI for the affected IPAM objects:

If a default VRF is resolved, the VRF should be auto-set and displayed as inherited (readable summary), and the user can explicitly override via a control (e.g., “Override VRF” toggle/button) that reveals the standard VRF selector.

The UI should show an indicator like:
“Default VRF: VRF-XYZ (inherited from Site Berlin)”
The indicator must identify the inheritance source (Device/Rack/Location/Site/Tenant).

If no default VRF is resolvable, behavior remains unchanged (normal empty VRF selector).

Also add the Default VRF field to the edit views/forms for:

Tenant, Site, Location, Rack, Device

  1. API behavior (important semantics)

Server-side defaulting for API create requests:

Apply the computed default only when the vrf field is omitted from the request payload.

Do not apply defaults when the client explicitly sets "vrf": null (or equivalent) — explicit null must remain null.

(Implementation note: this requires checking whether vrf is present in the incoming payload, not only whether the validated value is null.)

Use case

A device might be dedicated to a specific tenant/customer VRF while co-located with shared infrastructure.

A device might be used for a special purpose (e.g., lab, OT, security appliances) requiring a VRF different from the site default.

Devices without racks (or modeled without rack assignments) still need deterministic behavior; device defaults should work regardless and fall back to location/site as needed.

Having a Device.default_vrf as the highest-precedence default enables accurate, fast workflows for:

Assigning management IPs to device interfaces

Creating IP addresses/prefixes/ranges in the correct VRF during device onboarding

Handling per-device exceptions without forcing users to create separate sites/locations or rely on manual VRF selection

Concrete scenarios

Device provisioning: When assigning a management IP to an interface, the correct VRF is typically fixed per device; defaulting eliminates repetitive selection and prevents mistakes.

Exceptions inside a site: Most devices use the site’s VRF, but a subset must use a different VRF; device default cleanly models this.

Multi-tenant overlapping space: Device defaults reduce accidental placement into global/wrong VRFs when multiple tenants share RFC1918 space.

Summary benefit

Adding inherited defaults including Device-level default VRF improves speed, consistency, and correctness of IPAM operations by making VRF selection “safe by default,” while remaining fully overrideable when needed.

Database changes

Database changes

This feature requires adding a single new nullable foreign key field to several existing models:

New fields

Add default_vrf (FK → ipam.VRF) to:

tenancy.Tenant

dcim.Site

dcim.Location

dcim.Rack

dcim.Device

Field characteristics

Optional: null=True, blank=True

Suggested on_delete=PROTECT to prevent deleting a VRF that is still referenced as a default (alternatively SET_NULL if maintainers prefer permissive behavior).

Add DB index implicitly via FK (standard).

Migrations / compatibility

One schema migration adding these columns + constraints.

No data migration required; defaults are unset by default and do not change existing objects.

Backwards compatible: existing records behave exactly as before unless default_vrf is populated.

Notes

No new models are required; this is strictly additive fields on existing core models.

External dependencies

No response

*Originally created by @patrickpreuss on 1/12/2026* ### NetBox version v4.5.0 ### Feature type Data model extension ### Proposed functionality Introduce an inherited “Default VRF” capability that can be configured on Tenant, Site, Location, Rack, and Device and is used to auto-populate the VRF for newly created IPAM objects only when the user/API client does not explicitly specify a VRF. 1) Data model changes Add a nullable foreign key field default_vrf → ipam.VRF on: tenancy.Tenant dcim.Site dcim.Location dcim.Rack dcim.Device Field properties: optional (null=True, blank=True) deletion behavior: prefer on_delete=PROTECT (prevents deleting a VRF still referenced as a default), though SET_NULL would be acceptable if the project prefers permissive deletes. 2) VRF resolution / inheritance rules Implement a single canonical resolver used by UI + API: Precedence order Device.default_vrf Rack.default_vrf Location.default_vrf Site.default_vrf Tenant.default_vrf Fallback behavior If a device has no rack, the resolver should fall back to Location/Site automatically. The resolver should also return the source object (e.g., “inherited from Site ‘Berlin’”) for UI display. 3) Where defaults apply (workflows) Apply defaulting on create for these IPAM objects: IP Address (ipam.IPAddress) Prefix (ipam.Prefix) IP Range (ipam.IPRange) 4) UI behavior (“auto-set unless override”) Update create/edit UI for the affected IPAM objects: If a default VRF is resolved, the VRF should be auto-set and displayed as inherited (readable summary), and the user can explicitly override via a control (e.g., “Override VRF” toggle/button) that reveals the standard VRF selector. The UI should show an indicator like: “Default VRF: VRF-XYZ (inherited from Site Berlin)” The indicator must identify the inheritance source (Device/Rack/Location/Site/Tenant). If no default VRF is resolvable, behavior remains unchanged (normal empty VRF selector). Also add the Default VRF field to the edit views/forms for: Tenant, Site, Location, Rack, Device 5) API behavior (important semantics) Server-side defaulting for API create requests: Apply the computed default only when the vrf field is omitted from the request payload. Do not apply defaults when the client explicitly sets "vrf": null (or equivalent) — explicit null must remain null. (Implementation note: this requires checking whether vrf is present in the incoming payload, not only whether the validated value is null.) ### Use case A device might be dedicated to a specific tenant/customer VRF while co-located with shared infrastructure. A device might be used for a special purpose (e.g., lab, OT, security appliances) requiring a VRF different from the site default. Devices without racks (or modeled without rack assignments) still need deterministic behavior; device defaults should work regardless and fall back to location/site as needed. Having a Device.default_vrf as the highest-precedence default enables accurate, fast workflows for: Assigning management IPs to device interfaces Creating IP addresses/prefixes/ranges in the correct VRF during device onboarding Handling per-device exceptions without forcing users to create separate sites/locations or rely on manual VRF selection Concrete scenarios Device provisioning: When assigning a management IP to an interface, the correct VRF is typically fixed per device; defaulting eliminates repetitive selection and prevents mistakes. Exceptions inside a site: Most devices use the site’s VRF, but a subset must use a different VRF; device default cleanly models this. Multi-tenant overlapping space: Device defaults reduce accidental placement into global/wrong VRFs when multiple tenants share RFC1918 space. Summary benefit Adding inherited defaults including Device-level default VRF improves speed, consistency, and correctness of IPAM operations by making VRF selection “safe by default,” while remaining fully overrideable when needed. ### Database changes Database changes This feature requires adding a single new nullable foreign key field to several existing models: New fields Add default_vrf (FK → ipam.VRF) to: tenancy.Tenant dcim.Site dcim.Location dcim.Rack dcim.Device Field characteristics Optional: null=True, blank=True Suggested on_delete=PROTECT to prevent deleting a VRF that is still referenced as a default (alternatively SET_NULL if maintainers prefer permissive behavior). Add DB index implicitly via FK (standard). Migrations / compatibility One schema migration adding these columns + constraints. No data migration required; defaults are unset by default and do not change existing objects. Backwards compatible: existing records behave exactly as before unless default_vrf is populated. Notes No new models are required; this is strictly additive fields on existing core models. ### External dependencies _No response_
MrUnknownDE added the netboxtype: featurenetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxtype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: feature labels 2026-04-05 16:52:15 +02:00
Sign in to join this conversation.
No Label netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#607