diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/ethernet-interfaces.md b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/ethernet-interfaces.md index 35ef63f4061..e08227e15d2 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/ethernet-interfaces.md +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/ethernet-interfaces.md @@ -374,8 +374,16 @@ interface Ethernet1 switchport trunk group g2 no switchport switchport source-interface tx - switchport vlan translation in 23-37 45 - switchport vlan translation out 23-37 45 + switchport vlan translation 12 20 + switchport vlan translation 24 inner 78 network 46 + switchport vlan translation 43 dot1q-tunnel 30 + switchport vlan translation in required + switchport vlan translation in 37 inner 56 49 + switchport vlan translation in 23 dot1q-tunnel 45 + switchport vlan translation out 10 45 inner 34 + switchport vlan translation out 23 dot1q-tunnel 22 + switchport vlan translation out 34 50 + switchport vlan translation out 45 dot1q-tunnel all switchport trunk private-vlan secondary switchport pvlan mapping 20-30 switchport backup-link Ethernet5 prefer vlan 10 diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/port-channel-interfaces.md b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/port-channel-interfaces.md index deeb53821ba..d85d1e4bed2 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/port-channel-interfaces.md +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/port-channel-interfaces.md @@ -522,8 +522,16 @@ interface Port-Channel100 switchport trunk group g1 switchport trunk group g2 switchport source-interface tx multicast - switchport vlan translation in 23-37 45 - switchport vlan translation out 23-37 45 + switchport vlan translation 12 20 + switchport vlan translation 24 inner 78 network 46 + switchport vlan translation 43 dot1q-tunnel 30 + switchport vlan translation in required + switchport vlan translation in 37 inner 56 49 + switchport vlan translation in 23 dot1q-tunnel 45 + switchport vlan translation out 10 45 inner 34 + switchport vlan translation out 23 dot1q-tunnel 22 + switchport vlan translation out 34 50 + switchport vlan translation out 45 dot1q-tunnel all switchport trunk private-vlan secondary switchport pvlan mapping 20-30 switchport backup-link Ethernet5 diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/ethernet-interfaces.cfg b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/ethernet-interfaces.cfg index a3b7d1e6517..791970a04ce 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/ethernet-interfaces.cfg +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/ethernet-interfaces.cfg @@ -27,8 +27,16 @@ interface Ethernet1 switchport trunk group g2 no switchport switchport source-interface tx - switchport vlan translation in 23-37 45 - switchport vlan translation out 23-37 45 + switchport vlan translation 12 20 + switchport vlan translation 24 inner 78 network 46 + switchport vlan translation 43 dot1q-tunnel 30 + switchport vlan translation in required + switchport vlan translation in 37 inner 56 49 + switchport vlan translation in 23 dot1q-tunnel 45 + switchport vlan translation out 10 45 inner 34 + switchport vlan translation out 23 dot1q-tunnel 22 + switchport vlan translation out 34 50 + switchport vlan translation out 45 dot1q-tunnel all switchport trunk private-vlan secondary switchport pvlan mapping 20-30 switchport backup-link Ethernet5 prefer vlan 10 diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/port-channel-interfaces.cfg b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/port-channel-interfaces.cfg index 013c8684471..e4c5d1a74d6 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/port-channel-interfaces.cfg +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/port-channel-interfaces.cfg @@ -176,8 +176,16 @@ interface Port-Channel100 switchport trunk group g1 switchport trunk group g2 switchport source-interface tx multicast - switchport vlan translation in 23-37 45 - switchport vlan translation out 23-37 45 + switchport vlan translation 12 20 + switchport vlan translation 24 inner 78 network 46 + switchport vlan translation 43 dot1q-tunnel 30 + switchport vlan translation in required + switchport vlan translation in 37 inner 56 49 + switchport vlan translation in 23 dot1q-tunnel 45 + switchport vlan translation out 10 45 inner 34 + switchport vlan translation out 23 dot1q-tunnel 22 + switchport vlan translation out 34 50 + switchport vlan translation out 45 dot1q-tunnel all switchport trunk private-vlan secondary switchport pvlan mapping 20-30 switchport backup-link Ethernet5 diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/ethernet-interfaces.yml b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/ethernet-interfaces.yml index 6dcdb5e883b..4e64394710e 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/ethernet-interfaces.yml +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/ethernet-interfaces.yml @@ -54,12 +54,36 @@ ethernet_interfaces: dot1q: ethertype: 1536 vlan_translations: - - from: 23-37 - to: 45 - direction: in - - from: 23-37 - to: 45 - direction: out + direction_in: + - required: true + - from: 37 + to: 49 + inner_from: 56 + - from: 23 + to: 45 + dot1q_tunnel: true + direction_both: + - from: 24 + inner_from: 78 + network: true + to: 46 + - from: 12 + to: 20 + - from: 43 + to: 30 + dot1q_tunnel: true + direction_out: + - from: 10 + to: 45 + inner_to: 34 + - from: 34 + to: 50 + - from: 45 + dot1q_tunnel: + all: true + - from: 23 + dot1q_tunnel: + to: 22 vlan_forwarding_accept_all: true source_interface: tx backup_link: diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/port-channel-interfaces.yml b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/port-channel-interfaces.yml index d2d4a6baa26..9ad454bff34 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/port-channel-interfaces.yml +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/port-channel-interfaces.yml @@ -134,12 +134,36 @@ port_channel_interfaces: vlan_tag: required source_interface: tx multicast vlan_translations: - - from: 23-37 - to: 45 - direction: in - - from: 23-37 - to: 45 - direction: out + direction_in: + - required: true + - from: 37 + to: 49 + inner_from: 56 + - from: 23 + to: 45 + dot1q_tunnel: true + direction_both: + - from: 24 + inner_from: 78 + network: true + to: 46 + - from: 12 + to: 20 + - from: 43 + to: 30 + dot1q_tunnel: true + direction_out: + - from: 10 + to: 45 + inner_to: 34 + - from: 34 + to: 50 + - from: 45 + dot1q_tunnel: + all: true + - from: 23 + dot1q_tunnel: + to: 22 vlan_forwarding_accept_all: true backup_link: interface: Ethernet5 diff --git a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/ethernet-interfaces.md b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/ethernet-interfaces.md index e04aeb3fae8..471b9a69c6e 100644 --- a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/ethernet-interfaces.md +++ b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/ethernet-interfaces.md @@ -425,10 +425,26 @@ | [        trunk](## "ethernet_interfaces.[].switchport.phone.trunk") | String | | | Valid Values:
- tagged
- tagged phone
- untagged
- untagged phone | Warning: This should not be combined with `ethernet_interfaces[].phone.trunk` | | [      mode](## "ethernet_interfaces.[].switchport.mode") | String | | | Valid Values:
- access
- dot1q-tunnel
- trunk
- trunk phone | Warning: This should not be combined with `ethernet_interfaces[].mode` | | [      pvlan_mapping](## "ethernet_interfaces.[].switchport.pvlan_mapping") | String | | | | Secondary VLAN IDs of the private VLAN mapping.
Warning: This should not be combined with `ethernet_interfaces[].pvlan_mapping`. | - | [      vlan_translations](## "ethernet_interfaces.[].switchport.vlan_translations") | List, items: Dictionary | | | | Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`. | - | [        - from](## "ethernet_interfaces.[].switchport.vlan_translations.[].from") | String | Required | | | VLAN ID or range of VLAN IDs to map from. | - | [          to](## "ethernet_interfaces.[].switchport.vlan_translations.[].to") | Integer | Required | | | VLAN ID to map to. | - | [          direction](## "ethernet_interfaces.[].switchport.vlan_translations.[].direction") | String | Required, Unique | `both` | Valid Values:
- in
- out
- both | | + | [      vlan_translations](## "ethernet_interfaces.[].switchport.vlan_translations") | Dictionary | | | | Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`. | + | [        direction_in](## "ethernet_interfaces.[].switchport.vlan_translations.direction_in") | List, items: Dictionary | | | | Map ingress packets only. | + | [          - required](## "ethernet_interfaces.[].switchport.vlan_translations.direction_in.[].required") | Boolean | | | | Drop the packets that do not match any VLAN mapping. | + | [            from](## "ethernet_interfaces.[].switchport.vlan_translations.direction_in.[].from") | Integer | | | | VLAN ID or range of VLAN IDs to map from. | + | [            to](## "ethernet_interfaces.[].switchport.vlan_translations.direction_in.[].to") | Integer | | | | VLAN ID to map to. | + | [            dot1q_tunnel](## "ethernet_interfaces.[].switchport.vlan_translations.direction_in.[].dot1q_tunnel") | Boolean | | | | | + | [            inner_from](## "ethernet_interfaces.[].switchport.vlan_translations.direction_in.[].inner_from") | Integer | | | | Inner VLAN ID to map from. | + | [        direction_out](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out") | List, items: Dictionary | | | | Map egress packets only. | + | [          - from](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out.[].from") | Integer | Required | | | VLAN ID or range of VLAN IDs to map from. | + | [            to](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out.[].to") | Integer | | | | VLAN ID to map to. | + | [            dot1q_tunnel](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out.[].dot1q_tunnel") | Dictionary | | | | | + | [              all](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out.[].dot1q_tunnel.all") | Boolean | | | | | + | [              to](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out.[].dot1q_tunnel.to") | Integer | | | | VLAN ID or range(s) of VLAN IDs to map to. | + | [            inner_to](## "ethernet_interfaces.[].switchport.vlan_translations.direction_out.[].inner_to") | Integer | | | | Inner VLAN ID to map to. | + | [        direction_both](## "ethernet_interfaces.[].switchport.vlan_translations.direction_both") | List, items: Dictionary | | | | Map both egress and ingress packets. | + | [          - from](## "ethernet_interfaces.[].switchport.vlan_translations.direction_both.[].from") | Integer | Required | | | VLAN ID or range of VLAN IDs to map from. | + | [            to](## "ethernet_interfaces.[].switchport.vlan_translations.direction_both.[].to") | Integer | Required | | | VLAN ID to map to. | + | [            dot1q_tunnel](## "ethernet_interfaces.[].switchport.vlan_translations.direction_both.[].dot1q_tunnel") | Boolean | | | | | + | [            inner_from](## "ethernet_interfaces.[].switchport.vlan_translations.direction_both.[].inner_from") | Integer | | | | Inner VLAN ID to map from. | + | [            network](## "ethernet_interfaces.[].switchport.vlan_translations.direction_both.[].network") | Boolean | | | | Use network-side VLAN ID. | | [      vlan_forwarding_accept_all](## "ethernet_interfaces.[].switchport.vlan_forwarding_accept_all") | Boolean | | | | | | [      backup_link](## "ethernet_interfaces.[].switchport.backup_link") | Dictionary | | | | | | [        interface](## "ethernet_interfaces.[].switchport.backup_link.interface") | String | | | | Backup interface. Example - Ethernet4, Vlan10 etc. | @@ -1246,12 +1262,54 @@ # Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`. vlan_translations: - # VLAN ID or range of VLAN IDs to map from. - - from: + # Map ingress packets only. + direction_in: - # VLAN ID to map to. - to: - direction: + # Drop the packets that do not match any VLAN mapping. + - required: + + # VLAN ID or range of VLAN IDs to map from. + from: + + # VLAN ID to map to. + to: + dot1q_tunnel: + + # Inner VLAN ID to map from. + inner_from: + + # Map egress packets only. + direction_out: + + # VLAN ID or range of VLAN IDs to map from. + - from: + + # VLAN ID to map to. + to: + dot1q_tunnel: + all: + + # VLAN ID or range(s) of VLAN IDs to map to. + to: + + # Inner VLAN ID to map to. + inner_to: + + # Map both egress and ingress packets. + direction_both: + + # VLAN ID or range of VLAN IDs to map from. + - from: + + # VLAN ID to map to. + to: + dot1q_tunnel: + + # Inner VLAN ID to map from. + inner_from: + + # Use network-side VLAN ID. + network: vlan_forwarding_accept_all: backup_link: diff --git a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/port-channel-interfaces.md b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/port-channel-interfaces.md index 27bbd0ac9b7..be0d6ff63ec 100644 --- a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/port-channel-interfaces.md +++ b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/port-channel-interfaces.md @@ -276,10 +276,26 @@ | [        trunk](## "port_channel_interfaces.[].switchport.phone.trunk") | String | | | Valid Values:
- tagged
- tagged phone
- untagged
- untagged phone | Warning: This should not be combined with `port_channel_interfaces[].phone.trunk` | | [      mode](## "port_channel_interfaces.[].switchport.mode") | String | | | Valid Values:
- access
- dot1q-tunnel
- trunk
- trunk phone | Warning: This should not be combined with `port_channel_interfaces[].mode` | | [      pvlan_mapping](## "port_channel_interfaces.[].switchport.pvlan_mapping") | String | | | | Secondary VLAN IDs of the private VLAN mapping.
Warning: This should not be combined with `port_channel_interfaces[].pvlan_mapping`. | - | [      vlan_translations](## "port_channel_interfaces.[].switchport.vlan_translations") | List, items: Dictionary | | | | Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`. | - | [        - from](## "port_channel_interfaces.[].switchport.vlan_translations.[].from") | String | Required | | | VLAN ID or range of VLAN IDs to map from. | - | [          to](## "port_channel_interfaces.[].switchport.vlan_translations.[].to") | Integer | Required | | | VLAN ID to map to. | - | [          direction](## "port_channel_interfaces.[].switchport.vlan_translations.[].direction") | String | Required, Unique | `both` | Valid Values:
- in
- out
- both | | + | [      vlan_translations](## "port_channel_interfaces.[].switchport.vlan_translations") | Dictionary | | | | Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`. | + | [        direction_in](## "port_channel_interfaces.[].switchport.vlan_translations.direction_in") | List, items: Dictionary | | | | Map ingress packets only. | + | [          - required](## "port_channel_interfaces.[].switchport.vlan_translations.direction_in.[].required") | Boolean | | | | Drop the packets that do not match any VLAN mapping. | + | [            from](## "port_channel_interfaces.[].switchport.vlan_translations.direction_in.[].from") | Integer | | | | VLAN ID or range of VLAN IDs to map from. | + | [            to](## "port_channel_interfaces.[].switchport.vlan_translations.direction_in.[].to") | Integer | | | | VLAN ID to map to. | + | [            dot1q_tunnel](## "port_channel_interfaces.[].switchport.vlan_translations.direction_in.[].dot1q_tunnel") | Boolean | | | | | + | [            inner_from](## "port_channel_interfaces.[].switchport.vlan_translations.direction_in.[].inner_from") | Integer | | | | Inner VLAN ID to map from. | + | [        direction_out](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out") | List, items: Dictionary | | | | Map egress packets only. | + | [          - from](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out.[].from") | Integer | Required | | | VLAN ID or range of VLAN IDs to map from. | + | [            to](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out.[].to") | Integer | | | | VLAN ID to map to. | + | [            dot1q_tunnel](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out.[].dot1q_tunnel") | Dictionary | | | | | + | [              all](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out.[].dot1q_tunnel.all") | Boolean | | | | | + | [              to](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out.[].dot1q_tunnel.to") | Integer | | | | VLAN ID or range(s) of VLAN IDs to map to. | + | [            inner_to](## "port_channel_interfaces.[].switchport.vlan_translations.direction_out.[].inner_to") | Integer | | | | Inner VLAN ID to map to. | + | [        direction_both](## "port_channel_interfaces.[].switchport.vlan_translations.direction_both") | List, items: Dictionary | | | | Map both egress and ingress packets. | + | [          - from](## "port_channel_interfaces.[].switchport.vlan_translations.direction_both.[].from") | Integer | Required | | | VLAN ID or range of VLAN IDs to map from. | + | [            to](## "port_channel_interfaces.[].switchport.vlan_translations.direction_both.[].to") | Integer | Required | | | VLAN ID to map to. | + | [            dot1q_tunnel](## "port_channel_interfaces.[].switchport.vlan_translations.direction_both.[].dot1q_tunnel") | Boolean | | | | | + | [            inner_from](## "port_channel_interfaces.[].switchport.vlan_translations.direction_both.[].inner_from") | Integer | | | | Inner VLAN ID to map from. | + | [            network](## "port_channel_interfaces.[].switchport.vlan_translations.direction_both.[].network") | Boolean | | | | Use network-side VLAN ID. | | [      vlan_forwarding_accept_all](## "port_channel_interfaces.[].switchport.vlan_forwarding_accept_all") | Boolean | | | | | | [      backup_link](## "port_channel_interfaces.[].switchport.backup_link") | Dictionary | | | | | | [        interface](## "port_channel_interfaces.[].switchport.backup_link.interface") | String | Required | | | Backup interface. Example - Ethernet4, Vlan10 etc. | @@ -842,12 +858,54 @@ # Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`. vlan_translations: - # VLAN ID or range of VLAN IDs to map from. - - from: + # Map ingress packets only. + direction_in: - # VLAN ID to map to. - to: - direction: + # Drop the packets that do not match any VLAN mapping. + - required: + + # VLAN ID or range of VLAN IDs to map from. + from: + + # VLAN ID to map to. + to: + dot1q_tunnel: + + # Inner VLAN ID to map from. + inner_from: + + # Map egress packets only. + direction_out: + + # VLAN ID or range of VLAN IDs to map from. + - from: + + # VLAN ID to map to. + to: + dot1q_tunnel: + all: + + # VLAN ID or range(s) of VLAN IDs to map to. + to: + + # Inner VLAN ID to map to. + inner_to: + + # Map both egress and ingress packets. + direction_both: + + # VLAN ID or range of VLAN IDs to map from. + - from: + + # VLAN ID to map to. + to: + dot1q_tunnel: + + # Inner VLAN ID to map from. + inner_from: + + # Use network-side VLAN ID. + network: vlan_forwarding_accept_all: backup_link: diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/ethernet-interfaces.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/ethernet-interfaces.j2 index 89abb74b829..60909216365 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/ethernet-interfaces.j2 +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/ethernet-interfaces.j2 @@ -208,6 +208,55 @@ interface {{ ethernet_interface.name }} {{ vlan_translation_cli }} {% endif %} {% endfor %} +{% for vlan_translation in ethernet_interface.switchport.vlan_translations.direction_both | arista.avd.natural_sort('from') %} +{% set vlan_translation_both_cli = 'switchport vlan translation' %} +{% if vlan_translation.from is arista.avd.defined and vlan_translation.to is arista.avd.defined %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' ' ~ vlan_translation.from %} +{% if vlan_translation.dot1q_tunnel is arista.avd.defined(true) %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' dot1q-tunnel' %} +{% elif vlan_translation.inner_from is arista.avd.defined %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' inner ' ~ vlan_translation.inner_from %} +{% if vlan_translation.network is arista.avd.defined(true) %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' network' %} +{% endif %} +{% endif %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' ' ~ vlan_translation.to %} +{% endif %} + {{ vlan_translation_both_cli }} +{% endfor %} +{% if ethernet_interface.switchport.vlan_translations.direction_in is arista.avd.defined %} +{% for vlan_translation in ethernet_interface.switchport.vlan_translations.direction_in %} +{% set vlan_translation_in_cli = 'switchport vlan translation in' %} +{% if vlan_translation.required is arista.avd.defined(true) %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ ' required' %} +{% elif vlan_translation.from is arista.avd.defined and vlan_translation.to is arista.avd.defined %} +{% set vlan_translation_in_cli = 'switchport vlan translation in ' ~ vlan_translation.from %} +{% if vlan_translation.dot1q_tunnel is arista.avd.defined(true) %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ ' dot1q-tunnel' %} +{% elif vlan_translation.inner_from is arista.avd.defined %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ ' inner ' ~ vlan_translation.inner_from %} +{% endif %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ " " ~ vlan_translation.to %} +{% endif %} + {{ vlan_translation_in_cli }} +{% endfor %} +{% endif %} +{% for vlan_translation in ethernet_interface.switchport.vlan_translations.direction_out | arista.avd.natural_sort('from') %} +{% if vlan_translation.from is arista.avd.defined and vlan_translation.to is arista.avd.defined %} +{% set vlan_translation_out_cli = 'switchport vlan translation out ' ~ vlan_translation.from ~ ' ' ~ vlan_translation.to %} +{% if vlan_translation.inner_to is arista.avd.defined %} +{% set vlan_translation_out_cli = vlan_translation_out_cli ~ ' inner ' ~ vlan_translation.inner_to %} +{% endif %} +{% elif vlan_translation.from is arista.avd.defined and vlan_translation.dot1q_tunnel is arista.avd.defined %} +{% set vlan_translation_out_cli = 'switchport vlan translation out ' ~ vlan_translation.from %} +{% if vlan_translation.dot1q_tunnel.all is arista.avd.defined(true) %} +{% set vlan_translation_out_cli = vlan_translation_out_cli ~ ' dot1q-tunnel all' %} +{% elif vlan_translation.dot1q_tunnel.to is arista.avd.defined %} +{% set vlan_translation_out_cli = vlan_translation_out_cli ~ ' dot1q-tunnel ' ~ vlan_translation.dot1q_tunnel.to %} +{% endif %} +{% endif %} + {{ vlan_translation_out_cli }} +{% endfor %} {% if ethernet_interface.switchport.trunk.private_vlan_secondary is arista.avd.defined(true) %} switchport trunk private-vlan secondary {% endif %} diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/port-channel-interfaces.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/port-channel-interfaces.j2 index 79c1a312cb1..29d301a80f3 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/port-channel-interfaces.j2 +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/port-channel-interfaces.j2 @@ -146,15 +146,54 @@ interface {{ port_channel_interface.name }} {% if port_channel_interface.switchport.source_interface is arista.avd.defined %} switchport source-interface {{ port_channel_interface.switchport.source_interface }} {% endif %} -{% for vlan_translation in port_channel_interface.switchport.vlan_translations | arista.avd.natural_sort('direction') %} +{% for vlan_translation in port_channel_interface.switchport.vlan_translations.direction_both | arista.avd.natural_sort('from') %} +{% set vlan_translation_both_cli = 'switchport vlan translation' %} {% if vlan_translation.from is arista.avd.defined and vlan_translation.to is arista.avd.defined %} -{% set vlan_translation_cli = 'switchport vlan translation' %} -{% if vlan_translation.direction | arista.avd.default in ['in', 'out'] %} -{% set vlan_translation_cli = vlan_translation_cli ~ ' ' ~ vlan_translation.direction %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' ' ~ vlan_translation.from %} +{% if vlan_translation.dot1q_tunnel is arista.avd.defined(true) %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' dot1q-tunnel' %} +{% elif vlan_translation.inner_from is arista.avd.defined %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' inner ' ~ vlan_translation.inner_from %} +{% if vlan_translation.network is arista.avd.defined(true) %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' network' %} +{% endif %} +{% endif %} +{% set vlan_translation_both_cli = vlan_translation_both_cli ~ ' ' ~ vlan_translation.to %} +{% endif %} + {{ vlan_translation_both_cli }} +{% endfor %} +{% if port_channel_interface.switchport.vlan_translations.direction_in is arista.avd.defined %} +{% for vlan_translation in port_channel_interface.switchport.vlan_translations.direction_in %} +{% set vlan_translation_in_cli = 'switchport vlan translation in' %} +{% if vlan_translation.required is arista.avd.defined(true) %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ ' required' %} +{% elif vlan_translation.from is arista.avd.defined and vlan_translation.to is arista.avd.defined %} +{% set vlan_translation_in_cli = 'switchport vlan translation in ' ~ vlan_translation.from %} +{% if vlan_translation.dot1q_tunnel is arista.avd.defined(true) %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ ' dot1q-tunnel' %} +{% elif vlan_translation.inner_from is arista.avd.defined %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ ' inner ' ~ vlan_translation.inner_from %} +{% endif %} +{% set vlan_translation_in_cli = vlan_translation_in_cli ~ " " ~ vlan_translation.to %} +{% endif %} + {{ vlan_translation_in_cli }} +{% endfor %} +{% endif %} +{% for vlan_translation in port_channel_interface.switchport.vlan_translations.direction_out | arista.avd.natural_sort('from') %} +{% if vlan_translation.from is arista.avd.defined and vlan_translation.to is arista.avd.defined %} +{% set vlan_translation_out_cli = 'switchport vlan translation out ' ~ vlan_translation.from ~ ' ' ~ vlan_translation.to %} +{% if vlan_translation.inner_to is arista.avd.defined %} +{% set vlan_translation_out_cli = vlan_translation_out_cli ~ ' inner ' ~ vlan_translation.inner_to %} +{% endif %} +{% elif vlan_translation.from is arista.avd.defined and vlan_translation.dot1q_tunnel is arista.avd.defined %} +{% set vlan_translation_out_cli = 'switchport vlan translation out ' ~ vlan_translation.from %} +{% if vlan_translation.dot1q_tunnel.all is arista.avd.defined(true) %} +{% set vlan_translation_out_cli = vlan_translation_out_cli ~ ' dot1q-tunnel all' %} +{% elif vlan_translation.dot1q_tunnel.to is arista.avd.defined %} +{% set vlan_translation_out_cli = vlan_translation_out_cli ~ ' dot1q-tunnel ' ~ vlan_translation.dot1q_tunnel.to %} {% endif %} -{% set vlan_translation_cli = vlan_translation_cli ~ ' ' ~ vlan_translation.from ~ ' ' ~ vlan_translation.to %} - {{ vlan_translation_cli }} {% endif %} + {{ vlan_translation_out_cli }} {% endfor %} {% if port_channel_interface.switchport.trunk.private_vlan_secondary is arista.avd.defined(true) %} switchport trunk private-vlan secondary diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.jsonschema.json b/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.jsonschema.json index 3d5100ac212..17e968291dd 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.jsonschema.json +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.jsonschema.json @@ -5857,41 +5857,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -16286,41 +16389,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { 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 422ffcb8f95..0a68d2691f6 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 @@ -3550,30 +3550,94 @@ keys: Warning: This should not be combined with `ethernet_interfaces[].pvlan_mapping`.' vlan_translations: description: 'Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`.' - type: list - primary_key: direction - items: - type: dict - keys: - from: - type: str - convert_types: - - int - description: VLAN ID or range of VLAN IDs to map from. - required: true - to: - type: int - convert_types: - - str - description: VLAN ID to map to. - required: true - direction: - type: str - valid_values: - - in - - out - - both - default: both + type: dict + keys: + direction_in: + type: list + description: Map ingress packets only. + items: + type: dict + keys: + required: + type: bool + description: Drop the packets that do not match any VLAN mapping. + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + direction_out: + type: list + description: Map egress packets only. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: dict + keys: + all: + type: bool + to: + type: int + convert_types: + - str + description: VLAN ID or range(s) of VLAN IDs to map to. + inner_to: + type: int + convert_types: + - str + description: Inner VLAN ID to map to. + direction_both: + type: list + description: Map both egress and ingress packets. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + required: true + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + network: + type: bool + description: Use network-side VLAN ID. vlan_forwarding_accept_all: type: bool backup_link: @@ -9678,30 +9742,94 @@ keys: Warning: This should not be combined with `port_channel_interfaces[].pvlan_mapping`.' vlan_translations: description: 'Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`.' - type: list - primary_key: direction - items: - type: dict - keys: - from: - type: str - convert_types: - - int - description: VLAN ID or range of VLAN IDs to map from. - required: true - to: - type: int - convert_types: - - str - description: VLAN ID to map to. - required: true - direction: - type: str - valid_values: - - in - - out - - both - default: both + type: dict + keys: + direction_in: + type: list + description: Map ingress packets only. + items: + type: dict + keys: + required: + type: bool + description: Drop the packets that do not match any VLAN mapping. + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + direction_out: + type: list + description: Map egress packets only. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: dict + keys: + all: + type: bool + to: + type: int + convert_types: + - str + description: VLAN ID or range(s) of VLAN IDs to map to. + inner_to: + type: int + convert_types: + - str + description: Inner VLAN ID to map to. + direction_both: + type: list + description: Map both egress and ingress packets. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + required: true + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + network: + type: bool + description: Use network-side VLAN ID. vlan_forwarding_accept_all: type: bool backup_link: diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/ethernet_interfaces.schema.yml b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/ethernet_interfaces.schema.yml index 9127c2f87ed..0b8d44120c6 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/ethernet_interfaces.schema.yml +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/ethernet_interfaces.schema.yml @@ -1527,27 +1527,94 @@ keys: vlan_translations: description: |- Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`. - type: list - primary_key: direction - items: - type: dict - keys: - from: - type: str - convert_types: - - int - description: VLAN ID or range of VLAN IDs to map from. - required: true - to: - type: int - convert_types: - - str - description: VLAN ID to map to. - required: true - direction: - type: str - valid_values: ["in", "out", "both"] - default: "both" + type: dict + keys: + direction_in: + type: list + description: Map ingress packets only. + items: + type: dict + keys: + required: + type: bool + description: Drop the packets that do not match any VLAN mapping. + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + direction_out: + type: list + description: Map egress packets only. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: dict + keys: + all: + type: bool + to: + type: int + convert_types: + - str + description: VLAN ID or range(s) of VLAN IDs to map to. + inner_to: + type: int + convert_types: + - str + description: Inner VLAN ID to map to. + direction_both: + type: list + description: Map both egress and ingress packets. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + required: true + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + network: + type: bool + description: Use network-side VLAN ID. vlan_forwarding_accept_all: type: bool backup_link: diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/port_channel_interfaces.schema.yml b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/port_channel_interfaces.schema.yml index 4bdb9945141..1eb94176198 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/port_channel_interfaces.schema.yml +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/port_channel_interfaces.schema.yml @@ -1000,27 +1000,94 @@ keys: vlan_translations: description: |- Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`. - type: list - primary_key: direction - items: - type: dict - keys: - from: - type: str - convert_types: - - int - description: VLAN ID or range of VLAN IDs to map from. - required: true - to: - type: int - convert_types: - - str - description: VLAN ID to map to. - required: true - direction: - type: str - valid_values: ["in", "out", "both"] - default: "both" + type: dict + keys: + direction_in: + type: list + description: Map ingress packets only. + items: + type: dict + keys: + required: + type: bool + description: Drop the packets that do not match any VLAN mapping. + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + direction_out: + type: list + description: Map egress packets only. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + dot1q_tunnel: + type: dict + keys: + all: + type: bool + to: + type: int + convert_types: + - str + description: VLAN ID or range(s) of VLAN IDs to map to. + inner_to: + type: int + convert_types: + - str + description: Inner VLAN ID to map to. + direction_both: + type: list + description: Map both egress and ingress packets. + items: + type: dict + keys: + from: + type: int + convert_types: + - str + description: VLAN ID or range of VLAN IDs to map from. + required: true + to: + type: int + convert_types: + - str + description: VLAN ID to map to. + required: true + dot1q_tunnel: + type: bool + inner_from: + type: int + convert_types: + - str + description: Inner VLAN ID to map from. + network: + type: bool + description: Use network-side VLAN ID. vlan_forwarding_accept_all: type: bool backup_link: diff --git a/python-avd/pyavd/_eos_designs/schema/eos_designs.jsonschema.json b/python-avd/pyavd/_eos_designs/schema/eos_designs.jsonschema.json index 722a991acd2..cbe4504e6d9 100644 --- a/python-avd/pyavd/_eos_designs/schema/eos_designs.jsonschema.json +++ b/python-avd/pyavd/_eos_designs/schema/eos_designs.jsonschema.json @@ -11417,41 +11417,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -14642,41 +14745,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -17800,41 +18006,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -24591,41 +24900,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -35020,41 +35432,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -53992,41 +54507,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `port_channel_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": { @@ -57150,41 +57768,144 @@ }, "vlan_translations": { "description": "Warning: This should not be combined with `ethernet_interfaces[].vlan_translations`.", - "type": "array", - "items": { - "type": "object", - "properties": { - "from": { - "type": "string", - "description": "VLAN ID or range of VLAN IDs to map from.", - "title": "From" - }, - "to": { - "type": "integer", - "description": "VLAN ID to map to.", - "title": "To" + "type": "object", + "properties": { + "direction_in": { + "type": "array", + "description": "Map ingress packets only.", + "items": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Drop the packets that do not match any VLAN mapping.", + "title": "Required" + }, + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } }, - "direction": { - "type": "string", - "enum": [ - "in", - "out", - "both" + "title": "Direction In" + }, + "direction_out": { + "type": "array", + "description": "Map egress packets only.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "object", + "properties": { + "all": { + "type": "boolean", + "title": "All" + }, + "to": { + "type": "integer", + "description": "VLAN ID or range(s) of VLAN IDs to map to.", + "title": "To" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "title": "Dot1Q Tunnel" + }, + "inner_to": { + "type": "integer", + "description": "Inner VLAN ID to map to.", + "title": "Inner To" + } + }, + "required": [ + "from" ], - "default": "both", - "title": "Direction" - } + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Out" }, - "required": [ - "from", - "to", - "direction" - ], - "additionalProperties": false, - "patternProperties": { - "^_.+$": {} + "direction_both": { + "type": "array", + "description": "Map both egress and ingress packets.", + "items": { + "type": "object", + "properties": { + "from": { + "type": "integer", + "description": "VLAN ID or range of VLAN IDs to map from.", + "title": "From" + }, + "to": { + "type": "integer", + "description": "VLAN ID to map to.", + "title": "To" + }, + "dot1q_tunnel": { + "type": "boolean", + "title": "Dot1Q Tunnel" + }, + "inner_from": { + "type": "integer", + "description": "Inner VLAN ID to map from.", + "title": "Inner From" + }, + "network": { + "type": "boolean", + "description": "Use network-side VLAN ID.", + "title": "Network" + } + }, + "required": [ + "from", + "to" + ], + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + } + }, + "title": "Direction Both" } }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, "title": "VLAN Translations" }, "vlan_forwarding_accept_all": {