Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(eos_designs): Improve custom python class API for interface descriptions #3311

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Copyright (c) 2023 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 functools import cached_property

from ansible_collections.arista.avd.plugins.plugin_utils.utils import get
from ansible_collections.arista.avd.roles.eos_designs.python_modules.interface_descriptions import AvdInterfaceDescriptions, InterfaceDescriptionData


class CustomAvdInterfaceDescriptions(AvdInterfaceDescriptions):
@cached_property
def _custom_description_prefix(self):
return get(self._hostvars, "description_prefix", "")

def underlay_ethernet_interface(self, data: InterfaceDescriptionData) -> str:
"""
Implementation using new data.

Available data:
- link_type
- peer
- peer_interface
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
link_peer = str(data.peer).upper()
if data.link_type == "underlay_p2p":
return f"{self._custom_description_prefix}_P2P_LINK_TO_{link_peer}_{data.peer_interface}"

if data.link_type == "underlay_l2":
return f"{self._custom_description_prefix}_{link_peer}_{data.peer_interface}"

return ""

def underlay_port_channel_interface(self, data: InterfaceDescriptionData) -> str:
"""
Implementation using new data.

Available data:
- peer
- peer_channel_group_id
- port_channel_description
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
if data.port_channel_description is not None:
link_channel_description = str(data.port_channel_description).upper()
return f"{self._custom_description_prefix}_{link_channel_description}_Po{data.peer_channel_group_id}"

link_peer = str(data.peer).upper()
return f"{self._custom_description_prefix}_{link_peer}_Po{data.peer_channel_group_id}"

def mlag_ethernet_interface(self, data: InterfaceDescriptionData) -> str:
"""
Implementation using new data.

Available data:
- peer_interface
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
return f"{self._custom_description_prefix}_MLAG_PEER_{data.mlag_peer}_{data.interface}"

def mlag_port_channel_interface(self, data: InterfaceDescriptionData) -> str:
"""
Implementation using new data.

Available data:
- mlag_peer
- peer_channel_group_id
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
return f"{self._custom_description_prefix}_MLAG_PEER_{data.mlag_peer}_Po{data.mlag_port_channel_id}"

def connected_endpoints_ethernet_interface(self, data: InterfaceDescriptionData) -> str:
"""
Implementation using new data.

Available data:
- peer
- peer_interface
- description
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
elements = [data.peer, data.peer_interface]
return "_".join([str(element) for element in elements if element is not None])

def connected_endpoints_port_channel_interface(self, data: InterfaceDescriptionData) -> str:
"""
Implementation using new data.

Available data:
- peer
- description
- port_channel_description
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
elements = [self._custom_description_prefix, data.peer, data.port_channel_description]
return "_".join([str(element) for element in elements if element is not None])

def router_id_loopback_interface(self, data: InterfaceDescriptionData) -> str:
"""
Available data:
- description
- mpls_overlay_role
- mpls_lsr
- overlay_routing_protocol
- type
"""
switch_type = str(data.type).upper()
return f"{self._custom_description_prefix}_EVPN_Overlay_Peering_{switch_type}"

def vtep_loopback_interface(self) -> str:
"""
Implementation of custom code similar to jinja.
TODO: AVD5.0.0 Update to use InterfaceDescriptionData
"""
switch_type = str(self.shared_utils.type).upper()
return f"{self._custom_description_prefix}_VTEP_VXLAN_Tunnel_Source_{switch_type}"
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@ node_type_keys:
type: spine
default_evpn_role: server
interface_descriptions:
# Override interface description templates with our custom templates
underlay_ethernet_interfaces: 'custom_templates/interface_descriptions/underlay/ethernet-interfaces.j2'
chetryan marked this conversation as resolved.
Show resolved Hide resolved
underlay_port_channel_interfaces: 'custom_templates/interface_descriptions/underlay/port-channel-interfaces.j2'
mlag_ethernet_interfaces: 'custom_templates/interface_descriptions/mlag/ethernet-interfaces.j2'
mlag_port_channel_interfaces: 'custom_templates/interface_descriptions/mlag/port-channel-interfaces.j2'
connected_endpoints_ethernet_interfaces: 'custom_templates/interface_descriptions/connected_endpoints/ethernet-interfaces.j2'
connected_endpoints_port_channel_interfaces: 'custom_templates/interface_descriptions/connected_endpoints/port-channel-interfaces.j2'
tgodaA marked this conversation as resolved.
Show resolved Hide resolved
overlay_loopback_interface: 'custom_templates/interface_descriptions/loopbacks/overlay-loopback.j2'
vtep_loopback_interface: 'custom_templates/interface_descriptions/loopbacks/vtep-loopback.j2'
# Override default interface description with a custom python module
python_module: custom_interface_descriptions
python_class_name: CustomAvdInterfaceDescriptions

- key: l3leaf
type: l3leaf
connected_endpoints: true
Expand All @@ -31,8 +26,8 @@ node_type_keys:
python_class_name: CustomAvdIpAddressing

interface_descriptions:
# Override default interface description with a custom python module
python_module: custom_interface_descriptions
# Override default interface description with a custom python module using the new api with InterfaceDescriptionData object.
python_module: custom_interface_descriptions_with_data
python_class_name: CustomAvdInterfaceDescriptions

ip_offset_10: 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_null_from_data
from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get, replace_or_append_item

from ..interface_descriptions import InterfaceDescriptionData
from .utils import UtilsMixin


Expand Down Expand Up @@ -112,7 +113,15 @@ def _get_ethernet_interface_cfg(self, adapter: dict, node_index: int, connected_
"peer_interface": peer_interface,
"peer_type": connected_endpoint["type"],
"port_profile": adapter.get("profile"),
"description": self.shared_utils.interface_descriptions.connected_endpoints_ethernet_interfaces(peer, peer_interface, interface_description),
"description": self.shared_utils.interface_descriptions.connected_endpoints_ethernet_interface(
InterfaceDescriptionData(
shared_utils=self.shared_utils,
interface=adapter["switch_ports"][node_index],
peer=peer,
peer_interface=peer_interface,
description=interface_description,
)
),
"speed": adapter.get("speed"),
"shutdown": not adapter.get("enabled", True),
"eos_cli": adapter.get("raw_eos_cli"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_null_from_data
from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get

from ..interface_descriptions import InterfaceDescriptionData
from .utils import UtilsMixin


Expand Down Expand Up @@ -124,8 +125,14 @@ def _get_port_channel_interface_cfg(self, adapter: dict, port_channel_interface_
# Common port_channel_interface settings
port_channel_interface = {
"name": port_channel_interface_name,
"description": self.shared_utils.interface_descriptions.connected_endpoints_port_channel_interfaces(
peer, adapter_description, adapter_port_channel_description
"description": self.shared_utils.interface_descriptions.connected_endpoints_port_channel_interface(
InterfaceDescriptionData(
shared_utils=self.shared_utils,
interface=port_channel_interface_name,
peer=peer,
description=adapter_description,
port_channel_description=adapter_port_channel_description,
)
),
"type": port_channel_type,
"shutdown": not get(adapter, "port_channel.enabled", default=True),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
from .avdinterfacedescriptions import AvdInterfaceDescriptions
from .models import InterfaceDescriptionData

__all__ = ["AvdInterfaceDescriptions"]
__all__ = ["AvdInterfaceDescriptions", "InterfaceDescriptionData"]
Loading