Merge pull request '[Phase 2] Define Infrahub Schema for EVPN-VXLAN Fabric' (#51) from feature/41-infrahub-schema into main
Reviewed-on: #51
This commit was merged in pull request #51.
This commit is contained in:
7
.infrahub.yml
Normal file
7
.infrahub.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
# yaml-language-server: $schema=https://schema.infrahub.app/python-sdk/repository-config/latest.json
|
||||
---
|
||||
schemas:
|
||||
- schemas/
|
||||
|
||||
menus:
|
||||
- menus/fabric-menu.yml
|
||||
82
CLAUDE.md
Normal file
82
CLAUDE.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Claude Code Instructions — fabric-orchestrator
|
||||
|
||||
## Project Context
|
||||
|
||||
Fabric-orchestrator manages Arista EVPN-VXLAN fabrics using Infrahub as the source of truth.
|
||||
Gitea: https://gitea.arnodo.fr/Damien/fabric-orchestrator
|
||||
Branch: `feature/41-infrahub-schema`
|
||||
|
||||
## Reference Topology (overlaid.net)
|
||||
|
||||
- 2 spines (AS 65000), 8 leafs in 4 MLAG pairs (AS 65001–65004)
|
||||
- Loopback0: BGP router-id per device, Loopback1: shared VTEP IP per MLAG pair
|
||||
- VLANs 4090 (MLAG peer) / 4091 (MLAG iBGP) with trunk groups
|
||||
- Underlay: eBGP point-to-point (spine↔leaf) + iBGP (leaf↔leaf peer)
|
||||
- Overlay: EVPN eBGP multihop on loopbacks, spines as route-reflectors with next-hop-unchanged
|
||||
- L2VXLAN (EVPN Type-2): VLAN→VNI mapping, redistribute learned
|
||||
- L3VXLAN (EVPN Type-5): VRF→VNI mapping, redistribute connected
|
||||
- Border peering: BGP sessions inside VRF (leaf7/8 → AS 64999 in VRF gold)
|
||||
|
||||
## Schema Files (Infrahub YAML format, in `schemas/`)
|
||||
|
||||
| File | Content |
|
||||
| ---------------- | ----------------------------------------------------------------------------- |
|
||||
| `base.yml` | Device, Interfaces (Ethernet, Loopback, Vlan, Lag, Vxlan), IPAddress |
|
||||
| `bgp.yml` | AutonomousSystem, BGPRouterConfig, BGPPeerGroup, BGPSession, BGPAddressFamily |
|
||||
| `vlan_vxlan.yml` | VLAN, VNI, VTEP, VlanVniMapping, EVPNInstance |
|
||||
| `vrf.yml` | VRFConfig, RouteTarget, VRFDeviceAssignment |
|
||||
| `mlag.yml` | MlagDomain, MlagPeerConfig, MlagInterface |
|
||||
| `extensions.yml` | UnderlayLink, HostConnection, FabricSettings |
|
||||
|
||||
## Infrahub Schema Rules
|
||||
|
||||
1. `human_friendly_id` fields MUST have `unique: true` — globally unique across all instances
|
||||
2. To scope human_friendly_id per-device, traverse Parent relationships:
|
||||
`parent_rel__parent_attr__value` (e.g. `device__name__value`)
|
||||
3. Parent relationships (`kind: Parent`) need `optional: false` explicitly
|
||||
4. Self-referencing relationships need `direction: outbound`
|
||||
5. Multiple relationships to the same peer type need distinct `identifier` values
|
||||
6. Don't model the same concept twice (e.g. VTEP source_address vs InterfaceVxlan source_interface)
|
||||
7. `kind: Attribute` for association, `kind: Component` for ownership (lifecycle-coupled)
|
||||
8. `kind: Parent` implies the child cannot exist without the parent
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
infrahubctl schema check schemas/
|
||||
```
|
||||
|
||||
Always run before committing. Fix any errors before pushing.
|
||||
|
||||
## Commit Convention
|
||||
|
||||
```
|
||||
fix(schema): short description — refs #<issue>
|
||||
feat(schema): short description — refs #<issue>
|
||||
```
|
||||
|
||||
- One logical change per commit
|
||||
- Reference the Gitea issue number
|
||||
- Comment on the issue after implementation with changes summary
|
||||
|
||||
## Open Issues (prioritized)
|
||||
|
||||
Check https://gitea.arnodo.fr/Damien/fabric-orchestrator/issues for current backlog.
|
||||
Critical issues (blocking data load) take priority over functional improvements.
|
||||
Dependency chain: resolve critical → significant → minor sequentially.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Read the issue description fully before starting
|
||||
2. Read relevant schema files to understand current state
|
||||
3. Make minimal, targeted changes
|
||||
4. Validate with `infrahubctl schema check schemas/`
|
||||
5. Commit with proper message referencing the issue
|
||||
6. Comment on the Gitea issue with what was changed
|
||||
|
||||
## Don'ts
|
||||
|
||||
- Don't add fields not needed by the reference topology
|
||||
- Don't change `human_friendly_id` without checking uniqueness implications
|
||||
- Don't remove existing relationships without checking reverse dependencies
|
||||
- Don't create new schema files without discussing first
|
||||
68
README.md
68
README.md
@@ -24,14 +24,14 @@ Think `terraform plan` and `terraform apply`, but for your network fabric — po
|
||||
|
||||
We chose [InfraHub](https://github.com/opsmill/infrahub) over NetBox as Source of Truth for several reasons:
|
||||
|
||||
| Feature | NetBox | InfraHub |
|
||||
|---------|--------|----------|
|
||||
| **Schema** | Fixed DCIM/IPAM model | Fully customizable YAML schema |
|
||||
| **Git Integration** | External sync needed | Native - branches = data branches |
|
||||
| **Versioning** | Changelog only | True Git-like versioning with merges |
|
||||
| **Test/Redeploy** | Dump/restore | `git clone` = complete environment |
|
||||
| **Transforms** | Limited | Built-in Jinja2 + Python transforms |
|
||||
| **GraphQL** | Yes | Yes (auto-generated from schema) |
|
||||
| Feature | NetBox | InfraHub |
|
||||
| ------------------- | --------------------- | ------------------------------------ |
|
||||
| **Schema** | Fixed DCIM/IPAM model | Fully customizable YAML schema |
|
||||
| **Git Integration** | External sync needed | Native - branches = data branches |
|
||||
| **Versioning** | Changelog only | True Git-like versioning with merges |
|
||||
| **Test/Redeploy** | Dump/restore | `git clone` = complete environment |
|
||||
| **Transforms** | Limited | Built-in Jinja2 + Python transforms |
|
||||
| **GraphQL** | Yes | Yes (auto-generated from schema) |
|
||||
|
||||
**Key benefits for this project:**
|
||||
|
||||
@@ -98,16 +98,16 @@ git push
|
||||
|
||||
## 🎛 Why Prefect?
|
||||
|
||||
| Feature | Benefit |
|
||||
|---------|---------|
|
||||
| **Python-native workflows** | Use `@flow` and `@task` decorators — no YAML, just Python |
|
||||
| **Free secrets management** | Native `Secret` blocks for credentials (free in OSS) |
|
||||
| **Built-in UI** | Dashboard, logs, metrics, execution history via `prefect server start` |
|
||||
| **No containerization required** | Run flows directly with `.serve()` — no Docker needed |
|
||||
| **Event-driven triggers** | Schedule, webhooks (via FastAPI), flow triggers out of the box |
|
||||
| **Task dependencies** | Automatic dependency ordering via task result passing or `wait_for` |
|
||||
| **Retry & error handling** | Built-in retry policies with `@task(retries=3)` |
|
||||
| **Human-in-the-loop** | Native `pause_flow_run()` for approval workflows |
|
||||
| Feature | Benefit |
|
||||
| -------------------------------- | ---------------------------------------------------------------------- |
|
||||
| **Python-native workflows** | Use `@flow` and `@task` decorators — no YAML, just Python |
|
||||
| **Free secrets management** | Native `Secret` blocks for credentials (free in OSS) |
|
||||
| **Built-in UI** | Dashboard, logs, metrics, execution history via `prefect server start` |
|
||||
| **No containerization required** | Run flows directly with `.serve()` — no Docker needed |
|
||||
| **Event-driven triggers** | Schedule, webhooks (via FastAPI), flow triggers out of the box |
|
||||
| **Task dependencies** | Automatic dependency ordering via task result passing or `wait_for` |
|
||||
| **Retry & error handling** | Built-in retry policies with `@task(retries=3)` |
|
||||
| **Human-in-the-loop** | Native `pause_flow_run()` for approval workflows |
|
||||
|
||||
## 🎯 Target Fabric
|
||||
|
||||
@@ -124,12 +124,12 @@ Reference: [arista-evpn-vxlan-clab](https://gitea.arnodo.fr/Damien/arista-evpn-v
|
||||
|
||||
Progress is tracked via issues. See [all issues](https://gitea.arnodo.fr/Damien/fabric-orchestrator/issues) or filter by phase:
|
||||
|
||||
| Phase | Description | Status |
|
||||
|-------|-------------|--------|
|
||||
| **Phase 1** | YANG Path Discovery - Map EOS 4.35.0F YANG models, validate gNMI | ✅ Complete |
|
||||
| Phase | Description | Status |
|
||||
| ----------- | -------------------------------------------------------------------- | ------------- |
|
||||
| **Phase 1** | YANG Path Discovery - Map EOS 4.35.0F YANG models, validate gNMI | ✅ Complete |
|
||||
| **Phase 2** | InfraHub Setup & Core Reconciler - Schema, diff engine, YANG mappers | 🔄 In Progress |
|
||||
| **Phase 3** | Full Fabric Coverage - BGP, MLAG, VRFs mappers | 📋 Planned |
|
||||
| **Phase 4** | Prefect Integration - Flows, webhooks, drift detection | 📋 Planned |
|
||||
| **Phase 3** | Full Fabric Coverage - BGP, MLAG, VRFs mappers | 📋 Planned |
|
||||
| **Phase 4** | Prefect Integration - Flows, webhooks, drift detection | 📋 Planned |
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
@@ -197,17 +197,17 @@ fabric-orchestrator/
|
||||
|
||||
## 🛠️ Technology Stack
|
||||
|
||||
| Component | Technology | Purpose |
|
||||
|-----------|------------|---------|
|
||||
| Source of Truth | **InfraHub** | Intent definition via custom schema |
|
||||
| Data Storage | **This Git repo** | Schema + data versioned together |
|
||||
| Orchestrator | **Prefect** | Python-native workflow orchestration |
|
||||
| Transport | gNMI | Configuration and telemetry |
|
||||
| Data Models | YANG (OpenConfig + Arista) | Structured configuration |
|
||||
| Python Library | pygnmi + infrahub-sdk | gNMI/InfraHub interactions |
|
||||
| CLI | Click + Rich | YANG discovery tools |
|
||||
| Validation | Pydantic v2 | Intent data validation |
|
||||
| Lab | ContainerLab + cEOS | Development environment |
|
||||
| Component | Technology | Purpose |
|
||||
| --------------- | -------------------------- | ------------------------------------ |
|
||||
| Source of Truth | **InfraHub** | Intent definition via custom schema |
|
||||
| Data Storage | **This Git repo** | Schema + data versioned together |
|
||||
| Orchestrator | **Prefect** | Python-native workflow orchestration |
|
||||
| Transport | gNMI | Configuration and telemetry |
|
||||
| Data Models | YANG (OpenConfig + Arista) | Structured configuration |
|
||||
| Python Library | pygnmi + infrahub-sdk | gNMI/InfraHub interactions |
|
||||
| CLI | Click + Rich | YANG discovery tools |
|
||||
| Validation | Pydantic v2 | Intent data validation |
|
||||
| Lab | ContainerLab + cEOS | Development environment |
|
||||
|
||||
## 🔗 Related Projects
|
||||
|
||||
|
||||
247
menus/fabric-menu.yml
Normal file
247
menus/fabric-menu.yml
Normal file
@@ -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"
|
||||
217
schemas/README.md
Normal file
217
schemas/README.md
Normal file
@@ -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)
|
||||
347
schemas/base.yml
Normal file
347
schemas/base.yml
Normal file
@@ -0,0 +1,347 @@
|
||||
# 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"
|
||||
- name: border_leaf
|
||||
label: Border Leaf
|
||||
color: "#f59e0b"
|
||||
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: IPNetwork
|
||||
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
|
||||
271
schemas/bgp.yml
Normal file
271
schemas/bgp.yml
Normal file
@@ -0,0 +1,271 @@
|
||||
# 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:
|
||||
- ["bgp_config", "name__value"]
|
||||
human_friendly_id:
|
||||
- bgp_config__router_id__value
|
||||
- name__value
|
||||
display_label: "{{ name__value }}"
|
||||
attributes:
|
||||
- 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:
|
||||
- ["bgp_config", "peer_address__value"]
|
||||
human_friendly_id:
|
||||
- bgp_config__router_id__value
|
||||
- peer_address__value
|
||||
display_label: "{{ peer_address__value }}"
|
||||
attributes:
|
||||
- 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
|
||||
display_label: "{{ afi__value }}"
|
||||
attributes:
|
||||
- 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: networks
|
||||
peer: InfraIPAddress
|
||||
cardinality: many
|
||||
optional: true
|
||||
description: Networks to advertise
|
||||
164
schemas/extensions.yml
Normal file
164
schemas/extensions.yml
Normal file
@@ -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
|
||||
141
schemas/mlag.yml
Normal file
141
schemas/mlag.yml
Normal file
@@ -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
|
||||
221
schemas/vlan_vxlan.yml
Normal file
221
schemas/vlan_vxlan.yml
Normal file
@@ -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
|
||||
124
schemas/vrf.yml
Normal file
124
schemas/vrf.yml
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user