162 lines
7.4 KiB
Markdown
162 lines
7.4 KiB
Markdown
# Claude Code Instructions — fabric-orchestrator
|
||
|
||
## Project Context
|
||
|
||
Fabric-orchestrator manages Arista EVPN-VXLAN fabrics using Infrahub as the source of truth.
|
||
Gitea: https://gitea.arnodo.fr/Damien/fabric-orchestrator
|
||
Branch: `feature/52-object-files`
|
||
|
||
## Current Task: Issue #52 — Create Infrahub Object Files
|
||
|
||
Create YAML object files to load the reference topology data into Infrahub.
|
||
Object files use the `apiVersion: infrahub.app/v1` format and are loaded via `infrahubctl object load`.
|
||
|
||
### Data Sources (read-only references)
|
||
|
||
- **Arista configs**: https://gitea.arnodo.fr/Damien/arista-evpn-vxlan-clab (`configs/*.cfg`)
|
||
- **Reference article**: overlaid.net EVPN Configuration Example (document `arista-bgp-evpn-configuration-example-overlaid.md` if available locally)
|
||
- **These configs are the source of truth** — extract all IPs, ASNs, peer groups, VLANs, VNIs from them
|
||
|
||
### Target Structure
|
||
|
||
```
|
||
objects/
|
||
├── 01-foundation.yml # InfraFabric, InfraAutonomousSystem
|
||
├── 02-devices.yml # InfraDevice (10 devices)
|
||
├── 03-interfaces.yml # InterfaceLoopback, InterfaceEthernet, InterfaceLag, InterfaceVlan
|
||
├── 04-ipam.yml # InfraIPAddress (all /31, /32, /24 assignments)
|
||
├── 05-vlans-vxlan.yml # InfraVLAN, InfraVNI, InfraVTEP, InfraVlanVniMapping, InfraEVPNInstance
|
||
├── 06-bgp.yml # InfraBGPRouterConfig, InfraBGPPeerGroup, InfraBGPSession, InfraBGPAddressFamily
|
||
├── 07-vrfs.yml # InfraVRF, InfraRouteTarget
|
||
└── 08-mlag.yml # InfraMlagDomain, InfraMlagPeerConfig
|
||
```
|
||
|
||
**Order matters**: files are loaded sequentially, dependencies must be satisfied (devices before interfaces, interfaces before IPs, etc.).
|
||
|
||
## Reference Topology (overlaid.net)
|
||
|
||
- 2 spines (AS 65000), 8 leafs in 4 MLAG pairs (AS 65001–65004)
|
||
- Loopback0: BGP router-id per device, Loopback1: shared VTEP IP per MLAG pair
|
||
- VLANs 4090 (MLAG peer) / 4091 (MLAG iBGP) with trunk groups
|
||
- Underlay: eBGP point-to-point (spine↔leaf) + iBGP (leaf↔leaf peer)
|
||
- Overlay: EVPN eBGP multihop on loopbacks, spines with next-hop-unchanged
|
||
- L2VXLAN: VLAN 40 → VNI 110040, redistribute learned
|
||
- L3VXLAN: VRF gold → VNI 100001, redistribute connected (leaf3-4, leaf7-8)
|
||
- Border peering: BGP sessions inside VRF (leaf7/8 → AS 64999 in VRF gold)
|
||
|
||
### IP Addressing Quick Reference
|
||
|
||
| Device | Lo0 (router-id) | Lo1 (VTEP) | AS |
|
||
|---------|------------------|--------------|-------|
|
||
| spine1 | 10.0.250.1 | — | 65000 |
|
||
| spine2 | 10.0.250.2 | — | 65000 |
|
||
| leaf1 | 10.0.250.11 | 10.0.255.11 | 65001 |
|
||
| leaf2 | 10.0.250.12 | 10.0.255.11 | 65001 |
|
||
| leaf3 | 10.0.250.13 | 10.0.255.12 | 65002 |
|
||
| leaf4 | 10.0.250.14 | 10.0.255.12 | 65002 |
|
||
| leaf5 | 10.0.250.15 | 10.0.255.13 | 65003 |
|
||
| leaf6 | 10.0.250.16 | 10.0.255.13 | 65003 |
|
||
| leaf7 | 10.0.250.17 | 10.0.255.14 | 65004 |
|
||
| leaf8 | 10.0.250.18 | 10.0.255.14 | 65004 |
|
||
|
||
### P2P Addressing Pattern
|
||
|
||
- spine1→leaf{N}: `10.0.1.{(N-1)*2}/31` (spine side) / `10.0.1.{(N-1)*2+1}/31` (leaf side)
|
||
- spine2→leaf{N}: `10.0.2.{(N-1)*2}/31` (spine side) / `10.0.2.{(N-1)*2+1}/31` (leaf side)
|
||
- MLAG iBGP: leaf pairs on `10.0.3.{pair_offset}/31`
|
||
- MLAG peer: leaf pairs on `10.0.199.254/31` and `10.0.199.255/31`
|
||
|
||
## Infrahub Object File Format
|
||
|
||
```yaml
|
||
---
|
||
apiVersion: infrahub.app/v1
|
||
kind: Object
|
||
spec:
|
||
kind: InfraDevice
|
||
data:
|
||
- name: spine1
|
||
role: spine
|
||
platform: arista_eos # References InfraPlatform by HFID
|
||
```
|
||
|
||
### Key Rules
|
||
|
||
1. **Reference existing objects by their `human_friendly_id` (HFID)** — not by ID
|
||
2. For relationships with cardinality one, use the HFID value directly: `site: "dc1"`
|
||
3. For relationships with cardinality many, use a list: `vlans: ["40", "4090"]`
|
||
4. For nested objects (Component kind), use inline `data:` blocks
|
||
5. For multi-field HFIDs, use list format: `device: ["spine1", "Loopback0"]` → references `device__name + interface__name`
|
||
|
||
### Schema human_friendly_id Reference (critical for references)
|
||
|
||
| Node | HFID fields |
|
||
|-----------------------|------------------------------------------------|
|
||
| InfraDevice | `name__value` |
|
||
| InfraAutonomousSystem | `asn__value` |
|
||
| InfraInterfaceEthernet| `device__name__value` + `name__value` |
|
||
| InfraInterfaceLoopback| `device__name__value` + `name__value` |
|
||
| InfraInterfaceVlan | `device__name__value` + `name__value` |
|
||
| InfraInterfaceLag | `device__name__value` + `name__value` |
|
||
| InfraIPAddress | `address__value` |
|
||
| InfraVLAN | `vlan_id__value` |
|
||
| InfraVNI | `vni__value` |
|
||
| InfraVTEP | `device__name__value` |
|
||
| InfraBGPRouterConfig | `device__name__value` |
|
||
| InfraBGPPeerGroup | `bgp_config__router_id__value` + `name__value` |
|
||
| InfraBGPSession | `bgp_config__router_id__value` + `peer_address__value` |
|
||
| InfraVLAN | `vlan_id__value` |
|
||
| InfraFabric | `name__value` |
|
||
| LocationSite | `name__value` |
|
||
| InfraPlatform | `name__value` |
|
||
|
||
## Schema Files (in `schemas/`)
|
||
|
||
| File | Content |
|
||
|-------------------|-----------------------------------------------------------------------|
|
||
| `base.yml` | Device, Interfaces (Ethernet, Loopback, Vlan, Lag), IPAddress, Site, Platform |
|
||
| `bgp.yml` | AutonomousSystem, BGPRouterConfig, BGPPeerGroup, BGPSession, BGPAddressFamily |
|
||
| `vlan_vxlan.yml` | VLAN, VNI, VTEP, VlanVniMapping, EVPNInstance |
|
||
| `vrf.yml` | VRFConfig, RouteTarget, VRFDeviceAssignment |
|
||
| `mlag.yml` | MlagDomain, MlagPeerConfig, MlagInterface |
|
||
| `extensions.yml` | Fabric, UnderlayLink, HostConnection |
|
||
|
||
## Validation
|
||
|
||
```bash
|
||
# Validate object file format
|
||
infrahubctl object validate objects/01-foundation.yml
|
||
|
||
# Load objects sequentially
|
||
infrahubctl object load objects/01-foundation.yml
|
||
infrahubctl object load objects/02-devices.yml
|
||
# ... etc.
|
||
```
|
||
|
||
Always validate before committing. Fix any errors before pushing.
|
||
|
||
## Commit Convention
|
||
|
||
```
|
||
feat(objects): short description — refs #52
|
||
```
|
||
|
||
- One logical file per commit (or group of closely related files)
|
||
- Reference issue #52
|
||
|
||
## Workflow
|
||
|
||
1. Read the relevant schema file to understand required fields and relationships
|
||
2. Extract data from the clab configs (configs/*.cfg) or the reference topology doc
|
||
3. Create the object file respecting the Infrahub Object File format
|
||
4. Validate with `infrahubctl object validate`
|
||
5. Commit with proper message
|
||
|
||
## Don'ts
|
||
|
||
- Don't invent data not present in the reference topology configs
|
||
- Don't create schema modifications — the schema is frozen for this task
|
||
- Don't skip optional fields that have data in the configs (description, mtu, etc.)
|
||
- Don't forget the dependency order: foundation → devices → interfaces → IPs → rest
|
||
- Don't use `id` references — always use human_friendly_id (HFID) strings
|