From 251d9da4f814ce17dbc171b6421e2cab471ecfb7 Mon Sep 17 00:00:00 2001 From: Colin MacGiollaEain <43743234+colinmacgiolla@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:18:47 +0000 Subject: [PATCH] Feat(eos_cli_config_gen): Expand CLI to support DualEncap MH EVPN GW requirements (#4613) --- .../documentation/devices/router-bgp-evpn.md | 15 ++++++++++++++ .../intended/configs/router-bgp-evpn.cfg | 9 +++++++++ .../inventory/host_vars/router-bgp-evpn.yml | 8 ++++++++ .../docs/tables/router-bgp.md | 14 +++++++++++++ .../j2templates/documentation/router-bgp.j2 | 14 +++++++++++++ .../j2templates/eos/router-bgp.j2 | 13 ++++++++++++ .../schema/eos_cli_config_gen.schema.yml | 20 +++++++++++++++++++ .../schema_fragments/router_bgp.schema.yml | 20 +++++++++++++++++++ 8 files changed, 113 insertions(+) diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/router-bgp-evpn.md b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/router-bgp-evpn.md index 6116cb94039..7e28738025b 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/router-bgp-evpn.md +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/router-bgp-evpn.md @@ -146,9 +146,15 @@ ASN Notation: asplain | Settings | Value | | -------- | ----- | +| Local Domain | 65101:0 | +| Remote Domain | 65101:1 | | Remote Domain Peer Groups | EVPN-OVERLAY-PEERS | | L3 Gateway Configured | True | | L3 Gateway Inter-domain | True | +| Local Domain: Ethernet-Segment Identifier | 0011:1111:1111:1111:1111 | +| Local Domain: Ethernet-Segment import Route-Target | 11:11:11:11:11:11 | +| Remote Domain: Ethernet-Segment Identifier | 0022:2222:2222:2222:2222 | +| Remote Domain: Ethernet-Segment import Route-Target | 22:22:22:22:22:22 | #### Router BGP VLAN Aware Bundles @@ -325,11 +331,20 @@ router bgp 65101 neighbor 10.100.100.5 activate neighbor 10.100.100.5 encapsulation mpls domain identifier 65101:0 + domain identifier 65101:1 remote next-hop resolution disabled neighbor default next-hop-self received-evpn-routes route-type ip-prefix inter-domain host-flap detection window 10 threshold 1 expiry timeout 3 seconds layer-2 fec in-place update route import overlay-index gateway + ! + evpn ethernet-segment domain local + identifier 0011:1111:1111:1111:1111 + route-target import 11:11:11:11:11:11 + ! + evpn ethernet-segment domain remote + identifier 0022:2222:2222:2222:2222 + route-target import 22:22:22:22:22:22 ! address-family ipv4 no neighbor EVPN-OVERLAY-PEERS activate diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/router-bgp-evpn.cfg b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/router-bgp-evpn.cfg index 83bac4e7634..c2318bc8222 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/router-bgp-evpn.cfg +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/router-bgp-evpn.cfg @@ -148,11 +148,20 @@ router bgp 65101 neighbor 10.100.100.5 activate neighbor 10.100.100.5 encapsulation mpls domain identifier 65101:0 + domain identifier 65101:1 remote next-hop resolution disabled neighbor default next-hop-self received-evpn-routes route-type ip-prefix inter-domain host-flap detection window 10 threshold 1 expiry timeout 3 seconds layer-2 fec in-place update route import overlay-index gateway + ! + evpn ethernet-segment domain local + identifier 0011:1111:1111:1111:1111 + route-target import 11:11:11:11:11:11 + ! + evpn ethernet-segment domain remote + identifier 0022:2222:2222:2222:2222 + route-target import 22:22:22:22:22:22 ! address-family ipv4 no neighbor EVPN-OVERLAY-PEERS activate diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/router-bgp-evpn.yml b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/router-bgp-evpn.yml index a44a1b1234b..d9878868301 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/router-bgp-evpn.yml +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/router-bgp-evpn.yml @@ -122,6 +122,7 @@ router_bgp: inter_domain: true encapsulation: path-selection domain_identifier: "65101:0" + domain_identifier_remote: "65101:1" neighbors: - ip_address: 10.100.100.1 activate: true @@ -191,6 +192,13 @@ router_bgp: - name: TEST-ENCAPSULATION-2 activate: true encapsulation: path-selection + evpn_ethernet_segment: + - domain: remote + identifier: "0022:2222:2222:2222:2222" + route_target_import: "22:22:22:22:22:22" + - domain: local + identifier: "0011:1111:1111:1111:1111" + route_target_import: "11:11:11:11:11:11" evpn_hostflap_detection: enabled: true window: 10 diff --git a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/router-bgp.md b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/router-bgp.md index c24c212e4e3..330c78d14c9 100644 --- a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/router-bgp.md +++ b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/router-bgp.md @@ -345,6 +345,7 @@ | [          id_remote](## "router_bgp.vpws.[].pseudowires.[].id_remote") | Integer | | | | Must match id_local on other pe. | | [  address_family_evpn](## "router_bgp.address_family_evpn") | Dictionary | | | | | | [    domain_identifier](## "router_bgp.address_family_evpn.domain_identifier") | String | | | | | + | [    domain_identifier_remote](## "router_bgp.address_family_evpn.domain_identifier_remote") | String | | | | | | [    neighbor_default](## "router_bgp.address_family_evpn.neighbor_default") | Dictionary | | | | | | [      encapsulation](## "router_bgp.address_family_evpn.neighbor_default.encapsulation") | String | | | Valid Values:
- vxlan
- mpls
- path-selection | Transport encapsulation for neighbor. | | [      next_hop_self_source_interface](## "router_bgp.address_family_evpn.neighbor_default.next_hop_self_source_interface") | String | | | | Source interface name for MPLS encapsulation. Requires `encapsulation` to be set as `mpls`. | @@ -409,6 +410,10 @@ | [    layer_2_fec_in_place_update](## "router_bgp.address_family_evpn.layer_2_fec_in_place_update") | Dictionary | | | | BGP layer-2 in-place FEC operation. | | [      enabled](## "router_bgp.address_family_evpn.layer_2_fec_in_place_update.enabled") | Boolean | Required | | | | | [      timeout](## "router_bgp.address_family_evpn.layer_2_fec_in_place_update.timeout") | Integer | | | Min: 0
Max: 300 | In-place FEC update tracking timeout in seconds. | + | [    evpn_ethernet_segment](## "router_bgp.address_family_evpn.evpn_ethernet_segment") | List, items: Dictionary | | | | | + | [      - domain](## "router_bgp.address_family_evpn.evpn_ethernet_segment.[].domain") | String | Required, Unique | | Valid Values:
- all
- local
- remote | | + | [        identifier](## "router_bgp.address_family_evpn.evpn_ethernet_segment.[].identifier") | String | | | | EVPN Ethernet Segment Identifier (Type 1 format). | + | [        route_target_import](## "router_bgp.address_family_evpn.evpn_ethernet_segment.[].route_target_import") | String | | | | Low-order 6 bytes of ES-Import Route Target. | | [    bgp_additional_paths](## "router_bgp.address_family_evpn.bgp_additional_paths") deprecated | Dictionary | | | | BGP additional-paths commands.This key is deprecated. Support will be removed in AVD version 6.0.0. Use bgp.additional_paths instead. | | [      receive](## "router_bgp.address_family_evpn.bgp_additional_paths.receive") | Boolean | | | | Receive multiple paths. | | [      send](## "router_bgp.address_family_evpn.bgp_additional_paths.send") | Dictionary | | | | Send multiple paths. | @@ -2237,6 +2242,7 @@ id_remote: address_family_evpn: domain_identifier: + domain_identifier_remote: neighbor_default: # Transport encapsulation for neighbor. @@ -2388,6 +2394,14 @@ # In-place FEC update tracking timeout in seconds. timeout: + evpn_ethernet_segment: + - domain: + + # EVPN Ethernet Segment Identifier (Type 1 format). + identifier: + + # Low-order 6 bytes of ES-Import Route Target. + route_target_import: # BGP additional-paths commands. # This key is deprecated. diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/router-bgp.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/router-bgp.j2 index e0d1c532c35..ee85ab289c9 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/router-bgp.j2 +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/router-bgp.j2 @@ -645,6 +645,12 @@ ASN Notation: {{ router_bgp.as_notation | arista.avd.default('asplain') }} | Settings | Value | | -------- | ----- | +{% if router_bgp.address_family_evpn.domain_identifier is arista.avd.defined %} +| Local Domain | {{ router_bgp.address_family_evpn.domain_identifier }} | +{% endif %} +{% if router_bgp.address_family_evpn.domain_identifier_remote is arista.avd.defined %} +| Remote Domain | {{ router_bgp.address_family_evpn.domain_identifier_remote }} | +{% endif %} {% if evpn_gw_config.peer_groups | length > 0 %} | Remote Domain Peer Groups | {{ evpn_gw_config.peer_groups | join(", ") }} | {% endif %} @@ -654,6 +660,14 @@ ASN Notation: {{ router_bgp.as_notation | arista.avd.default('asplain') }} {% if router_bgp.address_family_evpn.neighbor_default.next_hop_self_received_evpn_routes.inter_domain is arista.avd.defined(true) %} | L3 Gateway Inter-domain | True | {% endif %} +{% for segment in router_bgp.address_family_evpn.evpn_ethernet_segment | arista.avd.natural_sort('domain') %} +{% if segment.identifier is arista.avd.defined %} +| {{ segment.domain | title }} Domain: Ethernet-Segment Identifier | {{ segment.identifier }} | +{% endif %} +{% if segment.route_target_import is arista.avd.defined %} +| {{ segment.domain | title }} Domain: Ethernet-Segment import Route-Target | {{ segment.route_target_import }} | +{% endif %} +{% endfor %} {% endif %} {% if router_bgp.address_family_ipv4_labeled_unicast is arista.avd.defined %} diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/router-bgp.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/router-bgp.j2 index 47e135d2831..2b7724fc4f0 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/router-bgp.j2 +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/router-bgp.j2 @@ -941,6 +941,9 @@ router bgp {{ router_bgp.as }} {% if router_bgp.address_family_evpn.domain_identifier is arista.avd.defined %} domain identifier {{ router_bgp.address_family_evpn.domain_identifier }} {% endif %} +{% if router_bgp.address_family_evpn.domain_identifier_remote is arista.avd.defined %} + domain identifier {{ router_bgp.address_family_evpn.domain_identifier_remote }} remote +{% endif %} {% if router_bgp.address_family_evpn.next_hop.resolution_disabled is arista.avd.defined(true) %} next-hop resolution disabled {% endif %} @@ -981,6 +984,16 @@ router bgp {{ router_bgp.as }} {% if router_bgp.address_family_evpn.route.import_overlay_index_gateway is arista.avd.defined(true) %} route import overlay-index gateway {% endif %} +{% for segment in router_bgp.address_family_evpn.evpn_ethernet_segment | arista.avd.natural_sort('domain') %} + ! + evpn ethernet-segment domain {{ segment.domain }} +{% if segment.identifier is arista.avd.defined %} + identifier {{ segment.identifier }} +{% endif %} +{% if segment.route_target_import is arista.avd.defined %} + route-target import {{ segment.route_target_import }} +{% endif %} +{% endfor %} {% endif %} {# address family flow-spec ipv4 activation #} {% if router_bgp.address_family_flow_spec_ipv4 is arista.avd.defined %} diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml b/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml index e0b5760c17b..0c853a01b8c 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml @@ -13118,6 +13118,8 @@ keys: keys: domain_identifier: type: str + domain_identifier_remote: + type: str neighbor_default: type: dict keys: @@ -13331,6 +13333,24 @@ keys: - str min: 0 max: 300 + evpn_ethernet_segment: + type: list + primary_key: domain + items: + type: dict + keys: + domain: + type: str + valid_values: + - all + - local + - remote + identifier: + type: str + description: EVPN Ethernet Segment Identifier (Type 1 format). + route_target_import: + type: str + description: Low-order 6 bytes of ES-Import Route Target. bgp_additional_paths: type: dict deprecation: diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/router_bgp.schema.yml b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/router_bgp.schema.yml index 77237147b3c..0141aef82ae 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/router_bgp.schema.yml +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/router_bgp.schema.yml @@ -1248,6 +1248,8 @@ keys: keys: domain_identifier: type: str + domain_identifier_remote: + type: str neighbor_default: type: dict keys: @@ -1455,6 +1457,24 @@ keys: - str min: 0 max: 300 + evpn_ethernet_segment: + type: list + primary_key: domain + items: + type: dict + keys: + domain: + type: str + valid_values: + - all + - local + - remote + identifier: + type: str + description: EVPN Ethernet Segment Identifier (Type 1 format). + route_target_import: + type: str + description: Low-order 6 bytes of ES-Import Route Target. bgp_additional_paths: type: dict deprecation: