From 5a335b37e6ecd57cbbf1469d0238503c47b8cb13 Mon Sep 17 00:00:00 2001 From: Damien Arnodo Date: Fri, 13 Feb 2026 19:47:57 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20update=20CLAUDE.md=20for=20issue=20#52?= =?UTF-8?q?=20object=20files=20task=20=E2=80=94=20refs=20#52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 171 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 46 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 4c28566..bf22f71 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,34 @@ Fabric-orchestrator manages Arista EVPN-VXLAN fabrics using Infrahub as the source of truth. Gitea: https://gitea.arnodo.fr/Damien/fabric-orchestrator -Branch: `feature/41-infrahub-schema` +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) @@ -12,71 +39,123 @@ Branch: `feature/41-infrahub-schema` - 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 as route-reflectors with next-hop-unchanged -- L2VXLAN (EVPN Type-2): VLAN→VNI mapping, redistribute learned -- L3VXLAN (EVPN Type-5): VRF→VNI mapping, redistribute connected +- 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) -## Schema Files (Infrahub YAML format, in `schemas/`) +### IP Addressing Quick Reference -| File | Content | -| ---------------- | ----------------------------------------------------------------------------- | -| `base.yml` | Device, Interfaces (Ethernet, Loopback, Vlan, Lag, Vxlan), IPAddress | -| `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` | UnderlayLink, HostConnection, FabricSettings | +| 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 | -## Infrahub Schema Rules +### P2P Addressing Pattern -1. `human_friendly_id` fields MUST have `unique: true` — globally unique across all instances -2. To scope human_friendly_id per-device, traverse Parent relationships: - `parent_rel__parent_attr__value` (e.g. `device__name__value`) -3. Parent relationships (`kind: Parent`) need `optional: false` explicitly -4. Self-referencing relationships need `direction: outbound` -5. Multiple relationships to the same peer type need distinct `identifier` values -6. Don't model the same concept twice (e.g. VTEP source_address vs InterfaceVxlan source_interface) -7. `kind: Attribute` for association, `kind: Component` for ownership (lifecycle-coupled) -8. `kind: Parent` implies the child cannot exist without the parent +- 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 -infrahubctl schema check schemas/ +# 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 run before committing. Fix any errors before pushing. +Always validate before committing. Fix any errors before pushing. ## Commit Convention ``` -fix(schema): short description — refs # -feat(schema): short description — refs # +feat(objects): short description — refs #52 ``` -- One logical change per commit -- Reference the Gitea issue number -- Comment on the issue after implementation with changes summary - -## Open Issues (prioritized) - -Check https://gitea.arnodo.fr/Damien/fabric-orchestrator/issues for current backlog. -Critical issues (blocking data load) take priority over functional improvements. -Dependency chain: resolve critical → significant → minor sequentially. +- One logical file per commit (or group of closely related files) +- Reference issue #52 ## Workflow -1. Read the issue description fully before starting -2. Read relevant schema files to understand current state -3. Make minimal, targeted changes -4. Validate with `infrahubctl schema check schemas/` -5. Commit with proper message referencing the issue -6. Comment on the Gitea issue with what was changed +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 add fields not needed by the reference topology -- Don't change `human_friendly_id` without checking uniqueness implications -- Don't remove existing relationships without checking reverse dependencies -- Don't create new schema files without discussing first +- 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