From 1b918a4cbc7c9a9467f00578f2d8ead7d3dd717e Mon Sep 17 00:00:00 2001 From: Damien Arnodo Date: Sun, 1 Mar 2026 13:22:51 +0000 Subject: [PATCH] feat: Add Infrahub Jinja2 transform for BGP configuration (#23) (#27) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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 ` 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 --- .infrahub.yml | 6 + infrahub/objects/11-bgp-sessions.yml | 22 ++ infrahub/schemas/bgp.yml | 6 + infrahub/transforms/queries/bgp_intent.gql | 105 +++++++ infrahub/transforms/templates/bgp_yang.j2 | 194 +++++++++++++ .../tests/bgp_yang/leaf1/input.json | 180 ++++++++++++ .../tests/bgp_yang/leaf1/output.json | 120 ++++++++ .../tests/bgp_yang/leaf7/input.json | 205 ++++++++++++++ .../tests/bgp_yang/leaf7/output.json | 140 +++++++++ .../tests/bgp_yang/spine1/input.json | 266 ++++++++++++++++++ .../tests/bgp_yang/spine1/output.json | 178 ++++++++++++ infrahub/transforms/tests/bgp_yang/test.yml | 27 ++ 12 files changed, 1449 insertions(+) create mode 100644 infrahub/transforms/queries/bgp_intent.gql create mode 100644 infrahub/transforms/templates/bgp_yang.j2 create mode 100644 infrahub/transforms/tests/bgp_yang/leaf1/input.json create mode 100644 infrahub/transforms/tests/bgp_yang/leaf1/output.json create mode 100644 infrahub/transforms/tests/bgp_yang/leaf7/input.json create mode 100644 infrahub/transforms/tests/bgp_yang/leaf7/output.json create mode 100644 infrahub/transforms/tests/bgp_yang/spine1/input.json create mode 100644 infrahub/transforms/tests/bgp_yang/spine1/output.json create mode 100644 infrahub/transforms/tests/bgp_yang/test.yml diff --git a/.infrahub.yml b/.infrahub.yml index a842200..18ca2b1 100644 --- a/.infrahub.yml +++ b/.infrahub.yml @@ -28,6 +28,8 @@ queries: file_path: infrahub/transforms/queries/vrf_intent.gql - name: mlag_intent file_path: infrahub/transforms/queries/mlag_intent.gql + - name: bgp_intent + file_path: infrahub/transforms/queries/bgp_intent.gql jinja2_transforms: - name: vlan_yang_transform @@ -50,3 +52,7 @@ jinja2_transforms: description: "Generate MLAG configuration payload from Infrahub intent" query: mlag_intent template_path: infrahub/transforms/templates/mlag_yang.j2 + - name: bgp_yang_transform + description: "Generate BGP configuration payload from Infrahub intent" + query: bgp_intent + template_path: infrahub/transforms/templates/bgp_yang.j2 diff --git a/infrahub/objects/11-bgp-sessions.yml b/infrahub/objects/11-bgp-sessions.yml index 54d835f..458ae32 100644 --- a/infrahub/objects/11-bgp-sessions.yml +++ b/infrahub/objects/11-bgp-sessions.yml @@ -512,6 +512,7 @@ spec: # Spine1 address families # ============================================================ - bgp_config: ["spine1"] + device: ["spine1"] local_identifier: "spine1__ipv4_unicast" afi: ipv4 safi: unicast @@ -527,6 +528,7 @@ spec: networks: - ["10.0.250.1/32"] - bgp_config: ["spine1"] + device: ["spine1"] local_identifier: "spine1__evpn_unicast" afi: evpn safi: unicast @@ -536,6 +538,7 @@ spec: # Spine2 address families # ============================================================ - bgp_config: ["spine2"] + device: ["spine2"] local_identifier: "spine2__ipv4_unicast" afi: ipv4 safi: unicast @@ -551,6 +554,7 @@ spec: networks: - ["10.0.250.2/32"] - bgp_config: ["spine2"] + device: ["spine2"] local_identifier: "spine2__evpn_unicast" afi: evpn safi: unicast @@ -560,6 +564,7 @@ spec: # Leaf1 address families # ============================================================ - bgp_config: ["leaf1"] + device: ["leaf1"] local_identifier: "leaf1__ipv4_unicast" afi: ipv4 safi: unicast @@ -570,6 +575,7 @@ spec: - ["10.0.250.11/32"] - ["10.0.255.11/32"] - bgp_config: ["leaf1"] + device: ["leaf1"] local_identifier: "leaf1__evpn_unicast" afi: evpn safi: unicast @@ -579,6 +585,7 @@ spec: # Leaf2 address families # ============================================================ - bgp_config: ["leaf2"] + device: ["leaf2"] local_identifier: "leaf2__ipv4_unicast" afi: ipv4 safi: unicast @@ -589,6 +596,7 @@ spec: - ["10.0.250.12/32"] - ["10.0.255.11/32"] - bgp_config: ["leaf2"] + device: ["leaf2"] local_identifier: "leaf2__evpn_unicast" afi: evpn safi: unicast @@ -598,6 +606,7 @@ spec: # Leaf3 address families # ============================================================ - bgp_config: ["leaf3"] + device: ["leaf3"] local_identifier: "leaf3__ipv4_unicast" afi: ipv4 safi: unicast @@ -608,6 +617,7 @@ spec: - ["10.0.250.13/32"] - ["10.0.255.12/32"] - bgp_config: ["leaf3"] + device: ["leaf3"] local_identifier: "leaf3__evpn_unicast" afi: evpn safi: unicast @@ -617,6 +627,7 @@ spec: # Leaf4 address families # ============================================================ - bgp_config: ["leaf4"] + device: ["leaf4"] local_identifier: "leaf4__ipv4_unicast" afi: ipv4 safi: unicast @@ -627,6 +638,7 @@ spec: - ["10.0.250.14/32"] - ["10.0.255.12/32"] - bgp_config: ["leaf4"] + device: ["leaf4"] local_identifier: "leaf4__evpn_unicast" afi: evpn safi: unicast @@ -636,6 +648,7 @@ spec: # Leaf5 address families # ============================================================ - bgp_config: ["leaf5"] + device: ["leaf5"] local_identifier: "leaf5__ipv4_unicast" afi: ipv4 safi: unicast @@ -646,6 +659,7 @@ spec: - ["10.0.250.15/32"] - ["10.0.255.13/32"] - bgp_config: ["leaf5"] + device: ["leaf5"] local_identifier: "leaf5__evpn_unicast" afi: evpn safi: unicast @@ -655,6 +669,7 @@ spec: # Leaf6 address families # ============================================================ - bgp_config: ["leaf6"] + device: ["leaf6"] local_identifier: "leaf6__ipv4_unicast" afi: ipv4 safi: unicast @@ -665,6 +680,7 @@ spec: - ["10.0.250.16/32"] - ["10.0.255.13/32"] - bgp_config: ["leaf6"] + device: ["leaf6"] local_identifier: "leaf6__evpn_unicast" afi: evpn safi: unicast @@ -674,6 +690,7 @@ spec: # Leaf7 address families # ============================================================ - bgp_config: ["leaf7"] + device: ["leaf7"] local_identifier: "leaf7__ipv4_unicast" afi: ipv4 safi: unicast @@ -684,6 +701,7 @@ spec: - ["10.0.250.17/32"] - ["10.0.255.14/32"] - bgp_config: ["leaf7"] + device: ["leaf7"] local_identifier: "leaf7__evpn_unicast" afi: evpn safi: unicast @@ -691,6 +709,7 @@ spec: - ["leaf7__evpn"] # Leaf7 IPv4 unicast in VRF gold (border peering) - bgp_config: ["leaf7"] + device: ["leaf7"] local_identifier: "leaf7__vrf_gold__ipv4_unicast" afi: ipv4 safi: unicast @@ -701,6 +720,7 @@ spec: # Leaf8 address families # ============================================================ - bgp_config: ["leaf8"] + device: ["leaf8"] local_identifier: "leaf8__ipv4_unicast" afi: ipv4 safi: unicast @@ -711,6 +731,7 @@ spec: - ["10.0.250.18/32"] - ["10.0.255.14/32"] - bgp_config: ["leaf8"] + device: ["leaf8"] local_identifier: "leaf8__evpn_unicast" afi: evpn safi: unicast @@ -718,6 +739,7 @@ spec: - ["leaf8__evpn"] # Leaf8 IPv4 unicast in VRF gold (border peering) - bgp_config: ["leaf8"] + device: ["leaf8"] local_identifier: "leaf8__vrf_gold__ipv4_unicast" afi: ipv4 safi: unicast diff --git a/infrahub/schemas/bgp.yml b/infrahub/schemas/bgp.yml index c246ebf..a8653d2 100644 --- a/infrahub/schemas/bgp.yml +++ b/infrahub/schemas/bgp.yml @@ -264,6 +264,12 @@ nodes: label: Multicast description: Sub Address Family Identifier relationships: + - name: device + peer: InfraDevice + cardinality: one + kind: Attribute + optional: false + description: Device this address family belongs to (denormalized for query filtering) - name: bgp_config peer: InfraBGPRouterConfig cardinality: one diff --git a/infrahub/transforms/queries/bgp_intent.gql b/infrahub/transforms/queries/bgp_intent.gql new file mode 100644 index 0000000..7650840 --- /dev/null +++ b/infrahub/transforms/queries/bgp_intent.gql @@ -0,0 +1,105 @@ +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 } + } + } + } + } + } + } +} diff --git a/infrahub/transforms/templates/bgp_yang.j2 b/infrahub/transforms/templates/bgp_yang.j2 new file mode 100644 index 0000000..5bfd01c --- /dev/null +++ b/infrahub/transforms/templates/bgp_yang.j2 @@ -0,0 +1,194 @@ +{# + bgp_yang.j2 — Produce a JSON object with the complete BGP configuration + for a single device. + + Input: GraphQL response from bgp_intent query. + Returns [] if the device has no BGP router config. + + Output structure: + { + "bgp": { + "global": { asn, router_id, flags, distance, ecmp }, + "peer_groups": [ ... ], + "neighbors": [ ... global-VRF sessions ... ], + "address_families": [ ... global-VRF AFs ... ], + "vrf_neighbors": [ ... VRF-scoped sessions ... ], + "vrf_address_families": [ ... VRF-scoped AFs ... ] + } + } +#} +{%- set router_configs = data.InfraBGPRouterConfig.edges -%} +{%- set af_edges = data.InfraBGPAddressFamily.edges -%} + +{%- if router_configs | length == 0 -%} +[] +{%- else -%} + {%- set rc = router_configs[0].node -%} + + {#— Global section —#} + {%- set asn = none -%} + {%- if rc.local_asn is defined and rc.local_asn is not none and rc.local_asn.node is not none -%} + {%- set asn = rc.local_asn.node.asn.value -%} + {%- endif -%} + + {#— Build peer_groups list —#} + {%- set peer_groups = [] -%} + {%- for pg_edge in rc.peer_groups.edges -%} + {%- set pg = pg_edge.node -%} + {%- set pg_remote_asn = none -%} + {%- if pg.remote_asn is defined and pg.remote_asn is not none and pg.remote_asn.node is not none -%} + {%- set pg_remote_asn = pg.remote_asn.node.asn.value -%} + {%- endif -%} + {%- set pg_send_community = none -%} + {%- if pg.send_community is defined and pg.send_community is not none and pg.send_community.value is not none and pg.send_community.value != "none" -%} + {%- set pg_send_community = pg.send_community.value -%} + {%- endif -%} + {%- set pg_update_source = none -%} + {%- if pg.update_source is defined and pg.update_source is not none and pg.update_source.value is not none -%} + {%- set pg_update_source = pg.update_source.value -%} + {%- endif -%} + {%- set pg_ebgp_multihop = none -%} + {%- if pg.ebgp_multihop is defined and pg.ebgp_multihop is not none and pg.ebgp_multihop.value is not none -%} + {%- set pg_ebgp_multihop = pg.ebgp_multihop.value -%} + {%- endif -%} + {%- set pg_max_routes = none -%} + {%- if pg.maximum_routes is defined and pg.maximum_routes is not none and pg.maximum_routes.value is not none -%} + {%- set pg_max_routes = pg.maximum_routes.value -%} + {%- endif -%} + {%- set _ = peer_groups.append({ + "name": pg.name.value, + "type": pg.peer_group_type.value, + "remote_asn": pg_remote_asn, + "update_source": pg_update_source, + "ebgp_multihop": pg_ebgp_multihop, + "send_community": pg_send_community, + "next_hop_self": pg.next_hop_self.value, + "next_hop_unchanged": pg.next_hop_unchanged.value, + "maximum_routes": pg_max_routes, + "maximum_routes_warning_only": pg.maximum_routes_warning_only.value + }) -%} + {%- endfor -%} + + {#— Split sessions into global and VRF-scoped —#} + {%- set neighbors = [] -%} + {%- set vrf_neighbors = [] -%} + {%- for sess_edge in rc.sessions.edges -%} + {%- set sess = sess_edge.node -%} + + {%- set sess_peer_group = none -%} + {%- if sess.peer_group is defined and sess.peer_group is not none and sess.peer_group.node is not none -%} + {%- set sess_peer_group = sess.peer_group.node.name.value -%} + {%- endif -%} + + {%- set sess_remote_asn = none -%} + {%- if sess.remote_asn is defined and sess.remote_asn is not none and sess.remote_asn.node is not none -%} + {%- set sess_remote_asn = sess.remote_asn.node.asn.value -%} + {%- endif -%} + + {%- set sess_vrf = none -%} + {%- if sess.vrf is defined and sess.vrf is not none and sess.vrf.node is not none -%} + {%- set sess_vrf = sess.vrf.node.name.value -%} + {%- endif -%} + + {%- set sess_obj = { + "peer_address": sess.peer_address.value, + "description": sess.description.value | default(none), + "enabled": sess.enabled.value, + "peer_group": sess_peer_group, + "remote_asn": sess_remote_asn + } -%} + + {%- if sess_vrf is not none -%} + {%- set vrf_sess_obj = { + "peer_address": sess.peer_address.value, + "description": sess.description.value | default(none), + "enabled": sess.enabled.value, + "peer_group": sess_peer_group, + "remote_asn": sess_remote_asn, + "vrf": sess_vrf + } -%} + {%- set _ = vrf_neighbors.append(vrf_sess_obj) -%} + {%- else -%} + {%- set _ = neighbors.append(sess_obj) -%} + {%- endif -%} + {%- endfor -%} + + {#— Split address families into global and VRF-scoped —#} + {%- set address_families = [] -%} + {%- set vrf_address_families = [] -%} + {%- for af_edge in af_edges -%} + {%- set af = af_edge.node -%} + + {%- set af_vrf = none -%} + {%- if af.vrf is defined and af.vrf is not none and af.vrf.node is not none -%} + {%- set af_vrf = af.vrf.node.name.value -%} + {%- endif -%} + + {%- set af_active_pgs = [] -%} + {%- for pg_edge in af.active_peer_groups.edges -%} + {%- set _ = af_active_pgs.append(pg_edge.node.name.value) -%} + {%- endfor -%} + + {%- set af_active_sess = [] -%} + {%- if af.active_sessions is defined and af.active_sessions is not none -%} + {%- for s_edge in af.active_sessions.edges -%} + {%- set _ = af_active_sess.append(s_edge.node.peer_address.value) -%} + {%- endfor -%} + {%- endif -%} + + {%- set af_networks = [] -%} + {%- if af.networks is defined and af.networks is not none -%} + {%- for net_edge in af.networks.edges -%} + {%- set _ = af_networks.append(net_edge.node.address.value) -%} + {%- endfor -%} + {%- endif -%} + + {%- set af_obj = { + "afi": af.afi.value, + "safi": af.safi.value, + "active_peer_groups": af_active_pgs, + "active_sessions": af_active_sess, + "networks": af_networks + } -%} + + {%- if af_vrf is not none -%} + {%- set vrf_af_obj = { + "afi": af.afi.value, + "safi": af.safi.value, + "vrf": af_vrf, + "active_peer_groups": af_active_pgs, + "active_sessions": af_active_sess, + "networks": af_networks + } -%} + {%- set _ = vrf_address_families.append(vrf_af_obj) -%} + {%- else -%} + {%- set _ = address_families.append(af_obj) -%} + {%- endif -%} + {%- endfor -%} + + {%- set result = { + "bgp": { + "global": { + "asn": asn, + "router_id": rc.router_id.value, + "default_ipv4_unicast": rc.default_ipv4_unicast.value, + "log_neighbor_changes": rc.log_neighbor_changes.value, + "distance": { + "ebgp": rc.ebgp_distance.value, + "ibgp": rc.ibgp_distance.value, + "local": rc.local_distance.value + }, + "ecmp": { + "max_paths": rc.ecmp_max_paths.value, + "max_ecmp": rc.ecmp_max_ecmp.value + } + }, + "peer_groups": peer_groups, + "neighbors": neighbors, + "address_families": address_families, + "vrf_neighbors": vrf_neighbors, + "vrf_address_families": vrf_address_families + } + } -%} +{{ result | tojson(indent=2) }} +{%- endif -%} diff --git a/infrahub/transforms/tests/bgp_yang/leaf1/input.json b/infrahub/transforms/tests/bgp_yang/leaf1/input.json new file mode 100644 index 0000000..06bc206 --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/leaf1/input.json @@ -0,0 +1,180 @@ +{ + "data": { + "InfraBGPRouterConfig": { + "edges": [ + { + "node": { + "router_id": { "value": "10.0.250.11" }, + "default_ipv4_unicast": { "value": false }, + "log_neighbor_changes": { "value": true }, + "ecmp_max_paths": { "value": 4 }, + "ecmp_max_ecmp": { "value": 64 }, + "ebgp_distance": { "value": 20 }, + "ibgp_distance": { "value": 200 }, + "local_distance": { "value": 200 }, + "local_asn": { + "node": { + "asn": { "value": 65001 } + } + }, + "peer_groups": { + "edges": [ + { + "node": { + "name": { "value": "underlay" }, + "peer_group_type": { "value": "underlay" }, + "update_source": { "value": null }, + "ebgp_multihop": { "value": null }, + "send_community": { "value": "none" }, + "next_hop_self": { "value": false }, + "next_hop_unchanged": { "value": false }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { + "node": { + "asn": { "value": 65000 } + } + } + } + }, + { + "node": { + "name": { "value": "underlay_ibgp" }, + "peer_group_type": { "value": "underlay_ibgp" }, + "update_source": { "value": null }, + "ebgp_multihop": { "value": null }, + "send_community": { "value": "none" }, + "next_hop_self": { "value": true }, + "next_hop_unchanged": { "value": false }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { + "node": { + "asn": { "value": 65001 } + } + } + } + }, + { + "node": { + "name": { "value": "evpn" }, + "peer_group_type": { "value": "evpn" }, + "update_source": { "value": "Loopback0" }, + "ebgp_multihop": { "value": 3 }, + "send_community": { "value": "extended" }, + "next_hop_self": { "value": false }, + "next_hop_unchanged": { "value": false }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { + "node": { + "asn": { "value": 65000 } + } + } + } + } + ] + }, + "sessions": { + "edges": [ + { + "node": { + "peer_address": { "value": "10.0.1.0" }, + "description": { "value": "underlay to spine1" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "underlay" }, "local_identifier": { "value": "leaf1__underlay" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine1" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.2.0" }, + "description": { "value": "underlay to spine2" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "underlay" }, "local_identifier": { "value": "leaf1__underlay" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine2" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.3.1" }, + "description": { "value": "iBGP to leaf2" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "underlay_ibgp" }, "local_identifier": { "value": "leaf1__underlay_ibgp" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf2" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.1" }, + "description": { "value": "EVPN to spine1" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "leaf1__evpn" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine1" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.2" }, + "description": { "value": "EVPN to spine2" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "leaf1__evpn" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine2" } } } + } + } + ] + } + } + } + ] + }, + "InfraBGPAddressFamily": { + "edges": [ + { + "node": { + "afi": { "value": "ipv4" }, + "safi": { "value": "unicast" }, + "vrf": { "node": null }, + "active_peer_groups": { + "edges": [ + { "node": { "name": { "value": "underlay" } } }, + { "node": { "name": { "value": "underlay_ibgp" } } } + ] + }, + "active_sessions": { "edges": [] }, + "networks": { + "edges": [ + { "node": { "address": { "value": "10.0.250.11/32" } } }, + { "node": { "address": { "value": "10.0.255.11/32" } } } + ] + } + } + }, + { + "node": { + "afi": { "value": "evpn" }, + "safi": { "value": "unicast" }, + "vrf": { "node": null }, + "active_peer_groups": { + "edges": [ + { "node": { "name": { "value": "evpn" } } } + ] + }, + "active_sessions": { "edges": [] }, + "networks": { "edges": [] } + } + } + ] + } + } +} diff --git a/infrahub/transforms/tests/bgp_yang/leaf1/output.json b/infrahub/transforms/tests/bgp_yang/leaf1/output.json new file mode 100644 index 0000000..1be13e7 --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/leaf1/output.json @@ -0,0 +1,120 @@ +{ + "bgp": { + "global": { + "asn": 65001, + "router_id": "10.0.250.11", + "default_ipv4_unicast": false, + "log_neighbor_changes": true, + "distance": { + "ebgp": 20, + "ibgp": 200, + "local": 200 + }, + "ecmp": { + "max_paths": 4, + "max_ecmp": 64 + } + }, + "peer_groups": [ + { + "name": "underlay", + "type": "underlay", + "remote_asn": 65000, + "update_source": null, + "ebgp_multihop": null, + "send_community": null, + "next_hop_self": false, + "next_hop_unchanged": false, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + }, + { + "name": "underlay_ibgp", + "type": "underlay_ibgp", + "remote_asn": 65001, + "update_source": null, + "ebgp_multihop": null, + "send_community": null, + "next_hop_self": true, + "next_hop_unchanged": false, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + }, + { + "name": "evpn", + "type": "evpn", + "remote_asn": 65000, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "send_community": "extended", + "next_hop_self": false, + "next_hop_unchanged": false, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + } + ], + "neighbors": [ + { + "peer_address": "10.0.1.0", + "description": "underlay to spine1", + "enabled": true, + "peer_group": "underlay", + "remote_asn": null + }, + { + "peer_address": "10.0.2.0", + "description": "underlay to spine2", + "enabled": true, + "peer_group": "underlay", + "remote_asn": null + }, + { + "peer_address": "10.0.3.1", + "description": "iBGP to leaf2", + "enabled": true, + "peer_group": "underlay_ibgp", + "remote_asn": null + }, + { + "peer_address": "10.0.250.1", + "description": "EVPN to spine1", + "enabled": true, + "peer_group": "evpn", + "remote_asn": null + }, + { + "peer_address": "10.0.250.2", + "description": "EVPN to spine2", + "enabled": true, + "peer_group": "evpn", + "remote_asn": null + } + ], + "address_families": [ + { + "afi": "ipv4", + "safi": "unicast", + "active_peer_groups": [ + "underlay", + "underlay_ibgp" + ], + "active_sessions": [], + "networks": [ + "10.0.250.11/32", + "10.0.255.11/32" + ] + }, + { + "afi": "evpn", + "safi": "unicast", + "active_peer_groups": [ + "evpn" + ], + "active_sessions": [], + "networks": [] + } + ], + "vrf_neighbors": [], + "vrf_address_families": [] + } +} diff --git a/infrahub/transforms/tests/bgp_yang/leaf7/input.json b/infrahub/transforms/tests/bgp_yang/leaf7/input.json new file mode 100644 index 0000000..870bf8f --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/leaf7/input.json @@ -0,0 +1,205 @@ +{ + "data": { + "InfraBGPRouterConfig": { + "edges": [ + { + "node": { + "router_id": { "value": "10.0.250.17" }, + "default_ipv4_unicast": { "value": false }, + "log_neighbor_changes": { "value": true }, + "ecmp_max_paths": { "value": 4 }, + "ecmp_max_ecmp": { "value": 64 }, + "ebgp_distance": { "value": 20 }, + "ibgp_distance": { "value": 200 }, + "local_distance": { "value": 200 }, + "local_asn": { + "node": { + "asn": { "value": 65004 } + } + }, + "peer_groups": { + "edges": [ + { + "node": { + "name": { "value": "underlay" }, + "peer_group_type": { "value": "underlay" }, + "update_source": { "value": null }, + "ebgp_multihop": { "value": null }, + "send_community": { "value": "none" }, + "next_hop_self": { "value": false }, + "next_hop_unchanged": { "value": false }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { + "node": { + "asn": { "value": 65000 } + } + } + } + }, + { + "node": { + "name": { "value": "underlay_ibgp" }, + "peer_group_type": { "value": "underlay_ibgp" }, + "update_source": { "value": null }, + "ebgp_multihop": { "value": null }, + "send_community": { "value": "none" }, + "next_hop_self": { "value": true }, + "next_hop_unchanged": { "value": false }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { + "node": { + "asn": { "value": 65004 } + } + } + } + }, + { + "node": { + "name": { "value": "evpn" }, + "peer_group_type": { "value": "evpn" }, + "update_source": { "value": "Loopback0" }, + "ebgp_multihop": { "value": 3 }, + "send_community": { "value": "extended" }, + "next_hop_self": { "value": false }, + "next_hop_unchanged": { "value": false }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { + "node": { + "asn": { "value": 65000 } + } + } + } + } + ] + }, + "sessions": { + "edges": [ + { + "node": { + "peer_address": { "value": "10.0.1.12" }, + "description": { "value": "underlay to spine1" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "underlay" }, "local_identifier": { "value": "leaf7__underlay" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine1" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.2.12" }, + "description": { "value": "underlay to spine2" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "underlay" }, "local_identifier": { "value": "leaf7__underlay" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine2" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.3.7" }, + "description": { "value": "iBGP to leaf8" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "underlay_ibgp" }, "local_identifier": { "value": "leaf7__underlay_ibgp" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf8" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.1" }, + "description": { "value": "EVPN to spine1" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "leaf7__evpn" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine1" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.2" }, + "description": { "value": "EVPN to spine2" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "leaf7__evpn" } } }, + "remote_asn": { "node": null }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "spine2" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.90.90.1" }, + "description": { "value": "border peering to AS 64999 in VRF gold" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 64999 } } }, + "vrf": { "node": { "name": { "value": "gold" } } }, + "peer_device": { "node": null } + } + } + ] + } + } + } + ] + }, + "InfraBGPAddressFamily": { + "edges": [ + { + "node": { + "afi": { "value": "ipv4" }, + "safi": { "value": "unicast" }, + "vrf": { "node": null }, + "active_peer_groups": { + "edges": [ + { "node": { "name": { "value": "underlay" } } }, + { "node": { "name": { "value": "underlay_ibgp" } } } + ] + }, + "active_sessions": { "edges": [] }, + "networks": { + "edges": [ + { "node": { "address": { "value": "10.0.250.17/32" } } }, + { "node": { "address": { "value": "10.0.255.14/32" } } } + ] + } + } + }, + { + "node": { + "afi": { "value": "evpn" }, + "safi": { "value": "unicast" }, + "vrf": { "node": null }, + "active_peer_groups": { + "edges": [ + { "node": { "name": { "value": "evpn" } } } + ] + }, + "active_sessions": { "edges": [] }, + "networks": { "edges": [] } + } + }, + { + "node": { + "afi": { "value": "ipv4" }, + "safi": { "value": "unicast" }, + "vrf": { "node": { "name": { "value": "gold" } } }, + "active_peer_groups": { "edges": [] }, + "active_sessions": { + "edges": [ + { "node": { "peer_address": { "value": "10.90.90.1" } } } + ] + }, + "networks": { "edges": [] } + } + } + ] + } + } +} diff --git a/infrahub/transforms/tests/bgp_yang/leaf7/output.json b/infrahub/transforms/tests/bgp_yang/leaf7/output.json new file mode 100644 index 0000000..51be6fe --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/leaf7/output.json @@ -0,0 +1,140 @@ +{ + "bgp": { + "global": { + "asn": 65004, + "router_id": "10.0.250.17", + "default_ipv4_unicast": false, + "log_neighbor_changes": true, + "distance": { + "ebgp": 20, + "ibgp": 200, + "local": 200 + }, + "ecmp": { + "max_paths": 4, + "max_ecmp": 64 + } + }, + "peer_groups": [ + { + "name": "underlay", + "type": "underlay", + "remote_asn": 65000, + "update_source": null, + "ebgp_multihop": null, + "send_community": null, + "next_hop_self": false, + "next_hop_unchanged": false, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + }, + { + "name": "underlay_ibgp", + "type": "underlay_ibgp", + "remote_asn": 65004, + "update_source": null, + "ebgp_multihop": null, + "send_community": null, + "next_hop_self": true, + "next_hop_unchanged": false, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + }, + { + "name": "evpn", + "type": "evpn", + "remote_asn": 65000, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "send_community": "extended", + "next_hop_self": false, + "next_hop_unchanged": false, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + } + ], + "neighbors": [ + { + "peer_address": "10.0.1.12", + "description": "underlay to spine1", + "enabled": true, + "peer_group": "underlay", + "remote_asn": null + }, + { + "peer_address": "10.0.2.12", + "description": "underlay to spine2", + "enabled": true, + "peer_group": "underlay", + "remote_asn": null + }, + { + "peer_address": "10.0.3.7", + "description": "iBGP to leaf8", + "enabled": true, + "peer_group": "underlay_ibgp", + "remote_asn": null + }, + { + "peer_address": "10.0.250.1", + "description": "EVPN to spine1", + "enabled": true, + "peer_group": "evpn", + "remote_asn": null + }, + { + "peer_address": "10.0.250.2", + "description": "EVPN to spine2", + "enabled": true, + "peer_group": "evpn", + "remote_asn": null + } + ], + "address_families": [ + { + "afi": "ipv4", + "safi": "unicast", + "active_peer_groups": [ + "underlay", + "underlay_ibgp" + ], + "active_sessions": [], + "networks": [ + "10.0.250.17/32", + "10.0.255.14/32" + ] + }, + { + "afi": "evpn", + "safi": "unicast", + "active_peer_groups": [ + "evpn" + ], + "active_sessions": [], + "networks": [] + } + ], + "vrf_neighbors": [ + { + "peer_address": "10.90.90.1", + "description": "border peering to AS 64999 in VRF gold", + "enabled": true, + "peer_group": null, + "remote_asn": 64999, + "vrf": "gold" + } + ], + "vrf_address_families": [ + { + "afi": "ipv4", + "safi": "unicast", + "vrf": "gold", + "active_peer_groups": [], + "active_sessions": [ + "10.90.90.1" + ], + "networks": [] + } + ] + } +} diff --git a/infrahub/transforms/tests/bgp_yang/spine1/input.json b/infrahub/transforms/tests/bgp_yang/spine1/input.json new file mode 100644 index 0000000..7749078 --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/spine1/input.json @@ -0,0 +1,266 @@ +{ + "data": { + "InfraBGPRouterConfig": { + "edges": [ + { + "node": { + "router_id": { "value": "10.0.250.1" }, + "default_ipv4_unicast": { "value": false }, + "log_neighbor_changes": { "value": true }, + "ecmp_max_paths": { "value": 4 }, + "ecmp_max_ecmp": { "value": 64 }, + "ebgp_distance": { "value": 20 }, + "ibgp_distance": { "value": 200 }, + "local_distance": { "value": 200 }, + "local_asn": { + "node": { + "asn": { "value": 65000 } + } + }, + "peer_groups": { + "edges": [ + { + "node": { + "name": { "value": "evpn" }, + "peer_group_type": { "value": "evpn" }, + "update_source": { "value": "Loopback0" }, + "ebgp_multihop": { "value": 3 }, + "send_community": { "value": "extended" }, + "next_hop_self": { "value": false }, + "next_hop_unchanged": { "value": true }, + "maximum_routes": { "value": 12000 }, + "maximum_routes_warning_only": { "value": true }, + "remote_asn": { "node": null } + } + } + ] + }, + "sessions": { + "edges": [ + { + "node": { + "peer_address": { "value": "10.0.1.1" }, + "description": { "value": "underlay to leaf1" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65001 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf1" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.3" }, + "description": { "value": "underlay to leaf2" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65001 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf2" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.5" }, + "description": { "value": "underlay to leaf3" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65002 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf3" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.7" }, + "description": { "value": "underlay to leaf4" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65002 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf4" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.9" }, + "description": { "value": "underlay to leaf5" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65003 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf5" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.11" }, + "description": { "value": "underlay to leaf6" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65003 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf6" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.13" }, + "description": { "value": "underlay to leaf7" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65004 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf7" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.1.15" }, + "description": { "value": "underlay to leaf8" }, + "enabled": { "value": true }, + "peer_group": { "node": null }, + "remote_asn": { "node": { "asn": { "value": 65004 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf8" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.11" }, + "description": { "value": "EVPN to leaf1" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65001 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf1" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.12" }, + "description": { "value": "EVPN to leaf2" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65001 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf2" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.13" }, + "description": { "value": "EVPN to leaf3" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65002 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf3" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.14" }, + "description": { "value": "EVPN to leaf4" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65002 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf4" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.15" }, + "description": { "value": "EVPN to leaf5" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65003 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf5" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.16" }, + "description": { "value": "EVPN to leaf6" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65003 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf6" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.17" }, + "description": { "value": "EVPN to leaf7" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65004 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf7" } } } + } + }, + { + "node": { + "peer_address": { "value": "10.0.250.18" }, + "description": { "value": "EVPN to leaf8" }, + "enabled": { "value": true }, + "peer_group": { "node": { "name": { "value": "evpn" }, "local_identifier": { "value": "spine1__evpn" } } }, + "remote_asn": { "node": { "asn": { "value": 65004 } } }, + "vrf": { "node": null }, + "peer_device": { "node": { "name": { "value": "leaf8" } } } + } + } + ] + } + } + } + ] + }, + "InfraBGPAddressFamily": { + "edges": [ + { + "node": { + "afi": { "value": "ipv4" }, + "safi": { "value": "unicast" }, + "vrf": { "node": null }, + "active_peer_groups": { "edges": [] }, + "active_sessions": { + "edges": [ + { "node": { "peer_address": { "value": "10.0.1.1" } } }, + { "node": { "peer_address": { "value": "10.0.1.3" } } }, + { "node": { "peer_address": { "value": "10.0.1.5" } } }, + { "node": { "peer_address": { "value": "10.0.1.7" } } }, + { "node": { "peer_address": { "value": "10.0.1.9" } } }, + { "node": { "peer_address": { "value": "10.0.1.11" } } }, + { "node": { "peer_address": { "value": "10.0.1.13" } } }, + { "node": { "peer_address": { "value": "10.0.1.15" } } } + ] + }, + "networks": { + "edges": [ + { "node": { "address": { "value": "10.0.250.1/32" } } } + ] + } + } + }, + { + "node": { + "afi": { "value": "evpn" }, + "safi": { "value": "unicast" }, + "vrf": { "node": null }, + "active_peer_groups": { + "edges": [ + { "node": { "name": { "value": "evpn" } } } + ] + }, + "active_sessions": { "edges": [] }, + "networks": { "edges": [] } + } + } + ] + } + } +} diff --git a/infrahub/transforms/tests/bgp_yang/spine1/output.json b/infrahub/transforms/tests/bgp_yang/spine1/output.json new file mode 100644 index 0000000..ebadf87 --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/spine1/output.json @@ -0,0 +1,178 @@ +{ + "bgp": { + "global": { + "asn": 65000, + "router_id": "10.0.250.1", + "default_ipv4_unicast": false, + "log_neighbor_changes": true, + "distance": { + "ebgp": 20, + "ibgp": 200, + "local": 200 + }, + "ecmp": { + "max_paths": 4, + "max_ecmp": 64 + } + }, + "peer_groups": [ + { + "name": "evpn", + "type": "evpn", + "remote_asn": null, + "update_source": "Loopback0", + "ebgp_multihop": 3, + "send_community": "extended", + "next_hop_self": false, + "next_hop_unchanged": true, + "maximum_routes": 12000, + "maximum_routes_warning_only": true + } + ], + "neighbors": [ + { + "peer_address": "10.0.1.1", + "description": "underlay to leaf1", + "enabled": true, + "peer_group": null, + "remote_asn": 65001 + }, + { + "peer_address": "10.0.1.3", + "description": "underlay to leaf2", + "enabled": true, + "peer_group": null, + "remote_asn": 65001 + }, + { + "peer_address": "10.0.1.5", + "description": "underlay to leaf3", + "enabled": true, + "peer_group": null, + "remote_asn": 65002 + }, + { + "peer_address": "10.0.1.7", + "description": "underlay to leaf4", + "enabled": true, + "peer_group": null, + "remote_asn": 65002 + }, + { + "peer_address": "10.0.1.9", + "description": "underlay to leaf5", + "enabled": true, + "peer_group": null, + "remote_asn": 65003 + }, + { + "peer_address": "10.0.1.11", + "description": "underlay to leaf6", + "enabled": true, + "peer_group": null, + "remote_asn": 65003 + }, + { + "peer_address": "10.0.1.13", + "description": "underlay to leaf7", + "enabled": true, + "peer_group": null, + "remote_asn": 65004 + }, + { + "peer_address": "10.0.1.15", + "description": "underlay to leaf8", + "enabled": true, + "peer_group": null, + "remote_asn": 65004 + }, + { + "peer_address": "10.0.250.11", + "description": "EVPN to leaf1", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65001 + }, + { + "peer_address": "10.0.250.12", + "description": "EVPN to leaf2", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65001 + }, + { + "peer_address": "10.0.250.13", + "description": "EVPN to leaf3", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65002 + }, + { + "peer_address": "10.0.250.14", + "description": "EVPN to leaf4", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65002 + }, + { + "peer_address": "10.0.250.15", + "description": "EVPN to leaf5", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65003 + }, + { + "peer_address": "10.0.250.16", + "description": "EVPN to leaf6", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65003 + }, + { + "peer_address": "10.0.250.17", + "description": "EVPN to leaf7", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65004 + }, + { + "peer_address": "10.0.250.18", + "description": "EVPN to leaf8", + "enabled": true, + "peer_group": "evpn", + "remote_asn": 65004 + } + ], + "address_families": [ + { + "afi": "ipv4", + "safi": "unicast", + "active_peer_groups": [], + "active_sessions": [ + "10.0.1.1", + "10.0.1.3", + "10.0.1.5", + "10.0.1.7", + "10.0.1.9", + "10.0.1.11", + "10.0.1.13", + "10.0.1.15" + ], + "networks": [ + "10.0.250.1/32" + ] + }, + { + "afi": "evpn", + "safi": "unicast", + "active_peer_groups": [ + "evpn" + ], + "active_sessions": [], + "networks": [] + } + ], + "vrf_neighbors": [], + "vrf_address_families": [] + } +} diff --git a/infrahub/transforms/tests/bgp_yang/test.yml b/infrahub/transforms/tests/bgp_yang/test.yml new file mode 100644 index 0000000..e1d463e --- /dev/null +++ b/infrahub/transforms/tests/bgp_yang/test.yml @@ -0,0 +1,27 @@ +--- +version: "1.0" +infrahub_tests: + - resource: Jinja2Transform + resource_name: bgp_yang_transform + tests: + - name: smoke_check + spec: + kind: jinja2-transform-smoke + - name: render_leaf1 + spec: + kind: jinja2-transform-unit-render + directory: infrahub/transforms/tests/bgp_yang/leaf1 + input: input.json + output: output.json + - name: render_spine1 + spec: + kind: jinja2-transform-unit-render + directory: infrahub/transforms/tests/bgp_yang/spine1 + input: input.json + output: output.json + - name: render_leaf7 + spec: + kind: jinja2-transform-unit-render + directory: infrahub/transforms/tests/bgp_yang/leaf7 + input: input.json + output: output.json