Files
fabric-orchestrator/docs/netbox-data-model.md
Damien Arnodo 555f8436f1 docs: Add NetBox data model documentation for fabric intent
Documents how EVPN-VXLAN fabric configuration is represented in NetBox
using native models and the BGP plugin.

Includes:
- Model mapping tables (native + BGP plugin)
- IP addressing scheme
- BGP session configuration
- VXLAN/EVPN L2VPN setup
- MLAG custom fields requirements
- VRF configuration
- Data retrieval examples with pynetbox

Relates to #5
2026-01-08 07:53:37 +00:00

296 lines
12 KiB
Markdown

# NetBox Data Model for Fabric Orchestrator
This document describes how fabric intent is represented in NetBox for the fabric-orchestrator to consume.
## Overview
The fabric-orchestrator uses NetBox as the **source of truth** for EVPN-VXLAN fabric configuration. Instead of using ConfigContexts, we leverage NetBox's native data models plus the [NetBox BGP Plugin](https://github.com/netbox-community/netbox-bgp) for comprehensive fabric representation.
### Requirements
- NetBox 4.4.x
- NetBox BGP Plugin v0.17.x
---
## Data Model Summary
### Native NetBox Models
| Feature | NetBox Model | API Endpoint |
|---------|--------------|--------------|
| **Devices** | `dcim.Device` | `/api/dcim/devices/` |
| **Interfaces** | `dcim.Interface` | `/api/dcim/interfaces/` |
| **LAGs/Port-Channels** | `dcim.Interface` (type=LAG) | `/api/dcim/interfaces/` |
| **VLANs** | `ipam.VLAN` | `/api/ipam/vlans/` |
| **VLAN Groups** | `ipam.VLANGroup` | `/api/ipam/vlan-groups/` |
| **VRFs** | `ipam.VRF` | `/api/ipam/vrfs/` |
| **Route Targets** | `ipam.RouteTarget` | `/api/ipam/route-targets/` |
| **IP Addresses** | `ipam.IPAddress` | `/api/ipam/ip-addresses/` |
| **Prefixes** | `ipam.Prefix` | `/api/ipam/prefixes/` |
| **ASNs** | `ipam.ASN` | `/api/ipam/asns/` |
| **L2VPN (EVPN)** | `vpn.L2VPN` | `/api/vpn/l2vpns/` |
| **L2VPN Terminations** | `vpn.L2VPNTermination` | `/api/vpn/l2vpn-terminations/` |
### NetBox BGP Plugin Models
| Feature | Plugin Model | API Endpoint |
|---------|--------------|--------------|
| **BGP Sessions** | `netbox_bgp.BGPSession` | `/api/plugins/bgp/sessions/` |
| **BGP Peer Groups** | `netbox_bgp.PeerGroup` | `/api/plugins/bgp/peer-groups/` |
| **BGP Communities** | `netbox_bgp.Community` | `/api/plugins/bgp/communities/` |
| **Routing Policies** | `netbox_bgp.RoutingPolicy` | `/api/plugins/bgp/routing-policies/` |
| **Prefix Lists** | `netbox_bgp.PrefixList` | `/api/plugins/bgp/prefix-lists/` |
| **AS Path Lists** | `netbox_bgp.ASPathList` | `/api/plugins/bgp/as-path-lists/` |
---
## Fabric Component Mapping
### Devices and Roles
| Fabric Role | NetBox Device Role | Description |
|-------------|-------------------|-------------|
| Spine | `spine` | Spine switches (AS 65000) |
| Leaf | `leaf` | Leaf switches (AS 65001-65004) |
**Example Device Setup:**
- `spine1`, `spine2` - Device Role: spine
- `leaf1` through `leaf8` - Device Role: leaf
### Interfaces
| Interface Type | NetBox Interface Type | Usage |
|----------------|----------------------|-------|
| Physical uplinks | `1000base-t` / `10gbase-x-sfpp` | Spine-Leaf connections |
| Loopback0 | `virtual` | BGP Router-ID |
| Loopback1 | `virtual` | VTEP source (shared by MLAG pair) |
| Port-Channel | `lag` | MLAG peer-link, host bonds |
| Vxlan1 | `virtual` | VXLAN tunnel interface |
| SVI | `virtual` | VLAN interfaces (Vlan40, etc.) |
### IP Addressing Scheme
Based on the reference topology:
| Purpose | Prefix | Example |
|---------|--------|---------|
| Spine-Leaf P2P (Spine1) | `10.0.1.0/24` | `10.0.1.0/31`, `10.0.1.2/31`, ... |
| Spine-Leaf P2P (Spine2) | `10.0.2.0/24` | `10.0.2.0/31`, `10.0.2.2/31`, ... |
| MLAG iBGP Peer | `10.0.3.0/24` | `10.0.3.0/31` per MLAG pair |
| MLAG Peer VLAN 4090 | `10.0.199.0/24` | `/31` per MLAG pair |
| Loopback0 (Router-ID) | `10.0.250.0/24` | Spine: `.1-.2`, Leaf: `.11-.18` |
| Loopback1 (VTEP) | `10.0.255.0/24` | `.11-.14` (shared per MLAG pair) |
---
## BGP Configuration
### ASN Assignments
| Device(s) | ASN | Type |
|-----------|-----|------|
| spine1, spine2 | 65000 | eBGP |
| leaf1, leaf2 | 65001 | iBGP pair |
| leaf3, leaf4 | 65002 | iBGP pair |
| leaf5, leaf6 | 65003 | iBGP pair |
| leaf7, leaf8 | 65004 | iBGP pair |
### BGP Sessions (Plugin)
#### Underlay eBGP Sessions
Each leaf has eBGP sessions to both spines over point-to-point interfaces:
| Local Device | Local IP | Remote Device | Remote IP | Remote ASN |
|--------------|----------|---------------|-----------|------------|
| leaf1 | 10.0.1.1 | spine1 | 10.0.1.0 | 65000 |
| leaf1 | 10.0.2.1 | spine2 | 10.0.2.0 | 65000 |
#### Underlay iBGP Sessions
Each MLAG pair has an iBGP session for redundancy:
| Local Device | Local IP | Remote Device | Remote IP | Notes |
|--------------|----------|---------------|-----------|-------|
| leaf1 | 10.0.3.0 | leaf2 | 10.0.3.1 | next-hop-self |
#### Overlay EVPN Sessions
EVPN sessions use loopback addresses with `ebgp-multihop 3`:
| Local Device | Local IP (Lo0) | Remote Device | Remote IP (Lo0) | AFI/SAFI |
|--------------|----------------|---------------|-----------------|----------|
| leaf1 | 10.0.250.11 | spine1 | 10.0.250.1 | L2VPN EVPN |
| leaf1 | 10.0.250.11 | spine2 | 10.0.250.2 | L2VPN EVPN |
### BGP Peer Groups (Plugin)
| Peer Group | Purpose | Key Settings |
|------------|---------|--------------|
| `underlay` | eBGP to spines | `remote-as 65000`, `maximum-routes 12000` |
| `underlay_ibgp` | iBGP to MLAG peer | `next-hop-self` |
| `evpn` | EVPN overlay | `update-source Loopback0`, `ebgp-multihop 3`, `send-community extended` |
---
## VXLAN / EVPN Configuration
### L2VPN for EVPN VNI Mappings
NetBox's L2VPN model represents EVPN instances:
| L2VPN Name | Type | Identifier (VNI) | Description |
|------------|------|------------------|-------------|
| `VLAN40-L2VNI` | EVPN | 100040 | L2 VXLAN for VLAN 40 |
| `VRF-gold` | EVPN | 100001 | L3 VNI for VRF gold |
### L2VPN Terminations
Link VLANs to L2VPNs on specific devices:
| L2VPN | Device | Interface/VLAN |
|-------|--------|----------------|
| `VLAN40-L2VNI` | leaf1 | VLAN 40 |
| `VLAN40-L2VNI` | leaf2 | VLAN 40 |
| `VLAN40-L2VNI` | leaf5 | VLAN 40 |
| `VLAN40-L2VNI` | leaf6 | VLAN 40 |
### Route Targets
| VRF/VLAN | Import RT | Export RT |
|----------|-----------|-----------|
| VLAN 40 | `40:100040` | `40:100040` |
| VRF gold | `1:100001` | `1:100001` |
---
## MLAG Configuration
MLAG configuration requires 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
| Device | Domain ID | Local IP | Peer IP | Virtual MAC |
|--------|-----------|----------|---------|-------------|
| leaf1 | leafs | 10.0.199.254 | 10.0.199.255 | c001.cafe.babe |
| leaf2 | leafs | 10.0.199.255 | 10.0.199.254 | c001.cafe.babe |
### MLAG-Related VLANs
| VLAN | Name | Purpose | Trunk Group |
|------|------|---------|-------------|
| 4090 | mlag-peer | MLAG peer communication | mlag-peer |
| 4091 | mlag-ibgp | iBGP between MLAG peers | mlag-peer |
---
## VRF Configuration
### VRF Definition
| VRF Name | RD | Import RT | Export RT | L3 VNI |
|----------|-------|-----------|-----------|--------|
| gold | `10.0.250.X:1` | `1:100001` | `1:100001` | 100001 |
> Note: RD uses device's Loopback0 IP for uniqueness
### VRF Interface Assignment
SVIs are assigned to VRFs in NetBox:
| Interface | VRF | IP Address | Virtual IP |
|-----------|-----|------------|------------|
| Vlan34 (leaf3) | gold | 10.34.34.2/24 | 10.34.34.1 |
| Vlan34 (leaf4) | gold | 10.34.34.3/24 | 10.34.34.1 |
| Vlan78 (leaf7) | gold | 10.78.78.2/24 | 10.78.78.1 |
| Vlan78 (leaf8) | gold | 10.78.78.3/24 | 10.78.78.1 |
---
## Data Retrieval Strategy
The fabric-orchestrator retrieves intent from NetBox using pynetbox:
```python
import pynetbox
nb = pynetbox.api('http://netbox.example.com', token='your-token')
# Get all leaf devices
leaves = nb.dcim.devices.filter(role='leaf')
# Get BGP sessions for a device
bgp_sessions = nb.plugins.bgp.sessions.filter(device='leaf1')
# Get L2VPNs (EVPN)
l2vpns = nb.vpn.l2vpns.filter(type='evpn')
# Get VLAN-to-VNI mappings via L2VPN terminations
terminations = nb.vpn.l2vpn_terminations.filter(l2vpn='VLAN40-L2VNI')
```
---
## Relationship Diagram
```
┌─────────────────────────────────────────────────────────────────┐
│ NetBox │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ Device │────▶│ Interface │────▶│ IP Address │ │
│ │ (leaf1) │ │ (Loopback0) │ │(10.0.250.11)│ │
│ └──────────┘ └──────────────┘ └─────────────┘ │
│ │ │
│ │ ASN assignment │
│ ▼ │
│ ┌──────────┐ │
│ │ ASN │ │
│ │ (65001) │ │
│ └──────────┘ │
│ │
│ ┌──────────────┐ ┌─────────────────┐ │
│ │ BGP Session │────▶│ Peer Group │ │
│ │ (plugin) │ │ (plugin) │ │
│ └──────────────┘ └─────────────────┘ │
│ │
│ ┌──────────┐ ┌─────────────────────┐ ┌──────────┐ │
│ │ VLAN │────▶│ L2VPN Termination │────▶│ L2VPN │ │
│ │ (40) │ │ │ │ (EVPN) │ │
│ └──────────┘ └─────────────────────┘ └──────────┘ │
│ │ │
│ │ VNI │
│ ▼ │
│ ┌──────────┐ │
│ │ 100040 │ │
│ └──────────┘ │
│ │
│ ┌──────────┐ ┌─────────────────┐ │
│ │ VRF │────▶│ Route Target │ │
│ │ (gold) │ │ (1:100001) │ │
│ └──────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## Next Steps
1. **Custom Fields Setup** - Create MLAG-related custom fields in NetBox
2. **Data Population** - Enter fabric topology data into NetBox
3. **NetBox Client** - Implement `src/netbox/client.py` using pynetbox
4. **Validation** - Verify data retrieval matches expected fabric config