feat: Add Infrahub Jinja2 transforms for MLAG configuration (#22) #26

Merged
Damien merged 1 commits from feat/infrahub-transforms-mlag into main 2026-03-01 11:06:56 +00:00
Owner

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)

{
  "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

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

🤖 Generated with Claude Code

## 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 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Damien added 1 commit 2026-03-01 11:05:05 +00:00
- Add GraphQL query mlag_intent.gql: queries InfraMlagPeerConfig by
  device name, returning local IP, peer address, heartbeat peer IP,
  MLAG domain (domain-id, virtual-mac, heartbeat VRF, dual-primary
  detection settings, peer/iBGP VLANs, peer devices), local interface
  SVI name, and peer-link LAG name
- Add Jinja2 template mlag_yang.j2: renders a JSON object targeting
  Arista-native YANG path /arista-mlag-augments:mlag/config; returns
  empty array [] for devices with no MLAG config (spines); all optional
  relationship accesses guarded with 'is defined and is not none' checks
- Update .infrahub.yml: register mlag_intent query and mlag_yang_transform
- Add unit test fixtures for leaf1 (full MLAG config) and spine1 (empty
  response → []) following jinja2-transform-unit-render format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Damien merged commit cf7da535ed into main 2026-03-01 11:06:56 +00:00
Damien deleted branch feat/infrahub-transforms-mlag 2026-03-01 11:07:02 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Damien/arista-evpn-vxlan-clab#26