docs: add complete custom fields reference and API compatibility notes

- Add comprehensive custom fields table for Device, Interface, VRF, and IP Address
- Include API examples for custom field creation
- Document working vs non-working API filters for NetBox 4.4
- Add workarounds for filters that don't exist (ASN by device, L2VPN terminations by device)
- Update VRF interface assignment to show IP-based VRF membership
- Add virtual_ip custom field for anycast gateway support
This commit is contained in:
2026-01-08 12:33:17 +00:00
parent b1c46686d2
commit 2f828f43d6

View File

@@ -45,6 +45,74 @@ The fabric-orchestrator uses NetBox as the **source of truth** for EVPN-VXLAN fa
--- ---
## Custom Fields Reference
NetBox doesn't natively support all fabric-specific configurations. The following custom fields must be created to support MLAG, ASN assignment, and VRF extensions.
### Complete Custom Fields List
#### Device Custom Fields
| Field Name | Label | Type | Required | Description |
|------------|-------|------|----------|-------------|
| `asn` | ASN | Integer | No | BGP Autonomous System Number assigned to this device |
| `mlag_domain_id` | MLAG Domain ID | Text | No | MLAG domain identifier (e.g., "leafs") |
| `mlag_peer_address` | MLAG Peer Address | Text | No | MLAG peer IP address |
| `mlag_local_address` | MLAG Local Address | Text | No | MLAG local IP address |
| `mlag_virtual_mac` | MLAG Virtual MAC | Text | No | Shared virtual-router MAC (e.g., "c001.cafe.babe") |
#### Interface Custom Fields
| Field Name | Label | Type | Required | Description |
|------------|-------|------|----------|-------------|
| `mlag_peer_link` | MLAG Peer Link | Boolean | No | Marks interface as MLAG peer-link |
| `mlag_id` | MLAG ID | Integer | No | MLAG port-channel ID for host-facing LAGs |
#### VRF Custom Fields
| Field Name | Label | Type | Required | Description |
|------------|-------|------|----------|-------------|
| `l3vni` | L3 VNI | Integer | No | Layer 3 VNI for EVPN symmetric IRB |
| `vrf_vlan` | VRF VLAN | Integer | No | VLAN ID used for L3 VNI SVI |
#### IP Address Custom Fields
| Field Name | Label | Type | Required | Description |
|------------|-------|------|----------|-------------|
| `virtual_ip` | Virtual IP | Boolean | No | Marks IP as anycast/virtual IP (shared across MLAG pair) |
### Custom Field Creation via API
```bash
# Example: Create ASN custom field on Device
curl -X POST "https://netbox.example.com/api/extras/custom-fields/" \
-H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content_types": ["dcim.device"],
"name": "asn",
"label": "ASN",
"type": "integer",
"required": false,
"description": "BGP Autonomous System Number assigned to this device"
}'
# Example: Create MLAG Peer Link custom field on Interface
curl -X POST "https://netbox.example.com/api/extras/custom-fields/" \
-H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content_types": ["dcim.interface"],
"name": "mlag_peer_link",
"label": "MLAG Peer Link",
"type": "boolean",
"required": false,
"description": "Marks interface as MLAG peer-link"
}'
```
---
## Fabric Component Mapping ## Fabric Component Mapping
### Devices and Roles ### Devices and Roles
@@ -88,13 +156,13 @@ Based on the reference topology:
### ASN Assignments ### ASN Assignments
| Device(s) | ASN | Type | | Device(s) | ASN | Type | Custom Field |
|-----------|-----|------| |-----------|-----|------|--------------|
| spine1, spine2 | 65000 | eBGP | | spine1, spine2 | 65000 | eBGP | `asn: 65000` |
| leaf1, leaf2 | 65001 | iBGP pair | | leaf1, leaf2 | 65001 | iBGP pair | `asn: 65001` |
| leaf3, leaf4 | 65002 | iBGP pair | | leaf3, leaf4 | 65002 | iBGP pair | `asn: 65002` |
| leaf5, leaf6 | 65003 | iBGP pair | | leaf5, leaf6 | 65003 | iBGP pair | `asn: 65003` |
| leaf7, leaf8 | 65004 | iBGP pair | | leaf7, leaf8 | 65004 | iBGP pair | `asn: 65004` |
### BGP Sessions (Plugin) ### BGP Sessions (Plugin)
@@ -167,17 +235,7 @@ Link VLANs to L2VPNs on specific devices:
## MLAG Configuration ## MLAG Configuration
MLAG configuration requires Custom Fields since NetBox doesn't have native MLAG support. MLAG configuration uses Custom Fields since NetBox doesn't have native MLAG support.
### Custom Fields Required
| Field Name | Object Type | Type | Description |
|------------|-------------|------|-------------|
| `mlag_domain_id` | Device | Text | MLAG domain identifier |
| `mlag_peer_address` | Device | Text (IP) | MLAG peer IP address |
| `mlag_local_address` | Device | Text (IP) | MLAG local IP address |
| `mlag_peer_link` | Interface | Boolean | Marks interface as MLAG peer-link |
| `mlag_virtual_mac` | Device | Text | Shared virtual-router MAC |
### MLAG Pair Configuration ### MLAG Pair Configuration
@@ -199,22 +257,24 @@ MLAG configuration requires Custom Fields since NetBox doesn't have native MLAG
### VRF Definition ### VRF Definition
| VRF Name | RD | Import RT | Export RT | L3 VNI | | VRF Name | RD | Import RT | Export RT | L3 VNI (custom field) |
|----------|-------|-----------|-----------|--------| |----------|-------|-----------|-----------|----------------------|
| gold | `10.0.250.X:1` | `1:100001` | `1:100001` | 100001 | | gold | `10.0.250.X:1` | `1:100001` | `1:100001` | 100001 |
> Note: RD uses device's Loopback0 IP for uniqueness > Note: RD uses device's Loopback0 IP for uniqueness
### VRF Interface Assignment ### VRF Interface Assignment
SVIs are assigned to VRFs in NetBox: SVIs are assigned to VRFs in NetBox. VRF membership is tracked via IP addresses assigned to interfaces:
| Interface | VRF | IP Address | Virtual IP | | Interface | VRF | IP Address | Virtual IP (custom field) |
|-----------|-----|------------|------------| |-----------|-----|------------|---------------------------|
| Vlan34 (leaf3) | gold | 10.34.34.2/24 | 10.34.34.1 | | Vlan34 (leaf3) | gold | 10.34.34.2/24 | No |
| Vlan34 (leaf4) | gold | 10.34.34.3/24 | 10.34.34.1 | | Vlan34 (leaf4) | gold | 10.34.34.3/24 | No |
| Vlan78 (leaf7) | gold | 10.78.78.2/24 | 10.78.78.1 | | Vlan34 (leaf3) | gold | 10.34.34.1/24 | Yes (anycast) |
| Vlan78 (leaf8) | gold | 10.78.78.3/24 | 10.78.78.1 | | Vlan78 (leaf7) | gold | 10.78.78.2/24 | No |
| Vlan78 (leaf8) | gold | 10.78.78.3/24 | No |
| Vlan78 (leaf7) | gold | 10.78.78.1/24 | Yes (anycast) |
--- ---
@@ -230,6 +290,10 @@ nb = pynetbox.api('http://netbox.example.com', token='your-token')
# Get all leaf devices # Get all leaf devices
leaves = nb.dcim.devices.filter(role='leaf') leaves = nb.dcim.devices.filter(role='leaf')
# Get device ASN from custom field
device = nb.dcim.devices.get(name='leaf1')
asn = device.custom_fields.get('asn')
# Get BGP sessions for a device # Get BGP sessions for a device
bgp_sessions = nb.plugins.bgp.sessions.filter(device='leaf1') bgp_sessions = nb.plugins.bgp.sessions.filter(device='leaf1')
@@ -238,6 +302,10 @@ l2vpns = nb.vpn.l2vpns.filter(type='evpn')
# Get VLAN-to-VNI mappings via L2VPN terminations # Get VLAN-to-VNI mappings via L2VPN terminations
terminations = nb.vpn.l2vpn_terminations.filter(l2vpn='VLAN40-L2VNI') terminations = nb.vpn.l2vpn_terminations.filter(l2vpn='VLAN40-L2VNI')
# Get VRF with L3 VNI
vrf = nb.ipam.vrfs.get(name='gold')
l3vni = vrf.custom_fields.get('l3vni')
``` ```
--- ---
@@ -245,51 +313,79 @@ terminations = nb.vpn.l2vpn_terminations.filter(l2vpn='VLAN40-L2VNI')
## Relationship Diagram ## Relationship Diagram
``` ```
┌─────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────────────
│ NetBox │ │ NetBox │
├─────────────────────────────────────────────────────────────────┤ ├─────────────────────────────────────────────────────────────────────────────
│ │ │ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────── │ ┌────────────┐ ┌────────────────┐ ┌───────────────┐
│ │ Device │────│ Interface │────│ IP Address │ │ Device │────│ Interface │────│ IP Address
│ │ (leaf1) │ │ (Loopback0) │ │(10.0.250.11) │ │ (leaf1) │ │ (Loopback0) │ │(10.0.250.11)
└──────────┘ └──────────────┘ └─────────────┘ │ cf:asn │ │ cf:mlag_peer_ │ │ cf:virtual_ip │
│ └────────────┘ │ link │ └───────────────┘ │
│ │ └────────────────┘ │
│ │ │ │ │ │
│ │ ASN assignment custom_fields
│ ▼ │ │ ▼ │
│ ┌────────── │ ┌────────────┐
│ │ ASN │ │ cf:asn │
│ │ (65001) │ │ │ │ (65001) │ │
│ └────────── │ └────────────┘
│ │ │ │
│ ┌──────────────┐ ┌───────────────── │ ┌──────────────────┐ ┌───────────────────┐
│ │ BGP Session │────│ Peer Group │ │ BGP Session │────│ Peer Group
│ │ (plugin) │ │ (plugin) │ │ │ │ (plugin) │ │ (plugin) │ │
│ └──────────────┘ └───────────────── │ └──────────────────┘ └───────────────────┘
│ │ │ │
│ ┌──────────┐ ┌─────────────────────┐ ┌────────── │ ┌────────────┐ ┌───────────────────────┐ ┌────────────┐
│ │ VLAN │────│ L2VPN Termination │────│ L2VPN │ │ VLAN │────│ L2VPN Termination │────│ L2VPN
│ │ (40) │ │ │ │ (EVPN) │ │ │ │ (40) │ │ │ │ (EVPN) │ │
│ └──────────┘ └─────────────────────┘ └────────── │ └────────────┘ └───────────────────────┘ └────────────┘
│ │ │ │ │ │
│ VNI │ identifier
│ ▼ │ │ ▼ │
────────── ┌────────────┐
│ │ 100040 │ │ │ │ 100040 │ │
└──────────┘ │ (VNI) │
│ └────────────┘ │
│ │ │ │
│ ┌──────────┐ ┌───────────────── │ ┌────────────┐ ┌───────────────────┐
│ │ VRF │────│ Route Target │ │ VRF │────│ Route Target
│ │ (gold) │ │ (1:100001) │ │ │ │ (gold) │ │ (1:100001) │ │
└──────────┘ └───────────────── │ cf:l3vni │ └───────────────────┘
│ └────────────┘ │
│ │ │ │
└─────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────────────
``` ```
--- ---
## API Filter Compatibility Notes
### Working Filters (NetBox 4.4)
| Endpoint | Filter | Example |
|----------|--------|---------|
| `/api/dcim/devices/` | `role`, `name`, `site` | `?role=leaf` |
| `/api/dcim/interfaces/` | `device`, `type`, `name` | `?device=leaf1&type=virtual` |
| `/api/ipam/ip-addresses/` | `device`, `interface`, `vrf` | `?device=leaf1&vrf=gold` |
| `/api/ipam/vlans/` | `vid`, `site`, `group` | `?vid=40` |
| `/api/vpn/l2vpns/` | `type`, `name` | `?type=evpn` |
| `/api/vpn/l2vpn-terminations/` | `l2vpn`, `vlan_id` | `?l2vpn=VLAN40-L2VNI` |
| `/api/plugins/bgp/sessions/` | `device`, `peer_group` | `?device=leaf1` |
### Non-Working Filters (Require Workarounds)
| Endpoint | Invalid Filter | Workaround |
|----------|----------------|------------|
| `/api/ipam/asns/` | `device` | Use custom field `asn` on Device |
| `/api/vpn/l2vpn-terminations/` | `device` | Filter by `vlan_id` then correlate |
| `/api/dcim/interfaces/` | `vrf` | Query IPs with VRF filter, get interface IDs |
---
## Next Steps ## Next Steps
1. **Custom Fields Setup** - Create MLAG-related custom fields in NetBox 1. **Custom Fields Setup** - Create all custom fields listed above in NetBox
2. **Data Population** - Enter fabric topology data into NetBox 2. **Data Population** - Enter fabric topology data into NetBox
3. **NetBox Client** - Implement `src/netbox/client.py` using pynetbox 3. **NetBox Client** - Update `src/netbox/client.py` to use custom fields
4. **Validation** - Verify data retrieval matches expected fabric config 4. **Validation** - Verify data retrieval matches expected fabric config