From 555f8436f14f359c8d10536b041462486590477f Mon Sep 17 00:00:00 2001 From: Damien Arnodo Date: Thu, 8 Jan 2026 07:53:37 +0000 Subject: [PATCH] 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 --- docs/netbox-data-model.md | 295 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 docs/netbox-data-model.md diff --git a/docs/netbox-data-model.md b/docs/netbox-data-model.md new file mode 100644 index 0000000..199c23a --- /dev/null +++ b/docs/netbox-data-model.md @@ -0,0 +1,295 @@ +# 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