Implement MLAG Infrahub Transforms #22

Closed
opened 2026-02-27 12:22:08 +00:00 by Damien · 0 comments
Owner

Description

Create Infrahub Transforms for MLAG configuration, handling peer-link, domain-id, and dual-active detection.

Context

MLAG is critical for leaf-pair redundancy in the fabric. Since MLAG isn't fully supported in OpenConfig, we rely on Arista-native YANG paths. Infrahub schema will store MLAG intent (replacing NetBox custom fields).

Tasks

  • Define Infrahub schema for MLAG objects
    • MLAG Domain (domain-id, virtual-mac)
    • MLAG Peer relationship (device ↔ device)
    • MLAG interfaces (peer-link, member ports)
  • Create GraphQL queries for MLAG intent
    • mlag_domain_intent.gql - Domain config, peer addresses
    • mlag_interfaces_intent.gql - Peer-link and MLAG members
  • Create Jinja2 transforms for YANG generation
    • mlag_config_yang.j2 - MLAG domain configuration
    • mlag_interfaces_yang.j2 - Port-channel MLAG IDs
  • Map virtual MAC address for anycast gateway
  • Handle dual-active detection (heartbeat via management)

MLAG Configuration Scope

# MLAG Peering VLAN
vlan 4090
  name mlag-peer
  trunk group mlag-peer

interface Vlan4090
  ip address 10.0.199.254/31
  no autostate

# MLAG Peer-Link
interface Port-Channel999
  description MLAG Peer
  switchport mode trunk
  switchport trunk group mlag-peer

# MLAG Configuration
mlag configuration
  domain-id leafs
  peer-link Port-Channel999
  local-interface Vlan4090
  peer-address 10.0.199.255
  dual-primary detection delay 10 action errdisable all-interfaces

# Virtual MAC for anycast gateway
ip virtual-router mac-address c001.cafe.babe

Infrahub Schema (proposed)

# InfraMlagDomain
- name: InfraMlagDomain
  namespace: Infra
  attributes:
    - name: domain_id
      kind: Text
    - name: virtual_mac
      kind: Text
    - name: peer_vlan
      kind: Number
    - name: dual_primary_enabled
      kind: Boolean
    - name: dual_primary_delay
      kind: Number
  relationships:
    - name: devices
      peer: InfraDevice
      cardinality: many

Example Implementation

GraphQL Query (mlag_domain_intent.gql)

query MlagDomainIntent($device: String!) {
  InfraDevice(name__value: $device) {
    edges {
      node {
        name { value }
        mlag_domain {
          node {
            domain_id { value }
            virtual_mac { value }
            peer_vlan { value }
            dual_primary_enabled { value }
            dual_primary_delay { value }
          }
        }
        mlag_peer { node { name { value } } }
        mlag_local_ip { value }
        mlag_peer_ip { value }
      }
    }
  }
}

Jinja2 Transform (mlag_config_yang.j2)

{% set device = data.InfraDevice.edges[0].node %}
{% if device.mlag_domain %}
{% set mlag = device.mlag_domain.node %}
{
  "path": "/arista-mlag-augments:mlag/config",
  "value": {
    "domain-id": "{{ mlag.domain_id.value }}",
    "peer-link": "Port-Channel999",
    "local-interface": "Vlan{{ mlag.peer_vlan.value }}",
    "peer-address": "{{ device.mlag_peer_ip.value }}",
    "shutdown": false
  }
}
{% endif %}

.infrahub.yml Addition

jinja2_transforms:
  - name: mlag_config_yang_transform
    description: "Generate YANG payload for MLAG domain config"
    query: mlag_domain_intent
    template_path: transforms/mlag_config_yang.j2

  - name: mlag_interfaces_yang_transform
    description: "Generate YANG payload for MLAG interface config"
    query: mlag_interfaces_intent
    template_path: transforms/mlag_interfaces_yang.j2

queries:
  - name: mlag_domain_intent
    file_path: queries/mlag_domain_intent.gql
  - name: mlag_interfaces_intent
    file_path: queries/mlag_interfaces_intent.gql

YANG Path Notes

MLAG uses Arista-native YANG, not OpenConfig:

  • /arista-mlag-augments:mlag/config - Main MLAG config
  • /arista-mlag-augments:mlag/config/domain-id
  • /arista-mlag-augments:mlag/config/peer-link
  • /arista-mlag-augments:mlag/config/local-interface
  • /arista-mlag-augments:mlag/config/peer-address

⚠️ Note: Full MLAG state may require eAPI fallback

Output Files

transforms/
├── mlag_config_yang.j2
└── mlag_interfaces_yang.j2
queries/
├── mlag_domain_intent.gql
└── mlag_interfaces_intent.gql
tests/
├── mlag_config_transform_test.yml
└── mlag_interfaces_transform_test.yml

Acceptance Criteria

  • Transforms produce valid MLAG YANG structures
  • Handles peer-link and MLAG member interfaces
  • Virtual MAC for anycast gateway configured
  • Dual-active detection settings included
  • Unit tests validate all scenarios

Migration Notes (from NetBox)

Before (NetBox) After (Infrahub)
Custom fields on Device InfraMlagDomain schema object
Custom fields on Interface Relationships in schema
MlagMapper class mlag_config_yang_transform
  • Depends on: #41 (Infrahub Schema definition)
  • Depends on: #30 (Base Transforms pattern)
  • Note: Some MLAG state requires eAPI (gNMI limitation)
