Files
arista-evpn-vxlan-clab/infrahub/transforms/queries/bgp_intent.gql
Damien Arnodo 1b918a4cbc feat: Add Infrahub Jinja2 transform for BGP configuration (#23) (#27)
## Summary

Closes #23. Implements a single unified `bgp_yang_transform` covering the complete BGP router stanza for all 10 fabric devices.

**Design decision:** One transform (one query + one template) rather than 4 separate transforms, because all BGP components (process config, peer groups, neighbors, AFs) live under a single `router bgp <ASN>` stanza and must be consistent. This avoids multiple API calls per device and keeps the data model coherent.

| File | Description |
|------|-------------|
| `infrahub/transforms/queries/bgp_intent.gql` | Unified GraphQL query — `InfraBGPRouterConfig` (with peer_groups, sessions) + `InfraBGPAddressFamily` (with active_peer_groups, active_sessions, networks, optional vrf) |
| `infrahub/transforms/templates/bgp_yang.j2` | Jinja2 template — renders `bgp.global`, `bgp.peer_groups`, `bgp.neighbors`, `bgp.address_families`, `bgp.vrf_neighbors`, `bgp.vrf_address_families`; returns `[]` for devices with no BGP config |
| `infrahub/transforms/tests/bgp_yang/test.yml` | Smoke check + unit render tests for leaf1, spine1, leaf7 |
| `infrahub/transforms/tests/bgp_yang/leaf1/` | 3 peer-groups, 5 global neighbors, 2 global AFs |
| `infrahub/transforms/tests/bgp_yang/spine1/` | 1 peer-group (evpn/next-hop-unchanged), 16 neighbors (8 direct underlay + 8 EVPN), IPv4 AF activates individual sessions |
| `infrahub/transforms/tests/bgp_yang/leaf7/` | leaf1 pattern + VRF gold border session (AS 64999) + VRF-scoped IPv4 unicast AF |
| `.infrahub.yml` | Registers `bgp_intent` query and `bgp_yang_transform` |

## Validation

| Device | Expected output |
|--------|----------------|
| `leaf1` | 3 peer-groups, 5 global neighbors (underlay×2, iBGP×1, EVPN×2), 2 AFs, empty VRF sections |
| `spine1` | 1 peer-group (evpn, next-hop-unchanged), 16 neighbors (8 direct with `remote_asn`, 8 EVPN via peer-group), IPv4 AF activates individual sessions |
| `leaf7` | Same as leaf1 (AS 65004) + `vrf_neighbors: [{10.90.90.1, AS 64999, VRF gold}]` + `vrf_address_families: [{ipv4, VRF gold, active_sessions: [10.90.90.1]}]` |

```bash
infrahubctl render bgp_yang_transform device_name=leaf1
infrahubctl render bgp_yang_transform device_name=spine1
infrahubctl render bgp_yang_transform device_name=leaf7
```

## Design notes

- Follows identical conventions to existing transforms (#20–#22)
- All optional relationships (`remote_asn`, `peer_group`, `vrf`, `peer_device`, `update_source`, etc.) wrapped in `is defined and is not none` guards
- `send_community` value `"none"` (schema default) is normalised to `null` in the output — keeps the rendered JSON clean for downstream consumers
- VRF-scoped sessions and AFs are separated into `vrf_neighbors` / `vrf_address_families` arrays, each entry carrying a `"vrf"` key, so the template consumer can trivially iterate per-VRF without filtering
2026-03-01 13:22:51 +00:00

106 lines
2.3 KiB
GraphQL

query BgpIntent($device_name: String!) {
InfraBGPRouterConfig(device__name__value: $device_name) {
edges {
node {
router_id { value }
default_ipv4_unicast { value }
log_neighbor_changes { value }
ecmp_max_paths { value }
ecmp_max_ecmp { value }
ebgp_distance { value }
ibgp_distance { value }
local_distance { value }
local_asn {
node {
asn { value }
}
}
peer_groups {
edges {
node {
name { value }
peer_group_type { value }
update_source { value }
ebgp_multihop { value }
send_community { value }
next_hop_self { value }
next_hop_unchanged { value }
maximum_routes { value }
maximum_routes_warning_only { value }
remote_asn {
node {
asn { value }
}
}
}
}
}
sessions {
edges {
node {
peer_address { value }
description { value }
enabled { value }
peer_group {
node {
name { value }
local_identifier { value }
}
}
remote_asn {
node {
asn { value }
}
}
vrf {
node {
name { value }
}
}
peer_device {
node {
name { value }
}
}
}
}
}
}
}
}
InfraBGPAddressFamily(device__name__value: $device_name) {
edges {
node {
afi { value }
safi { value }
vrf {
node {
name { value }
}
}
active_peer_groups {
edges {
node {
name { value }
}
}
}
active_sessions {
edges {
node {
peer_address { value }
}
}
}
networks {
edges {
node {
address { value }
}
}
}
}
}
}
}