From 327fd9e7fb2c4de626e8e4d4a5b1b260b72415b5 Mon Sep 17 00:00:00 2001 From: gmuloc Date: Thu, 22 Feb 2024 11:50:47 +0100 Subject: [PATCH] Refactor: Address PR comments --- ...v-pathfinder-edge-no-common-path-group.cfg | 22 +++ .../intended/configs/cv-pathfinder-edge.cfg | 22 +++ .../configs/cv-pathfinder-transit.cfg | 3 + .../configs/site-ha-disabled-leaf.cfg | 105 +++++++++++ .../autovpn-edge-no-default-policy.yml | 28 +-- .../structured_configs/autovpn-edge.yml | 28 +-- ...v-pathfinder-edge-no-common-path-group.yml | 108 ++++++++---- .../cv-pathfinder-edge-no-default-policy.yml | 28 +-- .../structured_configs/cv-pathfinder-edge.yml | 108 ++++++++---- .../cv-pathfinder-transit.yml | 3 + .../site-ha-disabled-leaf.yml | 164 ++++++++++++++++++ .../group_vars/CV_PATHFINDER_TESTS.yml | 19 +- .../eos_designs_facts/eos_designs_facts.py | 3 +- .../plugin_utils/eos_designs_facts/vrfs.py | 27 +++ .../filtered_tenants.py | 28 ++- .../python_modules/network_services/utils.py | 3 +- .../network_services/vxlan_interface.py | 16 +- 17 files changed, 568 insertions(+), 147 deletions(-) create mode 100644 ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/vrfs.py diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge-no-common-path-group.cfg b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge-no-common-path-group.cfg index f63bbc25083..3414d07b74e 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge-no-common-path-group.cfg +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge-no-common-path-group.cfg @@ -175,6 +175,22 @@ interface Ethernet52 flow tracker hardware WAN-FLOW-TRACKER ip address 172.17.0.3/31 ! +interface Ethernet52.142 + description P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet2.142_vrf_PROD + no shutdown + mtu 9214 + encapsulation dot1q vlan 142 + vrf PROD + ip address 172.17.0.3/31 +! +interface Ethernet52.1000 + description P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet2.1000_vrf_IT + no shutdown + mtu 9214 + encapsulation dot1q vlan 1000 + vrf IT + ip address 172.17.0.3/31 +! interface Loopback0 description Router_ID no shutdown @@ -339,6 +355,9 @@ router bgp 65000 route-target import evpn 1000:1000 route-target export evpn 1000:1000 router-id 192.168.42.2 + neighbor 172.17.0.2 remote-as 65000 + neighbor 172.17.0.2 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.2 description site-ha-disabled-leaf_Ethernet2.1000_vrf_IT redistribute connected redistribute static ! @@ -347,6 +366,9 @@ router bgp 65000 route-target import evpn 142:142 route-target export evpn 142:142 router-id 192.168.42.2 + neighbor 172.17.0.2 remote-as 65000 + neighbor 172.17.0.2 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.2 description site-ha-disabled-leaf_Ethernet2.142_vrf_PROD redistribute connected ! router traffic-engineering diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge.cfg b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge.cfg index 30ab419cb74..2f64dd0734b 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge.cfg +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-edge.cfg @@ -223,6 +223,22 @@ interface Ethernet52 flow tracker hardware WAN-FLOW-TRACKER ip address 172.17.0.1/31 ! +interface Ethernet52.142 + description P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet1.142_vrf_PROD + no shutdown + mtu 9214 + encapsulation dot1q vlan 142 + vrf PROD + ip address 172.17.0.1/31 +! +interface Ethernet52.1000 + description P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet1.1000_vrf_IT + no shutdown + mtu 9214 + encapsulation dot1q vlan 1000 + vrf IT + ip address 172.17.0.1/31 +! interface Loopback0 description Router_ID no shutdown @@ -395,6 +411,9 @@ router bgp 65000 route-target import evpn 1000:1000 route-target export evpn 1000:1000 router-id 192.168.42.1 + neighbor 172.17.0.0 remote-as 65000 + neighbor 172.17.0.0 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.0 description site-ha-disabled-leaf_Ethernet1.1000_vrf_IT redistribute connected redistribute static ! @@ -403,6 +422,9 @@ router bgp 65000 route-target import evpn 142:142 route-target export evpn 142:142 router-id 192.168.42.1 + neighbor 172.17.0.0 remote-as 65000 + neighbor 172.17.0.0 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.0 description site-ha-disabled-leaf_Ethernet1.142_vrf_PROD redistribute connected ! router traffic-engineering diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-transit.cfg b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-transit.cfg index ea7b0860b93..05738268a82 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-transit.cfg +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/cv-pathfinder-transit.cfg @@ -176,6 +176,8 @@ vrf instance IT ! vrf instance MGMT ! +vrf instance NOT-WAN-VRF +! vrf instance PROD ! vrf instance TRANSIT @@ -298,6 +300,7 @@ application traffic recognition ip routing ip routing vrf IT no ip routing vrf MGMT +ip routing vrf NOT-WAN-VRF ip routing vrf PROD ip routing vrf TRANSIT ! diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/site-ha-disabled-leaf.cfg b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/site-ha-disabled-leaf.cfg index 082235910b1..6a26ae6898f 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/site-ha-disabled-leaf.cfg +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/site-ha-disabled-leaf.cfg @@ -11,11 +11,18 @@ hostname site-ha-disabled-leaf no enable password no aaa root ! +vlan 100 + name VLAN100 +! vlan 101 name VLAN101 ! +vrf instance IT +! vrf instance MGMT ! +vrf instance PROD +! interface Ethernet1 description P2P_LINK_TO_CV-PATHFINDER-EDGE_Ethernet52 no shutdown @@ -23,6 +30,22 @@ interface Ethernet1 no switchport ip address 172.17.0.0/31 ! +interface Ethernet1.142 + description P2P_LINK_TO_CV-PATHFINDER-EDGE_Ethernet52.142_vrf_PROD + no shutdown + mtu 9214 + encapsulation dot1q vlan 142 + vrf PROD + ip address 172.17.0.0/31 +! +interface Ethernet1.1000 + description P2P_LINK_TO_CV-PATHFINDER-EDGE_Ethernet52.1000_vrf_IT + no shutdown + mtu 9214 + encapsulation dot1q vlan 1000 + vrf IT + ip address 172.17.0.0/31 +! interface Ethernet2 description P2P_LINK_TO_CV-PATHFINDER-EDGE-NO-COMMON-PATH-GROUP_Ethernet52 no shutdown @@ -30,6 +53,22 @@ interface Ethernet2 no switchport ip address 172.17.0.2/31 ! +interface Ethernet2.142 + description P2P_LINK_TO_CV-PATHFINDER-EDGE-NO-COMMON-PATH-GROUP_Ethernet52.142_vrf_PROD + no shutdown + mtu 9214 + encapsulation dot1q vlan 142 + vrf PROD + ip address 172.17.0.2/31 +! +interface Ethernet2.1000 + description P2P_LINK_TO_CV-PATHFINDER-EDGE-NO-COMMON-PATH-GROUP_Ethernet52.1000_vrf_IT + no shutdown + mtu 9214 + encapsulation dot1q vlan 1000 + vrf IT + ip address 172.17.0.2/31 +! interface Loopback0 description EVPN_Overlay_Peering no shutdown @@ -40,24 +79,50 @@ interface Loopback1 no shutdown ip address 192.168.255.3/32 ! +interface Vlan100 + description VLAN100 + shutdown + vrf PROD + ip address virtual 10.0.100.1/24 +! interface Vxlan1 description site-ha-disabled-leaf_VTEP vxlan source-interface Loopback1 vxlan udp-port 4789 + vxlan vlan 100 vni 1100 vxlan vlan 101 vni 1101 + vxlan vrf default vni 1 + vxlan vrf IT vni 1000 + vxlan vrf PROD vni 142 ! ip virtual-router mac-address 00:1c:73:00:00:01 ! ip routing +ip routing vrf IT no ip routing vrf MGMT +ip routing vrf PROD ! ip prefix-list PL-LOOPBACKS-EVPN-OVERLAY seq 10 permit 192.168.45.0/24 eq 32 seq 20 permit 192.168.255.0/24 eq 32 ! +ip prefix-list PL-STATIC-VRF-DEFAULT + seq 10 permit 172.0.0.0/8 +! +ip route 172.0.0.0/8 172.2.10.100 +ip route vrf IT 10.0.0.0/8 10.2.10.100 +! +route-map RM-BGP-UNDERLAY-PEERS-OUT deny 15 + match ip address prefix-list PL-STATIC-VRF-DEFAULT +! +route-map RM-BGP-UNDERLAY-PEERS-OUT permit 20 +! route-map RM-CONN-2-BGP permit 10 match ip address prefix-list PL-LOOPBACKS-EVPN-OVERLAY ! +route-map RM-EVPN-EXPORT-VRF-DEFAULT permit 20 + match ip address prefix-list PL-STATIC-VRF-DEFAULT +! router bfd multihop interval 300 min-rx 300 multiplier 3 ! @@ -75,6 +140,7 @@ router bgp 65000 neighbor IPv4-UNDERLAY-PEERS peer group neighbor IPv4-UNDERLAY-PEERS send-community neighbor IPv4-UNDERLAY-PEERS maximum-routes 12000 + neighbor IPv4-UNDERLAY-PEERS route-map RM-BGP-UNDERLAY-PEERS-OUT out neighbor 172.17.0.1 peer group IPv4-UNDERLAY-PEERS neighbor 172.17.0.1 remote-as 65000 neighbor 172.17.0.1 description cv-pathfinder-edge_Ethernet52 @@ -82,6 +148,12 @@ router bgp 65000 neighbor 172.17.0.3 remote-as 65000 neighbor 172.17.0.3 description cv-pathfinder-edge-no-common-path-group_Ethernet52 redistribute connected route-map RM-CONN-2-BGP + redistribute static + ! + vlan 100 + rd 192.168.45.3:1100 + route-target both 1100:1100 + redistribute learned ! vlan 101 rd 192.168.45.3:1101 @@ -94,6 +166,39 @@ router bgp 65000 address-family ipv4 no neighbor EVPN-OVERLAY-PEERS activate neighbor IPv4-UNDERLAY-PEERS activate + ! + vrf default + rd 192.168.45.3:1 + route-target import evpn 1:1 + route-target export evpn 1:1 + route-target export evpn route-map RM-EVPN-EXPORT-VRF-DEFAULT + ! + vrf IT + rd 192.168.45.3:1000 + route-target import evpn 1000:1000 + route-target export evpn 1000:1000 + router-id 192.168.45.3 + neighbor 172.17.0.1 remote-as 65000 + neighbor 172.17.0.1 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.1 description cv-pathfinder-edge_Ethernet52.1000_vrf_IT + neighbor 172.17.0.3 remote-as 65000 + neighbor 172.17.0.3 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.3 description cv-pathfinder-edge-no-common-path-group_Ethernet52.1000_vrf_IT + redistribute connected + redistribute static + ! + vrf PROD + rd 192.168.45.3:142 + route-target import evpn 142:142 + route-target export evpn 142:142 + router-id 192.168.45.3 + neighbor 172.17.0.1 remote-as 65000 + neighbor 172.17.0.1 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.1 description cv-pathfinder-edge_Ethernet52.142_vrf_PROD + neighbor 172.17.0.3 remote-as 65000 + neighbor 172.17.0.3 peer group IPv4-UNDERLAY-PEERS + neighbor 172.17.0.3 description cv-pathfinder-edge-no-common-path-group_Ethernet52.142_vrf_PROD + redistribute connected ! management api http-commands protocol https diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge-no-default-policy.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge-no-default-policy.yml index 38c38e5d8c5..feecb7d555e 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge-no-default-policy.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge-no-default-policy.yml @@ -52,6 +52,18 @@ router_bgp: peer: autovpn-rr3 description: autovpn-rr3 vrfs: + - name: default + rd: 192.168.30.1:1 + route_targets: + import: + - address_family: evpn + route_targets: + - '1:1' + export: + - address_family: evpn + route_targets: + - '1:1' + - route-map RM-EVPN-EXPORT-VRF-DEFAULT - name: IT router_id: 192.168.30.1 rd: 192.168.30.1:100 @@ -80,18 +92,6 @@ router_bgp: - '42:42' redistribute_routes: - source_protocol: connected - - name: default - rd: 192.168.30.1:1 - route_targets: - import: - - address_family: evpn - route_targets: - - '1:1' - export: - - address_family: evpn - route_targets: - - '1:1' - - route-map RM-EVPN-EXPORT-VRF-DEFAULT service_routing_protocols_model: multi-agent ip_routing: true transceiver_qsfp_default_mode_4x10: false @@ -253,9 +253,9 @@ vxlan_interface: udp_port: 4789 source_interface: Dps1 vrfs: + - name: default + vni: 1 - name: IT vni: 100 - name: PROD vni: 42 - - name: default - vni: 1 diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge.yml index ba73536f3fe..85e8d9a0c28 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/autovpn-edge.yml @@ -56,6 +56,18 @@ router_bgp: peer: autovpn-rr2 description: autovpn-rr2 vrfs: + - name: default + rd: 192.168.30.1:1 + route_targets: + import: + - address_family: evpn + route_targets: + - '1:1' + export: + - address_family: evpn + route_targets: + - '1:1' + - route-map RM-EVPN-EXPORT-VRF-DEFAULT - name: IT router_id: 192.168.30.1 rd: 192.168.30.1:100 @@ -84,18 +96,6 @@ router_bgp: - '42:42' redistribute_routes: - source_protocol: connected - - name: default - rd: 192.168.30.1:1 - route_targets: - import: - - address_family: evpn - route_targets: - - '1:1' - export: - - address_family: evpn - route_targets: - - '1:1' - - route-map RM-EVPN-EXPORT-VRF-DEFAULT service_routing_protocols_model: multi-agent ip_routing: true transceiver_qsfp_default_mode_4x10: false @@ -291,9 +291,9 @@ vxlan_interface: udp_port: 4789 source_interface: Dps1 vrfs: + - name: default + vni: 1 - name: IT vni: 100 - name: PROD vni: 42 - - name: default - vni: 1 diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-common-path-group.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-common-path-group.yml index d69c217bed5..0fe872d316b 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-common-path-group.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-common-path-group.yml @@ -43,47 +43,14 @@ router_bgp: remote_as: '65000' peer: site-ha-disabled-leaf description: site-ha-disabled-leaf_Ethernet2 - address_family_evpn: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - route_map_in: RM-EVPN-SOO-IN - route_map_out: RM-EVPN-SOO-OUT - address_family_ipv4_sr_te: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - address_family_link_state: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - path_selection: - roles: - producer: true - address_family_path_selection: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - bgp: - additional_paths: - receive: true - send: - any: true vrfs: - - name: default - rd: 192.168.42.2:1 - route_targets: - import: - - address_family: evpn - route_targets: - - '1:1' - export: - - address_family: evpn - route_targets: - - '1:1' - - route-map RM-EVPN-EXPORT-VRF-DEFAULT - name: IT router_id: 192.168.42.2 + neighbors: + - ip_address: 172.17.0.2 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: site-ha-disabled-leaf_Ethernet2.1000_vrf_IT rd: 192.168.42.2:1000 route_targets: import: @@ -99,6 +66,11 @@ router_bgp: - source_protocol: static - name: PROD router_id: 192.168.42.2 + neighbors: + - ip_address: 172.17.0.2 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: site-ha-disabled-leaf_Ethernet2.142_vrf_PROD rd: 192.168.42.2:142 route_targets: import: @@ -111,6 +83,44 @@ router_bgp: - 142:142 redistribute_routes: - source_protocol: connected + - name: default + rd: 192.168.42.2:1 + route_targets: + import: + - address_family: evpn + route_targets: + - '1:1' + export: + - address_family: evpn + route_targets: + - '1:1' + - route-map RM-EVPN-EXPORT-VRF-DEFAULT + address_family_evpn: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + route_map_in: RM-EVPN-SOO-IN + route_map_out: RM-EVPN-SOO-OUT + address_family_ipv4_sr_te: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + address_family_link_state: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + path_selection: + roles: + producer: true + address_family_path_selection: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + bgp: + additional_paths: + receive: true + send: + any: true service_routing_protocols_model: multi-agent ip_routing: true transceiver_qsfp_default_mode_4x10: false @@ -141,6 +151,28 @@ ethernet_interfaces: ip_address: 172.17.0.3/31 flow_tracker: hardware: WAN-FLOW-TRACKER +- name: Ethernet52.1000 + peer: site-ha-disabled-leaf + peer_interface: Ethernet2.1000 + peer_type: l3leaf + vrf: IT + description: P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet2.1000_vrf_IT + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 1000 + mtu: 9214 + ip_address: 172.17.0.3/31 +- name: Ethernet52.142 + peer: site-ha-disabled-leaf + peer_interface: Ethernet2.142 + peer_type: l3leaf + vrf: PROD + description: P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet2.142_vrf_PROD + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 142 + mtu: 9214 + ip_address: 172.17.0.3/31 - name: Ethernet1 peer_type: l3_interface ip_address: dhcp diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-default-policy.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-default-policy.yml index 8b82f6f89fb..76167c1ad3c 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-default-policy.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge-no-default-policy.yml @@ -63,6 +63,18 @@ router_bgp: peer: cv-pathfinder-pathfinder description: cv-pathfinder-pathfinder vrfs: + - name: default + rd: 192.168.42.1:1 + route_targets: + import: + - address_family: evpn + route_targets: + - '1:1' + export: + - address_family: evpn + route_targets: + - '1:1' + - route-map RM-EVPN-EXPORT-VRF-DEFAULT - name: IT router_id: 192.168.42.1 rd: 192.168.42.1:100 @@ -91,18 +103,6 @@ router_bgp: - '42:42' redistribute_routes: - source_protocol: connected - - name: default - rd: 192.168.42.1:1 - route_targets: - import: - - address_family: evpn - route_targets: - - '1:1' - export: - - address_family: evpn - route_targets: - - '1:1' - - route-map RM-EVPN-EXPORT-VRF-DEFAULT service_routing_protocols_model: multi-agent ip_routing: true transceiver_qsfp_default_mode_4x10: false @@ -364,12 +364,12 @@ vxlan_interface: udp_port: 4789 source_interface: Dps1 vrfs: + - name: default + vni: 1 - name: IT vni: 100 - name: PROD vni: 42 - - name: default - vni: 1 metadata: cv_tags: device_tags: diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge.yml index 5ce3a0402c7..378de2b83f0 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-edge.yml @@ -51,47 +51,14 @@ router_bgp: peer_group: WAN-OVERLAY-PEERS peer: cv-pathfinder-pathfinder description: cv-pathfinder-pathfinder - address_family_evpn: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - route_map_in: RM-EVPN-SOO-IN - route_map_out: RM-EVPN-SOO-OUT - address_family_ipv4_sr_te: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - address_family_link_state: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - path_selection: - roles: - producer: true - address_family_path_selection: - peer_groups: - - name: WAN-OVERLAY-PEERS - activate: true - bgp: - additional_paths: - receive: true - send: - any: true vrfs: - - name: default - rd: 192.168.42.1:1 - route_targets: - import: - - address_family: evpn - route_targets: - - '1:1' - export: - - address_family: evpn - route_targets: - - '1:1' - - route-map RM-EVPN-EXPORT-VRF-DEFAULT - name: IT router_id: 192.168.42.1 + neighbors: + - ip_address: 172.17.0.0 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: site-ha-disabled-leaf_Ethernet1.1000_vrf_IT rd: 192.168.42.1:1000 route_targets: import: @@ -107,6 +74,11 @@ router_bgp: - source_protocol: static - name: PROD router_id: 192.168.42.1 + neighbors: + - ip_address: 172.17.0.0 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: site-ha-disabled-leaf_Ethernet1.142_vrf_PROD rd: 192.168.42.1:142 route_targets: import: @@ -119,6 +91,44 @@ router_bgp: - 142:142 redistribute_routes: - source_protocol: connected + - name: default + rd: 192.168.42.1:1 + route_targets: + import: + - address_family: evpn + route_targets: + - '1:1' + export: + - address_family: evpn + route_targets: + - '1:1' + - route-map RM-EVPN-EXPORT-VRF-DEFAULT + address_family_evpn: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + route_map_in: RM-EVPN-SOO-IN + route_map_out: RM-EVPN-SOO-OUT + address_family_ipv4_sr_te: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + address_family_link_state: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + path_selection: + roles: + producer: true + address_family_path_selection: + peer_groups: + - name: WAN-OVERLAY-PEERS + activate: true + bgp: + additional_paths: + receive: true + send: + any: true service_routing_protocols_model: multi-agent ip_routing: true transceiver_qsfp_default_mode_4x10: false @@ -149,6 +159,28 @@ ethernet_interfaces: ip_address: 172.17.0.1/31 flow_tracker: hardware: WAN-FLOW-TRACKER +- name: Ethernet52.1000 + peer: site-ha-disabled-leaf + peer_interface: Ethernet1.1000 + peer_type: l3leaf + vrf: IT + description: P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet1.1000_vrf_IT + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 1000 + mtu: 9214 + ip_address: 172.17.0.1/31 +- name: Ethernet52.142 + peer: site-ha-disabled-leaf + peer_interface: Ethernet1.142 + peer_type: l3leaf + vrf: PROD + description: P2P_LINK_TO_SITE-HA-DISABLED-LEAF_Ethernet1.142_vrf_PROD + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 142 + mtu: 9214 + ip_address: 172.17.0.1/31 - name: Ethernet1 peer_type: l3_interface ip_address: dhcp diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-transit.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-transit.yml index a67c6732402..719cf0e1856 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-transit.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/cv-pathfinder-transit.yml @@ -142,6 +142,9 @@ vrfs: - name: PROD tenant: TenantA ip_routing: true +- name: NOT-WAN-VRF + tenant: TenantB + ip_routing: true - name: TRANSIT tenant: TenantB ip_routing: true diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/site-ha-disabled-leaf.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/site-ha-disabled-leaf.yml index 636205eea31..b4780dd5e6c 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/site-ha-disabled-leaf.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/site-ha-disabled-leaf.yml @@ -16,6 +16,7 @@ router_bgp: type: ipv4 maximum_routes: 12000 send_community: all + route_map_out: RM-BGP-UNDERLAY-PEERS-OUT - name: EVPN-OVERLAY-PEERS type: evpn update_source: Loopback0 @@ -32,6 +33,7 @@ router_bgp: redistribute_routes: - source_protocol: connected route_map: RM-CONN-2-BGP + - source_protocol: static neighbors: - ip_address: 172.17.0.1 peer_group: IPv4-UNDERLAY-PEERS @@ -43,11 +45,79 @@ router_bgp: remote_as: '65000' peer: cv-pathfinder-edge-no-common-path-group description: cv-pathfinder-edge-no-common-path-group_Ethernet52 + vrfs: + - name: IT + router_id: 192.168.45.3 + neighbors: + - ip_address: 172.17.0.1 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: cv-pathfinder-edge_Ethernet52.1000_vrf_IT + - ip_address: 172.17.0.3 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: cv-pathfinder-edge-no-common-path-group_Ethernet52.1000_vrf_IT + rd: 192.168.45.3:1000 + route_targets: + import: + - address_family: evpn + route_targets: + - 1000:1000 + export: + - address_family: evpn + route_targets: + - 1000:1000 + redistribute_routes: + - source_protocol: connected + - source_protocol: static + - name: PROD + router_id: 192.168.45.3 + neighbors: + - ip_address: 172.17.0.1 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: cv-pathfinder-edge_Ethernet52.142_vrf_PROD + - ip_address: 172.17.0.3 + peer_group: IPv4-UNDERLAY-PEERS + remote_as: '65000' + description: cv-pathfinder-edge-no-common-path-group_Ethernet52.142_vrf_PROD + rd: 192.168.45.3:142 + route_targets: + import: + - address_family: evpn + route_targets: + - 142:142 + export: + - address_family: evpn + route_targets: + - 142:142 + redistribute_routes: + - source_protocol: connected + - name: default + rd: 192.168.45.3:1 + route_targets: + import: + - address_family: evpn + route_targets: + - '1:1' + export: + - address_family: evpn + route_targets: + - '1:1' + - route-map RM-EVPN-EXPORT-VRF-DEFAULT address_family_evpn: peer_groups: - name: EVPN-OVERLAY-PEERS activate: true vlans: + - id: 100 + tenant: TenantA + rd: 192.168.45.3:1100 + route_targets: + both: + - 1100:1100 + redistribute_routes: + - learned - id: 101 tenant: TenantA rd: 192.168.45.3:1101 @@ -66,6 +136,12 @@ vlan_internal_order: vrfs: - name: MGMT ip_routing: false +- name: IT + tenant: TenantA + ip_routing: true +- name: PROD + tenant: TenantA + ip_routing: true management_api_http: enable_vrfs: - name: MGMT @@ -80,6 +156,28 @@ ethernet_interfaces: mtu: 9214 type: routed ip_address: 172.17.0.0/31 +- name: Ethernet1.1000 + peer: cv-pathfinder-edge + peer_interface: Ethernet52.1000 + peer_type: wan_edge + vrf: IT + description: P2P_LINK_TO_CV-PATHFINDER-EDGE_Ethernet52.1000_vrf_IT + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 1000 + mtu: 9214 + ip_address: 172.17.0.0/31 +- name: Ethernet1.142 + peer: cv-pathfinder-edge + peer_interface: Ethernet52.142 + peer_type: wan_edge + vrf: PROD + description: P2P_LINK_TO_CV-PATHFINDER-EDGE_Ethernet52.142_vrf_PROD + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 142 + mtu: 9214 + ip_address: 172.17.0.0/31 - name: Ethernet2 peer: cv-pathfinder-edge-no-common-path-group peer_interface: Ethernet52 @@ -89,6 +187,28 @@ ethernet_interfaces: mtu: 9214 type: routed ip_address: 172.17.0.2/31 +- name: Ethernet2.1000 + peer: cv-pathfinder-edge-no-common-path-group + peer_interface: Ethernet52.1000 + peer_type: wan_edge + vrf: IT + description: P2P_LINK_TO_CV-PATHFINDER-EDGE-NO-COMMON-PATH-GROUP_Ethernet52.1000_vrf_IT + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 1000 + mtu: 9214 + ip_address: 172.17.0.2/31 +- name: Ethernet2.142 + peer: cv-pathfinder-edge-no-common-path-group + peer_interface: Ethernet52.142 + peer_type: wan_edge + vrf: PROD + description: P2P_LINK_TO_CV-PATHFINDER-EDGE-NO-COMMON-PATH-GROUP_Ethernet52.142_vrf_PROD + shutdown: false + type: l3dot1q + encapsulation_dot1q_vlan: 142 + mtu: 9214 + ip_address: 172.17.0.2/31 loopback_interfaces: - name: Loopback0 description: EVPN_Overlay_Peering @@ -105,6 +225,10 @@ prefix_lists: action: permit 192.168.45.0/24 eq 32 - sequence: 20 action: permit 192.168.255.0/24 eq 32 +- name: PL-STATIC-VRF-DEFAULT + sequence_numbers: + - sequence: 10 + action: permit 172.0.0.0/8 route_maps: - name: RM-CONN-2-BGP sequence_numbers: @@ -112,18 +236,49 @@ route_maps: type: permit match: - ip address prefix-list PL-LOOPBACKS-EVPN-OVERLAY +- name: RM-EVPN-EXPORT-VRF-DEFAULT + sequence_numbers: + - sequence: 20 + type: permit + match: + - ip address prefix-list PL-STATIC-VRF-DEFAULT +- name: RM-BGP-UNDERLAY-PEERS-OUT + sequence_numbers: + - sequence: 15 + type: deny + match: + - ip address prefix-list PL-STATIC-VRF-DEFAULT + - sequence: 20 + type: permit router_bfd: multihop: interval: 300 min_rx: 300 multiplier: 3 vlans: +- id: 100 + name: VLAN100 + tenant: TenantA - id: 101 name: VLAN101 tenant: TenantA ip_igmp_snooping: globally_enabled: true ip_virtual_router_mac_address: 00:1c:73:00:00:01 +vlan_interfaces: +- name: Vlan100 + tenant: TenantA + description: VLAN100 + shutdown: true + ip_address_virtual: 10.0.100.1/24 + vrf: PROD +static_routes: +- destination_address_prefix: 172.0.0.0/8 + gateway: 172.2.10.100 + vrf: default +- destination_address_prefix: 10.0.0.0/8 + gateway: 10.2.10.100 + vrf: IT vxlan_interface: Vxlan1: description: site-ha-disabled-leaf_VTEP @@ -131,5 +286,14 @@ vxlan_interface: udp_port: 4789 source_interface: Loopback1 vlans: + - id: 100 + vni: 1100 - id: 101 vni: 1101 + vrfs: + - name: default + vni: 1 + - name: IT + vni: 1000 + - name: PROD + vni: 142 diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/CV_PATHFINDER_TESTS.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/CV_PATHFINDER_TESTS.yml index 42ac8ff6ef3..a9e7f86ef5e 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/CV_PATHFINDER_TESTS.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/CV_PATHFINDER_TESTS.yml @@ -69,24 +69,6 @@ wan_edge: cv_pathfinder_region: AVD_Land_East cv_pathfinder_site: Site511 id: 1 - l3_interfaces: - - name: Ethernet1 - wan_carrier: ATT - wan_circuit_id: 666 - dhcp_accept_default_route: true - ip_address: dhcp - - name: Ethernet2 - wan_carrier: Colt - wan_circuit_id: 10555 - ip_address: 172.15.5.5/31 - - name: Ethernet3 - wan_carrier: Comcast-5G - wan_circuit_id: AF830 - ip_address: 172.20.20.20/31 - connected_to_pathfinder: False - # Disabling HA - TODO once implemented, for now it is disabled by default - # wan_ha: - # enabled: False nodes: - name: cv-pathfinder-edge id: 1 @@ -279,6 +261,7 @@ tenants: wan_vni: 66 - name: NOT-WAN-VRF vrf_id: 13 + address_families: [] wan_virtual_topologies: vrfs: diff --git a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/eos_designs_facts.py b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/eos_designs_facts.py index c9a5a8817a3..8b8756dd842 100644 --- a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/eos_designs_facts.py +++ b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/eos_designs_facts.py @@ -14,10 +14,11 @@ from .short_esi import ShortEsiMixin from .uplinks import UplinksMixin from .vlans import VlansMixin +from .vrfs import VrfsMixin from .wan import WanMixin -class EosDesignsFacts(AvdFacts, MlagMixin, ShortEsiMixin, OverlayMixin, WanMixin, UplinksMixin, VlansMixin): +class EosDesignsFacts(AvdFacts, MlagMixin, ShortEsiMixin, OverlayMixin, WanMixin, UplinksMixin, VlansMixin, VrfsMixin): """ `EosDesignsFacts` is based on `AvdFacts`, so make sure to read the description there first. diff --git a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/vrfs.py b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/vrfs.py new file mode 100644 index 00000000000..df647c10fb6 --- /dev/null +++ b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/vrfs.py @@ -0,0 +1,27 @@ +# Copyright (c) 2023-2024 Arista Networks, Inc. +# Use of this source code is governed by the Apache License 2.0 +# that can be found in the LICENSE file. +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .eos_designs_facts import EosDesignsFacts + + +class VrfsMixin: + """ + Mixin Class used to generate some of the EosDesignsFacts. + Class should only be used as Mixin to the EosDesignsFacts class + Using type-hint on self to get proper type-hints on attributes across all Mixins. + """ + + @cached_property + def vrfs(self: EosDesignsFacts) -> str: + """ + Exposed in avd_switch_facts + + Return the list of VRF names configured on this switch + """ + return self.shared_utils.vrfs diff --git a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/filtered_tenants.py b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/filtered_tenants.py index 59b666524c0..535d8c99827 100644 --- a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/filtered_tenants.py +++ b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/filtered_tenants.py @@ -162,6 +162,25 @@ def accepted_vlans(self: SharedUtils) -> list[int]: return accepted_vlans + def is_attracted_from_uplink_switch_vrf(self: SharedUtils, vrf_name: str) -> bool: + """ + For a WAN router with wan_role client, look up on the uplink switches to check if a VRF should be attracted to the router. + + Note that if the attracted VRF does not have a wan_vni configured, the code will raise an error + TODO: should we silently not attract the VRF -> probably not as it would be difficult to understand why + """ + if not self.is_wan_client: + return False + + # TODO may need to filter on EVPN address family + for uplink_switch in self.uplink_switches: + # Go over all the uplink_switches VRFs and return True if the VRF is present + uplink_switch_facts = self.get_peer_facts(uplink_switch, required=True) + if vrf_name in get(uplink_switch_facts, "vrfs", default=[]): + return True + + return False + def filtered_vrfs(self: SharedUtils, tenant: dict) -> list[dict]: """ Return sorted and filtered vrf list from given tenant. @@ -242,20 +261,13 @@ def filtered_vrfs(self: SharedUtils, tenant: dict) -> list[dict]: ) ] - if self.wan_role is not None and (wan_vni := get(original_vrf, "wan_vni")): - vrf["wan_vni"] = wan_vni - else: - continue - if ( vrf["svis"] or vrf["l3_interfaces"] or vrf["loopbacks"] or "all" in always_include_vrfs_in_tenants or tenant["name"] in always_include_vrfs_in_tenants - # PROBLEM TODO - this does not allow to filter any WAN VRF on ANY WAN routers (breaks filtering - # mechanism so ...) - # or vrf.get("wan_vni", None) is not None + or self.is_attracted_from_uplink_switch_vrf(vrf["name"]) ): filtered_vrfs.append(vrf) diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py index 8bc67b3e8f5..88342f89b91 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py @@ -6,6 +6,7 @@ import ipaddress from functools import cached_property +from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get, get_item @@ -120,7 +121,7 @@ def _vrf_default_ipv4_static_routes(self) -> dict: redistribute_in_overlay = False return { - "static_routes": list(vrf_default_ipv4_static_routes), + "static_routes": natural_sort(vrf_default_ipv4_static_routes), "redistribute_in_underlay": redistribute_in_underlay, "redistribute_in_overlay": redistribute_in_overlay, } diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py index 06e56ab0746..155e0f5636a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py @@ -133,7 +133,21 @@ def _get_vxlan_interface_config_for_vrf(self, vrf: dict, tenant: dict, vrfs: lis return if self.shared_utils.is_wan_router: - vni = get(vrf, "wan_vni", required=True, org_key=f"VRF {vrf_name} in tenant {tenant['name']} does not have a `wan_vni` defined.") + vni = get( + vrf, + "wan_vni", + required=True, + # TODO when adding VRF filter, change the error message + # org_key=( + # f"VRF {vrf_name} in tenant {tenant['name']} does not have a `wan_vni` defined. " + # "If this VRF was not intended to be extended over WAN, set address family to none. " + # "If not intended on the WAN router, use the VRF filter" + # ) + org_key=( + f"VRF {vrf_name} in tenant {tenant['name']} does not have a `wan_vni` defined. " + "If this VRF was not intended to be extended over WAN, set address family to none." + ), + ) else: vni = default( vrf.get("vrf_vni"),