## Description Create Infrahub Transforms for MLAG configuration, handling peer-link, domain-id, and dual-active detection. ## Context MLAG is critical for leaf-pair redundancy in the fabric. Since MLAG isn't fully supported in OpenConfig, we rely on Arista-native YANG paths. Infrahub schema will store MLAG intent (replacing NetBox custom fields). ## Tasks - [x] Define Infrahub schema for MLAG objects - MLAG Domain (domain-id, virtual-mac) - MLAG Peer relationship (device ↔ device) - MLAG interfaces (peer-link, member ports) - [x] Create GraphQL queries for MLAG intent - `mlag_domain_intent.gql` - Domain config, peer addresses - `mlag_interfaces_intent.gql` - Peer-link and MLAG members - [x] Create Jinja2 transforms for YANG generation - `mlag_config_yang.j2` - MLAG domain configuration - `mlag_interfaces_yang.j2` - Port-channel MLAG IDs - [x] Map virtual MAC address for anycast gateway - [x] Handle dual-active detection (heartbeat via management) ## MLAG Configuration Scope ``` # MLAG Peering VLAN vlan 4090 name mlag-peer trunk group mlag-peer interface Vlan4090 ip address 10.0.199.254/31 no autostate # MLAG Peer-Link interface Port-Channel999 description MLAG Peer switchport mode trunk switchport trunk group mlag-peer # MLAG Configuration mlag configuration domain-id leafs peer-link Port-Channel999 local-interface Vlan4090 peer-address 10.0.199.255 dual-primary detection delay 10 action errdisable all-interfaces # Virtual MAC for anycast gateway ip virtual-router mac-address c001.cafe.babe ``` ## Infrahub Schema (proposed) ```yaml # InfraMlagDomain - name: InfraMlagDomain namespace: Infra attributes: - name: domain_id kind: Text - name: virtual_mac kind: Text - name: peer_vlan kind: Number - name: dual_primary_enabled kind: Boolean - name: dual_primary_delay kind: Number relationships: - name: devices peer: InfraDevice cardinality: many ``` ## Example Implementation ### GraphQL Query (`mlag_domain_intent.gql`) ```graphql query MlagDomainIntent($device: String!) { InfraDevice(name__value: $device) { edges { node { name { value } mlag_domain { node { domain_id { value } virtual_mac { value } peer_vlan { value } dual_primary_enabled { value } dual_primary_delay { value } } } mlag_peer { node { name { value } } } mlag_local_ip { value } mlag_peer_ip { value } } } } } ``` ### Jinja2 Transform (`mlag_config_yang.j2`) ```jinja2 {% set device = data.InfraDevice.edges[0].node %} {% if device.mlag_domain %} {% set mlag = device.mlag_domain.node %} { "path": "/arista-mlag-augments:mlag/config", "value": { "domain-id": "{{ mlag.domain_id.value }}", "peer-link": "Port-Channel999", "local-interface": "Vlan{{ mlag.peer_vlan.value }}", "peer-address": "{{ device.mlag_peer_ip.value }}", "shutdown": false } } {% endif %} ``` ### `.infrahub.yml` Addition ```yaml jinja2_transforms: - name: mlag_config_yang_transform description: "Generate YANG payload for MLAG domain config" query: mlag_domain_intent template_path: transforms/mlag_config_yang.j2 - name: mlag_interfaces_yang_transform description: "Generate YANG payload for MLAG interface config" query: mlag_interfaces_intent template_path: transforms/mlag_interfaces_yang.j2 queries: - name: mlag_domain_intent file_path: queries/mlag_domain_intent.gql - name: mlag_interfaces_intent file_path: queries/mlag_interfaces_intent.gql ``` ## YANG Path Notes MLAG uses Arista-native YANG, not OpenConfig: - `/arista-mlag-augments:mlag/config` - Main MLAG config - `/arista-mlag-augments:mlag/config/domain-id` - `/arista-mlag-augments:mlag/config/peer-link` - `/arista-mlag-augments:mlag/config/local-interface` - `/arista-mlag-augments:mlag/config/peer-address` ⚠️ **Note**: Full MLAG state may require eAPI fallback ## Output Files ``` transforms/ ├── mlag_config_yang.j2 └── mlag_interfaces_yang.j2 queries/ ├── mlag_domain_intent.gql └── mlag_interfaces_intent.gql tests/ ├── mlag_config_transform_test.yml └── mlag_interfaces_transform_test.yml ``` ## Acceptance Criteria - [ ] Transforms produce valid MLAG YANG structures - [ ] Handles peer-link and MLAG member interfaces - [ ] Virtual MAC for anycast gateway configured - [ ] Dual-active detection settings included - [ ] Unit tests validate all scenarios ## Migration Notes (from NetBox) | Before (NetBox) | After (Infrahub) | |-----------------|------------------| | Custom fields on Device | `InfraMlagDomain` schema object | | Custom fields on Interface | Relationships in schema | | `MlagMapper` class | `mlag_config_yang_transform` | ## Related - **Depends on: #41** (Infrahub Schema definition) - Depends on: #30 (Base Transforms pattern) - Note: Some MLAG state requires eAPI (gNMI limitation)
Damien added reference feat/infrahub-transforms-mlag 2026-03-01 11:05:34 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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