## 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
179 lines
5.2 KiB
YAML
179 lines
5.2 KiB
YAML
# Extensions Schema for EVPN-VXLAN Fabric
|
|
# Custom attributes and fabric-specific configurations
|
|
---
|
|
version: "1.0"
|
|
nodes:
|
|
# ================================================================
|
|
# Fabric (Top-level container for all fabric objects)
|
|
# ================================================================
|
|
- name: Fabric
|
|
namespace: Infra
|
|
description: EVPN-VXLAN Fabric definition
|
|
label: Fabric
|
|
icon: mdi--vector-polygon
|
|
include_in_menu: false
|
|
human_friendly_id:
|
|
- name__value
|
|
order_by:
|
|
- name__value
|
|
display_label: "{{ name__value }}"
|
|
attributes:
|
|
- name: name
|
|
kind: Text
|
|
unique: true
|
|
description: Fabric name (e.g., arista-evpn-fabric)
|
|
- name: description
|
|
kind: Text
|
|
optional: true
|
|
- name: underlay_protocol
|
|
kind: Dropdown
|
|
default_value: ebgp
|
|
choices:
|
|
- name: ebgp
|
|
label: eBGP
|
|
- name: ospf
|
|
label: OSPF
|
|
- name: isis
|
|
label: IS-IS
|
|
- name: overlay_protocol
|
|
kind: Dropdown
|
|
default_value: evpn
|
|
choices:
|
|
- name: evpn
|
|
label: EVPN
|
|
- name: ingress_replication
|
|
label: Ingress Replication
|
|
- name: anycast_gateway_mac
|
|
kind: Text
|
|
optional: true
|
|
description: "Shared MAC for anycast gateway (format: xxxx.xxxx.xxxx)"
|
|
relationships:
|
|
- name: spine_asn
|
|
peer: InfraAutonomousSystem
|
|
cardinality: one
|
|
optional: true
|
|
description: AS used by spine layer
|
|
- name: sites
|
|
peer: LocationSite
|
|
identifier: fabric__sites
|
|
cardinality: many
|
|
optional: true
|
|
- name: devices
|
|
peer: InfraDevice
|
|
identifier: fabric__devices
|
|
cardinality: many
|
|
kind: Generic
|
|
description: Devices in this fabric
|
|
|
|
# ================================================================
|
|
# Underlay P2P Link
|
|
# ================================================================
|
|
- name: UnderlayLink
|
|
namespace: Infra
|
|
description: Point-to-point underlay link between devices
|
|
label: Underlay Link
|
|
icon: mdi--cable-data
|
|
include_in_menu: false
|
|
uniqueness_constraints:
|
|
- ["local_identifier__value"]
|
|
human_friendly_id:
|
|
- local_identifier__value
|
|
display_label: "{{ description__value }}"
|
|
attributes:
|
|
- name: local_identifier
|
|
kind: Text
|
|
description: "Unique identifier combining local and remote device/interface (e.g. spine1-eth1__leaf1-eth11)"
|
|
- name: description
|
|
kind: Text
|
|
description: Link description (e.g., spine1:eth1 <-> leaf1:eth11)
|
|
- name: mtu
|
|
kind: Number
|
|
default_value: 9214
|
|
relationships:
|
|
- name: fabric
|
|
peer: InfraFabric
|
|
cardinality: one
|
|
kind: Parent
|
|
optional: false
|
|
- name: local_device
|
|
peer: InfraDevice
|
|
identifier: underlay_link_local_device
|
|
cardinality: one
|
|
direction: outbound
|
|
- name: local_interface
|
|
peer: InfraInterfaceEthernet
|
|
identifier: underlay_link_local_interface
|
|
cardinality: one
|
|
direction: outbound
|
|
- name: local_ip_address
|
|
peer: InfraIPAddress
|
|
identifier: underlay_link_local_ip
|
|
cardinality: one
|
|
direction: outbound
|
|
- name: remote_device
|
|
peer: InfraDevice
|
|
identifier: underlay_link_remote_device
|
|
cardinality: one
|
|
direction: outbound
|
|
- name: remote_interface
|
|
peer: InfraInterfaceEthernet
|
|
identifier: underlay_link_remote_interface
|
|
cardinality: one
|
|
direction: outbound
|
|
- name: remote_ip_address
|
|
peer: InfraIPAddress
|
|
identifier: underlay_link_remote_ip
|
|
cardinality: one
|
|
direction: outbound
|
|
|
|
# ================================================================
|
|
# Host Connection
|
|
# ================================================================
|
|
- name: HostConnection
|
|
namespace: Infra
|
|
description: Host connection to fabric (single or dual-homed)
|
|
label: Host Connection
|
|
icon: mdi--desktop-tower
|
|
include_in_menu: false
|
|
human_friendly_id:
|
|
- hostname__value
|
|
display_label: "{{ hostname__value }}"
|
|
attributes:
|
|
- name: hostname
|
|
kind: Text
|
|
description: Connected host name
|
|
- name: description
|
|
kind: Text
|
|
optional: true
|
|
- name: connection_type
|
|
kind: Dropdown
|
|
default_value: dual_homed
|
|
choices:
|
|
- name: single_homed
|
|
label: Single-Homed
|
|
- name: dual_homed
|
|
label: Dual-Homed (MLAG)
|
|
- name: lacp_mode
|
|
kind: Dropdown
|
|
default_value: active
|
|
choices:
|
|
- name: active
|
|
label: Active
|
|
- name: passive
|
|
label: Passive
|
|
relationships:
|
|
- name: vlans
|
|
peer: InfraVLAN
|
|
cardinality: many
|
|
description: VLANs allowed on this connection
|
|
- name: mlag_interface
|
|
peer: InfraMlagInterface
|
|
cardinality: one
|
|
optional: true
|
|
description: MLAG interface for dual-homed
|
|
- name: lag_interface
|
|
peer: InfraInterfaceLag
|
|
cardinality: one
|
|
optional: true
|
|
description: LAG for single-homed
|