Damien
12d927d460
fix: add human_friendly_id to 4 schemas for idempotent Repository sync ( #29 )
...
## Summary
- Add `local_identifier` attribute + `uniqueness_constraints` + `human_friendly_id` to **InfraVlanVniMapping**, **InfraEVPNInstance**, **InfraMlagInterface**, and **InfraUnderlayLink**, following the same pattern already used for `InfraBGPPeerGroup` and `InfraBGPSession`
- Populate `local_identifier` in all corresponding object YAML files with deterministic composite keys so Infrahub can upsert objects during Repository backend sync instead of creating duplicates
## Schema changes
| Schema file | Model | human_friendly_id |
|---|---|---|
| `infrahub/schemas/vlan_vxlan.yml` | `InfraVlanVniMapping` | `local_identifier__value` |
| `infrahub/schemas/vlan_vxlan.yml` | `InfraEVPNInstance` | `local_identifier__value` |
| `infrahub/schemas/mlag.yml` | `InfraMlagInterface` | `local_identifier__value` |
| `infrahub/schemas/extensions.yml` | `InfraUnderlayLink` | `local_identifier__value` |
## Object file changes
| Object file | Kind | Key format | Example |
|---|---|---|---|
| `infrahub/objects/06-vlans-vxlan.yml` | `InfraVlanVniMapping` | `{device}__vlan{vlan_id}__vni{vni_id}` | `leaf1__vlan40__vni110040` |
| `infrahub/objects/06-vlans-vxlan.yml` | `InfraEVPNInstance` | `{device}__vlan{vlan_id}` | `leaf1__vlan40` |
| `infrahub/objects/12-mlag.yml` | `InfraMlagInterface` | `mlag{id}__{device1}-{device2}` | `mlag1__leaf1-leaf2` |
| `infrahub/objects/14-fabric-links.yml` | `InfraUnderlayLink` | `{local_dev}-{local_intf}__{remote_dev}-{remote_intf}` | `spine1-eth1__leaf1-eth11` |
Note: `InfraMlagInterface` objects (4 entries, one per MLAG pair) and `InfraUnderlayLink` objects (16 entries, all spine↔leaf P2P links) are new additions to their respective files.
## Test plan
- [x] `infrahubctl schema load infrahub/schemas/*.yml` succeeds without errors
- [x] `infrahubctl object load infrahub/objects/06-vlans-vxlan.yml` succeeds
- [x] `infrahubctl object load infrahub/objects/12-mlag.yml` succeeds
- [x] `infrahubctl object load infrahub/objects/14-fabric-links.yml` succeeds
- [x] Re-running the same load is idempotent (no duplicate objects created)
- [x] Gitea Repository backend sync completes without import errors
2026-03-03 16:26:46 +00:00
Damien
1dfec839c7
Actualiser .infrahub.yml
2026-03-01 19:38:46 +00:00
Damien
833a460ddf
Actualiser .infrahub.yml
2026-03-01 18:27:07 +00:00
Damien
68b9e88483
docs: Add README for Infrahub transforms ( #28 )
...
Adds a concise README in `infrahub/transforms/` documenting the 6 available Jinja2 transforms, usage commands, directory structure, and how to add new transforms.
Reviewed-on: #28
2026-03-01 16:29:40 +00:00
Damien
1b918a4cbc
feat: Add Infrahub Jinja2 transform for BGP configuration ( #23 ) ( #27 )
...
## Summary
Closes #23 . Implements a single unified `bgp_yang_transform` covering the complete BGP router stanza for all 10 fabric devices.
**Design decision:** One transform (one query + one template) rather than 4 separate transforms, because all BGP components (process config, peer groups, neighbors, AFs) live under a single `router bgp <ASN>` stanza and must be consistent. This avoids multiple API calls per device and keeps the data model coherent.
| File | Description |
|------|-------------|
| `infrahub/transforms/queries/bgp_intent.gql` | Unified GraphQL query — `InfraBGPRouterConfig` (with peer_groups, sessions) + `InfraBGPAddressFamily` (with active_peer_groups, active_sessions, networks, optional vrf) |
| `infrahub/transforms/templates/bgp_yang.j2` | Jinja2 template — renders `bgp.global`, `bgp.peer_groups`, `bgp.neighbors`, `bgp.address_families`, `bgp.vrf_neighbors`, `bgp.vrf_address_families`; returns `[]` for devices with no BGP config |
| `infrahub/transforms/tests/bgp_yang/test.yml` | Smoke check + unit render tests for leaf1, spine1, leaf7 |
| `infrahub/transforms/tests/bgp_yang/leaf1/` | 3 peer-groups, 5 global neighbors, 2 global AFs |
| `infrahub/transforms/tests/bgp_yang/spine1/` | 1 peer-group (evpn/next-hop-unchanged), 16 neighbors (8 direct underlay + 8 EVPN), IPv4 AF activates individual sessions |
| `infrahub/transforms/tests/bgp_yang/leaf7/` | leaf1 pattern + VRF gold border session (AS 64999) + VRF-scoped IPv4 unicast AF |
| `.infrahub.yml` | Registers `bgp_intent` query and `bgp_yang_transform` |
## Validation
| Device | Expected output |
|--------|----------------|
| `leaf1` | 3 peer-groups, 5 global neighbors (underlay×2, iBGP×1, EVPN×2), 2 AFs, empty VRF sections |
| `spine1` | 1 peer-group (evpn, next-hop-unchanged), 16 neighbors (8 direct with `remote_asn`, 8 EVPN via peer-group), IPv4 AF activates individual sessions |
| `leaf7` | Same as leaf1 (AS 65004) + `vrf_neighbors: [{10.90.90.1, AS 64999, VRF gold}]` + `vrf_address_families: [{ipv4, VRF gold, active_sessions: [10.90.90.1]}]` |
```bash
infrahubctl render bgp_yang_transform device_name=leaf1
infrahubctl render bgp_yang_transform device_name=spine1
infrahubctl render bgp_yang_transform device_name=leaf7
```
## Design notes
- Follows identical conventions to existing transforms (#20–#22)
- All optional relationships (`remote_asn`, `peer_group`, `vrf`, `peer_device`, `update_source`, etc.) wrapped in `is defined and is not none` guards
- `send_community` value `"none"` (schema default) is normalised to `null` in the output — keeps the rendered JSON clean for downstream consumers
- VRF-scoped sessions and AFs are separated into `vrf_neighbors` / `vrf_address_families` arrays, each entry carrying a `"vrf"` key, so the template consumer can trivially iterate per-VRF without filtering
2026-03-01 13:22:51 +00:00
Damien
cf7da535ed
feat: Add Infrahub Jinja2 transforms for MLAG configuration ( #22 ) ( #26 )
...
## Summary
Closes #22 . Implements Infrahub Jinja2 transforms for MLAG configuration, generating Arista-native YANG-compatible JSON payloads from Infrahub intent data.
| File | Description |
|------|-------------|
| `infrahub/transforms/queries/mlag_intent.gql` | GraphQL query — fetches `InfraMlagPeerConfig` by `$device_name`, including MLAG domain attributes, peer/iBGP VLANs, local interface SVI, and peer-link LAG |
| `infrahub/transforms/templates/mlag_yang.j2` | Jinja2 template — renders a JSON object targeting `/arista-mlag-augments:mlag/config`; returns `[]` for devices with no MLAG (spines) |
| `infrahub/transforms/tests/mlag_yang/test.yml` | Test spec: smoke check + unit render tests for `leaf1` and `spine1` |
| `infrahub/transforms/tests/mlag_yang/leaf1/` | Mock input + expected output for leaf1 (full MLAG config, domain `leafs-1-2`) |
| `infrahub/transforms/tests/mlag_yang/spine1/` | Mock input (empty edges) + expected output `[]` for spine1 |
| `.infrahub.yml` | Registers `mlag_intent` query and `mlag_yang_transform` jinja2 transform |
## Output shape (leaf1)
```json
{
"mlag": {
"config": {
"domain-id": "leafs-1-2",
"peer-link": "Port-Channel999",
"local-interface": "Vlan4090",
"peer-address": "10.0.199.255",
"shutdown": false
},
"dual_primary_detection": {
"enabled": true,
"delay": 10,
"action": "errdisable",
"heartbeat_peer_ip": "172.16.0.50",
"heartbeat_vrf": "mgmt"
},
"virtual_mac": "c001.cafe.babe",
"peer_vlan_id": 4090,
"ibgp_vlan_id": 4091,
"local_interface_ip": "10.0.199.254/31"
}
}
```
## Validation
```bash
infrahubctl render mlag_yang_transform device_name=leaf1 # → MLAG config JSON
infrahubctl render mlag_yang_transform device_name=spine1 # → []
```
## Design notes
- Follows identical conventions to existing transforms (#20 VLAN/interface/VXLAN, #21 VRF/L3VNI)
- All optional relationship accesses wrapped in `is defined and is not none` guards
- Spine/non-MLAG devices return `[]` (empty array) — consistent with the "no data → empty collection" pattern used in vxlan_yang for devices without VTEP
2026-03-01 11:06:55 +00:00
Damien
a105e44bbd
feat: Add Infrahub Jinja2 transform for VRF/L3VNI configuration ( #21 ) ( #25 )
...
## Summary
Implements Infrahub Jinja2 Transform for VRF/L3VNI configuration, generating structured JSON payloads from Infrahub intent data. Closes #21 .
## What's included
- **GraphQL query** (`transforms/queries/vrf_intent.gql`): Queries `InfraVRFDeviceAssignment` by device name, fetching VRF details, L3VNI, route targets, and device-specific route distinguisher
- **Jinja2 transform** (`transforms/templates/vrf_yang.j2`): Renders VRF config payloads with defensive null handling (lessons learned from #20 )
- **`.infrahub.yml`** updated with the new query and transform definitions
- **Tests** (`transforms/tests/vrf_yang/`) using correct Infrahub pytest format (`jinja2-transform-smoke` + `jinja2-transform-unit-render`)
## Validation
All transforms render correctly:
| Device | Expected | Result |
|--------|----------|--------|
| `leaf3` | VRF gold, RD `10.0.250.13:1`, L3VNI 100001 | ✅ |
| `leaf7` | VRF gold, RD `10.0.250.17:1`, L3VNI 100001 | ✅ |
| `leaf1` | Empty array (no VRF assignment) | ✅ |
| `spine1` | Empty array (no VRF assignment) | ✅ |
## Usage
```bash
# Local debugging
infrahubctl render vrf_yang_transform device_name=leaf3
# API endpoint
GET /api/transform/jinja2/vrf_yang_transform?device_name=leaf3
```
## Related
- Depends on: #20 (base transforms infrastructure, already merged)
- Reference: Arista EVPN Type-5 / L3VXLAN configuration from lab topology
2026-03-01 10:45:01 +00:00
Damien
668e9cbada
feat: Add Infrahub Jinja2 transforms for VLANs, interfaces, and VXLAN ( #20 ) ( #24 )
...
## Summary
Closes #20
Adds Infrahub Jinja2 transforms that query device intent from Infrahub via GraphQL and produce structured JSON payloads (YANG-style) suitable for gNMI Set operations on Arista EOS devices.
- **3 GraphQL queries** — `vlan_intent`, `interface_intent`, `vxlan_intent` — each parameterized by `$device_name`
- **3 Jinja2 templates** — `vlan_yang.j2`, `interface_yang.j2`, `vxlan_yang.j2` — producing JSON arrays/objects from the GraphQL response
- **Integration test fixtures** — one directory per transform with `input.json`, `output.json`, and `test.yml`, using leaf1 from the lab topology as sample device
- **`.infrahub.yml` updated** with `queries` and `jinja2_transforms` sections
## Files added
```
transforms/
├── queries/
│ ├── vlan_intent.gql # VLANs via VTEP mappings + SVI interfaces
│ ├── interface_intent.gql # All interface types with IPs
│ └── vxlan_intent.gql # VTEP config + VLAN/VNI/VRF mappings
├── templates/
│ ├── vlan_yang.j2 # JSON array of VLANs (merged, deduplicated, sorted)
│ ├── interface_yang.j2 # JSON array of interfaces with type discriminator
│ └── vxlan_yang.j2 # JSON object: vtep + vlan_vni + vrf_vni mappings
└── tests/
├── vlan_yang/{input,output,test}.{json,yml}
├── interface_yang/{input,output,test}.{json,yml}
└── vxlan_yang/{input,output,test}.{json,yml}
```
## Transform usage
```bash
# Render locally
infrahubctl render vlan_yang_transform device_name=leaf1
infrahubctl render interface_yang_transform device_name=leaf1
infrahubctl render vxlan_yang_transform device_name=leaf1
# Via API
GET /api/transform/jinja2/vlan_yang_transform?device_name=leaf1
GET /api/transform/jinja2/interface_yang_transform?device_name=leaf1
GET /api/transform/jinja2/vxlan_yang_transform?device_name=leaf1
```
## Test plan
- [x] Load branch into Infrahub (`infrahubctl schema load` + `infrahubctl object load`)
- [x] Run `infrahubctl render vlan_yang_transform device_name=leaf1` and verify JSON output matches expected VLANs (40, 4090, 4091)
- [x] Run `infrahubctl render interface_yang_transform device_name=leaf1` and verify all interface types are present with correct attributes
- [x] Run `infrahubctl render vxlan_yang_transform device_name=leaf1` and verify VTEP source address, UDP port, and VLAN-VNI mapping for VLAN 40 / VNI 110040
- [x] Run `infrahubctl render vxlan_yang_transform device_name=leaf3` and verify VRF gold / L3VNI 100001 appears in `vrf_vni_mappings`
- ~~[ ] Verify `infrahubctl test` passes for all three test fixtures~~
Reviewed-on: #24
2026-02-28 17:42:08 +00:00
Damien
e00cf517e3
Merge pull request 'Add bidirectional navigation relationships' ( #18 ) from feat/update-identifiers into main
...
Reviewed-on: #18
2026-02-22 09:27:20 +00:00
Damien
db54e56b41
chore: Repository cleanup - Remove unnecessary files ( #16 )
...
## Summary
Repository cleanup to remove unnecessary files and streamline documentation after the successful EVPN-VXLAN lab implementation.
Closes #15
---
## Changes
### Files Removed (13 files total)
**Scripts folder:**
- `scripts/deploy.sh`
- `scripts/test-connectivity.sh`
- `scripts/cleanup.sh`
**Root-level markdown files:**
- `BRANCH_SUMMARY.md`
- `BUGFIX_EVPN_ACTIVATION.md`
- `DEPLOYMENT_GUIDE.md`
- `FIXES_APPLIED.md`
- `TESTING_CHECKLIST.md`
- `VLAN_TAGGING_FIX_EXPLANATION.md`
**docs/ folder (entire folder removed):**
- `docs/HOST_INTERFACE_CONFIGURATION.md`
- `docs/configuration-guide.md`
- `docs/quick-reference.md`
- `docs/validation-commands.md`
### Files Updated
- `hosts/README.md` - Fixed broken links
- `README.md` - Updated repository structure section
---
## Final Repository Structure
```
├── .gitignore
├── README.md # Main documentation
├── TROUBLESHOOTING.md # Troubleshooting guide
├── END_TO_END_TESTING.md # Testing procedures
├── evpn-lab.clab.yml # ContainerLab topology
├── configs/ # Switch configurations (10 files)
└── hosts/ # Host interface configs (5 files)
```
---
## Testing
- [x] Lab redeployed successfully with `containerlab deploy -t evpn-lab.clab.yml`
- [x] L2 VXLAN connectivity verified (host1 ↔ host3)
- [x] L3 VXLAN connectivity verified (host2 ↔ host4)
- [x] All BGP EVPN sessions established
- [x] MLAG pairs operational
Reviewed-on: #16
2025-11-30 19:07:22 +00:00
Damien
9502302b76
Revert topology to original version before accidental commits
2025-11-30 08:55:08 +00:00
Damien
d6acdfbe75
Revert accidental commit to main - remove HOST_CONFIGURATION.md
2025-11-30 08:53:58 +00:00
Damien
e6210267a6
Revert accidental commit to main - remove host4-interfaces
2025-11-30 08:53:44 +00:00
Damien
67816b84a1
Revert accidental commit to main - remove host3-interfaces
2025-11-30 08:53:32 +00:00
Damien
aef0890f34
Revert accidental commit to main - remove host2-interfaces
2025-11-30 08:53:21 +00:00
Damien
0baec91037
Revert accidental commit to main - remove host interface files
2025-11-30 08:53:11 +00:00
Damien
7c08125826
Add comprehensive host interface configuration documentation
2025-11-30 08:21:24 +00:00
Damien
e04a531a86
Update topology to use persistent interface files via binds instead of exec commands
2025-11-30 08:20:58 +00:00
Damien
926ab47337
Add host4 interface configuration for LACP bonding with VLAN 78
2025-11-30 08:20:31 +00:00
Damien
ce76b0c342
Add host3 interface configuration for LACP bonding with VLAN 40
2025-11-30 08:20:26 +00:00
Damien
31e1e345cd
Add host2 interface configuration for LACP bonding with VLAN 34
2025-11-30 08:20:21 +00:00
Damien
050a529c68
Add host1 interface configuration for LACP bonding with VLAN 40
2025-11-30 08:20:16 +00:00
Damien
4fc902ee13
Add DEPLOYMENT_GUIDE.md with step-by-step instructions
...
Provide clear deployment instructions, verification checklist, and
troubleshooting guidance for the EVPN-VXLAN lab with applied fixes.
2025-11-28 09:28:13 +00:00
Damien
783e12cea6
Add FIXES_APPLIED.md to main branch
...
Document all critical fixes discovered during lab testing:
- Spine routing: ip routing command added
- MLAG: static LAG mode enabled
- Pending: port-channel access mode, host networking
Track status of each fix for deployment readiness.
2025-11-28 09:27:56 +00:00
Damien
62efe9fc93
Apply critical fix: Add ip routing command to spine2
...
This enables BGP and IP forwarding on spine switches. Without this command,
BGP sessions cannot be established and routing is disabled. This is essential
for the underlay fabric to function properly.
2025-11-28 09:27:19 +00:00
Damien
41a7e5e9e3
Apply critical fix: Add ip routing command to spine1
...
This enables BGP and IP forwarding on spine switches. Without this command,
BGP sessions cannot be established and routing is disabled. This is essential
for the underlay fabric to function properly.
2025-11-28 09:27:03 +00:00
Damien
d2cdab6b5e
Add quick reference guide
2025-11-16 15:41:44 +00:00
Damien
2759d9cb38
Add .gitignore file
2025-11-16 15:41:05 +00:00
Damien
279515edd6
Add comprehensive configuration guide
2025-11-16 15:40:19 +00:00
Damien
4991e18430
Add cleanup script
2025-11-16 15:39:20 +00:00
Damien
21e1cb2891
Add connectivity test script
2025-11-16 15:38:45 +00:00
Damien
600c8e9f57
Add deployment script with interactive menu
2025-11-16 15:38:18 +00:00
Damien
222ffb6bb5
Add validation commands documentation
2025-11-16 15:37:49 +00:00
Damien
944977510c
Add leaf8 configuration with VRF gold and BGP border
2025-11-16 15:37:07 +00:00
Damien
61824f2ddf
Add leaf7 configuration with VRF gold and BGP border
2025-11-16 15:36:49 +00:00
Damien
a1b87aabeb
Add leaf6 configuration
2025-11-16 15:36:31 +00:00
Damien
c90a104528
Add leaf5 configuration
2025-11-16 15:36:16 +00:00
Damien
18f2f88440
Add leaf4 configuration with VRF gold
2025-11-16 15:36:02 +00:00
Damien
2e025f7116
Add leaf3 configuration with VRF gold
2025-11-16 15:35:47 +00:00
Damien
15d5d4017c
Add leaf2 configuration
2025-11-16 15:35:29 +00:00
Damien
471722f0b5
Add leaf1 configuration
2025-11-16 15:35:13 +00:00
Damien
f7dc787960
Add spine2 configuration
2025-11-16 15:34:50 +00:00
Damien
1d2b843d45
Add spine1 configuration
2025-11-16 15:34:37 +00:00
Damien
0ea0e8c740
Add comprehensive README
2025-11-16 15:34:18 +00:00
Damien
240f5493ed
Add ContainerLab topology file
2025-11-16 15:33:43 +00:00