diff --git a/.infrahub.yml b/.infrahub.yml index a2e5752..f1dce06 100644 --- a/.infrahub.yml +++ b/.infrahub.yml @@ -16,3 +16,25 @@ objects: - infrahub/objects/10-bgp-sessions.yml - infrahub/objects/11-vrfs.yml - infrahub/objects/12-mlag.yml + +queries: + - name: vlan_intent + file_path: infrahub/transforms/queries/vlan_intent.gql + - name: interface_intent + file_path: infrahub/transforms/queries/interface_intent.gql + - name: vxlan_intent + file_path: infrahub/transforms/queries/vxlan_intent.gql + +jinja2_transforms: + - name: vlan_yang_transform + description: "Generate VLAN configuration payload from Infrahub intent" + query: vlan_intent + template_path: infrahub/transforms/templates/vlan_yang.j2 + - name: interface_yang_transform + description: "Generate interface configuration payload from Infrahub intent" + query: interface_intent + template_path: infrahub/transforms/templates/interface_yang.j2 + - name: vxlan_yang_transform + description: "Generate VXLAN/VTEP configuration payload from Infrahub intent" + query: vxlan_intent + template_path: infrahub/transforms/templates/vxlan_yang.j2 diff --git a/infrahub/transforms/queries/interface_intent.gql b/infrahub/transforms/queries/interface_intent.gql new file mode 100644 index 0000000..1cb1106 --- /dev/null +++ b/infrahub/transforms/queries/interface_intent.gql @@ -0,0 +1,155 @@ +query InterfaceIntent($device_name: String!) { + # Loopback interfaces + InfraInterfaceLoopback(device__name__value: $device_name) { + edges { + node { + name { + value + } + description { + value + } + enabled { + value + } + mtu { + value + } + ip_addresses { + edges { + node { + address { + value + } + } + } + } + } + } + } + # Ethernet interfaces + InfraInterfaceEthernet(device__name__value: $device_name) { + edges { + node { + name { + value + } + description { + value + } + enabled { + value + } + mtu { + value + } + speed { + value + } + mode { + value + } + lag { + node { + name { + value + } + } + } + ip_addresses { + edges { + node { + address { + value + } + } + } + } + } + } + } + # VLAN SVI interfaces + InfraInterfaceVlan(device__name__value: $device_name) { + edges { + node { + name { + value + } + description { + value + } + enabled { + value + } + mtu { + value + } + virtual_router_address { + value + } + autostate { + value + } + vlan { + node { + vlan_id { + value + } + } + } + ip_addresses { + edges { + node { + address { + value + } + } + } + } + } + } + } + # LAG / Port-Channel interfaces + InfraInterfaceLag(device__name__value: $device_name) { + edges { + node { + name { + value + } + description { + value + } + enabled { + value + } + mtu { + value + } + lacp_mode { + value + } + mlag_id { + value + } + members { + edges { + node { + name { + value + } + } + } + } + ip_addresses { + edges { + node { + address { + value + } + } + } + } + } + } + } +} diff --git a/infrahub/transforms/queries/vlan_intent.gql b/infrahub/transforms/queries/vlan_intent.gql new file mode 100644 index 0000000..bcd0f7b --- /dev/null +++ b/infrahub/transforms/queries/vlan_intent.gql @@ -0,0 +1,92 @@ +query VlanIntent($device_name: String!) { + # VLANs reachable via VTEP VLAN-VNI mappings (L2/VXLAN VLANs) + InfraVTEP(device__name__value: $device_name) { + edges { + node { + source_address { + value + } + udp_port { + value + } + vlan_vni_mappings { + edges { + node { + vlan { + node { + vlan_id { + value + } + name { + value + } + status { + value + } + vlan_type { + value + } + trunk_groups { + value + } + stp_enabled { + value + } + vni { + node { + vni { + value + } + vni_type { + value + } + } + } + } + } + } + } + } + } + } + } + # VLANs reachable via SVI interfaces (MLAG, routing, and other local VLANs) + InfraInterfaceVlan(device__name__value: $device_name) { + edges { + node { + vlan { + node { + vlan_id { + value + } + name { + value + } + status { + value + } + vlan_type { + value + } + trunk_groups { + value + } + stp_enabled { + value + } + vni { + node { + vni { + value + } + vni_type { + value + } + } + } + } + } + } + } + } +} diff --git a/infrahub/transforms/queries/vxlan_intent.gql b/infrahub/transforms/queries/vxlan_intent.gql new file mode 100644 index 0000000..ed182c6 --- /dev/null +++ b/infrahub/transforms/queries/vxlan_intent.gql @@ -0,0 +1,100 @@ +query VxlanIntent($device_name: String!) { + # VTEP configuration for the device + InfraVTEP(device__name__value: $device_name) { + edges { + node { + source_address { + value + } + udp_port { + value + } + learn_restrict { + value + } + source_interface { + node { + name { + value + } + } + } + # VLAN-to-VNI mappings (L2 VXLAN) + vlan_vni_mappings { + edges { + node { + description { + value + } + vlan { + node { + vlan_id { + value + } + name { + value + } + } + } + vni { + node { + vni { + value + } + vni_type { + value + } + } + } + } + } + } + } + } + } + # VRF-to-VNI mappings (L3 VXLAN) via VRF device assignments + InfraVRFDeviceAssignment(device__name__value: $device_name) { + edges { + node { + route_distinguisher { + value + } + vrf { + node { + name { + value + } + l3vni { + node { + vni { + value + } + vni_type { + value + } + } + } + import_targets { + edges { + node { + target { + value + } + } + } + } + export_targets { + edges { + node { + target { + value + } + } + } + } + } + } + } + } + } +} diff --git a/infrahub/transforms/templates/interface_yang.j2 b/infrahub/transforms/templates/interface_yang.j2 new file mode 100644 index 0000000..2739c2b --- /dev/null +++ b/infrahub/transforms/templates/interface_yang.j2 @@ -0,0 +1,101 @@ +{# + interface_yang.j2 — Produce a JSON array of interface configuration objects. + + Input: GraphQL response from interface_intent query. + Returns all interface types (loopback, ethernet, vlan, lag) for the device, + each with a "type" discriminator and type-specific attributes. +#} +{%- set interfaces = [] -%} + +{#— Loopback interfaces —#} +{%- for edge in data.InfraInterfaceLoopback.edges -%} + {%- set iface = edge.node -%} + {%- set ip_list = [] -%} + {%- for ip_edge in iface.ip_addresses.edges -%} + {%- set _ = ip_list.append(ip_edge.node.address.value) -%} + {%- endfor -%} + {%- set _ = interfaces.append({ + "type": "loopback", + "name": iface.name.value, + "description": iface.description.value | default(none), + "enabled": iface.enabled.value, + "mtu": iface.mtu.value | default(none), + "ip_addresses": ip_list + }) -%} +{%- endfor -%} + +{#— Ethernet interfaces —#} +{%- for edge in data.InfraInterfaceEthernet.edges -%} + {%- set iface = edge.node -%} + {%- set ip_list = [] -%} + {%- for ip_edge in iface.ip_addresses.edges -%} + {%- set _ = ip_list.append(ip_edge.node.address.value) -%} + {%- endfor -%} + {%- set lag_name = none -%} + {%- if iface.lag is defined and iface.lag is not none and iface.lag.node is not none -%} + {%- set lag_name = iface.lag.node.name.value -%} + {%- endif -%} + {%- set _ = interfaces.append({ + "type": "ethernet", + "name": iface.name.value, + "description": iface.description.value | default(none), + "enabled": iface.enabled.value, + "mtu": iface.mtu.value | default(none), + "speed": iface.speed.value | default(none), + "mode": iface.mode.value | default(none), + "lag": lag_name, + "ip_addresses": ip_list + }) -%} +{%- endfor -%} + +{#— VLAN SVI interfaces —#} +{%- for edge in data.InfraInterfaceVlan.edges -%} + {%- set iface = edge.node -%} + {%- set ip_list = [] -%} + {%- for ip_edge in iface.ip_addresses.edges -%} + {%- set _ = ip_list.append(ip_edge.node.address.value) -%} + {%- endfor -%} + {%- set vlan_id = none -%} + {%- if iface.vlan is defined and iface.vlan is not none and iface.vlan.node is not none -%} + {%- set vlan_id = iface.vlan.node.vlan_id.value -%} + {%- endif -%} + {%- set _ = interfaces.append({ + "type": "vlan", + "name": iface.name.value, + "description": iface.description.value | default(none), + "enabled": iface.enabled.value, + "mtu": iface.mtu.value | default(none), + "vlan_id": vlan_id, + "virtual_router_address": iface.virtual_router_address.value | default(none), + "autostate": iface.autostate.value, + "ip_addresses": ip_list + }) -%} +{%- endfor -%} + +{#— LAG / Port-Channel interfaces —#} +{%- for edge in data.InfraInterfaceLag.edges -%} + {%- set iface = edge.node -%} + {%- set ip_list = [] -%} + {%- for ip_edge in iface.ip_addresses.edges -%} + {%- set _ = ip_list.append(ip_edge.node.address.value) -%} + {%- endfor -%} + {%- set member_list = [] -%} + {%- for member_edge in iface.members.edges -%} + {%- set _ = member_list.append(member_edge.node.name.value) -%} + {%- endfor -%} + {%- set _ = interfaces.append({ + "type": "lag", + "name": iface.name.value, + "description": iface.description.value | default(none), + "enabled": iface.enabled.value, + "mtu": iface.mtu.value | default(none), + "lacp_mode": iface.lacp_mode.value | default(none), + "mlag_id": iface.mlag_id.value | default(none), + "members": member_list, + "ip_addresses": ip_list + }) -%} +{%- endfor -%} + +{#— Sort by name and emit JSON array —#} +{%- set sorted_ifaces = interfaces | sort(attribute='name') -%} +{{ sorted_ifaces | tojson(indent=2) }} diff --git a/infrahub/transforms/templates/vlan_yang.j2 b/infrahub/transforms/templates/vlan_yang.j2 new file mode 100644 index 0000000..423fc02 --- /dev/null +++ b/infrahub/transforms/templates/vlan_yang.j2 @@ -0,0 +1,67 @@ +{# + vlan_yang.j2 — Produce a JSON array of VLAN configuration objects. + + Input: GraphQL response from vlan_intent query. + The query returns VLANs from two sources: + 1. data.InfraVTEP[].vlan_vni_mappings[].vlan (L2/VXLAN VLANs) + 2. data.InfraInterfaceVlan[].vlan (SVI/routing/MLAG VLANs) + + We merge both sources, deduplicate by vlan_id, and emit one object per VLAN. +#} +{%- set vlans = {} -%} + +{#— Collect VLANs from VTEP VLAN-VNI mappings —#} +{%- for vtep_edge in data.InfraVTEP.edges -%} + {%- for mapping_edge in vtep_edge.node.vlan_vni_mappings.edges -%} + {%- set vlan_node = mapping_edge.node.vlan.node -%} + {%- set vid = vlan_node.vlan_id.value | string -%} + {%- if vid not in vlans -%} + {%- set vni_val = none -%} + {%- set vni_type_val = none -%} + {%- if vlan_node.vni is defined and vlan_node.vni is not none and vlan_node.vni.node is not none -%} + {%- set vni_val = vlan_node.vni.node.vni.value -%} + {%- set vni_type_val = vlan_node.vni.node.vni_type.value -%} + {%- endif -%} + {%- set _ = vlans.update({vid: { + "vlan_id": vlan_node.vlan_id.value, + "name": vlan_node.name.value, + "status": vlan_node.status.value | default('') | upper, + "vlan_type": vlan_node.vlan_type.value | default(none), + "trunk_groups": vlan_node.trunk_groups.value | default([]), + "stp_enabled": vlan_node.stp_enabled.value, + "vni": vni_val, + "vni_type": vni_type_val + }}) -%} + {%- endif -%} + {%- endfor -%} +{%- endfor -%} + +{#— Collect VLANs from SVI interfaces —#} +{%- for svi_edge in data.InfraInterfaceVlan.edges -%} + {%- if svi_edge.node.vlan is defined and svi_edge.node.vlan is not none and svi_edge.node.vlan.node is not none -%} + {%- set vlan_node = svi_edge.node.vlan.node -%} + {%- set vid = vlan_node.vlan_id.value | string -%} + {%- if vid not in vlans -%} + {%- set vni_val = none -%} + {%- set vni_type_val = none -%} + {%- if vlan_node.vni is defined and vlan_node.vni is not none and vlan_node.vni.node is not none -%} + {%- set vni_val = vlan_node.vni.node.vni.value -%} + {%- set vni_type_val = vlan_node.vni.node.vni_type.value -%} + {%- endif -%} + {%- set _ = vlans.update({vid: { + "vlan_id": vlan_node.vlan_id.value, + "name": vlan_node.name.value, + "status": vlan_node.status.value | default('') | upper, + "vlan_type": vlan_node.vlan_type.value | default(none), + "trunk_groups": vlan_node.trunk_groups.value | default([]), + "stp_enabled": vlan_node.stp_enabled.value, + "vni": vni_val, + "vni_type": vni_type_val + }}) -%} + {%- endif -%} + {%- endif -%} +{%- endfor -%} + +{#— Sort by vlan_id and emit JSON array —#} +{%- set sorted_vlans = vlans.values() | sort(attribute='vlan_id') -%} +{{ sorted_vlans | tojson(indent=2) }} diff --git a/infrahub/transforms/templates/vxlan_yang.j2 b/infrahub/transforms/templates/vxlan_yang.j2 new file mode 100644 index 0000000..c57d036 --- /dev/null +++ b/infrahub/transforms/templates/vxlan_yang.j2 @@ -0,0 +1,88 @@ +{# + vxlan_yang.j2 — Produce a JSON object representing the VXLAN/VTEP configuration + for the device, including VLAN-to-VNI mappings and VRF-to-VNI mappings. + + Input: GraphQL response from vxlan_intent query. +#} +{%- set vtep_edges = data.InfraVTEP.edges -%} +{%- set vrf_edges = data.InfraVRFDeviceAssignment.edges -%} + +{#— Build VTEP section (there is one VTEP per device) —#} +{%- if vtep_edges | length > 0 -%} + {%- set vtep = vtep_edges[0].node -%} + {%- set source_iface = none -%} + {%- if vtep.source_interface is defined and vtep.source_interface is not none and vtep.source_interface.node is not none -%} + {%- set source_iface = vtep.source_interface.node.name.value -%} + {%- endif -%} + + {#— Build VLAN-to-VNI mapping list —#} + {%- set vlan_vni_list = [] -%} + {%- for mapping_edge in vtep.vlan_vni_mappings.edges -%} + {%- set m = mapping_edge.node -%} + {%- set vlan_id = none -%} + {%- set vlan_name = none -%} + {%- if m.vlan is defined and m.vlan is not none and m.vlan.node is not none -%} + {%- set vlan_id = m.vlan.node.vlan_id.value -%} + {%- set vlan_name = m.vlan.node.name.value -%} + {%- endif -%} + {%- set vni_val = none -%} + {%- set vni_type_val = none -%} + {%- if m.vni is defined and m.vni is not none and m.vni.node is not none -%} + {%- set vni_val = m.vni.node.vni.value -%} + {%- set vni_type_val = m.vni.node.vni_type.value -%} + {%- endif -%} + {%- set _ = vlan_vni_list.append({ + "vlan_id": vlan_id, + "vlan_name": vlan_name, + "vni": vni_val, + "vni_type": vni_type_val + }) -%} + {%- endfor -%} + + {#— Build VRF-to-VNI mapping list —#} + {%- set vrf_vni_list = [] -%} + {%- for vrf_edge in vrf_edges -%} + {%- set assignment = vrf_edge.node -%} + {%- set vrf_name = none -%} + {%- set l3vni = none -%} + {%- set import_rts = [] -%} + {%- set export_rts = [] -%} + {%- if assignment.vrf is defined and assignment.vrf is not none and assignment.vrf.node is not none -%} + {%- set vrf_node = assignment.vrf.node -%} + {%- set vrf_name = vrf_node.name.value -%} + {%- if vrf_node.l3vni is defined and vrf_node.l3vni is not none and vrf_node.l3vni.node is not none -%} + {%- set l3vni = vrf_node.l3vni.node.vni.value -%} + {%- endif -%} + {%- for rt_edge in vrf_node.import_targets.edges -%} + {%- set _ = import_rts.append(rt_edge.node.target.value) -%} + {%- endfor -%} + {%- for rt_edge in vrf_node.export_targets.edges -%} + {%- set _ = export_rts.append(rt_edge.node.target.value) -%} + {%- endfor -%} + {%- endif -%} + {%- set _ = vrf_vni_list.append({ + "vrf": vrf_name, + "l3vni": l3vni, + "route_distinguisher": assignment.route_distinguisher.value | default(none), + "import_targets": import_rts, + "export_targets": export_rts + }) -%} + {%- endfor -%} + + {%- set result = { + "vtep": { + "source_address": vtep.source_address.value, + "source_interface": source_iface, + "udp_port": vtep.udp_port.value, + "learn_restrict": vtep.learn_restrict.value | default(none), + "vlan_vni_mappings": vlan_vni_list | sort(attribute='vlan_id'), + "vrf_vni_mappings": vrf_vni_list + } + } -%} +{%- else -%} + {%- set result = { + "vtep": none, + "vrf_vni_mappings": [] + } -%} +{%- endif -%} +{{ result | tojson(indent=2) }} diff --git a/infrahub/transforms/tests/interface_yang/input.json b/infrahub/transforms/tests/interface_yang/input.json new file mode 100644 index 0000000..8a94fe7 --- /dev/null +++ b/infrahub/transforms/tests/interface_yang/input.json @@ -0,0 +1,350 @@ +{ + "data": { + "InfraInterfaceLoopback": { + "edges": [ + { + "node": { + "name": { + "value": "Loopback0" + }, + "description": { + "value": "Router-ID" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "ip_addresses": { + "edges": [ + { + "node": { + "address": { + "value": "10.0.250.11/32" + } + } + } + ] + } + } + }, + { + "node": { + "name": { + "value": "Loopback1" + }, + "description": { + "value": "VTEP" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "ip_addresses": { + "edges": [] + } + } + } + ] + }, + "InfraInterfaceEthernet": { + "edges": [ + { + "node": { + "name": { + "value": "Ethernet1" + }, + "description": { + "value": "host1" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "speed": { + "value": null + }, + "mode": { + "value": "trunk" + }, + "lag": { + "node": { + "name": { + "value": "Port-Channel1" + } + } + }, + "ip_addresses": { + "edges": [] + } + } + }, + { + "node": { + "name": { + "value": "Ethernet10" + }, + "description": { + "value": "mlag peer link" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "speed": { + "value": null + }, + "mode": { + "value": "trunk" + }, + "lag": { + "node": { + "name": { + "value": "Port-Channel999" + } + } + }, + "ip_addresses": { + "edges": [] + } + } + }, + { + "node": { + "name": { + "value": "Ethernet11" + }, + "description": { + "value": "spine1" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": 9214 + }, + "speed": { + "value": null + }, + "mode": { + "value": "routed" + }, + "lag": null, + "ip_addresses": { + "edges": [ + { + "node": { + "address": { + "value": "10.0.1.1/31" + } + } + } + ] + } + } + }, + { + "node": { + "name": { + "value": "Ethernet12" + }, + "description": { + "value": "spine2" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": 9214 + }, + "speed": { + "value": null + }, + "mode": { + "value": "routed" + }, + "lag": null, + "ip_addresses": { + "edges": [ + { + "node": { + "address": { + "value": "10.0.2.1/31" + } + } + } + ] + } + } + } + ] + }, + "InfraInterfaceVlan": { + "edges": [ + { + "node": { + "name": { + "value": "Vlan4090" + }, + "description": { + "value": "MLAG Peer-Link" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "virtual_router_address": { + "value": null + }, + "autostate": { + "value": false + }, + "vlan": { + "node": { + "vlan_id": { + "value": 4090 + } + } + }, + "ip_addresses": { + "edges": [ + { + "node": { + "address": { + "value": "10.0.199.254/31" + } + } + } + ] + } + } + }, + { + "node": { + "name": { + "value": "Vlan4091" + }, + "description": { + "value": "MLAG iBGP Peering" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": 9214 + }, + "virtual_router_address": { + "value": null + }, + "autostate": { + "value": true + }, + "vlan": { + "node": { + "vlan_id": { + "value": 4091 + } + } + }, + "ip_addresses": { + "edges": [ + { + "node": { + "address": { + "value": "10.0.3.0/31" + } + } + } + ] + } + } + } + ] + }, + "InfraInterfaceLag": { + "edges": [ + { + "node": { + "name": { + "value": "Port-Channel1" + }, + "description": { + "value": "host1" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "lacp_mode": { + "value": "active" + }, + "mlag_id": { + "value": 1 + }, + "members": { + "edges": [ + { + "node": { + "name": { + "value": "Ethernet1" + } + } + } + ] + }, + "ip_addresses": { + "edges": [] + } + } + }, + { + "node": { + "name": { + "value": "Port-Channel999" + }, + "description": { + "value": "MLAG Peer" + }, + "enabled": { + "value": true + }, + "mtu": { + "value": null + }, + "lacp_mode": { + "value": "active" + }, + "mlag_id": { + "value": null + }, + "members": { + "edges": [ + { + "node": { + "name": { + "value": "Ethernet10" + } + } + } + ] + }, + "ip_addresses": { + "edges": [] + } + } + } + ] + } + } +} diff --git a/infrahub/transforms/tests/interface_yang/output.json b/infrahub/transforms/tests/interface_yang/output.json new file mode 100644 index 0000000..c19e90d --- /dev/null +++ b/infrahub/transforms/tests/interface_yang/output.json @@ -0,0 +1,12 @@ +[ + {"description":"host1","enabled":true,"ip_addresses":[],"lag":"Port-Channel1","mode":"trunk","mtu":null,"name":"Ethernet1","speed":null,"type":"ethernet"}, + {"description":"mlag peer link","enabled":true,"ip_addresses":[],"lag":"Port-Channel999","mode":"trunk","mtu":null,"name":"Ethernet10","speed":null,"type":"ethernet"}, + {"description":"spine1","enabled":true,"ip_addresses":["10.0.1.1/31"],"lag":null,"mode":"routed","mtu":9214,"name":"Ethernet11","speed":null,"type":"ethernet"}, + {"description":"spine2","enabled":true,"ip_addresses":["10.0.2.1/31"],"lag":null,"mode":"routed","mtu":9214,"name":"Ethernet12","speed":null,"type":"ethernet"}, + {"description":"Router-ID","enabled":true,"ip_addresses":["10.0.250.11/32"],"mtu":null,"name":"Loopback0","type":"loopback"}, + {"description":"VTEP","enabled":true,"ip_addresses":[],"mtu":null,"name":"Loopback1","type":"loopback"}, + {"description":"host1","enabled":true,"ip_addresses":[],"lacp_mode":"active","members":["Ethernet1"],"mlag_id":1,"mtu":null,"name":"Port-Channel1","type":"lag"}, + {"description":"MLAG Peer","enabled":true,"ip_addresses":[],"lacp_mode":"active","members":["Ethernet10"],"mlag_id":null,"mtu":null,"name":"Port-Channel999","type":"lag"}, + {"autostate":false,"description":"MLAG Peer-Link","enabled":true,"ip_addresses":["10.0.199.254/31"],"mtu":null,"name":"Vlan4090","type":"vlan","virtual_router_address":null,"vlan_id":4090}, + {"autostate":true,"description":"MLAG iBGP Peering","enabled":true,"ip_addresses":["10.0.3.0/31"],"mtu":9214,"name":"Vlan4091","type":"vlan","virtual_router_address":null,"vlan_id":4091} +] diff --git a/infrahub/transforms/tests/interface_yang/test.yml b/infrahub/transforms/tests/interface_yang/test.yml new file mode 100644 index 0000000..82727c4 --- /dev/null +++ b/infrahub/transforms/tests/interface_yang/test.yml @@ -0,0 +1,15 @@ +--- +version: "1.0" +infrahub_tests: + - resource: Jinja2Transform + resource_name: interface_yang_transform + tests: + - name: smoke_check + spec: + kind: jinja2-transform-smoke + - name: render_leaf1 + spec: + kind: jinja2-transform-unit-render + directory: infrahub/transforms/tests/interface_yang + input: input.json + output: output.json diff --git a/infrahub/transforms/tests/vlan_yang/input.json b/infrahub/transforms/tests/vlan_yang/input.json new file mode 100644 index 0000000..ed75a16 --- /dev/null +++ b/infrahub/transforms/tests/vlan_yang/input.json @@ -0,0 +1,116 @@ +{ + "data": { + "InfraVTEP": { + "edges": [ + { + "node": { + "source_address": { + "value": "10.0.255.11" + }, + "udp_port": { + "value": 4789 + }, + "vlan_vni_mappings": { + "edges": [ + { + "node": { + "vlan": { + "node": { + "vlan_id": { + "value": 40 + }, + "name": { + "value": "test-l2-vxlan" + }, + "status": { + "value": "active" + }, + "vlan_type": { + "value": "standard" + }, + "trunk_groups": { + "value": null + }, + "stp_enabled": { + "value": true + }, + "vni": { + "node": { + "vni": { + "value": 110040 + }, + "vni_type": { + "value": "l2vni" + } + } + } + } + } + } + } + ] + } + } + } + ] + }, + "InfraInterfaceVlan": { + "edges": [ + { + "node": { + "vlan": { + "node": { + "vlan_id": { + "value": 4090 + }, + "name": { + "value": "mlag-peer" + }, + "status": { + "value": "active" + }, + "vlan_type": { + "value": "mlag_peer" + }, + "trunk_groups": { + "value": ["mlag-peer"] + }, + "stp_enabled": { + "value": false + }, + "vni": null + } + } + } + }, + { + "node": { + "vlan": { + "node": { + "vlan_id": { + "value": 4091 + }, + "name": { + "value": "mlag-ibgp" + }, + "status": { + "value": "active" + }, + "vlan_type": { + "value": "mlag_ibgp" + }, + "trunk_groups": { + "value": ["mlag-peer"] + }, + "stp_enabled": { + "value": false + }, + "vni": null + } + } + } + } + ] + } + } +} diff --git a/infrahub/transforms/tests/vlan_yang/output.json b/infrahub/transforms/tests/vlan_yang/output.json new file mode 100644 index 0000000..d97bbbb --- /dev/null +++ b/infrahub/transforms/tests/vlan_yang/output.json @@ -0,0 +1,32 @@ +[ + { + "name": "test-l2-vxlan", + "status": "ACTIVE", + "stp_enabled": true, + "trunk_groups": null, + "vlan_id": 40, + "vlan_type": "standard", + "vni": 110040, + "vni_type": "l2vni" + }, + { + "name": "mlag-peer", + "status": "ACTIVE", + "stp_enabled": false, + "trunk_groups": ["mlag-peer"], + "vlan_id": 4090, + "vlan_type": "mlag_peer", + "vni": null, + "vni_type": null + }, + { + "name": "mlag-ibgp", + "status": "ACTIVE", + "stp_enabled": false, + "trunk_groups": ["mlag-peer"], + "vlan_id": 4091, + "vlan_type": "mlag_ibgp", + "vni": null, + "vni_type": null + } +] diff --git a/infrahub/transforms/tests/vlan_yang/test.yml b/infrahub/transforms/tests/vlan_yang/test.yml new file mode 100644 index 0000000..f6ea77b --- /dev/null +++ b/infrahub/transforms/tests/vlan_yang/test.yml @@ -0,0 +1,15 @@ +--- +version: "1.0" +infrahub_tests: + - resource: Jinja2Transform + resource_name: vlan_yang_transform + tests: + - name: smoke_check + spec: + kind: jinja2-transform-smoke + - name: render_leaf1 + spec: + kind: jinja2-transform-unit-render + directory: infrahub/transforms/tests/vlan_yang + input: input.json + output: output.json diff --git a/infrahub/transforms/tests/vxlan_yang/input.json b/infrahub/transforms/tests/vxlan_yang/input.json new file mode 100644 index 0000000..40a35b2 --- /dev/null +++ b/infrahub/transforms/tests/vxlan_yang/input.json @@ -0,0 +1,62 @@ +{ + "data": { + "InfraVTEP": { + "edges": [ + { + "node": { + "source_address": { + "value": "10.0.255.11/32" + }, + "udp_port": { + "value": 4789 + }, + "learn_restrict": { + "value": "any" + }, + "source_interface": { + "node": { + "name": { + "value": "Loopback1" + } + } + }, + "vlan_vni_mappings": { + "edges": [ + { + "node": { + "description": { + "value": "VLAN 40 <-> VNI 110040" + }, + "vlan": { + "node": { + "vlan_id": { + "value": 40 + }, + "name": { + "value": "test-l2-vxlan" + } + } + }, + "vni": { + "node": { + "vni": { + "value": 110040 + }, + "vni_type": { + "value": "l2vni" + } + } + } + } + } + ] + } + } + } + ] + }, + "InfraVRFDeviceAssignment": { + "edges": [] + } + } +} diff --git a/infrahub/transforms/tests/vxlan_yang/output.json b/infrahub/transforms/tests/vxlan_yang/output.json new file mode 100644 index 0000000..906e00e --- /dev/null +++ b/infrahub/transforms/tests/vxlan_yang/output.json @@ -0,0 +1,12 @@ +{ + "vtep": { + "learn_restrict": "any", + "source_address": "10.0.255.11/32", + "source_interface": "Loopback1", + "udp_port": 4789, + "vlan_vni_mappings": [ + {"vlan_id": 40, "vlan_name": "test-l2-vxlan", "vni": 110040, "vni_type": "l2vni"} + ], + "vrf_vni_mappings": [] + } +} diff --git a/infrahub/transforms/tests/vxlan_yang/test.yml b/infrahub/transforms/tests/vxlan_yang/test.yml new file mode 100644 index 0000000..519f926 --- /dev/null +++ b/infrahub/transforms/tests/vxlan_yang/test.yml @@ -0,0 +1,15 @@ +--- +version: "1.0" +infrahub_tests: + - resource: Jinja2Transform + resource_name: vxlan_yang_transform + tests: + - name: smoke_check + spec: + kind: jinja2-transform-smoke + - name: render_leaf1 + spec: + kind: jinja2-transform-unit-render + directory: infrahub/transforms/tests/vxlan_yang + input: input.json + output: output.json