From b042e13b38afbb77ded762602db5b642dea83a2d Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 20 Feb 2026 16:12:07 +0100 Subject: [PATCH] fea(infrahub): Add infrahub configuration --- .infrahub.yml | 18 + menus/fabric-menu.yml | 247 +++++++++++ objects/01-foundation.yml | 44 ++ objects/02-fabric.yml | 15 + objects/03-devices.yml | 83 ++++ objects/04-interfaces.yml | 492 ++++++++++++++++++++++ objects/05-ipam.yml | 132 ++++++ objects/06-vlans-vxlan.yml | 167 ++++++++ objects/07-interface-vlans.yml | 143 +++++++ objects/08-ipam-vlans.yml | 64 +++ objects/09-bgp.yml | 411 +++++++++++++++++++ objects/10-bgp-sessions.yml | 726 +++++++++++++++++++++++++++++++++ objects/11-vrfs.yml | 62 +++ objects/12-mlag.yml | 134 ++++++ schemas/README.md | 217 ++++++++++ schemas/base.yml | 344 ++++++++++++++++ schemas/bgp.yml | 291 +++++++++++++ schemas/extensions.yml | 164 ++++++++ schemas/mlag.yml | 141 +++++++ schemas/vlan_vxlan.yml | 221 ++++++++++ schemas/vrf.yml | 124 ++++++ 21 files changed, 4240 insertions(+) create mode 100644 .infrahub.yml create mode 100644 menus/fabric-menu.yml create mode 100644 objects/01-foundation.yml create mode 100644 objects/02-fabric.yml create mode 100644 objects/03-devices.yml create mode 100644 objects/04-interfaces.yml create mode 100644 objects/05-ipam.yml create mode 100644 objects/06-vlans-vxlan.yml create mode 100644 objects/07-interface-vlans.yml create mode 100644 objects/08-ipam-vlans.yml create mode 100644 objects/09-bgp.yml create mode 100644 objects/10-bgp-sessions.yml create mode 100644 objects/11-vrfs.yml create mode 100644 objects/12-mlag.yml create mode 100644 schemas/README.md create mode 100644 schemas/base.yml create mode 100644 schemas/bgp.yml create mode 100644 schemas/extensions.yml create mode 100644 schemas/mlag.yml create mode 100644 schemas/vlan_vxlan.yml create mode 100644 schemas/vrf.yml diff --git a/.infrahub.yml b/.infrahub.yml new file mode 100644 index 0000000..f7f584e --- /dev/null +++ b/.infrahub.yml @@ -0,0 +1,18 @@ +--- +schemas: + - schemas +menus: + - menus +objects: + - objects/01-foundation.yml + - objects/02-fabric.yml + - objects/03-devices.yml + - objects/04-interfaces.yml + - objects/05-ipam.yml + - objects/06-vlans-vxlan.yml + - objects/07-interface-vlans.yml + - objects/08-ipam-vlans.yml + - objects/09-bgp.yml + - objects/10-bgp-sessions.yml + - objects/11-vrfs.yml + - objects/12-mlag.yml diff --git a/menus/fabric-menu.yml b/menus/fabric-menu.yml new file mode 100644 index 0000000..49b5bc6 --- /dev/null +++ b/menus/fabric-menu.yml @@ -0,0 +1,247 @@ +# yaml-language-server: $schema=https://schema.infrahub.app/infrahub/menu/latest.json +# Custom menu for EVPN-VXLAN Fabric Orchestrator +# Organizes schema nodes into logical topology-aligned categories +--- +apiversion: infrahub.app/v1 +kind: Menu +spec: + data: + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # Fabric Topology + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Topology + name: Mainmenu + label: Fabric Topology + icon: "mdi:lan" + children: + data: + - namespace: Topology + name: Fabric + label: Fabrics + kind: InfraFabric + icon: "mdi:vector-polygon" + + - namespace: Topology + name: Site + label: Sites + kind: LocationSite + icon: "mingcute:building-4-line" + + - namespace: Topology + name: Device + label: Devices + kind: InfraDevice + icon: "mdi:server-network" + + - namespace: Topology + name: Platform + label: Platforms + kind: InfraPlatform + icon: "mdi:chip" + + - namespace: Topology + name: UnderlayLink + label: Underlay Links + kind: InfraUnderlayLink + icon: "mdi:cable-data" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # Interfaces + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Interfaces + name: Mainmenu + label: Interfaces + icon: "mdi:ethernet" + children: + data: + - namespace: Interfaces + name: Ethernet + label: Ethernet + kind: InfraInterfaceEthernet + icon: "mdi:ethernet" + + - namespace: Interfaces + name: Loopback + label: Loopback + kind: InfraInterfaceLoopback + icon: "mdi:reload" + + - namespace: Interfaces + name: VlanSvi + label: VLAN SVI + kind: InfraInterfaceVlan + icon: "mdi:lan" + + - namespace: Interfaces + name: Lag + label: LAG / Port-Channel + kind: InfraInterfaceLag + icon: "mdi:link-variant" + + - namespace: Interfaces + name: Vxlan + label: VXLAN Tunnel + kind: InfraInterfaceVxlan + icon: "mdi:tunnel" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # IP Addressing + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Addressing + name: Mainmenu + label: IP Addressing + icon: "mdi:ip-network" + children: + data: + - namespace: Addressing + name: IPAddress + label: IP Addresses + kind: InfraIPAddress + icon: "mdi:ip-network" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # Layer 2 / VXLAN + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Layer2 + name: Mainmenu + label: Layer 2 / VXLAN + icon: "mdi:switch" + children: + data: + - namespace: Layer2 + name: Vlan + label: VLANs + kind: InfraVLAN + icon: "mdi:lan-connect" + + - namespace: Layer2 + name: Vni + label: VNIs + kind: InfraVNI + icon: "mdi:tunnel-outline" + + - namespace: Layer2 + name: Vtep + label: VTEPs + kind: InfraVTEP + icon: "mdi:server-network-outline" + + - namespace: Layer2 + name: VlanVniMapping + label: VLAN-VNI Mappings + kind: InfraVlanVniMapping + icon: "mdi:swap-horizontal" + + - namespace: Layer2 + name: EvpnInstance + label: EVPN Instances + kind: InfraEVPNInstance + icon: "mdi:cloud-sync" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # Routing / BGP + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Routing + name: Mainmenu + label: Routing / BGP + icon: "mdi:routes" + children: + data: + - namespace: Routing + name: AutonomousSystem + label: Autonomous Systems + kind: InfraAutonomousSystem + icon: "mdi:cloud-outline" + + - namespace: Routing + name: BGPRouterConfig + label: BGP Router Config + kind: InfraBGPRouterConfig + icon: "mdi:router-wireless" + + - namespace: Routing + name: BGPPeerGroup + label: BGP Peer Groups + kind: InfraBGPPeerGroup + icon: "mdi:account-group" + + - namespace: Routing + name: BGPSession + label: BGP Sessions + kind: InfraBGPSession + icon: "mdi:connection" + + - namespace: Routing + name: BGPAddressFamily + label: BGP Address Families + kind: InfraBGPAddressFamily + icon: "mdi:format-list-bulleted" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # VRF + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Vrf + name: Mainmenu + label: VRF + icon: "mdi:router" + children: + data: + - namespace: Vrf + name: Vrf + label: VRFs + kind: InfraVRF + icon: "mdi:router" + + - namespace: Vrf + name: RouteTarget + label: Route Targets + kind: InfraRouteTarget + icon: "mdi:target" + + - namespace: Vrf + name: VrfAssignment + label: VRF Assignments + kind: InfraVRFDeviceAssignment + icon: "mdi:router-network" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # MLAG + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Mlag + name: Mainmenu + label: MLAG + icon: "mdi:link-variant" + children: + data: + - namespace: Mlag + name: MlagDomain + label: MLAG Domains + kind: InfraMlagDomain + icon: "mdi:link-variant" + + - namespace: Mlag + name: MlagPeerConfig + label: MLAG Peer Config + kind: InfraMlagPeerConfig + icon: "mdi:server-network" + + - namespace: Mlag + name: MlagInterface + label: MLAG Interfaces + kind: InfraMlagInterface + icon: "mdi:ethernet-cable" + + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + # Host Connectivity + # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + - namespace: Connectivity + name: Mainmenu + label: Host Connectivity + icon: "mdi:desktop-tower" + children: + data: + - namespace: Connectivity + name: HostConnection + label: Host Connections + kind: InfraHostConnection + icon: "mdi:desktop-tower" diff --git a/objects/01-foundation.yml b/objects/01-foundation.yml new file mode 100644 index 0000000..faaf1ad --- /dev/null +++ b/objects/01-foundation.yml @@ -0,0 +1,44 @@ +# Foundation objects: Site, Platform, Autonomous Systems +# Must be loaded first — referenced by all subsequent files +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: LocationSite + data: + - name: dc1 + description: Primary data center +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraPlatform + data: + - name: arista_eos + description: Arista EOS + napalm_driver: eos + netmiko_device_type: arista_eos +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraAutonomousSystem + data: + - asn: 64999 + description: Router for VRF gold external peering + as_type: private + - asn: 65000 + description: Spine AS + as_type: private + - asn: 65001 + description: Leaf pair 1 (leaf1/leaf2) + as_type: private + - asn: 65002 + description: Leaf pair 2 (leaf3/leaf4) + as_type: private + - asn: 65003 + description: Leaf pair 3 (leaf5/leaf6) + as_type: private + - asn: 65004 + description: Leaf pair 4 (leaf7/leaf8) + as_type: private diff --git a/objects/02-fabric.yml b/objects/02-fabric.yml new file mode 100644 index 0000000..c0861f4 --- /dev/null +++ b/objects/02-fabric.yml @@ -0,0 +1,15 @@ +# Fabric definition — depends on LocationSite and InfraAutonomousSystem from 01-foundation +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraFabric + data: + - name: evpn-lab + description: Arista EVPN-VXLAN reference fabric + underlay_protocol: ebgp + overlay_protocol: evpn + anycast_gateway_mac: "c001.cafe.babe" + spine_asn: ["65000"] + sites: + - ["dc1"] diff --git a/objects/03-devices.yml b/objects/03-devices.yml new file mode 100644 index 0000000..794921b --- /dev/null +++ b/objects/03-devices.yml @@ -0,0 +1,83 @@ +# Devices: 2 spines + 8 leafs +# Depends on: 01-foundation (Platform, Site, AutonomousSystem) +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraDevice + data: + # Spines + - name: spine1 + description: Spine1 - BGP EVPN Spine + role: spine + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65000"] + - name: spine2 + description: Spine2 - BGP EVPN Spine + role: spine + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65000"] + # Leaf pair 1 (VTEP1) + - name: leaf1 + description: Leaf1 - VTEP1 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65001"] + - name: leaf2 + description: Leaf2 - VTEP1 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65001"] + # Leaf pair 2 (VTEP2) + - name: leaf3 + description: Leaf3 - VTEP2 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65002"] + - name: leaf4 + description: Leaf4 - VTEP2 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65002"] + # Leaf pair 3 (VTEP3) + - name: leaf5 + description: Leaf5 - VTEP3 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65003"] + - name: leaf6 + description: Leaf6 - VTEP3 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65003"] + # Leaf pair 4 (VTEP4) + - name: leaf7 + description: Leaf7 - VTEP4 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65004"] + - name: leaf8 + description: Leaf8 - VTEP4 + role: leaf + status: active + platform: ["arista_eos"] + site: ["dc1"] + asn: ["65004"] diff --git a/objects/04-interfaces.yml b/objects/04-interfaces.yml new file mode 100644 index 0000000..80ace90 --- /dev/null +++ b/objects/04-interfaces.yml @@ -0,0 +1,492 @@ +# Interfaces: Loopback, Ethernet, LAG (Port-Channel), VLAN SVIs +# Depends on: 02-devices +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraInterfaceLoopback + data: + # Spine loopbacks (Lo0 only) + - device: ["spine1"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["spine2"] + name: Loopback0 + description: Router-ID + enabled: true + # Leaf loopbacks (Lo0 + Lo1) + - device: ["leaf1"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf1"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf2"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf2"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf3"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf3"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf4"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf4"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf5"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf5"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf6"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf6"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf7"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf7"] + name: Loopback1 + description: VTEP + enabled: true + - device: ["leaf8"] + name: Loopback0 + description: Router-ID + enabled: true + - device: ["leaf8"] + name: Loopback1 + description: VTEP + enabled: true +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraInterfaceLag + data: + # Port-Channel999 — MLAG peer-link (all leafs) + - device: ["leaf1"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf2"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf3"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf4"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf5"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf6"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf7"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + - device: ["leaf8"] + name: Port-Channel999 + description: MLAG Peer + enabled: true + lacp_mode: active + # Port-Channel1 — Host-facing MLAG LAG (all leafs) + - device: ["leaf1"] + name: Port-Channel1 + description: host1 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf2"] + name: Port-Channel1 + description: host1 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf3"] + name: Port-Channel1 + description: host2 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf4"] + name: Port-Channel1 + description: host2 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf5"] + name: Port-Channel1 + description: host3 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf6"] + name: Port-Channel1 + description: host3 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf7"] + name: Port-Channel1 + description: host4 + enabled: true + lacp_mode: active + mlag_id: 1 + - device: ["leaf8"] + name: Port-Channel1 + description: host4 + enabled: true + lacp_mode: active + mlag_id: 1 +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraInterfaceEthernet + data: + # ============================================================ + # Spine1 Ethernet interfaces (underlay to leafs) + # ============================================================ + - device: ["spine1"] + name: Ethernet1 + description: leaf1 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet2 + description: leaf2 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet3 + description: leaf3 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet4 + description: leaf4 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet5 + description: leaf5 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet6 + description: leaf6 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet7 + description: leaf7 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine1"] + name: Ethernet8 + description: leaf8 + enabled: true + mtu: 9214 + mode: routed + # ============================================================ + # Spine2 Ethernet interfaces (underlay to leafs) + # ============================================================ + - device: ["spine2"] + name: Ethernet1 + description: leaf1 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet2 + description: leaf2 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet3 + description: leaf3 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet4 + description: leaf4 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet5 + description: leaf5 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet6 + description: leaf6 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet7 + description: leaf7 + enabled: true + mtu: 9214 + mode: routed + - device: ["spine2"] + name: Ethernet8 + description: leaf8 + enabled: true + mtu: 9214 + mode: routed + # ============================================================ + # Leaf Ethernet interfaces + # Each leaf has: Ethernet1 (host), Ethernet10 (mlag peer-link), + # Ethernet11 (spine1), Ethernet12 (spine2) + # ============================================================ + # Leaf1 + - device: ["leaf1"] + name: Ethernet1 + description: host1 + enabled: true + mode: trunk + lag: ["leaf1", "Port-Channel1"] + - device: ["leaf1"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf1", "Port-Channel999"] + - device: ["leaf1"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf1"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf2 + - device: ["leaf2"] + name: Ethernet1 + description: host1 + enabled: true + mode: trunk + lag: ["leaf2", "Port-Channel1"] + - device: ["leaf2"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf2", "Port-Channel999"] + - device: ["leaf2"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf2"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf3 + - device: ["leaf3"] + name: Ethernet1 + description: host2 + enabled: true + mode: trunk + lag: ["leaf3", "Port-Channel1"] + - device: ["leaf3"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf3", "Port-Channel999"] + - device: ["leaf3"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf3"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf4 + - device: ["leaf4"] + name: Ethernet1 + description: host2 + enabled: true + mode: trunk + lag: ["leaf4", "Port-Channel1"] + - device: ["leaf4"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf4", "Port-Channel999"] + - device: ["leaf4"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf4"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf5 + - device: ["leaf5"] + name: Ethernet1 + description: host3 + enabled: true + mode: trunk + lag: ["leaf5", "Port-Channel1"] + - device: ["leaf5"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf5", "Port-Channel999"] + - device: ["leaf5"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf5"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf6 + - device: ["leaf6"] + name: Ethernet1 + description: host3 + enabled: true + mode: trunk + lag: ["leaf6", "Port-Channel1"] + - device: ["leaf6"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf6", "Port-Channel999"] + - device: ["leaf6"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf6"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf7 + - device: ["leaf7"] + name: Ethernet1 + description: host4 + enabled: true + mode: trunk + lag: ["leaf7", "Port-Channel1"] + - device: ["leaf7"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf7", "Port-Channel999"] + - device: ["leaf7"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf7"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + # Leaf8 + - device: ["leaf8"] + name: Ethernet1 + description: host4 + enabled: true + mode: trunk + lag: ["leaf8", "Port-Channel1"] + - device: ["leaf8"] + name: Ethernet10 + description: mlag peer link + enabled: true + mode: trunk + lag: ["leaf8", "Port-Channel999"] + - device: ["leaf8"] + name: Ethernet11 + description: spine1 + enabled: true + mtu: 9214 + mode: routed + - device: ["leaf8"] + name: Ethernet12 + description: spine2 + enabled: true + mtu: 9214 + mode: routed + diff --git a/objects/05-ipam.yml b/objects/05-ipam.yml new file mode 100644 index 0000000..5cfa050 --- /dev/null +++ b/objects/05-ipam.yml @@ -0,0 +1,132 @@ +# IP Addresses: Loopbacks, P2P underlay links, MLAG SVIs, VRF SVIs +# Depends on: 03-interfaces +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraIPAddress + data: + # ============================================================ + # Loopback0 addresses (Router-ID) — /32 + # ============================================================ + - address: "10.0.250.1/32" + description: spine1 Router-ID + - address: "10.0.250.2/32" + description: spine2 Router-ID + - address: "10.0.250.11/32" + description: leaf1 Router-ID + - address: "10.0.250.12/32" + description: leaf2 Router-ID + - address: "10.0.250.13/32" + description: leaf3 Router-ID + - address: "10.0.250.14/32" + description: leaf4 Router-ID + - address: "10.0.250.15/32" + description: leaf5 Router-ID + - address: "10.0.250.16/32" + description: leaf6 Router-ID + - address: "10.0.250.17/32" + description: leaf7 Router-ID + - address: "10.0.250.18/32" + description: leaf8 Router-ID + # ============================================================ + # Loopback1 addresses (VTEP) — /32 + # ============================================================ + - address: "10.0.255.11/32" + description: leaf1 VTEP (shared VTEP1) + - address: "10.0.255.11/32" + description: leaf2 VTEP (shared VTEP1) + - address: "10.0.255.12/32" + description: leaf3 VTEP (shared VTEP2) + - address: "10.0.255.12/32" + description: leaf4 VTEP (shared VTEP2) + - address: "10.0.255.13/32" + description: leaf5 VTEP (shared VTEP3) + - address: "10.0.255.13/32" + description: leaf6 VTEP (shared VTEP3) + - address: "10.0.255.14/32" + description: leaf7 VTEP (shared VTEP4) + - address: "10.0.255.14/32" + description: leaf8 VTEP (shared VTEP4) + # ============================================================ + # Spine1 P2P underlay — /31 + # ============================================================ + - address: "10.0.1.0/31" + description: spine1 Ethernet1 to leaf1 + - address: "10.0.1.2/31" + description: spine1 Ethernet2 to leaf2 + - address: "10.0.1.4/31" + description: spine1 Ethernet3 to leaf3 + - address: "10.0.1.6/31" + description: spine1 Ethernet4 to leaf4 + - address: "10.0.1.8/31" + description: spine1 Ethernet5 to leaf5 + - address: "10.0.1.10/31" + description: spine1 Ethernet6 to leaf6 + - address: "10.0.1.12/31" + description: spine1 Ethernet7 to leaf7 + - address: "10.0.1.14/31" + description: spine1 Ethernet8 to leaf8 + # ============================================================ + # Spine2 P2P underlay — /31 + # ============================================================ + - address: "10.0.2.0/31" + description: spine2 Ethernet1 to leaf1 + - address: "10.0.2.2/31" + description: spine2 Ethernet2 to leaf2 + - address: "10.0.2.4/31" + description: spine2 Ethernet3 to leaf3 + - address: "10.0.2.6/31" + description: spine2 Ethernet4 to leaf4 + - address: "10.0.2.8/31" + description: spine2 Ethernet5 to leaf5 + - address: "10.0.2.10/31" + description: spine2 Ethernet6 to leaf6 + - address: "10.0.2.12/31" + description: spine2 Ethernet7 to leaf7 + - address: "10.0.2.14/31" + description: spine2 Ethernet8 to leaf8 + # ============================================================ + # Leaf P2P underlay (leaf side) — /31 + # ============================================================ + # Leaf1 + - address: "10.0.1.1/31" + description: leaf1 Ethernet11 to spine1 + - address: "10.0.2.1/31" + description: leaf1 Ethernet12 to spine2 + # Leaf2 + - address: "10.0.1.3/31" + description: leaf2 Ethernet11 to spine1 + - address: "10.0.2.3/31" + description: leaf2 Ethernet12 to spine2 + # Leaf3 + - address: "10.0.1.5/31" + description: leaf3 Ethernet11 to spine1 + - address: "10.0.2.5/31" + description: leaf3 Ethernet12 to spine2 + # Leaf4 + - address: "10.0.1.7/31" + description: leaf4 Ethernet11 to spine1 + - address: "10.0.2.7/31" + description: leaf4 Ethernet12 to spine2 + # Leaf5 + - address: "10.0.1.9/31" + description: leaf5 Ethernet11 to spine1 + - address: "10.0.2.9/31" + description: leaf5 Ethernet12 to spine2 + # Leaf6 + - address: "10.0.1.11/31" + description: leaf6 Ethernet11 to spine1 + - address: "10.0.2.11/31" + description: leaf6 Ethernet12 to spine2 + # Leaf7 + - address: "10.0.1.13/31" + description: leaf7 Ethernet11 to spine1 + - address: "10.0.2.13/31" + description: leaf7 Ethernet12 to spine2 + # Leaf8 + - address: "10.0.1.15/31" + description: leaf8 Ethernet11 to spine1 + - address: "10.0.2.15/31" + description: leaf8 Ethernet12 to spine2 + diff --git a/objects/06-vlans-vxlan.yml b/objects/06-vlans-vxlan.yml new file mode 100644 index 0000000..96a4ff8 --- /dev/null +++ b/objects/06-vlans-vxlan.yml @@ -0,0 +1,167 @@ +# VLANs, VNIs, VTEPs, VLAN-VNI mappings, EVPN instances +# Depends on: 02-devices, 03-interfaces +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraVLAN + data: + - vlan_id: 34 + name: vrf-gold-subnet + description: VRF gold L3 subnet (leaf3/leaf4) + status: active + vlan_type: standard + - vlan_id: 40 + name: test-l2-vxlan + description: L2 VXLAN test VLAN + status: active + vlan_type: standard + - vlan_id: 78 + name: vrf-gold-subnet + description: VRF gold L3 subnet (leaf7/leaf8) + status: active + vlan_type: standard + - vlan_id: 900 + name: bgp-border + description: BGP border peering VLAN + status: active + vlan_type: standard + - vlan_id: 4090 + name: mlag-peer + description: MLAG peer-link control + status: active + vlan_type: mlag_peer + trunk_groups: + - mlag-peer + stp_enabled: false + - vlan_id: 4091 + name: mlag-ibgp + description: MLAG iBGP peering + status: active + vlan_type: mlag_ibgp + trunk_groups: + - mlag-peer + stp_enabled: false +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraVNI + data: + - vni: 110040 + description: L2VNI for VLAN 40 (test-l2-vxlan) + vni_type: l2vni + vlan: ["40"] + - vni: 100001 + description: L3VNI for VRF gold + vni_type: l3vni +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraVTEP + data: + # VTEP on leaf1 (shared VTEP1 IP 10.0.255.11) + - device: ["leaf1"] + source_address: "10.0.255.11" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf1", "Loopback1"] + # VTEP on leaf2 (shared VTEP1 IP 10.0.255.11) + - device: ["leaf2"] + source_address: "10.0.255.11" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf2", "Loopback1"] + # VTEP on leaf3 (shared VTEP2 IP 10.0.255.12) + - device: ["leaf3"] + source_address: "10.0.255.12" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf3", "Loopback1"] + # VTEP on leaf4 (shared VTEP2 IP 10.0.255.12) + - device: ["leaf4"] + source_address: "10.0.255.12" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf4", "Loopback1"] + # VTEP on leaf5 (shared VTEP3 IP 10.0.255.13) + - device: ["leaf5"] + source_address: "10.0.255.13" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf5", "Loopback1"] + # VTEP on leaf6 (shared VTEP3 IP 10.0.255.13) + - device: ["leaf6"] + source_address: "10.0.255.13" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf6", "Loopback1"] + # VTEP on leaf7 (shared VTEP4 IP 10.0.255.14) + - device: ["leaf7"] + source_address: "10.0.255.14" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf7", "Loopback1"] + # VTEP on leaf8 (shared VTEP4 IP 10.0.255.14) + - device: ["leaf8"] + source_address: "10.0.255.14" + udp_port: 4789 + learn_restrict: any + source_interface: ["leaf8", "Loopback1"] +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraVlanVniMapping + data: + # VLAN 40 <-> VNI 110040 on leaf1/2/5/6 (L2 VXLAN leafs) + - vtep: ["leaf1"] + vlan: ["40"] + vni: ["110040"] + description: "VLAN 40 <-> VNI 110040" + - vtep: ["leaf2"] + vlan: ["40"] + vni: ["110040"] + description: "VLAN 40 <-> VNI 110040" + - vtep: ["leaf5"] + vlan: ["40"] + vni: ["110040"] + description: "VLAN 40 <-> VNI 110040" + - vtep: ["leaf6"] + vlan: ["40"] + vni: ["110040"] + description: "VLAN 40 <-> VNI 110040" +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraEVPNInstance + data: + # EVPN instance for VLAN 40 on L2 VXLAN leafs + # leaf1: rd 65001:110040, rt both 40:110040 + - device: ["leaf1"] + vlan: ["40"] + route_distinguisher: "65001:110040" + route_target_import: "40:110040" + route_target_export: "40:110040" + redistribute_learned: true + - device: ["leaf2"] + vlan: ["40"] + route_distinguisher: "65001:110040" + route_target_import: "40:110040" + route_target_export: "40:110040" + redistribute_learned: true + # leaf5/6: rd 65003:110040, rt both 40:110040 + - device: ["leaf5"] + vlan: ["40"] + route_distinguisher: "65003:110040" + route_target_import: "40:110040" + route_target_export: "40:110040" + redistribute_learned: true + - device: ["leaf6"] + vlan: ["40"] + route_distinguisher: "65003:110040" + route_target_import: "40:110040" + route_target_export: "40:110040" + redistribute_learned: true diff --git a/objects/07-interface-vlans.yml b/objects/07-interface-vlans.yml new file mode 100644 index 0000000..69ec20e --- /dev/null +++ b/objects/07-interface-vlans.yml @@ -0,0 +1,143 @@ +# VLAN SVI interfaces +# Depends on: 03-devices, 06-vlans-vxlan (VLANs must exist) +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraInterfaceVlan + data: + # Vlan4090 — MLAG Peer-Link SVI (all leafs) + - device: ["leaf1"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf2"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf3"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf4"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf5"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf6"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf7"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + - device: ["leaf8"] + name: Vlan4090 + description: MLAG Peer-Link + enabled: true + autostate: false + vlan: ["4090"] + # Vlan4091 — MLAG iBGP Peering SVI (all leafs) + - device: ["leaf1"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf2"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf3"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf4"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf5"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf6"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf7"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + - device: ["leaf8"] + name: Vlan4091 + description: MLAG iBGP Peering + enabled: true + mtu: 9214 + vlan: ["4091"] + # Vlan34 — VRF gold subnet (leaf3/leaf4) + - device: ["leaf3"] + name: Vlan34 + description: VRF gold subnet + enabled: true + virtual_router_address: "10.34.34.1" + vlan: ["34"] + - device: ["leaf4"] + name: Vlan34 + description: VRF gold subnet + enabled: true + virtual_router_address: "10.34.34.1" + vlan: ["34"] + # Vlan78 — VRF gold subnet (leaf7/leaf8) + - device: ["leaf7"] + name: Vlan78 + description: VRF gold subnet + enabled: true + virtual_router_address: "10.78.78.1" + vlan: ["78"] + - device: ["leaf8"] + name: Vlan78 + description: VRF gold subnet + enabled: true + virtual_router_address: "10.78.78.1" + vlan: ["78"] + # Vlan900 — BGP border peering (leaf7/leaf8) + - device: ["leaf7"] + name: Vlan900 + description: BGP border peering + enabled: true + vlan: ["900"] + - device: ["leaf8"] + name: Vlan900 + description: BGP border peering + enabled: true + vlan: ["900"] \ No newline at end of file diff --git a/objects/08-ipam-vlans.yml b/objects/08-ipam-vlans.yml new file mode 100644 index 0000000..759a1f2 --- /dev/null +++ b/objects/08-ipam-vlans.yml @@ -0,0 +1,64 @@ +# IP Addresses for VLAN SVI interfaces +# Depends on: 07-interface-vlans (Vlan SVIs must exist) +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraIPAddress + data: + # ============================================================ + # MLAG Peer-Link SVI (Vlan4090) — /31 + # ============================================================ + - address: "10.0.199.254/31" + description: leaf1 MLAG peer-link + - address: "10.0.199.255/31" + description: leaf2 MLAG peer-link + - address: "10.0.199.252/31" + description: leaf3 MLAG peer-link + - address: "10.0.199.253/31" + description: leaf4 MLAG peer-link + - address: "10.0.199.250/31" + description: leaf5 MLAG peer-link + - address: "10.0.199.251/31" + description: leaf6 MLAG peer-link + - address: "10.0.199.248/31" + description: leaf7 MLAG peer-link + - address: "10.0.199.249/31" + description: leaf8 MLAG peer-link + # ============================================================ + # MLAG iBGP Peering SVI (Vlan4091) — /31 + # ============================================================ + - address: "10.0.3.0/31" + description: leaf1 MLAG iBGP peering + - address: "10.0.3.1/31" + description: leaf2 MLAG iBGP peering + - address: "10.0.3.2/31" + description: leaf3 MLAG iBGP peering + - address: "10.0.3.3/31" + description: leaf4 MLAG iBGP peering + - address: "10.0.3.4/31" + description: leaf5 MLAG iBGP peering + - address: "10.0.3.5/31" + description: leaf6 MLAG iBGP peering + - address: "10.0.3.6/31" + description: leaf7 MLAG iBGP peering + - address: "10.0.3.7/31" + description: leaf8 MLAG iBGP peering + # ============================================================ + # VRF gold SVI addresses — /24 + # ============================================================ + # Vlan34 (leaf3/leaf4) + - address: "10.34.34.2/24" + description: leaf3 Vlan34 VRF gold + - address: "10.34.34.3/24" + description: leaf4 Vlan34 VRF gold + # Vlan78 (leaf7/leaf8) + - address: "10.78.78.2/24" + description: leaf7 Vlan78 VRF gold + - address: "10.78.78.3/24" + description: leaf8 Vlan78 VRF gold + # Vlan900 — BGP border (leaf7/leaf8) + - address: "10.90.90.2/29" + description: leaf7 Vlan900 BGP border + - address: "10.90.90.3/29" + description: leaf8 Vlan900 BGP border diff --git a/objects/09-bgp.yml b/objects/09-bgp.yml new file mode 100644 index 0000000..c9c7d31 --- /dev/null +++ b/objects/09-bgp.yml @@ -0,0 +1,411 @@ +# BGP: RouterConfig, PeerGroups, Sessions, AddressFamilies +# Depends on: 01-foundation (ASNs), 02-devices, 04-ipam +# +# Spine BGP: no named peer-groups in config (neighbors defined directly), +# but evpn peer-group is defined. Underlay neighbors are direct. +# Leaf BGP: underlay, underlay_ibgp, evpn peer-groups. +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraBGPRouterConfig + data: + # ============================================================ + # Spine1 BGP — AS 65000, router-id 10.0.250.1 + # ============================================================ + - device: ["spine1"] + router_id: "10.0.250.1" + local_asn: ["65000"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Spine2 BGP — AS 65000, router-id 10.0.250.2 + # ============================================================ + - device: ["spine2"] + router_id: "10.0.250.2" + local_asn: ["65000"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf1 BGP — AS 65001, router-id 10.0.250.11 + # ============================================================ + - device: ["leaf1"] + router_id: "10.0.250.11" + local_asn: ["65001"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf2 BGP — AS 65001, router-id 10.0.250.12 + # ============================================================ + - device: ["leaf2"] + router_id: "10.0.250.12" + local_asn: ["65001"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf3 BGP — AS 65002, router-id 10.0.250.13 + # ============================================================ + - device: ["leaf3"] + router_id: "10.0.250.13" + local_asn: ["65002"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf4 BGP — AS 65002, router-id 10.0.250.14 + # ============================================================ + - device: ["leaf4"] + router_id: "10.0.250.14" + local_asn: ["65002"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf5 BGP — AS 65003, router-id 10.0.250.15 + # ============================================================ + - device: ["leaf5"] + router_id: "10.0.250.15" + local_asn: ["65003"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf6 BGP — AS 65003, router-id 10.0.250.16 + # ============================================================ + - device: ["leaf6"] + router_id: "10.0.250.16" + local_asn: ["65003"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf7 BGP — AS 65004, router-id 10.0.250.17 + # ============================================================ + - device: ["leaf7"] + router_id: "10.0.250.17" + local_asn: ["65004"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 + # ============================================================ + # Leaf8 BGP — AS 65004, router-id 10.0.250.18 + # ============================================================ + - device: ["leaf8"] + router_id: "10.0.250.18" + local_asn: ["65004"] + default_ipv4_unicast: false + log_neighbor_changes: true + ecmp_max_paths: 4 + ecmp_max_ecmp: 64 + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 200 +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraBGPPeerGroup + data: + # ============================================================ + # Spine peer-groups (evpn only — underlay neighbors are direct) + # ============================================================ + # Spine1 — evpn peer-group + - bgp_config: ["spine1"] + local_identifier: "spine1__evpn" + name: evpn + description: EVPN overlay to leaf loopbacks + peer_group_type: evpn + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + next_hop_unchanged: true + maximum_routes: 12000 + maximum_routes_warning_only: true + # Spine2 — evpn peer-group + - bgp_config: ["spine2"] + local_identifier: "spine2__evpn" + name: evpn + description: EVPN overlay to leaf loopbacks + peer_group_type: evpn + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + next_hop_unchanged: true + maximum_routes: 12000 + maximum_routes_warning_only: true + # ============================================================ + # Leaf peer-groups (underlay, underlay_ibgp, evpn) + # ============================================================ + # Leaf1 + - bgp_config: ["leaf1"] + local_identifier: "leaf1__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf1"] + local_identifier: "leaf1__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65001"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf1"] + local_identifier: "leaf1__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf2 + - bgp_config: ["leaf2"] + local_identifier: "leaf2__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf2"] + local_identifier: "leaf2__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65001"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf2"] + local_identifier: "leaf2__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf3 + - bgp_config: ["leaf3"] + local_identifier: "leaf3__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf3"] + local_identifier: "leaf3__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65002"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf3"] + local_identifier: "leaf3__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf4 + - bgp_config: ["leaf4"] + local_identifier: "leaf4__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf4"] + local_identifier: "leaf4__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65002"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf4"] + local_identifier: "leaf4__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf5 + - bgp_config: ["leaf5"] + local_identifier: "leaf5__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf5"] + local_identifier: "leaf5__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65003"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf5"] + local_identifier: "leaf5__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf6 + - bgp_config: ["leaf6"] + local_identifier: "leaf6__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf6"] + local_identifier: "leaf6__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65003"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf6"] + local_identifier: "leaf6__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf7 + - bgp_config: ["leaf7"] + local_identifier: "leaf7__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf7"] + local_identifier: "leaf7__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65004"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf7"] + local_identifier: "leaf7__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + # Leaf8 + - bgp_config: ["leaf8"] + local_identifier: "leaf8__underlay" + name: underlay + description: Underlay eBGP to spines + peer_group_type: underlay + remote_asn: ["65000"] + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf8"] + local_identifier: "leaf8__underlay_ibgp" + name: underlay_ibgp + description: MLAG iBGP peering + peer_group_type: underlay_ibgp + remote_asn: ["65004"] + next_hop_self: true + maximum_routes: 12000 + maximum_routes_warning_only: true + - bgp_config: ["leaf8"] + local_identifier: "leaf8__evpn" + name: evpn + description: EVPN overlay to spines + peer_group_type: evpn + remote_asn: ["65000"] + update_source: Loopback0 + ebgp_multihop: 3 + send_community: extended + maximum_routes: 12000 + maximum_routes_warning_only: true + diff --git a/objects/10-bgp-sessions.yml b/objects/10-bgp-sessions.yml new file mode 100644 index 0000000..c41986c --- /dev/null +++ b/objects/10-bgp-sessions.yml @@ -0,0 +1,726 @@ +# BGP Sessions and Address Families +# Depends on: 09-bgp (RouterConfig and PeerGroups must exist) +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraBGPSession + data: + # ============================================================ + # Spine1 sessions + # ============================================================ + # Spine1 underlay (direct neighbors, no peer-group — use remote_asn) + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.1" + peer_address: "10.0.1.1" + description: "underlay to leaf1" + remote_asn: ["65001"] + peer_device: ["leaf1"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.3" + peer_address: "10.0.1.3" + description: "underlay to leaf2" + remote_asn: ["65001"] + peer_device: ["leaf2"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.5" + peer_address: "10.0.1.5" + description: "underlay to leaf3" + remote_asn: ["65002"] + peer_device: ["leaf3"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.7" + peer_address: "10.0.1.7" + description: "underlay to leaf4" + remote_asn: ["65002"] + peer_device: ["leaf4"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.9" + peer_address: "10.0.1.9" + description: "underlay to leaf5" + remote_asn: ["65003"] + peer_device: ["leaf5"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.11" + peer_address: "10.0.1.11" + description: "underlay to leaf6" + remote_asn: ["65003"] + peer_device: ["leaf6"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.13" + peer_address: "10.0.1.13" + description: "underlay to leaf7" + remote_asn: ["65004"] + peer_device: ["leaf7"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.1.15" + peer_address: "10.0.1.15" + description: "underlay to leaf8" + remote_asn: ["65004"] + peer_device: ["leaf8"] + # Spine1 EVPN (via evpn peer-group) + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.11" + peer_address: "10.0.250.11" + description: "EVPN to leaf1" + peer_group: "spine1__evpn" + remote_asn: ["65001"] + peer_device: ["leaf1"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.12" + peer_address: "10.0.250.12" + description: "EVPN to leaf2" + peer_group: "spine1__evpn" + remote_asn: ["65001"] + peer_device: ["leaf2"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.13" + peer_address: "10.0.250.13" + description: "EVPN to leaf3" + peer_group: "spine1__evpn" + remote_asn: ["65002"] + peer_device: ["leaf3"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.14" + peer_address: "10.0.250.14" + description: "EVPN to leaf4" + peer_group: "spine1__evpn" + remote_asn: ["65002"] + peer_device: ["leaf4"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.15" + peer_address: "10.0.250.15" + description: "EVPN to leaf5" + peer_group: "spine1__evpn" + remote_asn: ["65003"] + peer_device: ["leaf5"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.16" + peer_address: "10.0.250.16" + description: "EVPN to leaf6" + peer_group: "spine1__evpn" + remote_asn: ["65003"] + peer_device: ["leaf6"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.17" + peer_address: "10.0.250.17" + description: "EVPN to leaf7" + peer_group: "spine1__evpn" + remote_asn: ["65004"] + peer_device: ["leaf7"] + - bgp_config: ["spine1"] + local_identifier: "spine1__10.0.250.18" + peer_address: "10.0.250.18" + description: "EVPN to leaf8" + peer_group: "spine1__evpn" + remote_asn: ["65004"] + peer_device: ["leaf8"] + # ============================================================ + # Spine2 sessions + # ============================================================ + # Spine2 underlay + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.1" + peer_address: "10.0.2.1" + description: "underlay to leaf1" + remote_asn: ["65001"] + peer_device: ["leaf1"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.3" + peer_address: "10.0.2.3" + description: "underlay to leaf2" + remote_asn: ["65001"] + peer_device: ["leaf2"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.5" + peer_address: "10.0.2.5" + description: "underlay to leaf3" + remote_asn: ["65002"] + peer_device: ["leaf3"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.7" + peer_address: "10.0.2.7" + description: "underlay to leaf4" + remote_asn: ["65002"] + peer_device: ["leaf4"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.9" + peer_address: "10.0.2.9" + description: "underlay to leaf5" + remote_asn: ["65003"] + peer_device: ["leaf5"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.11" + peer_address: "10.0.2.11" + description: "underlay to leaf6" + remote_asn: ["65003"] + peer_device: ["leaf6"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.13" + peer_address: "10.0.2.13" + description: "underlay to leaf7" + remote_asn: ["65004"] + peer_device: ["leaf7"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.2.15" + peer_address: "10.0.2.15" + description: "underlay to leaf8" + remote_asn: ["65004"] + peer_device: ["leaf8"] + # Spine2 EVPN + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.11" + peer_address: "10.0.250.11" + description: "EVPN to leaf1" + peer_group: "spine2__evpn" + remote_asn: ["65001"] + peer_device: ["leaf1"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.12" + peer_address: "10.0.250.12" + description: "EVPN to leaf2" + peer_group: "spine2__evpn" + remote_asn: ["65001"] + peer_device: ["leaf2"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.13" + peer_address: "10.0.250.13" + description: "EVPN to leaf3" + peer_group: "spine2__evpn" + remote_asn: ["65002"] + peer_device: ["leaf3"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.14" + peer_address: "10.0.250.14" + description: "EVPN to leaf4" + peer_group: "spine2__evpn" + remote_asn: ["65002"] + peer_device: ["leaf4"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.15" + peer_address: "10.0.250.15" + description: "EVPN to leaf5" + peer_group: "spine2__evpn" + remote_asn: ["65003"] + peer_device: ["leaf5"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.16" + peer_address: "10.0.250.16" + description: "EVPN to leaf6" + peer_group: "spine2__evpn" + remote_asn: ["65003"] + peer_device: ["leaf6"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.17" + peer_address: "10.0.250.17" + description: "EVPN to leaf7" + peer_group: "spine2__evpn" + remote_asn: ["65004"] + peer_device: ["leaf7"] + - bgp_config: ["spine2"] + local_identifier: "spine2__10.0.250.18" + peer_address: "10.0.250.18" + description: "EVPN to leaf8" + peer_group: "spine2__evpn" + remote_asn: ["65004"] + peer_device: ["leaf8"] + # ============================================================ + # Leaf1 sessions + # ============================================================ + - bgp_config: ["leaf1"] + local_identifier: "leaf1__10.0.1.0" + peer_address: "10.0.1.0" + description: "underlay to spine1" + peer_group: "leaf1__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf1"] + local_identifier: "leaf1__10.0.2.0" + peer_address: "10.0.2.0" + description: "underlay to spine2" + peer_group: "leaf1__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf1"] + local_identifier: "leaf1__10.0.3.1" + peer_address: "10.0.3.1" + description: "iBGP to leaf2" + peer_group: "leaf1__underlay_ibgp" + peer_device: ["leaf2"] + - bgp_config: ["leaf1"] + local_identifier: "leaf1__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf1__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf1"] + local_identifier: "leaf1__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf1__evpn" + peer_device: ["spine2"] + # ============================================================ + # Leaf2 sessions + # ============================================================ + - bgp_config: ["leaf2"] + local_identifier: "leaf2__10.0.1.2" + peer_address: "10.0.1.2" + description: "underlay to spine1" + peer_group: "leaf2__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf2"] + local_identifier: "leaf2__10.0.2.2" + peer_address: "10.0.2.2" + description: "underlay to spine2" + peer_group: "leaf2__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf2"] + local_identifier: "leaf2__10.0.3.0" + peer_address: "10.0.3.0" + description: "iBGP to leaf1" + peer_group: "leaf2__underlay_ibgp" + peer_device: ["leaf1"] + - bgp_config: ["leaf2"] + local_identifier: "leaf2__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf2__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf2"] + local_identifier: "leaf2__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf2__evpn" + peer_device: ["spine2"] + # ============================================================ + # Leaf3 sessions + # ============================================================ + - bgp_config: ["leaf3"] + local_identifier: "leaf3__10.0.1.4" + peer_address: "10.0.1.4" + description: "underlay to spine1" + peer_group: "leaf3__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf3"] + local_identifier: "leaf3__10.0.2.4" + peer_address: "10.0.2.4" + description: "underlay to spine2" + peer_group: "leaf3__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf3"] + local_identifier: "leaf3__10.0.3.3" + peer_address: "10.0.3.3" + description: "iBGP to leaf4" + peer_group: "leaf3__underlay_ibgp" + peer_device: ["leaf4"] + - bgp_config: ["leaf3"] + local_identifier: "leaf3__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf3__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf3"] + local_identifier: "leaf3__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf3__evpn" + peer_device: ["spine2"] + # ============================================================ + # Leaf4 sessions + # ============================================================ + - bgp_config: ["leaf4"] + local_identifier: "leaf4__10.0.1.6" + peer_address: "10.0.1.6" + description: "underlay to spine1" + peer_group: "leaf4__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf4"] + local_identifier: "leaf4__10.0.2.6" + peer_address: "10.0.2.6" + description: "underlay to spine2" + peer_group: "leaf4__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf4"] + local_identifier: "leaf4__10.0.3.2" + peer_address: "10.0.3.2" + description: "iBGP to leaf3" + peer_group: "leaf4__underlay_ibgp" + peer_device: ["leaf3"] + - bgp_config: ["leaf4"] + local_identifier: "leaf4__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf4__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf4"] + local_identifier: "leaf4__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf4__evpn" + peer_device: ["spine2"] + # ============================================================ + # Leaf5 sessions + # ============================================================ + - bgp_config: ["leaf5"] + local_identifier: "leaf5__10.0.1.8" + peer_address: "10.0.1.8" + description: "underlay to spine1" + peer_group: "leaf5__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf5"] + local_identifier: "leaf5__10.0.2.8" + peer_address: "10.0.2.8" + description: "underlay to spine2" + peer_group: "leaf5__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf5"] + local_identifier: "leaf5__10.0.3.5" + peer_address: "10.0.3.5" + description: "iBGP to leaf6" + peer_group: "leaf5__underlay_ibgp" + peer_device: ["leaf6"] + - bgp_config: ["leaf5"] + local_identifier: "leaf5__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf5__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf5"] + local_identifier: "leaf5__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf5__evpn" + peer_device: ["spine2"] + # ============================================================ + # Leaf6 sessions + # ============================================================ + - bgp_config: ["leaf6"] + local_identifier: "leaf6__10.0.1.10" + peer_address: "10.0.1.10" + description: "underlay to spine1" + peer_group: "leaf6__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf6"] + local_identifier: "leaf6__10.0.2.10" + peer_address: "10.0.2.10" + description: "underlay to spine2" + peer_group: "leaf6__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf6"] + local_identifier: "leaf6__10.0.3.4" + peer_address: "10.0.3.4" + description: "iBGP to leaf5" + peer_group: "leaf6__underlay_ibgp" + peer_device: ["leaf5"] + - bgp_config: ["leaf6"] + local_identifier: "leaf6__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf6__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf6"] + local_identifier: "leaf6__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf6__evpn" + peer_device: ["spine2"] + # ============================================================ + # Leaf7 sessions + # ============================================================ + - bgp_config: ["leaf7"] + local_identifier: "leaf7__10.0.1.12" + peer_address: "10.0.1.12" + description: "underlay to spine1" + peer_group: "leaf7__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf7"] + local_identifier: "leaf7__10.0.2.12" + peer_address: "10.0.2.12" + description: "underlay to spine2" + peer_group: "leaf7__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf7"] + local_identifier: "leaf7__10.0.3.7" + peer_address: "10.0.3.7" + description: "iBGP to leaf8" + peer_group: "leaf7__underlay_ibgp" + peer_device: ["leaf8"] + - bgp_config: ["leaf7"] + local_identifier: "leaf7__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf7__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf7"] + local_identifier: "leaf7__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf7__evpn" + peer_device: ["spine2"] + # Leaf7 VRF gold border peering + - bgp_config: ["leaf7"] + local_identifier: "leaf7__10.90.90.1" + peer_address: "10.90.90.1" + description: "border peering to AS 64999 in VRF gold" + remote_asn: ["64999"] + vrf: "gold" + # ============================================================ + # Leaf8 sessions + # ============================================================ + - bgp_config: ["leaf8"] + local_identifier: "leaf8__10.0.1.14" + peer_address: "10.0.1.14" + description: "underlay to spine1" + peer_group: "leaf8__underlay" + peer_device: ["spine1"] + - bgp_config: ["leaf8"] + local_identifier: "leaf8__10.0.2.14" + peer_address: "10.0.2.14" + description: "underlay to spine2" + peer_group: "leaf8__underlay" + peer_device: ["spine2"] + - bgp_config: ["leaf8"] + local_identifier: "leaf8__10.0.3.6" + peer_address: "10.0.3.6" + description: "iBGP to leaf7" + peer_group: "leaf8__underlay_ibgp" + peer_device: ["leaf7"] + - bgp_config: ["leaf8"] + local_identifier: "leaf8__10.0.250.1" + peer_address: "10.0.250.1" + description: "EVPN to spine1" + peer_group: "leaf8__evpn" + peer_device: ["spine1"] + - bgp_config: ["leaf8"] + local_identifier: "leaf8__10.0.250.2" + peer_address: "10.0.250.2" + description: "EVPN to spine2" + peer_group: "leaf8__evpn" + peer_device: ["spine2"] + # Leaf8 VRF gold border peering + - bgp_config: ["leaf8"] + local_identifier: "leaf8__10.90.90.1" + peer_address: "10.90.90.1" + description: "border peering to AS 64999 in VRF gold" + remote_asn: ["64999"] + vrf: "gold" +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraBGPAddressFamily + data: + # ============================================================ + # Spine1 address families + # ============================================================ + - bgp_config: ["spine1"] + local_identifier: "spine1__ipv4_unicast" + afi: ipv4 + safi: unicast + active_sessions: + - ["spine1__10.0.1.1"] + - ["spine1__10.0.1.3"] + - ["spine1__10.0.1.5"] + - ["spine1__10.0.1.7"] + - ["spine1__10.0.1.9"] + - ["spine1__10.0.1.11"] + - ["spine1__10.0.1.13"] + - ["spine1__10.0.1.15"] + networks: + - ["10.0.250.1/32"] + - bgp_config: ["spine1"] + local_identifier: "spine1__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["spine1__evpn"] + # ============================================================ + # Spine2 address families + # ============================================================ + - bgp_config: ["spine2"] + local_identifier: "spine2__ipv4_unicast" + afi: ipv4 + safi: unicast + active_sessions: + - ["spine2__10.0.2.1"] + - ["spine2__10.0.2.3"] + - ["spine2__10.0.2.5"] + - ["spine2__10.0.2.7"] + - ["spine2__10.0.2.9"] + - ["spine2__10.0.2.11"] + - ["spine2__10.0.2.13"] + - ["spine2__10.0.2.15"] + networks: + - ["10.0.250.2/32"] + - bgp_config: ["spine2"] + local_identifier: "spine2__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["spine2__evpn"] + # ============================================================ + # Leaf1 address families + # ============================================================ + - bgp_config: ["leaf1"] + local_identifier: "leaf1__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf1__underlay"] + - ["leaf1__underlay_ibgp"] + networks: + - ["10.0.250.11/32"] + - ["10.0.255.11/32"] + - bgp_config: ["leaf1"] + local_identifier: "leaf1__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf1__evpn"] + # ============================================================ + # Leaf2 address families + # ============================================================ + - bgp_config: ["leaf2"] + local_identifier: "leaf2__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf2__underlay"] + - ["leaf2__underlay_ibgp"] + networks: + - ["10.0.250.12/32"] + - ["10.0.255.11/32"] + - bgp_config: ["leaf2"] + local_identifier: "leaf2__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf2__evpn"] + # ============================================================ + # Leaf3 address families + # ============================================================ + - bgp_config: ["leaf3"] + local_identifier: "leaf3__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf3__underlay"] + - ["leaf3__underlay_ibgp"] + networks: + - ["10.0.250.13/32"] + - ["10.0.255.12/32"] + - bgp_config: ["leaf3"] + local_identifier: "leaf3__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf3__evpn"] + # ============================================================ + # Leaf4 address families + # ============================================================ + - bgp_config: ["leaf4"] + local_identifier: "leaf4__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf4__underlay"] + - ["leaf4__underlay_ibgp"] + networks: + - ["10.0.250.14/32"] + - ["10.0.255.12/32"] + - bgp_config: ["leaf4"] + local_identifier: "leaf4__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf4__evpn"] + # ============================================================ + # Leaf5 address families + # ============================================================ + - bgp_config: ["leaf5"] + local_identifier: "leaf5__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf5__underlay"] + - ["leaf5__underlay_ibgp"] + networks: + - ["10.0.250.15/32"] + - ["10.0.255.13/32"] + - bgp_config: ["leaf5"] + local_identifier: "leaf5__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf5__evpn"] + # ============================================================ + # Leaf6 address families + # ============================================================ + - bgp_config: ["leaf6"] + local_identifier: "leaf6__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf6__underlay"] + - ["leaf6__underlay_ibgp"] + networks: + - ["10.0.250.16/32"] + - ["10.0.255.13/32"] + - bgp_config: ["leaf6"] + local_identifier: "leaf6__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf6__evpn"] + # ============================================================ + # Leaf7 address families + # ============================================================ + - bgp_config: ["leaf7"] + local_identifier: "leaf7__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf7__underlay"] + - ["leaf7__underlay_ibgp"] + networks: + - ["10.0.250.17/32"] + - ["10.0.255.14/32"] + - bgp_config: ["leaf7"] + local_identifier: "leaf7__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf7__evpn"] + # Leaf7 IPv4 unicast in VRF gold (border peering) + - bgp_config: ["leaf7"] + local_identifier: "leaf7__vrf_gold__ipv4_unicast" + afi: ipv4 + safi: unicast + vrf: "gold" + active_sessions: + - ["leaf7__10.90.90.1"] + # ============================================================ + # Leaf8 address families + # ============================================================ + - bgp_config: ["leaf8"] + local_identifier: "leaf8__ipv4_unicast" + afi: ipv4 + safi: unicast + active_peer_groups: + - ["leaf8__underlay"] + - ["leaf8__underlay_ibgp"] + networks: + - ["10.0.250.18/32"] + - ["10.0.255.14/32"] + - bgp_config: ["leaf8"] + local_identifier: "leaf8__evpn_unicast" + afi: evpn + safi: unicast + active_peer_groups: + - ["leaf8__evpn"] + # Leaf8 IPv4 unicast in VRF gold (border peering) + - bgp_config: ["leaf8"] + local_identifier: "leaf8__vrf_gold__ipv4_unicast" + afi: ipv4 + safi: unicast + vrf: "gold" + active_sessions: + - ["leaf8__10.90.90.1"] diff --git a/objects/11-vrfs.yml b/objects/11-vrfs.yml new file mode 100644 index 0000000..9f5adb6 --- /dev/null +++ b/objects/11-vrfs.yml @@ -0,0 +1,62 @@ +# VRFs, Route Targets, VRF Device Assignments +# Depends on: 02-devices, 03-interfaces, 05-vlans-vxlan (VNI 100001) +# +# VRF gold is used on leaf3/4 (VLAN 34) and leaf7/8 (VLAN 78 + border) +# L3VNI 100001 for symmetric IRB +# Route targets: import/export evpn 1:100001 +# Per-device RD: :1 +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraRouteTarget + data: + - target: "1:100001" + description: VRF gold EVPN route target +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraVRF + data: + - name: gold + description: VRF gold - L3 VXLAN with symmetric IRB + l3vni: ["100001"] + import_targets: + - ["1:100001"] + export_targets: + - ["1:100001"] +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraVRFDeviceAssignment + data: + - device: ["leaf3"] + vrf: ["gold"] + route_distinguisher: "10.0.250.13:1" + import_targets: + - ["1:100001"] + export_targets: + - ["1:100001"] + - device: ["leaf4"] + vrf: ["gold"] + route_distinguisher: "10.0.250.14:1" + import_targets: + - ["1:100001"] + export_targets: + - ["1:100001"] + - device: ["leaf7"] + vrf: ["gold"] + route_distinguisher: "10.0.250.17:1" + import_targets: + - ["1:100001"] + export_targets: + - ["1:100001"] + - device: ["leaf8"] + vrf: ["gold"] + route_distinguisher: "10.0.250.18:1" + import_targets: + - ["1:100001"] + export_targets: + - ["1:100001"] diff --git a/objects/12-mlag.yml b/objects/12-mlag.yml new file mode 100644 index 0000000..29b8e56 --- /dev/null +++ b/objects/12-mlag.yml @@ -0,0 +1,134 @@ +# MLAG: Domains and Peer Configs +# Depends on: 02-devices, 03-interfaces (Vlan4090, Port-Channel999), 05-vlans-vxlan (VLAN 4090/4091) +# +# All 4 MLAG pairs share domain-id "leafs" and virtual-mac c001.cafe.babe +# but each is a separate MlagDomain object linking two devices. +# MLAG peer VLAN: 4090, MLAG iBGP VLAN: 4091 +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraMlagDomain + data: + # MLAG pair 1: leaf1 + leaf2 + - domain_id: leafs-1-2 + description: MLAG domain for leaf1/leaf2 pair + virtual_mac: "c001.cafe.babe" + heartbeat_vrf: mgmt + dual_primary_detection: true + dual_primary_delay: 10 + dual_primary_action: errdisable + devices: + - ["leaf1"] + - ["leaf2"] + peer_vlan: ["4090"] + ibgp_vlan: ["4091"] + # MLAG pair 2: leaf3 + leaf4 + - domain_id: leafs-3-4 + description: MLAG domain for leaf3/leaf4 pair + virtual_mac: "c001.cafe.babe" + heartbeat_vrf: mgmt + dual_primary_detection: true + dual_primary_delay: 10 + dual_primary_action: errdisable + devices: + - ["leaf3"] + - ["leaf4"] + peer_vlan: ["4090"] + ibgp_vlan: ["4091"] + # MLAG pair 3: leaf5 + leaf6 + - domain_id: leafs-5-6 + description: MLAG domain for leaf5/leaf6 pair + virtual_mac: "c001.cafe.babe" + heartbeat_vrf: mgmt + dual_primary_detection: true + dual_primary_delay: 10 + dual_primary_action: errdisable + devices: + - ["leaf5"] + - ["leaf6"] + peer_vlan: ["4090"] + ibgp_vlan: ["4091"] + # MLAG pair 4: leaf7 + leaf8 + - domain_id: leafs-7-8 + description: MLAG domain for leaf7/leaf8 pair + virtual_mac: "c001.cafe.babe" + heartbeat_vrf: mgmt + dual_primary_detection: true + dual_primary_delay: 10 + dual_primary_action: errdisable + devices: + - ["leaf7"] + - ["leaf8"] + peer_vlan: ["4090"] + ibgp_vlan: ["4091"] +--- +apiVersion: infrahub.app/v1 +kind: Object +spec: + kind: InfraMlagPeerConfig + data: + # Leaf1 MLAG peer config + - device: ["leaf1"] + mlag_domain: ["leafs-1-2"] + local_interface_ip: "10.0.199.254/31" + peer_address: "10.0.199.255" + heartbeat_peer_ip: "172.16.0.50" + local_interface: ["leaf1", "Vlan4090"] + peer_link: ["leaf1", "Port-Channel999"] + # Leaf2 MLAG peer config + - device: ["leaf2"] + mlag_domain: ["leafs-1-2"] + local_interface_ip: "10.0.199.255/31" + peer_address: "10.0.199.254" + heartbeat_peer_ip: "172.16.0.25" + local_interface: ["leaf2", "Vlan4090"] + peer_link: ["leaf2", "Port-Channel999"] + # Leaf3 MLAG peer config + - device: ["leaf3"] + mlag_domain: ["leafs-3-4"] + local_interface_ip: "10.0.199.252/31" + peer_address: "10.0.199.253" + heartbeat_peer_ip: "172.16.0.28" + local_interface: ["leaf3", "Vlan4090"] + peer_link: ["leaf3", "Port-Channel999"] + # Leaf4 MLAG peer config + - device: ["leaf4"] + mlag_domain: ["leafs-3-4"] + local_interface_ip: "10.0.199.253/31" + peer_address: "10.0.199.252" + heartbeat_peer_ip: "172.16.0.27" + local_interface: ["leaf4", "Vlan4090"] + peer_link: ["leaf4", "Port-Channel999"] + # Leaf5 MLAG peer config + - device: ["leaf5"] + mlag_domain: ["leafs-5-6"] + local_interface_ip: "10.0.199.250/31" + peer_address: "10.0.199.251" + heartbeat_peer_ip: "172.16.0.30" + local_interface: ["leaf5", "Vlan4090"] + peer_link: ["leaf5", "Port-Channel999"] + # Leaf6 MLAG peer config + - device: ["leaf6"] + mlag_domain: ["leafs-5-6"] + local_interface_ip: "10.0.199.251/31" + peer_address: "10.0.199.250" + heartbeat_peer_ip: "172.16.0.29" + local_interface: ["leaf6", "Vlan4090"] + peer_link: ["leaf6", "Port-Channel999"] + # Leaf7 MLAG peer config + - device: ["leaf7"] + mlag_domain: ["leafs-7-8"] + local_interface_ip: "10.0.199.248/31" + peer_address: "10.0.199.249" + heartbeat_peer_ip: "172.16.0.32" + local_interface: ["leaf7", "Vlan4090"] + peer_link: ["leaf7", "Port-Channel999"] + # Leaf8 MLAG peer config + - device: ["leaf8"] + mlag_domain: ["leafs-7-8"] + local_interface_ip: "10.0.199.249/31" + peer_address: "10.0.199.248" + heartbeat_peer_ip: "172.16.0.31" + local_interface: ["leaf8", "Vlan4090"] + peer_link: ["leaf8", "Port-Channel999"] diff --git a/schemas/README.md b/schemas/README.md new file mode 100644 index 0000000..ce54fc2 --- /dev/null +++ b/schemas/README.md @@ -0,0 +1,217 @@ +# Infrahub Schema for EVPN-VXLAN Fabric + +This directory contains the Infrahub schema definitions for modeling an EVPN-VXLAN fabric. The schema is designed to represent the [overlaid.net reference topology](https://overlaid.net/2019/01/27/arista-bgp-evpn-configuration-example/) (2 spines, 8 leafs in 4 MLAG pairs). + +## Schema Files + +| File | Nodes | Description | +|------|-------|-------------| +| `base.yml` | Device, InterfaceEthernet, InterfaceLoopback, InterfaceVlan, InterfaceLag, IPAddress, Site, Platform | Core infrastructure and generic Interface | +| `bgp.yml` | AutonomousSystem, BGPRouterConfig, BGPPeerGroup, BGPSession, BGPAddressFamily | BGP routing configuration | +| `vlan_vxlan.yml` | VLAN, VNI, VTEP, VlanVniMapping, EVPNInstance | Layer 2 overlay and VXLAN tunneling | +| `vrf.yml` | VRF, RouteTarget, VRFDeviceAssignment | VRF and L3VNI configuration | +| `mlag.yml` | MlagDomain, MlagPeerConfig, MlagInterface | MLAG domain and peer configuration | +| `extensions.yml` | Fabric, UnderlayLink, HostConnection | Fabric topology and connectivity | + +## Entity Relationship Diagram + +``` + ┌──────────────┐ + │ InfraFabric │ + └──────┬───────┘ + ┌───────────┼───────────┐ + ▼ ▼ ▼ + ┌────────────┐ ┌──────────┐ ┌──────────────────┐ + │LocationSite│ │InfraAS │ │InfraUnderlayLink │ + └────────────┘ └────┬─────┘ │ local/remote: │ + │ │ Device,Interface,│ + │ │ IPAddress │ + ┌────────────┘ └──────────────────┘ + ▼ + ┌──────────────┐ ┌────────────────┐ + │ InfraDevice │◄────────│ InfraPlatform │ + └──────┬───────┘ └────────────────┘ + │ + ┌─────────────┼──────────────┬────────────────┐ + ▼ ▼ ▼ ▼ +┌─────────────┐ ┌──────────┐ ┌───────────┐ ┌──────────────┐ +│InfraInterface│ │InfraBGP- │ │InfraVTEP │ │InfraMlagDomain│ +│ (generic) │ │RouterCfg │ │ │ │ (2 devices) │ +└──────┬──────┘ └────┬─────┘ └─────┬─────┘ └──────┬───────┘ + │ │ │ │ + ▼ ▼ ▼ ▼ + Subtypes: ┌──────────┐ ┌──────────┐ ┌───────────────┐ + - Ethernet │BGPPeer- │ │VlanVni- │ │MlagPeerConfig │ + - Loopback │ Group │ │ Mapping │ │ (per device) │ + - Vlan └──────────┘ └──────────┘ └───────────────┘ + - Lag ┌──────────┐ ┌───────────────┐ + │ │BGPSession│ │MlagInterface │ + ▼ └────┬─────┘ └───────────────┘ +┌──────────────┐ │ +│InfraIPAddress│ │ optional vrf +└──────────────┘ ▼ + ┌─────────┐ ┌──────────────┐ + │InfraVRF │◄────│InfraRoute- │ + └────┬────┘ │ Target │ + │ └──────────────┘ + ▼ + ┌────────────────┐ + │VRFDevice- │ + │ Assignment │ + │ (per device RD)│ + └────────────────┘ + +Layer 2 / EVPN: +┌──────────┐ ┌──────────┐ ┌──────────────┐ +│InfraVLAN │◄──►│ InfraVNI │ │EVPNInstance │ +│ │ │(L2/L3) │ │(per device │ +│ │ └──────────┘ │ RD/RT) │ +└──────────┘ └──────────────┘ +``` + +### Relationship Legend + +| Symbol | Meaning | +|--------|---------| +| `Parent` → child | Child lifecycle depends on parent (e.g., Device → Interface) | +| `Component` → child | Owned collection (e.g., VTEP → VlanVniMapping) | +| `Attribute` | Association without ownership (e.g., BGPSession → VRF) | +| `Generic` | Polymorphic (e.g., IPAddress → any Interface subtype) | + +### All Relationships + +| Source | Relationship | Target | Kind | Cardinality | +|--------|-------------|--------|------|-------------| +| **base.yml** | | | | | +| InfraInterface | `device` | InfraDevice | Parent | one | +| InfraInterface | `ip_addresses` | InfraIPAddress | Generic | many | +| InfraDevice | `site` | LocationSite | Attribute | one (opt) | +| InfraDevice | `platform` | InfraPlatform | Attribute | one (opt) | +| InfraDevice | `asn` | InfraAutonomousSystem | Attribute | one (opt) | +| InfraDevice | `interfaces` | InfraInterface | Component | many | +| InfraDevice | `mlag_domain` | InfraMlagDomain | Attribute | one (opt) | +| InterfaceEthernet | `lag` | InterfaceLag | Attribute | one (opt) | +| InterfaceEthernet | `connected_interface` | InterfaceEthernet | outbound | one (opt) | +| InterfaceVlan | `vlan` | InfraVLAN | Attribute | one (opt) | +| InterfaceLag | `members` | InterfaceEthernet | Component | many | +| InfraIPAddress | `interface` | InfraInterface | Attribute | one (opt) | +| **bgp.yml** | | | | | +| BGPRouterConfig | `device` | InfraDevice | Parent | one | +| BGPRouterConfig | `local_asn` | InfraAutonomousSystem | Attribute | one | +| BGPRouterConfig | `peer_groups` | BGPPeerGroup | Component | many | +| BGPRouterConfig | `sessions` | BGPSession | Component | many | +| BGPPeerGroup | `bgp_config` | BGPRouterConfig | Parent | one | +| BGPPeerGroup | `remote_asn` | InfraAutonomousSystem | Attribute | one (opt) | +| BGPSession | `bgp_config` | BGPRouterConfig | Parent | one | +| BGPSession | `peer_group` | BGPPeerGroup | Attribute | one (opt) | +| BGPSession | `remote_asn` | InfraAutonomousSystem | Attribute | one (opt) | +| BGPSession | `peer_device` | InfraDevice | Attribute | one (opt) | +| BGPSession | `vrf` | InfraVRF | Attribute | one (opt) | +| BGPAddressFamily | `bgp_config` | BGPRouterConfig | Parent | one | +| BGPAddressFamily | `active_peer_groups` | BGPPeerGroup | Attribute | many | +| BGPAddressFamily | `networks` | InfraIPAddress | Attribute | many (opt) | +| **vlan_vxlan.yml** | | | | | +| InfraVLAN | `vni` | InfraVNI | Attribute | one (opt) | +| InfraVLAN | `site` | LocationSite | Attribute | one (opt) | +| InfraVNI | `vlan` | InfraVLAN | Attribute | one (opt) | +| InfraVNI | `vrf` | InfraVRF | Attribute | one (opt) | +| InfraVTEP | `device` | InfraDevice | Parent | one | +| InfraVTEP | `source_interface` | InterfaceLoopback | Attribute | one | +| InfraVTEP | `vlan_vni_mappings` | VlanVniMapping | Component | many | +| VlanVniMapping | `vtep` | InfraVTEP | Parent | one | +| VlanVniMapping | `vlan` | InfraVLAN | Attribute | one | +| VlanVniMapping | `vni` | InfraVNI | Attribute | one | +| EVPNInstance | `device` | InfraDevice | Parent | one | +| EVPNInstance | `vlan` | InfraVLAN | Attribute | one | +| **vrf.yml** | | | | | +| InfraVRF | `l3vni` | InfraVNI | Attribute | one (opt) | +| InfraVRF | `import_targets` | InfraRouteTarget | outbound | many (opt) | +| InfraVRF | `export_targets` | InfraRouteTarget | outbound | many (opt) | +| InfraVRF | `interfaces` | InfraInterface | Attribute | many (opt) | +| VRFDeviceAssignment | `vrf` | InfraVRF | Attribute | one | +| VRFDeviceAssignment | `device` | InfraDevice | Parent | one | +| VRFDeviceAssignment | `import_targets` | InfraRouteTarget | outbound | many (opt) | +| VRFDeviceAssignment | `export_targets` | InfraRouteTarget | outbound | many (opt) | +| **mlag.yml** | | | | | +| MlagDomain | `devices` | InfraDevice | Attribute | many (2) | +| MlagDomain | `peer_vlan` | InfraVLAN | outbound | one | +| MlagDomain | `ibgp_vlan` | InfraVLAN | outbound | one (opt) | +| MlagPeerConfig | `device` | InfraDevice | Parent | one | +| MlagPeerConfig | `mlag_domain` | MlagDomain | Attribute | one | +| MlagPeerConfig | `local_interface` | InterfaceVlan | Attribute | one | +| MlagPeerConfig | `peer_link` | InterfaceLag | Attribute | one | +| MlagInterface | `mlag_domain` | MlagDomain | Attribute | one | +| MlagInterface | `lag_interfaces` | InterfaceLag | Attribute | many (1-2) | +| **extensions.yml** | | | | | +| InfraFabric | `spine_asn` | InfraAutonomousSystem | Attribute | one (opt) | +| InfraFabric | `sites` | LocationSite | Attribute | many (opt) | +| UnderlayLink | `fabric` | InfraFabric | Parent | one | +| UnderlayLink | `local_device` | InfraDevice | outbound | one | +| UnderlayLink | `local_interface` | InterfaceEthernet | outbound | one | +| UnderlayLink | `local_ip_address` | InfraIPAddress | outbound | one | +| UnderlayLink | `remote_device` | InfraDevice | outbound | one | +| UnderlayLink | `remote_interface` | InterfaceEthernet | outbound | one | +| UnderlayLink | `remote_ip_address` | InfraIPAddress | outbound | one | +| HostConnection | `vlans` | InfraVLAN | Attribute | many | +| HostConnection | `mlag_interface` | MlagInterface | Attribute | one (opt) | +| HostConnection | `lag_interface` | InterfaceLag | Attribute | one (opt) | + +## Reference Topology Mapping + +| Physical | Infrahub Model | +|----------|----------------| +| spine1, spine2 | InfraDevice (role: spine) | +| leaf1-8 | InfraDevice (role: leaf) | +| AS 65000 | InfraAutonomousSystem (spines) | +| AS 65001-65004 | InfraAutonomousSystem (leaf pairs) | +| AS 64999 | InfraAutonomousSystem (border router) | +| VLAN 40, 34, 78, 900 | InfraVLAN + InfraVNI | +| VLAN 4090, 4091 | InfraVLAN (vlan_type: mlag_peer/mlag_ibgp, trunk_groups, stp_enabled: false) | +| VRF gold | InfraVRF + VRFDeviceAssignment (per-device RD) | +| Route targets 1:100001 | InfraRouteTarget | +| leaf1+leaf2 pair | InfraMlagDomain | +| Port-Channel999 | InfraInterfaceLag (peer-link) | +| Port-Channel1 | InfraMlagInterface (host-facing) | +| Ethernet1-12 | InfraInterfaceEthernet | +| Loopback0 | InfraInterfaceLoopback (BGP router-id) | +| Loopback1 | InfraInterfaceLoopback (shared VTEP IP per MLAG pair) | +| Vxlan1 | InfraVTEP | +| Vlan34/78 SVIs | InfraInterfaceVlan (virtual_router_address for anycast gateway) | +| peer groups (underlay, evpn, underlay_ibgp) | InfraBGPPeerGroup | +| BGP sessions (global) | InfraBGPSession (vrf: null) | +| BGP sessions in VRF gold (leaf7/8 → AS 64999) | InfraBGPSession (vrf: gold) | +| spine1/2 p2p links | InfraUnderlayLink (IPAddress relations, not attributes) | +| distance bgp 20 200 200 | BGPRouterConfig (ebgp_distance, ibgp_distance, local_distance) | + +## Usage + +### Loading the Schema + +```bash +infrahubctl schema load schemas/ +``` + +### Validation + +```bash +infrahubctl schema check schemas/ +``` + +## Key Design Decisions + +1. **Generic Interface**: All interface types inherit from `InfraInterface` generic for polymorphic queries +2. **MLAG as Domain**: MLAG is modeled as a domain containing exactly 2 devices, with per-device config via MlagPeerConfig +3. **BGP Hierarchy**: BGPRouterConfig → PeerGroups → Sessions allows template-based configuration +4. **BGP VRF Sessions**: BGPSession has an optional `vrf` relation (kind: Attribute) to support peering inside a VRF context (#50) +5. **VTEP as single model**: VTEP is the unique VXLAN model (InterfaceVxlan was removed to avoid duplication — #44) +6. **EVPN Instance per VLAN**: Allows device-specific RD/RT while referencing common VLAN/VNI +7. **Per-device scoped IDs**: BGPPeerGroup and BGPSession use `bgp_config__router_id__value` prefix in human_friendly_id for global uniqueness (#43) +8. **UnderlayLink IPs as relations**: local/remote IPs reference InfraIPAddress objects instead of inline attributes to avoid dual source of truth (#47) +9. **VRFDeviceAssignment**: Separates VRF definition (global) from per-device assignment (with device-specific RD/RT overrides) +10. **Anycast gateway**: InterfaceVlan has `virtual_router_address` for `ip virtual-router address` and `autostate` for MLAG SVIs (#46) + +## Related Issues + +- Parent issue: [#41 — Define Infrahub Schema for EVPN-VXLAN Fabric](https://gitea.arnodo.fr/Damien/fabric-orchestrator/issues/41) +- Schema fixes: #43 (unique IDs), #44 (remove duplicate VTEP), #45 (VLAN unique), #46 (anycast gateway), #47 (underlay IPs), #48 (BGP distance), #49 (trunk groups), #50 (VRF BGP sessions) +- Depends on: Schema being loaded before transforms (#30, #31, #32, #33) diff --git a/schemas/base.yml b/schemas/base.yml new file mode 100644 index 0000000..7bd5aa9 --- /dev/null +++ b/schemas/base.yml @@ -0,0 +1,344 @@ +# Base Infrastructure Schema for EVPN-VXLAN Fabric +# This schema defines core infrastructure objects required for fabric orchestration +--- +version: "1.0" +generics: + - name: Interface + namespace: Infra + description: Generic interface - parent for all interface types + label: Interface + include_in_menu: false + hierarchical: false + display_label: "{{ name__value }}" + attributes: + - name: name + kind: Text + description: Interface name (e.g., Ethernet1, Loopback0) + - name: description + kind: Text + optional: true + - name: enabled + kind: Boolean + default_value: true + - name: mtu + kind: Number + optional: true + description: Maximum Transmission Unit + relationships: + - name: device + peer: InfraDevice + cardinality: one + kind: Parent + optional: false + - name: ip_addresses + peer: InfraIPAddress + identifier: interface__ip_addresses + cardinality: many + kind: Generic + +nodes: + # ================================================================ + # Location + # ================================================================ + - name: Site + namespace: Location + description: Physical site or data center + label: Site + icon: mingcute--building-4-line + include_in_menu: false + human_friendly_id: + - name__value + order_by: + - name__value + display_label: "{{ name__value }}" + attributes: + - name: name + kind: Text + unique: true + - name: description + kind: Text + optional: true + - name: facility + kind: Text + optional: true + description: Facility identifier or code + + # ================================================================ + # Platform + # ================================================================ + - name: Platform + namespace: Infra + description: Device platform/OS (e.g., Arista EOS, Cisco NX-OS) + label: Platform + icon: mdi--chip + 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: Platform name (e.g., arista_eos, cisco_nxos) + - name: description + kind: Text + optional: true + - name: napalm_driver + kind: Text + optional: true + description: NAPALM driver name + - name: netmiko_device_type + kind: Text + optional: true + description: Netmiko device type + + # ================================================================ + # Device + # ================================================================ + - name: Device + namespace: Infra + description: Network device (spine, leaf, etc.) + label: Device + icon: mdi--server-network + 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: Device hostname + - name: description + kind: Text + optional: true + - name: role + kind: Dropdown + choices: + - name: spine + label: Spine + color: "#3b82f6" + - name: leaf + label: Leaf + color: "#22c55e" + description: Fabric role + - name: status + kind: Dropdown + default_value: active + choices: + - name: active + label: Active + color: "#22c55e" + - name: planned + label: Planned + color: "#3b82f6" + - name: maintenance + label: Maintenance + color: "#f59e0b" + - name: decommissioned + label: Decommissioned + color: "#ef4444" + relationships: + - name: site + peer: LocationSite + cardinality: one + optional: true + - name: platform + peer: InfraPlatform + cardinality: one + optional: true + - name: asn + peer: InfraAutonomousSystem + cardinality: one + optional: true + description: BGP Autonomous System + - name: interfaces + peer: InfraInterface + cardinality: many + kind: Component + - name: mlag_domain + peer: InfraMlagDomain + cardinality: one + optional: true + + # ================================================================ + # Interface Types (inherit from InfraInterface generic) + # ================================================================ + - name: InterfaceEthernet + namespace: Infra + description: Physical Ethernet interface + label: Ethernet Interface + icon: mdi--ethernet + include_in_menu: false + inherit_from: + - InfraInterface + uniqueness_constraints: + - ["device", "name__value"] + human_friendly_id: + - device__name__value + - name__value + display_label: "{{ name__value }}" + attributes: + - name: speed + kind: Dropdown + optional: true + choices: + - name: "1000" + label: 1 Gbps + - name: "10000" + label: 10 Gbps + - name: "25000" + label: 25 Gbps + - name: "40000" + label: 40 Gbps + - name: "100000" + label: 100 Gbps + - name: mode + kind: Dropdown + optional: true + choices: + - name: access + label: Access + - name: trunk + label: Trunk + - name: routed + label: Routed (L3) + description: Switchport mode + relationships: + - name: lag + peer: InfraInterfaceLag + cardinality: one + optional: true + description: Parent LAG interface + - name: connected_interface + peer: InfraInterfaceEthernet + identifier: ethernet_connected_to + direction: outbound + cardinality: one + optional: true + description: Connected peer interface + + - name: InterfaceLoopback + namespace: Infra + description: Loopback interface + label: Loopback Interface + icon: mdi--reload + include_in_menu: false + inherit_from: + - InfraInterface + uniqueness_constraints: + - ["device", "name__value"] + human_friendly_id: + - device__name__value + - name__value + display_label: "{{ name__value }}" + + - name: InterfaceVlan + namespace: Infra + description: VLAN SVI interface + label: VLAN Interface + icon: mdi--lan + include_in_menu: false + inherit_from: + - InfraInterface + uniqueness_constraints: + - ["device", "name__value"] + human_friendly_id: + - device__name__value + - name__value + display_label: "{{ name__value }}" + attributes: + - name: virtual_router_address + kind: IPHost + optional: true + description: Anycast gateway IP (ip virtual-router address) + - name: autostate + kind: Boolean + default_value: true + description: "Enable autostate (set false for MLAG peer SVIs)" + relationships: + - name: vlan + peer: InfraVLAN + cardinality: one + optional: true + + - name: InterfaceLag + namespace: Infra + description: Link Aggregation (Port-Channel) interface + label: LAG Interface + icon: mdi--link-variant + include_in_menu: false + inherit_from: + - InfraInterface + uniqueness_constraints: + - ["device", "name__value"] + human_friendly_id: + - device__name__value + - name__value + display_label: "{{ name__value }}" + attributes: + - name: lacp_mode + kind: Dropdown + optional: true + choices: + - name: active + label: Active + - name: passive + label: Passive + - name: static + label: Static (No LACP) + - name: mlag_id + kind: Number + optional: true + description: MLAG interface ID + relationships: + - name: members + peer: InfraInterfaceEthernet + cardinality: many + kind: Component + + # ================================================================ + # IP Address + # ================================================================ + - name: IPAddress + namespace: Infra + description: IP Address assignment + label: IP Address + icon: mdi--ip-network + include_in_menu: false + human_friendly_id: + - address__value + order_by: + - address__value + display_label: "{{ address__value }}" + attributes: + - name: address + kind: IPHost + description: IP address with prefix (e.g., 10.0.1.1/31) + - name: description + kind: Text + optional: true + - name: status + kind: Dropdown + default_value: active + choices: + - name: active + label: Active + color: "#22c55e" + - name: reserved + label: Reserved + color: "#3b82f6" + - name: deprecated + label: Deprecated + color: "#ef4444" + relationships: + - name: interface + peer: InfraInterface + identifier: interface__ip_addresses + cardinality: one + optional: true + kind: Attribute diff --git a/schemas/bgp.yml b/schemas/bgp.yml new file mode 100644 index 0000000..c246ebf --- /dev/null +++ b/schemas/bgp.yml @@ -0,0 +1,291 @@ +# BGP Schema for EVPN-VXLAN Fabric +# Defines Autonomous System, Peer Groups, and BGP Sessions +--- +version: "1.0" +nodes: + # ================================================================ + # Autonomous System + # ================================================================ + - name: AutonomousSystem + namespace: Infra + description: BGP Autonomous System + label: Autonomous System + icon: mdi--cloud-outline + include_in_menu: false + human_friendly_id: + - asn__value + order_by: + - asn__value + display_label: "{{ asn__value }}" + attributes: + - name: asn + kind: Number + unique: true + description: AS Number (e.g., 65000) + - name: description + kind: Text + optional: true + - name: as_type + kind: Dropdown + default_value: private + choices: + - name: private + label: Private + - name: public + label: Public + + # ================================================================ + # BGP Router Configuration (per device) + # ================================================================ + - name: BGPRouterConfig + namespace: Infra + description: BGP router configuration on a device + label: BGP Router Config + icon: mdi--router-wireless + include_in_menu: false + human_friendly_id: + - device__name__value + display_label: "{{ router_id__value }}" + attributes: + - name: router_id + kind: IPHost + unique: true + description: BGP Router ID + - name: default_ipv4_unicast + kind: Boolean + default_value: false + description: Enable default IPv4 unicast + - name: log_neighbor_changes + kind: Boolean + default_value: true + - name: ecmp_max_paths + kind: Number + default_value: 4 + description: Maximum ECMP paths + - name: ecmp_max_ecmp + kind: Number + default_value: 64 + description: Maximum ECMP routes + - name: ebgp_distance + kind: Number + default_value: 20 + description: eBGP administrative distance + - name: ibgp_distance + kind: Number + default_value: 200 + description: iBGP administrative distance + - name: local_distance + kind: Number + default_value: 200 + description: Local route administrative distance + relationships: + - name: device + peer: InfraDevice + cardinality: one + kind: Parent + optional: false + - name: local_asn + peer: InfraAutonomousSystem + cardinality: one + - name: peer_groups + peer: InfraBGPPeerGroup + cardinality: many + kind: Component + - name: sessions + peer: InfraBGPSession + cardinality: many + kind: Component + + # ================================================================ + # BGP Peer Group + # ================================================================ + - name: BGPPeerGroup + namespace: Infra + description: BGP peer group template + label: BGP Peer Group + icon: mdi--account-group + include_in_menu: false + uniqueness_constraints: + - ["local_identifier__value"] + human_friendly_id: + - local_identifier__value + display_label: "{{ name__value }}" + attributes: + - name: local_identifier + kind: Text + description: "Unique identifier combining device name and peer group name (e.g. spine1__evpn)" + - name: name + kind: Text + description: Peer group name (e.g., underlay, evpn) + - name: description + kind: Text + optional: true + - name: update_source + kind: Text + optional: true + description: Update source interface (e.g., Loopback0) + - name: ebgp_multihop + kind: Number + optional: true + description: eBGP multihop TTL + - name: send_community + kind: Dropdown + default_value: none + choices: + - name: none + label: None + - name: standard + label: Standard + - name: extended + label: Extended + - name: both + label: Both + - name: next_hop_self + kind: Boolean + default_value: false + - name: next_hop_unchanged + kind: Boolean + default_value: false + description: Keep next-hop unchanged (for route reflector) + - name: maximum_routes + kind: Number + optional: true + - name: maximum_routes_warning_only + kind: Boolean + default_value: true + - name: peer_group_type + kind: Dropdown + default_value: underlay + choices: + - name: underlay + label: Underlay IPv4 + - name: underlay_ibgp + label: Underlay iBGP + - name: evpn + label: EVPN Overlay + relationships: + - name: bgp_config + peer: InfraBGPRouterConfig + cardinality: one + kind: Parent + optional: false + - name: remote_asn + peer: InfraAutonomousSystem + cardinality: one + optional: true + + # ================================================================ + # BGP Session (Neighbor) + # ================================================================ + - name: BGPSession + namespace: Infra + description: BGP neighbor session + label: BGP Session + icon: mdi--connection + include_in_menu: false + uniqueness_constraints: + - ["local_identifier__value"] + human_friendly_id: + - local_identifier__value + display_label: "{{ peer_address__value }}" + attributes: + - name: local_identifier + kind: Text + description: "Unique identifier combining device name and peer address (e.g. spine1__10.0.250.11)" + - name: peer_address + kind: IPHost + description: Neighbor IP address + - name: description + kind: Text + optional: true + - name: enabled + kind: Boolean + default_value: true + relationships: + - name: bgp_config + peer: InfraBGPRouterConfig + cardinality: one + kind: Parent + optional: false + - name: peer_group + peer: InfraBGPPeerGroup + cardinality: one + optional: true + - name: remote_asn + peer: InfraAutonomousSystem + cardinality: one + optional: true + description: Override peer group remote-as + - name: peer_device + peer: InfraDevice + cardinality: one + optional: true + description: Remote peer device (for documentation) + - name: vrf + peer: InfraVRF + cardinality: one + kind: Attribute + optional: true + description: VRF context for this session (null = global BGP process) + + # ================================================================ + # BGP Address Family Configuration + # ================================================================ + - name: BGPAddressFamily + namespace: Infra + description: BGP address family configuration + label: BGP Address Family + icon: mdi--format-list-bulleted + include_in_menu: false + human_friendly_id: + - local_identifier__value + display_label: "{{ afi__value }}" + attributes: + - name: local_identifier + kind: Text + description: "Unique identifier combining device name and AFI/SAFI (e.g. spine1__ipv4_unicast)" + - name: afi + kind: Dropdown + choices: + - name: ipv4 + label: IPv4 + - name: ipv6 + label: IPv6 + - name: evpn + label: EVPN + description: Address Family Identifier + - name: safi + kind: Dropdown + default_value: unicast + choices: + - name: unicast + label: Unicast + - name: multicast + label: Multicast + description: Sub Address Family Identifier + relationships: + - name: bgp_config + peer: InfraBGPRouterConfig + cardinality: one + kind: Parent + optional: false + - name: active_peer_groups + peer: InfraBGPPeerGroup + cardinality: many + description: Peer groups activated in this AF + - name: active_sessions + peer: InfraBGPSession + cardinality: many + optional: true + description: Individual sessions activated in this AF (e.g. spine direct neighbors) + - name: vrf + peer: InfraVRF + cardinality: one + kind: Attribute + optional: true + description: VRF context for this AF (null = global BGP process) + - name: networks + peer: InfraIPAddress + cardinality: many + optional: true + description: Networks to advertise diff --git a/schemas/extensions.yml b/schemas/extensions.yml new file mode 100644 index 0000000..d2d8c9e --- /dev/null +++ b/schemas/extensions.yml @@ -0,0 +1,164 @@ +# 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 + cardinality: many + optional: true + + # ================================================================ + # 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 + display_label: "{{ description__value }}" + attributes: + - 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 diff --git a/schemas/mlag.yml b/schemas/mlag.yml new file mode 100644 index 0000000..7a6c220 --- /dev/null +++ b/schemas/mlag.yml @@ -0,0 +1,141 @@ +# MLAG Schema for EVPN-VXLAN Fabric +# Defines MLAG domain and peer configuration +--- +version: "1.0" +nodes: + # ================================================================ + # MLAG Domain + # ================================================================ + - name: MlagDomain + namespace: Infra + description: MLAG domain configuration for leaf pair + label: MLAG Domain + icon: mdi--link-variant + include_in_menu: false + human_friendly_id: + - domain_id__value + display_label: "{{ domain_id__value }}" + attributes: + - name: domain_id + kind: Text + description: MLAG domain identifier (e.g., leafs) + - name: description + kind: Text + optional: true + - name: virtual_mac + kind: Text + description: "Shared virtual MAC (format: xxxx.xxxx.xxxx)" + - name: heartbeat_vrf + kind: Text + default_value: mgmt + description: VRF for heartbeat (typically mgmt) + - name: dual_primary_detection + kind: Boolean + default_value: true + - name: dual_primary_delay + kind: Number + default_value: 10 + description: Delay in seconds before dual-primary action + - name: dual_primary_action + kind: Dropdown + default_value: errdisable + choices: + - name: errdisable + label: Error Disable Interfaces + - name: none + label: No Action + relationships: + - name: devices + peer: InfraDevice + cardinality: many + min_count: 2 + max_count: 2 + description: MLAG peer devices + - name: peer_vlan + peer: InfraVLAN + identifier: mlag_domain_peer_vlan + cardinality: one + direction: outbound + description: VLAN for MLAG peer-link control traffic + - name: ibgp_vlan + peer: InfraVLAN + identifier: mlag_domain_ibgp_vlan + cardinality: one + direction: outbound + optional: true + description: VLAN for iBGP peering between MLAG peers + + # ================================================================ + # MLAG Peer Configuration (per device) + # ================================================================ + - name: MlagPeerConfig + namespace: Infra + description: MLAG configuration on a specific device + label: MLAG Peer Config + icon: mdi--server-network + include_in_menu: false + human_friendly_id: + - device__name__value + display_label: "{{ local_interface_ip__value }}" + attributes: + - name: local_interface_ip + kind: IPNetwork + description: IP on MLAG peer VLAN SVI + - name: peer_address + kind: IPHost + description: Peer's MLAG SVI IP address + - name: heartbeat_peer_ip + kind: IPHost + description: Peer's management IP for heartbeat + relationships: + - name: device + peer: InfraDevice + cardinality: one + kind: Parent + optional: false + - name: mlag_domain + peer: InfraMlagDomain + cardinality: one + - name: local_interface + peer: InfraInterfaceVlan + cardinality: one + description: Local MLAG SVI + - name: peer_link + peer: InfraInterfaceLag + cardinality: one + description: Peer-link port-channel + + # ================================================================ + # MLAG Interface (MLAG-enabled LAG) + # ================================================================ + - name: MlagInterface + namespace: Infra + description: MLAG interface configuration + label: MLAG Interface + icon: mdi--ethernet-cable + include_in_menu: false + display_label: "{{ mlag_id__value }}" + attributes: + - name: mlag_id + kind: Number + description: MLAG interface ID + - name: description + kind: Text + optional: true + - name: lacp_fallback_timeout + kind: Number + default_value: 5 + description: LACP fallback timeout in seconds + - name: lacp_fallback_individual + kind: Boolean + default_value: true + relationships: + - name: mlag_domain + peer: InfraMlagDomain + cardinality: one + - name: lag_interfaces + peer: InfraInterfaceLag + cardinality: many + min_count: 1 + max_count: 2 + description: LAG interfaces on each MLAG peer diff --git a/schemas/vlan_vxlan.yml b/schemas/vlan_vxlan.yml new file mode 100644 index 0000000..b17cf82 --- /dev/null +++ b/schemas/vlan_vxlan.yml @@ -0,0 +1,221 @@ +# VLAN and VXLAN Schema for EVPN-VXLAN Fabric +# Defines VLAN, VNI mappings, and VTEP configuration +--- +version: "1.0" +nodes: + # ================================================================ + # VLAN + # ================================================================ + - name: VLAN + namespace: Infra + description: Virtual LAN configuration + label: VLAN + icon: mdi--lan-connect + include_in_menu: false + human_friendly_id: + - vlan_id__value + order_by: + - vlan_id__value + display_label: "{{ vlan_id__value }} ({{ name__value }})" + attributes: + - name: vlan_id + kind: Number + unique: true + description: VLAN ID (1-4094) + - name: name + kind: Text + description: VLAN name + - name: description + kind: Text + optional: true + - name: status + kind: Dropdown + default_value: active + choices: + - name: active + label: Active + color: "#22c55e" + - name: reserved + label: Reserved + color: "#3b82f6" + - name: deprecated + label: Deprecated + color: "#ef4444" + - name: vlan_type + kind: Dropdown + default_value: standard + choices: + - name: standard + label: Standard + - name: mlag_peer + label: MLAG Peer + - name: mlag_ibgp + label: MLAG iBGP + description: VLAN purpose + - name: trunk_groups + kind: List + optional: true + description: "Trunk groups restricting VLAN propagation (e.g., mlag-peer)" + - name: stp_enabled + kind: Boolean + default_value: true + description: "Enable spanning-tree on this VLAN (set false for MLAG peer VLANs)" + relationships: + - name: vni + peer: InfraVNI + cardinality: one + optional: true + description: Associated L2VNI for VXLAN + - name: site + peer: LocationSite + cardinality: one + optional: true + + # ================================================================ + # VNI (VXLAN Network Identifier) + # ================================================================ + - name: VNI + namespace: Infra + description: VXLAN Network Identifier + label: VNI + icon: mdi--tunnel-outline + include_in_menu: false + human_friendly_id: + - vni__value + order_by: + - vni__value + display_label: "{{ vni__value }}" + attributes: + - name: vni + kind: Number + unique: true + description: VNI value (1-16777215) + - name: description + kind: Text + optional: true + - name: vni_type + kind: Dropdown + default_value: l2vni + choices: + - name: l2vni + label: L2 VNI + color: "#3b82f6" + - name: l3vni + label: L3 VNI + color: "#22c55e" + description: VNI type for EVPN + relationships: + - name: vlan + peer: InfraVLAN + cardinality: one + optional: true + description: Associated VLAN for L2VNI + - name: vrf + peer: InfraVRF + cardinality: one + optional: true + description: Associated VRF for L3VNI + + # ================================================================ + # VTEP (VXLAN Tunnel Endpoint) + # ================================================================ + - name: VTEP + namespace: Infra + description: VXLAN Tunnel Endpoint configuration + label: VTEP + icon: mdi--server-network-outline + include_in_menu: false + human_friendly_id: + - device__name__value + display_label: "{{ source_address__value }}" + attributes: + - name: source_address + kind: IPHost + description: VTEP source IP (typically from Loopback1) + - name: udp_port + kind: Number + default_value: 4789 + - name: learn_restrict + kind: Dropdown + default_value: any + choices: + - name: any + label: Any + - name: flood + label: Flood + description: MAC learning restriction mode + relationships: + - name: device + peer: InfraDevice + cardinality: one + kind: Parent + optional: false + - name: source_interface + peer: InfraInterfaceLoopback + cardinality: one + description: Source interface for VTEP + - name: vlan_vni_mappings + peer: InfraVlanVniMapping + cardinality: many + kind: Component + + # ================================================================ + # VLAN to VNI Mapping (per-device) + # ================================================================ + - name: VlanVniMapping + namespace: Infra + description: VLAN to VNI mapping on a VTEP + label: VLAN-VNI Mapping + icon: mdi--swap-horizontal + include_in_menu: false + display_label: "{{ description__value }}" + attributes: + - name: description + kind: Text + optional: true + description: "Mapping description (e.g., VLAN 40 <-> VNI 10040)" + relationships: + - name: vtep + peer: InfraVTEP + cardinality: one + kind: Parent + optional: false + - name: vlan + peer: InfraVLAN + cardinality: one + - name: vni + peer: InfraVNI + cardinality: one + + # ================================================================ + # EVPN Instance (per VLAN) + # ================================================================ + - name: EVPNInstance + namespace: Infra + description: EVPN instance configuration (route targets for L2 extension) + label: EVPN Instance + icon: mdi--cloud-sync + include_in_menu: false + display_label: "{{ route_distinguisher__value }}" + attributes: + - name: route_distinguisher + kind: Text + description: "Route Distinguisher (format: ASN:VNI or IP:VNI)" + - name: route_target_import + kind: Text + description: "Import Route Target (format: VNI:VNI)" + - name: route_target_export + kind: Text + description: "Export Route Target (format: VNI:VNI)" + - name: redistribute_learned + kind: Boolean + default_value: true + relationships: + - name: vlan + peer: InfraVLAN + cardinality: one + - name: device + peer: InfraDevice + cardinality: one + kind: Parent + optional: false diff --git a/schemas/vrf.yml b/schemas/vrf.yml new file mode 100644 index 0000000..68e1569 --- /dev/null +++ b/schemas/vrf.yml @@ -0,0 +1,124 @@ +# VRF Schema for EVPN-VXLAN Fabric +# Defines VRF and Route Target configuration for L3 VPN +--- +version: "1.0" +nodes: + # ================================================================ + # VRF (Virtual Routing and Forwarding) + # ================================================================ + - name: VRF + namespace: Infra + description: Virtual Routing and Forwarding instance + label: VRF + icon: mdi--router + 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: VRF name + - name: description + kind: Text + optional: true + - name: route_distinguisher + kind: Text + optional: true + description: "Route Distinguisher (format: ASN:NN or IP:NN)" + - name: vrf_id + kind: Number + optional: true + description: VRF table ID + relationships: + - name: l3vni + peer: InfraVNI + cardinality: one + optional: true + description: L3 VNI for symmetric IRB + - name: import_targets + peer: InfraRouteTarget + identifier: vrf_import_targets + cardinality: many + direction: outbound + optional: true + - name: export_targets + peer: InfraRouteTarget + identifier: vrf_export_targets + cardinality: many + direction: outbound + optional: true + - name: interfaces + peer: InfraInterface + cardinality: many + optional: true + description: Interfaces assigned to this VRF + + # ================================================================ + # Route Target + # ================================================================ + - name: RouteTarget + namespace: Infra + description: BGP Route Target for VPN import/export + label: Route Target + icon: mdi--target + include_in_menu: false + human_friendly_id: + - target__value + order_by: + - target__value + display_label: "{{ target__value }}" + attributes: + - name: target + kind: Text + unique: true + description: "Route Target value (format: ASN:NN or IP:NN)" + - name: description + kind: Text + optional: true + + # ================================================================ + # VRF Device Assignment + # ================================================================ + - name: VRFDeviceAssignment + namespace: Infra + description: VRF assignment to a specific device + label: VRF Assignment + icon: mdi--router-network + include_in_menu: false + human_friendly_id: + - device__name__value + - vrf__name__value + display_label: "{{ device__name__value }} - {{ vrf__name__value }}" + attributes: + - name: route_distinguisher + kind: Text + optional: true + description: "Device-specific RD (overrides VRF default)" + relationships: + - name: vrf + peer: InfraVRF + cardinality: one + optional: false + - name: device + peer: InfraDevice + cardinality: one + kind: Parent + optional: false + - name: import_targets + peer: InfraRouteTarget + identifier: vrf_assignment_import_targets + cardinality: many + direction: outbound + optional: true + description: Device-specific import RTs + - name: export_targets + peer: InfraRouteTarget + identifier: vrf_assignment_export_targets + cardinality: many + direction: outbound + optional: true + description: Device-specific export RTs