From 765f599186cd95e4f21978cd0d2073ec7a72c464 Mon Sep 17 00:00:00 2001 From: Claus Holbech Date: Mon, 17 Jun 2024 17:02:05 +0200 Subject: [PATCH] Refactor(eos_designs): Move eos_designs Python modules to PyAVD (#4120) --- .pre-commit-config.yaml | 11 +- .../eos_designs_internal_notes.md | 13 +- .../yaml_templates_to_facts.md | 2 +- .../inventory/host_vars/missing-mlag-peer.yml | 5 +- .../custom_interface_descriptions.py | 2 + ...custom_interface_descriptions_with_data.py | 2 + .../custom_modules/custom_ip_addressing.py | 1 + .../configs/UNDERLAY-MULTICAST-L3LEAF2B.cfg | 2 +- .../UNDERLAY-MULTICAST-L3LEAF2B.yml | 2 +- .../avd/plugins/action/eos_designs_facts.py | 6 +- .../action/eos_designs_structured_config.py | 17 ++- .../plugins/action/yaml_templates_to_facts.py | 2 +- .../modules/yaml_templates_to_facts.py | 2 +- .../eos_designs_facts/MOVED_TO_PYAVD.txt | 1 + .../eos_designs_shared_utils/shared_utils.py | 2 +- .../plugins/plugin_utils/utils/template.py | 11 +- ansible_collections/arista/avd/pylintrc | 131 ++++++++++++++++++ .../python_modules/MOVED_TO_PYAVD.txt | 1 + .../python_modules/base/__init__.py | 6 - .../connected_endpoints/__init__.py | 6 - .../core_interfaces_and_l3_edge/__init__.py | 6 - .../__init__.py | 6 - .../python_modules/flows/__init__.py | 6 - .../get_structured_config/__init__.py | 6 - .../inband_management/__init__.py | 6 - .../interface_descriptions/__init__.py | 17 ++- .../python_modules/ip_addressing/__init__.py | 15 +- .../python_modules/metadata/__init__.py | 6 - .../python_modules/mlag/__init__.py | 6 - .../network_services/__init__.py | 6 - .../python_modules/overlay/__init__.py | 6 - .../python_modules/underlay/__init__.py | 6 - pylintrc | 104 +------------- python-avd/Makefile | 7 +- python-avd/pyavd/_eos_designs/__init__.py | 3 + .../eos_designs_facts/__init__.py | 3 +- .../_eos_designs/eos_designs_facts/overlay.py | 3 +- .../_eos_designs/eos_designs_facts/uplinks.py | 12 +- .../_eos_designs/eos_designs_facts/vlans.py | 10 +- .../interface_descriptions/__init__.py | 8 +- .../interface_descriptions/models.py | 2 +- .../interface_descriptions/utils.py | 15 +- .../_eos_designs/ip_addressing/__init__.py | 43 +++--- .../_eos_designs}/ip_addressing/utils.py | 50 +++---- .../structured_config/__init__.py | 37 +++-- .../structured_config/base/__init__.py | 27 ++-- .../structured_config}/base/ntp.py | 13 +- .../structured_config}/base/snmp_server.py | 36 ++--- .../structured_config}/base/utils.py | 15 +- .../connected_endpoints/__init__.py | 3 +- .../ethernet_interfaces.py | 21 +-- .../connected_endpoints/monitor_sessions.py | 17 ++- .../port_channel_interfaces.py | 31 +++-- .../connected_endpoints/utils.py | 47 ++++--- .../core_interfaces_and_l3_edge/__init__.py | 3 +- .../ethernet_interfaces.py | 9 +- .../port_channel_interfaces.py | 7 +- .../core_interfaces_and_l3_edge/router_bgp.py | 11 +- .../router_ospf.py | 6 +- .../core_interfaces_and_l3_edge/utils.py | 39 +++--- .../__init__.py | 4 +- .../structured_config/flows/__init__.py | 12 +- .../inband_management/__init__.py | 14 +- .../structured_config/metadata/__init__.py | 5 +- .../metadata/cv_pathfinder.py | 6 +- .../structured_config}/metadata/cv_tags.py | 8 +- .../structured_config/mlag/__init__.py | 11 +- .../network_services/__init__.py | 3 +- .../application_traffic_recognition.py | 19 +-- .../network_services/dps_interfaces.py | 10 +- .../network_services/eos_cli.py | 9 +- .../network_services/ethernet_interfaces.py | 13 +- .../network_services/ip_access_lists.py | 11 +- .../network_services/ip_igmp_snooping.py | 13 +- .../network_services/ip_nat.py | 6 +- .../network_services/ip_security.py | 11 +- .../ip_virtual_router_mac_address.py | 6 +- .../network_services/ipv6_static_routes.py | 6 +- .../network_services/loopback_interfaces.py | 13 +- .../network_services/metadata.py | 11 +- .../network_services/monitor_connectivity.py | 11 +- .../network_services/patch_panel.py | 11 +- .../port_channel_interfaces.py | 17 ++- .../network_services/prefix_lists.py | 13 +- .../network_services/route_maps.py | 25 ++-- .../router_adaptive_virtual_topology.py | 17 ++- .../network_services/router_bgp.py | 114 +++++++-------- .../network_services/router_internet_exit.py | 9 +- .../network_services/router_isis.py | 6 +- .../network_services/router_multicast.py | 10 +- .../network_services/router_ospf.py | 11 +- .../network_services/router_path_selection.py | 15 +- .../router_pim_sparse_mode.py | 10 +- .../router_service_insertion.py | 6 +- .../network_services/spanning_tree.py | 12 +- .../network_services/standard_access_lists.py | 9 +- .../network_services/static_routes.py | 6 +- .../network_services/struct_cfgs.py | 12 +- .../network_services/tunnel_interfaces.py | 9 +- .../network_services/utils.py | 109 ++++++++------- .../network_services/utils_zscaler.py | 24 ++-- .../virtual_source_nat_vrfs.py | 12 +- .../network_services/vlan_interfaces.py | 17 ++- .../network_services/vlans.py | 13 +- .../network_services/vrfs.py | 11 +- .../network_services/vxlan_interface.py | 31 ++--- .../structured_config/overlay/__init__.py | 3 +- .../structured_config}/overlay/cvx.py | 11 +- .../overlay/ip_extcommunity_lists.py | 6 +- .../structured_config}/overlay/ip_security.py | 23 +-- .../overlay/management_cvx.py | 9 +- .../overlay/management_security.py | 6 +- .../structured_config}/overlay/route_maps.py | 9 +- .../router_adaptive_virtual_topology.py | 6 +- .../structured_config}/overlay/router_bfd.py | 9 +- .../structured_config}/overlay/router_bgp.py | 47 ++++--- .../overlay/router_path_selection.py | 33 +++-- .../overlay/router_traffic_engineering.py | 6 +- .../structured_config}/overlay/stun.py | 9 +- .../structured_config}/overlay/utils.py | 53 ++++--- .../structured_config/underlay/__init__.py | 3 +- .../structured_config}/underlay/agents.py | 6 +- .../structured_config}/underlay/as_path.py | 6 +- .../underlay/ethernet_interfaces.py | 15 +- .../underlay/ip_access_lists.py | 11 +- .../underlay/loopback_interfaces.py | 15 +- .../structured_config}/underlay/mpls.py | 6 +- .../underlay/port_channel_interfaces.py | 17 ++- .../underlay/prefix_lists.py | 8 +- .../structured_config}/underlay/route_maps.py | 6 +- .../structured_config}/underlay/router_bgp.py | 14 +- .../underlay/router_isis.py | 15 +- .../underlay/router_msdp.py | 13 +- .../underlay/router_ospf.py | 9 +- .../underlay/router_pim_sparse_mode.py | 9 +- .../underlay/standard_access_lists.py | 6 +- .../underlay/static_routes.py | 9 +- .../structured_config}/underlay/utils.py | 38 +++-- .../structured_config}/underlay/vlans.py | 13 +- .../pyavd/get_device_structured_config.py | 2 +- .../schema_tools/generate_docs/tablerowgen.py | 4 +- .../test_validate_structured_config.py | 2 +- .../pyavd/eos_designs/test_get_avd_facts.py | 6 +- .../test_validate_structured_config.py | 2 +- .../metaschema/test_meta_schema_model.py | 2 +- python-avd/tests/utils.py | 2 +- python-avd/vendor_overrides/schema/store.py | 2 +- python-avd/vendor_overrides/utils/template.py | 10 -- 148 files changed, 1173 insertions(+), 938 deletions(-) create mode 100644 ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/MOVED_TO_PYAVD.txt create mode 100644 ansible_collections/arista/avd/pylintrc create mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/MOVED_TO_PYAVD.txt delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/base/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/__init__.py delete mode 100644 ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/__init__.py create mode 100644 python-avd/pyavd/_eos_designs/__init__.py rename ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/avdinterfacedescriptions.py => python-avd/pyavd/_eos_designs/interface_descriptions/__init__.py (98%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs}/interface_descriptions/models.py (96%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs}/interface_descriptions/utils.py (76%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/avdipaddressing.py => python-avd/pyavd/_eos_designs/ip_addressing/__init__.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs}/ip_addressing/utils.py (78%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py => python-avd/pyavd/_eos_designs/structured_config/__init__.py (74%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/base/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/base/__init__.py (97%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/base/ntp.py (91%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/base/snmp_server.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/base/utils.py (83%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/__init__.py (94%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/connected_endpoints/ethernet_interfaces.py (92%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/connected_endpoints/monitor_sessions.py (91%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/connected_endpoints/port_channel_interfaces.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/connected_endpoints/utils.py (85%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/__init__.py (95%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/core_interfaces_and_l3_edge/ethernet_interfaces.py (89%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/core_interfaces_and_l3_edge/port_channel_interfaces.py (84%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/core_interfaces_and_l3_edge/router_bgp.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/core_interfaces_and_l3_edge/router_ospf.py (85%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/core_interfaces_and_l3_edge/utils.py (90%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/custom_structured_configuration/__init__.py (97%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/flows/__init__.py (95%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/inband_management/__init__.py (94%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/metadata/__init__.py (93%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/metadata/cv_pathfinder.py (97%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/metadata/cv_tags.py (96%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/mlag/__init__.py (97%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/network_services/__init__.py (98%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/application_traffic_recognition.py (95%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/dps_interfaces.py (78%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/eos_cli.py (83%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ethernet_interfaces.py (97%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ip_access_lists.py (83%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ip_igmp_snooping.py (91%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ip_nat.py (86%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ip_security.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ip_virtual_router_mac_address.py (80%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/ipv6_static_routes.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/loopback_interfaces.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/metadata.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/monitor_connectivity.py (88%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/patch_panel.py (94%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/port_channel_interfaces.py (92%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/prefix_lists.py (89%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/route_maps.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_adaptive_virtual_topology.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_bgp.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_internet_exit.py (91%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_isis.py (85%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_multicast.py (81%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_ospf.py (93%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_path_selection.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_pim_sparse_mode.py (82%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/router_service_insertion.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/spanning_tree.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/standard_access_lists.py (89%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/static_routes.py (94%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/struct_cfgs.py (86%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/tunnel_interfaces.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/utils.py (89%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/utils_zscaler.py (80%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/virtual_source_nat_vrfs.py (88%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/vlan_interfaces.py (93%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/vlans.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/vrfs.py (89%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/network_services/vxlan_interface.py (92%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/overlay/__init__.py (96%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/cvx.py (86%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/ip_extcommunity_lists.py (86%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/ip_security.py (84%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/management_cvx.py (85%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/management_security.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/route_maps.py (93%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/router_adaptive_virtual_topology.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/router_bfd.py (77%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/router_bgp.py (93%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/router_path_selection.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/router_traffic_engineering.py (78%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/stun.py (84%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/overlay/utils.py (85%) rename ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/avdstructuredconfig.py => python-avd/pyavd/_eos_designs/structured_config/underlay/__init__.py (96%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/agents.py (82%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/as_path.py (87%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/ethernet_interfaces.py (96%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/ip_access_lists.py (78%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/loopback_interfaces.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/mpls.py (86%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/port_channel_interfaces.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/prefix_lists.py (93%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/route_maps.py (96%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/router_bgp.py (95%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/router_isis.py (92%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/router_msdp.py (85%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/router_ospf.py (90%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/router_pim_sparse_mode.py (91%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/standard_access_lists.py (89%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/static_routes.py (88%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/utils.py (92%) rename {ansible_collections/arista/avd/roles/eos_designs/python_modules => python-avd/pyavd/_eos_designs/structured_config}/underlay/vlans.py (88%) delete mode 100644 python-avd/vendor_overrides/utils/template.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a7444315ae0..f279081ec4c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -105,12 +105,21 @@ repos: rev: "v3.1.1" hooks: - id: pylint # Use pylintrc file in repository - name: Check for Linting errors on Python files with settings defined in `pylintrc`. + name: Check for Linting errors on Python files outside the Ansible collection. description: This hook runs pylint. types: [python] args: # Suppress duplicate code for modules header - -d duplicate-code + - id: pylint # Use pylintrc file in Ansible collection + name: Check for Linting errors on Python files in the Ansible collection. + description: This hook runs pylint. + types: [python] + files: ansible_collections/arista/avd/ + args: + - --rcfile=ansible_collections/arista/avd/pylintrc + # Suppress duplicate code for modules header + - -d duplicate-code - repo: https://github.com/adrienverge/yamllint.git rev: "v1.35.1" diff --git a/ansible_collections/arista/avd/docs/contribution/eos_designs_internal_notes.md b/ansible_collections/arista/avd/docs/contribution/eos_designs_internal_notes.md index 683434febbd..c571e3bd590 100644 --- a/ansible_collections/arista/avd/docs/contribution/eos_designs_internal_notes.md +++ b/ansible_collections/arista/avd/docs/contribution/eos_designs_internal_notes.md @@ -230,18 +230,7 @@ which at the time where `eos_designs_structured_config` run, is a nested `dict`. Subclasses are typically using Mixin classes to split all the attributes/`cached_properties` into manageable files. -Source code: - -- [AvdStructuredConfigBase](../../roles/eos_designs/python_modules/base/__init__.py) - (Unfortunate naming. Base here refers to base configurations. Not a Base class.) -- [AvdStructuredConfigConnectedEndpoints](../../roles/eos_designs/python_modules/connected_endpoints/__init__.py) -- [AvdStructuredConfigCoreInterfacesAndL3Edge](../../roles/eos_designs/python_modules/core_interfaces_and_l3_edge/__init__.py) -- [AvdStructuredConfigCustomStructuredConfiguration](../../roles/eos_designs/python_modules/custom_structured_configuration/__init__.py) -- [AvdStructuredConfigInbandManagement](../../roles/eos_designs/python_modules/inband_management/__init__.py) -- [AvdStructuredConfigMlag](../../roles/eos_designs/python_modules/mlag/__init__.py) -- [AvdStructuredConfigNetworkServices](../../roles/eos_designs/python_modules/network_services/__init__.py) -- [AvdStructuredConfigOverlay](../../roles/eos_designs/python_modules/overlay/__init__.py) -- [AvdStructuredConfigUnderlay](../../roles/eos_designs/python_modules/underlay/__init__.py) +See the source code [here](https://github.com/aristanetworks/avd/tree/devel/python-avd/pyavd/_eos_designs/structured_config) ```mermaid classDiagram diff --git a/ansible_collections/arista/avd/docs/plugins/Modules_and_action_plugins/yaml_templates_to_facts.md b/ansible_collections/arista/avd/docs/plugins/Modules_and_action_plugins/yaml_templates_to_facts.md index 53772f46228..bcf7abac5ca 100644 --- a/ansible_collections/arista/avd/docs/plugins/Modules_and_action_plugins/yaml_templates_to_facts.md +++ b/ansible_collections/arista/avd/docs/plugins/Modules_and_action_plugins/yaml_templates_to_facts.md @@ -51,7 +51,7 @@ Set facts from YAML produced by Jinja2 templates arista.avd.yaml_templates_to_facts: root_key: structured_config templates: - - python_module: "ansible_collections.arista.avd.roles.eos_designs.python_modules.base" + - python_module: "pyavd._eos_designs.structured_config.base" python_class_name: "AvdStructuredConfig" - template: "mlag/main.j2" - template: "designs/underlay/main.j2" diff --git a/ansible_collections/arista/avd/molecule/eos_designs_negative_unit_tests/inventory/host_vars/missing-mlag-peer.yml b/ansible_collections/arista/avd/molecule/eos_designs_negative_unit_tests/inventory/host_vars/missing-mlag-peer.yml index f6d38a7b288..d40d204ca60 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_negative_unit_tests/inventory/host_vars/missing-mlag-peer.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_negative_unit_tests/inventory/host_vars/missing-mlag-peer.yml @@ -12,4 +12,7 @@ l2leaf: - name: some-missing-device id: 2 -expected_error_message: "Facts not found for node 'some-missing-device'. Something in the input vars is pointing to this node. Check that 'some-missing-device' is in the inventory and is part of the group set by 'fabric_name'. Node is required but was not found for host 'missing-mlag-peer'" +expected_error_message: >- + Facts not found for node 'some-missing-device'. Something in the input vars is pointing to this node. + Check that 'some-missing-device' is in the inventory and is part of the group set by 'fabric_name'. + Node is required but was not found for host 'missing-mlag-peer' diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions.py b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions.py index 5fedd2a1b8f..b321344e92d 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions.py +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions.py @@ -4,6 +4,8 @@ from functools import cached_property from ansible_collections.arista.avd.plugins.plugin_utils.utils import get + +# TODO: AVD5.0 change this to import from PyAVD instead and remove the python_modules folder. from ansible_collections.arista.avd.roles.eos_designs.python_modules.interface_descriptions import AvdInterfaceDescriptions diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions_with_data.py b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions_with_data.py index bdc057f3c6c..fba12068886 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions_with_data.py +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_interface_descriptions_with_data.py @@ -4,6 +4,8 @@ from functools import cached_property from ansible_collections.arista.avd.plugins.plugin_utils.utils import get + +# TODO: AVD5.0 change this to import from PyAVD instead and remove the python_modules folder. from ansible_collections.arista.avd.roles.eos_designs.python_modules.interface_descriptions import AvdInterfaceDescriptions, InterfaceDescriptionData diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_ip_addressing.py b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_ip_addressing.py index db38f031e0b..a19d844d781 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_ip_addressing.py +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/custom_modules/custom_ip_addressing.py @@ -3,6 +3,7 @@ # that can be found in the LICENSE file. from functools import cached_property +# TODO: AVD5.0 change this to import from PyAVD instead and remove the python_modules folder. from ansible_collections.arista.avd.roles.eos_designs.python_modules.ip_addressing import AvdIpAddressing diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/UNDERLAY-MULTICAST-L3LEAF2B.cfg b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/UNDERLAY-MULTICAST-L3LEAF2B.cfg index b798f2e6906..c7cacc2596b 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/UNDERLAY-MULTICAST-L3LEAF2B.cfg +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/configs/UNDERLAY-MULTICAST-L3LEAF2B.cfg @@ -191,7 +191,7 @@ router pim sparse-mode router msdp originator-id local-interface Loopback0 ! - peer 192.168.255.6 + peer 192.168.255.5 mesh-group ANYCAST-RP local-interface Loopback0 description UNDERLAY-MULTICAST-L3LEAF2A diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/UNDERLAY-MULTICAST-L3LEAF2B.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/UNDERLAY-MULTICAST-L3LEAF2B.yml index 8236f9e3068..a0f5a1c1d20 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/UNDERLAY-MULTICAST-L3LEAF2B.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/intended/structured_configs/UNDERLAY-MULTICAST-L3LEAF2B.yml @@ -220,7 +220,7 @@ prefix_lists: router_msdp: originator_id_local_interface: Loopback0 peers: - - ipv4_address: 192.168.255.6 + - ipv4_address: 192.168.255.5 local_interface: Loopback0 description: UNDERLAY-MULTICAST-L3LEAF2A mesh_groups: diff --git a/ansible_collections/arista/avd/plugins/action/eos_designs_facts.py b/ansible_collections/arista/avd/plugins/action/eos_designs_facts.py index 52dce386dc3..57ccee3dd6b 100644 --- a/ansible_collections/arista/avd/plugins/action/eos_designs_facts.py +++ b/ansible_collections/arista/avd/plugins/action/eos_designs_facts.py @@ -3,8 +3,6 @@ # that can be found in the LICENSE file. from __future__ import absolute_import, division, print_function -from ansible_collections.arista.avd.plugins.plugin_utils.pyavd_wrappers import RaiseOnUse - __metaclass__ = type import cProfile @@ -15,6 +13,7 @@ from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError +from ansible_collections.arista.avd.plugins.plugin_utils.pyavd_wrappers import RaiseOnUse from ansible_collections.arista.avd.plugins.plugin_utils.schema.avdschematools import AvdSchemaTools from ansible_collections.arista.avd.plugins.plugin_utils.utils import get_templar @@ -22,6 +21,7 @@ try: from pyavd._eos_designs.eos_designs_facts import EosDesignsFacts + from pyavd.vendor.errors.errors import AristaAvdMissingVariableError as PyavdMissingVariableError except ImportError as e: EosDesignsFacts = RaiseOnUse( AnsibleActionFail( @@ -204,7 +204,7 @@ def render_avd_switch_facts(self, avd_switch_facts_instances: dict): for host in avd_switch_facts_instances: try: rendered_facts[host] = {"switch": avd_switch_facts_instances[host]["switch"].render()} - except AristaAvdMissingVariableError as e: + except (AristaAvdMissingVariableError, PyavdMissingVariableError) as e: raise AnsibleActionFail(f"{e} is required but was not found for host '{host}'") from e # If the argument 'template_output' is set, run the output data through jinja2 rendering. diff --git a/ansible_collections/arista/avd/plugins/action/eos_designs_structured_config.py b/ansible_collections/arista/avd/plugins/action/eos_designs_structured_config.py index c00adc02081..22ef1daa640 100644 --- a/ansible_collections/arista/avd/plugins/action/eos_designs_structured_config.py +++ b/ansible_collections/arista/avd/plugins/action/eos_designs_structured_config.py @@ -15,11 +15,22 @@ from ansible.plugins.action import ActionBase, display from ansible_collections.arista.avd.plugins.plugin_utils.merge import merge +from ansible_collections.arista.avd.plugins.plugin_utils.pyavd_wrappers import RaiseOnUse from ansible_collections.arista.avd.plugins.plugin_utils.schema.avdschematools import AvdSchemaTools 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 get, get_templar from ansible_collections.arista.avd.plugins.plugin_utils.utils import template as templater -from ansible_collections.arista.avd.roles.eos_designs.python_modules.get_structured_config import get_structured_config + +PLUGIN_NAME = "arista.avd.eos_designs_structured_config" +try: + from pyavd._eos_designs.structured_config import get_structured_config +except ImportError as e: + get_structured_config = RaiseOnUse( + AnsibleActionFail( + f"The '{PLUGIN_NAME}' plugin requires the 'pyavd' Python library. Got import error", + orig_exc=e, + ) + ) class ActionModule(ActionBase): @@ -79,7 +90,7 @@ def run(self, tmp=None, task_vars=None): plugin_name="arista.avd.eos_cli_config_gen", ) - # Get Structured Config from builtin eos_designs python_modules + # Get Structured Config from modules in PyAVD using internal api so we can supply our own templar try: output = get_structured_config( vars=dict(task_vars), @@ -101,7 +112,7 @@ def run(self, tmp=None, task_vars=None): # Any var assignments will end up in output, so all other objects are protected. template_vars = ChainMap(output, task_vars) - # eos_designs_custom_templates can contain a list of jinja templates to run after the builtin eos_designs python_modules + # eos_designs_custom_templates can contain a list of jinja templates to run after PyAVD for template_item in eos_designs_custom_templates: template_options = template_item.get("options", {}) list_merge = template_options.get("list_merge", "append_rp") diff --git a/ansible_collections/arista/avd/plugins/action/yaml_templates_to_facts.py b/ansible_collections/arista/avd/plugins/action/yaml_templates_to_facts.py index d11d8475686..a5d494c81b4 100644 --- a/ansible_collections/arista/avd/plugins/action/yaml_templates_to_facts.py +++ b/ansible_collections/arista/avd/plugins/action/yaml_templates_to_facts.py @@ -147,7 +147,7 @@ def run(self, tmp=None, task_vars=None): if debug: avd_yaml_templates_to_facts_debug = task_vars.get("avd_yaml_templates_to_facts_debug", []) - # template_list can contain templates or python_modules + # template_list can contain templates or python modules for template_item in template_list: if debug: debug_item = template_item diff --git a/ansible_collections/arista/avd/plugins/modules/yaml_templates_to_facts.py b/ansible_collections/arista/avd/plugins/modules/yaml_templates_to_facts.py index 07cc287a9cd..524768179cc 100644 --- a/ansible_collections/arista/avd/plugins/modules/yaml_templates_to_facts.py +++ b/ansible_collections/arista/avd/plugins/modules/yaml_templates_to_facts.py @@ -131,7 +131,7 @@ arista.avd.yaml_templates_to_facts: root_key: structured_config templates: - - python_module: "ansible_collections.arista.avd.roles.eos_designs.python_modules.base" + - python_module: "pyavd._eos_designs.structured_config.base" python_class_name: "AvdStructuredConfig" - template: "mlag/main.j2" - template: "designs/underlay/main.j2" diff --git a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/MOVED_TO_PYAVD.txt b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/MOVED_TO_PYAVD.txt new file mode 100644 index 00000000000..b0177c5e71c --- /dev/null +++ b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_facts/MOVED_TO_PYAVD.txt @@ -0,0 +1 @@ +The eos_designs_facts Python module has been moved to PyAVD in the folder /python-avd/pyavd/_eos_designs/eos_designs_facts/ diff --git a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/shared_utils.py b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/shared_utils.py index 56229d4f516..60ce02a2049 100644 --- a/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/shared_utils.py +++ b/ansible_collections/arista/avd/plugins/plugin_utils/eos_designs_shared_utils/shared_utils.py @@ -52,7 +52,7 @@ class SharedUtils( FlowTrackingMixin, ): """ - Class with commonly used methods / cached_properties to be shared between all the python_modules + Class with commonly used methods / cached_properties to be shared between all the python modules loaded in eos_designs. This class is instantiated in 'EosDesignsFacts' class and set as 'shared_utils' property. diff --git a/ansible_collections/arista/avd/plugins/plugin_utils/utils/template.py b/ansible_collections/arista/avd/plugins/plugin_utils/utils/template.py index 49fb4e88da8..814c02353c6 100644 --- a/ansible_collections/arista/avd/plugins/plugin_utils/utils/template.py +++ b/ansible_collections/arista/avd/plugins/plugin_utils/utils/template.py @@ -1,9 +1,6 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from ansible.module_utils._text import to_text - - def template(template_file, template_vars, templar): """ Run Ansible Templar with template file. @@ -30,6 +27,14 @@ def template(template_file, template_vars, templar): str The rendered template """ + if templar is None: + raise NotImplementedError("Jinja Templating is not implemented in pyavd") + + # We only get here when running from Ansible, so it is safe to import from ansible. + # pylint: disable=import-outside-toplevel + from ansible.module_utils._text import to_text + + # pylint: enable=import-outside-toplevel dataloader = templar._loader searchpath = templar.environment.loader.searchpath diff --git a/ansible_collections/arista/avd/pylintrc b/ansible_collections/arista/avd/pylintrc new file mode 100644 index 00000000000..488ddd038aa --- /dev/null +++ b/ansible_collections/arista/avd/pylintrc @@ -0,0 +1,131 @@ +# Configuration applied to collection by ansible-test +# https://github.com/ansible/ansible/blob/devel/test/lib/ansible_test/_data/sanity/pylint/config/collection.cfg + +[MASTER] +ignore-paths= + # The cv_client api is generated from proto files, so it should not be linted. + plugins/plugin_utils/cv_client/api/ + +[MESSAGES CONTROL] +disable= + abstract-method, + access-member-before-definition, + arguments-differ, + assignment-from-no-return, + assignment-from-none, + attribute-defined-outside-init, + bad-indentation, + bad-mcs-classmethod-argument, + broad-except, + c-extension-no-member, + cell-var-from-loop, + chained-comparison, + comparison-with-callable, + consider-iterating-dictionary, + consider-merging-isinstance, + consider-using-dict-comprehension, + consider-using-enumerate, + consider-using-get, + consider-using-in, + consider-using-set-comprehension, + consider-using-ternary, + deprecated-method, + deprecated-module, + eval-used, + exec-used, + expression-not-assigned, + fixme, + function-redefined, + global-statement, + global-variable-undefined, + import-error, + import-self, + inconsistent-return-statements, + invalid-envvar-default, + invalid-name, + invalid-sequence-index, + keyword-arg-before-vararg, + len-as-condition, + line-too-long, + literal-comparison, + locally-disabled, + method-hidden, + missing-docstring, + no-else-raise, + no-else-return, + no-member, + no-name-in-module, + no-value-for-parameter, + non-iterator-returned, + not-a-mapping, + not-an-iterable, + not-callable, + pointless-statement, + pointless-string-statement, + possibly-unused-variable, + protected-access, + redefined-argument-from-local, + redefined-builtin, + redefined-outer-name, + reimported, + relative-beyond-top-level, # https://github.com/PyCQA/pylint/issues/2967 + signature-differs, + simplifiable-if-expression, + simplifiable-if-statement, + subprocess-popen-preexec-fn, + super-init-not-called, + superfluous-parens, + too-few-public-methods, + too-many-ancestors, + too-many-arguments, + too-many-boolean-expressions, + too-many-branches, + too-many-function-args, + too-many-instance-attributes, + too-many-lines, + too-many-locals, + too-many-nested-blocks, + too-many-public-methods, + too-many-return-statements, + too-many-statements, + trailing-comma-tuple, + trailing-comma-tuple, + try-except-raise, + unbalanced-tuple-unpacking, + undefined-loop-variable, + unexpected-keyword-arg, + ungrouped-imports, + unidiomatic-typecheck, + unnecessary-pass, + unsubscriptable-object, + unsupported-assignment-operation, + unsupported-delete-operation, + unsupported-membership-test, + unused-argument, + unused-import, + unused-variable, + used-before-assignment, + useless-object-inheritance, + useless-return, + useless-super-delegation, + wrong-import-order, + wrong-import-position, + +[BASIC] +bad-names=foo, + bar, + baz, + toto, + tutu, + tata, + _, + +good-names=i, + j, + k, + ex, + Run, + +[TYPECHECK] +ignored-modules= + _MovedItems, diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/MOVED_TO_PYAVD.txt b/ansible_collections/arista/avd/roles/eos_designs/python_modules/MOVED_TO_PYAVD.txt new file mode 100644 index 00000000000..b48ae49ac62 --- /dev/null +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/MOVED_TO_PYAVD.txt @@ -0,0 +1 @@ +All Python modules have been moved to PyAVD in the folder /python-avd/pyavd/_eos_designs/structured_config/ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/__init__.py deleted file mode 100644 index c1beaa89fa8..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigBase - -__all__ = ["AvdStructuredConfigBase"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/__init__.py deleted file mode 100644 index 22bb3e5f9de..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigConnectedEndpoints - -__all__ = ["AvdStructuredConfigConnectedEndpoints"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/__init__.py deleted file mode 100644 index 78376b19054..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigCoreInterfacesAndL3Edge - -__all__ = ["AvdStructuredConfigCoreInterfacesAndL3Edge"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/__init__.py deleted file mode 100644 index cac30e1c99a..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigCustomStructuredConfiguration - -__all__ = ["AvdStructuredConfigCustomStructuredConfiguration"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py deleted file mode 100644 index 25ad0425934..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigFlows - -__all__ = ["AvdStructuredConfigFlows"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/__init__.py deleted file mode 100644 index b30b27207fa..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .get_structured_config import get_structured_config - -__all__ = ["get_structured_config"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/__init__.py deleted file mode 100644 index 742da52c029..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigInbandManagement - -__all__ = ["AvdStructuredConfigInbandManagement"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/__init__.py index ae34148fc1d..360d52c3978 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/__init__.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/__init__.py @@ -1,7 +1,20 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from .avdinterfacedescriptions import AvdInterfaceDescriptions -from .models import InterfaceDescriptionData +from ansible.errors import AnsibleActionFail + +from ansible_collections.arista.avd.plugins.plugin_utils.pyavd_wrappers import RaiseOnUse + +try: + from pyavd._eos_designs.interface_descriptions import AvdInterfaceDescriptions + from pyavd._eos_designs.interface_descriptions.models import InterfaceDescriptionData +except ImportError as e: + AvdInterfaceDescriptions = InterfaceDescriptionData = RaiseOnUse( + AnsibleActionFail( + "The 'arista.avd.eos_designs' collection requires the 'pyavd' Python library. Got import error", + orig_exc=e, + ) + ) + __all__ = ["AvdInterfaceDescriptions", "InterfaceDescriptionData"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/__init__.py index 60387bb6cf5..36dee1d7bcd 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/__init__.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/__init__.py @@ -1,6 +1,19 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from .avdipaddressing import AvdIpAddressing +from ansible.errors import AnsibleActionFail + +from ansible_collections.arista.avd.plugins.plugin_utils.pyavd_wrappers import RaiseOnUse + +try: + from pyavd._eos_designs.ip_addressing import AvdIpAddressing +except ImportError as e: + AvdIpAddressing = RaiseOnUse( + AnsibleActionFail( + "The 'arista.avd.eos_designs' collection requires the 'pyavd' Python library. Got import error", + orig_exc=e, + ) + ) + __all__ = ["AvdIpAddressing"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/__init__.py deleted file mode 100644 index 2b901c71692..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigMetadata - -__all__ = ["AvdStructuredConfigMetadata"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/__init__.py deleted file mode 100644 index 1ba0488ce1e..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigMlag - -__all__ = ["AvdStructuredConfigMlag"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/__init__.py deleted file mode 100644 index 518d60dbb70..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigNetworkServices - -__all__ = ["AvdStructuredConfigNetworkServices"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/__init__.py deleted file mode 100644 index 2019fdfa5c5..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigOverlay - -__all__ = ["AvdStructuredConfigOverlay"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/__init__.py deleted file mode 100644 index db7257ea459..00000000000 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigUnderlay - -__all__ = ["AvdStructuredConfigUnderlay"] diff --git a/pylintrc b/pylintrc index e59f227123b..d53f99236b9 100644 --- a/pylintrc +++ b/pylintrc @@ -1,131 +1,33 @@ -# Configuration applied to collection by ansible-test -# https://github.com/ansible/ansible/blob/devel/test/lib/ansible_test/_data/sanity/pylint/config/collection.cfg - [MASTER] ignore-paths= - # The cv_client api is generated from proto files, so it should not be linted. - ansible_collections/arista/avd/plugins/plugin_utils/cv_client/api/ + # We will Pylint for ansible_collections separately since it uses it's own pylintrc in the collection root. + ansible_collections + [MESSAGES CONTROL] disable= - abstract-method, - access-member-before-definition, - arguments-differ, - assignment-from-no-return, - assignment-from-none, attribute-defined-outside-init, - bad-indentation, - bad-mcs-classmethod-argument, - broad-except, - c-extension-no-member, - cell-var-from-loop, - chained-comparison, - comparison-with-callable, - consider-iterating-dictionary, - consider-merging-isinstance, - consider-using-dict-comprehension, - consider-using-enumerate, - consider-using-get, - consider-using-in, - consider-using-set-comprehension, - consider-using-ternary, - deprecated-method, - deprecated-module, - eval-used, - exec-used, expression-not-assigned, fixme, - function-redefined, global-statement, - global-variable-undefined, import-error, - import-self, inconsistent-return-statements, - invalid-envvar-default, invalid-name, - invalid-sequence-index, - keyword-arg-before-vararg, - len-as-condition, line-too-long, - literal-comparison, - locally-disabled, - method-hidden, missing-docstring, - no-else-raise, - no-else-return, no-member, - no-name-in-module, - no-value-for-parameter, - non-iterator-returned, - not-a-mapping, - not-an-iterable, - not-callable, - pointless-statement, pointless-string-statement, - possibly-unused-variable, protected-access, - redefined-argument-from-local, redefined-builtin, redefined-outer-name, - reimported, - relative-beyond-top-level, # https://github.com/PyCQA/pylint/issues/2967 - signature-differs, - simplifiable-if-expression, - simplifiable-if-statement, - subprocess-popen-preexec-fn, - super-init-not-called, - superfluous-parens, too-few-public-methods, too-many-ancestors, too-many-arguments, - too-many-boolean-expressions, too-many-branches, - too-many-function-args, too-many-instance-attributes, - too-many-lines, too-many-locals, too-many-nested-blocks, too-many-public-methods, too-many-return-statements, too-many-statements, - trailing-comma-tuple, - trailing-comma-tuple, - try-except-raise, - unbalanced-tuple-unpacking, - undefined-loop-variable, - unexpected-keyword-arg, - ungrouped-imports, - unidiomatic-typecheck, - unnecessary-pass, - unsubscriptable-object, - unsupported-assignment-operation, - unsupported-delete-operation, - unsupported-membership-test, - unused-argument, - unused-import, - unused-variable, - used-before-assignment, - useless-object-inheritance, - useless-return, - useless-super-delegation, - wrong-import-order, wrong-import-position, - -[BASIC] -bad-names=foo, - bar, - baz, - toto, - tutu, - tata, - _, - -good-names=i, - j, - k, - ex, - Run, - -[TYPECHECK] -ignored-modules= - _MovedItems, diff --git a/python-avd/Makefile b/python-avd/Makefile index 55777423a00..e66f12f3eb6 100644 --- a/python-avd/Makefile +++ b/python-avd/Makefile @@ -12,6 +12,7 @@ EOS_CLI_CONFIG_GEN_TEMPLATE_DIR = $(VENDOR_DIR)/templates SCHEMAS_DIR = $(VENDOR_DIR)/schemas EOS_DESIGNS_MODULES_DIR = $(VENDOR_DIR)/eos_designs PYAVD_FILTER_IMPORT = $(PACKAGE_DIR).j2filters +EOS_DESIGNS_IMPORT = $(PACKAGE_DIR)._eos_designs # export PYTHONPATH=$(CURRENT_DIR) # Uncomment to test from source .PHONY: help @@ -61,7 +62,6 @@ copy-libs: ## Copy files from Ansible AVD collection cp -r $(ANSIBLE_AVD_DIR)/ansible_collections/arista/avd/roles/eos_cli_config_gen/templates/* $(EOS_CLI_CONFIG_GEN_TEMPLATE_DIR) rm -f $(EOS_CLI_CONFIG_GEN_TEMPLATE_DIR)/avd_schema_documentation.j2 - cp -r $(ANSIBLE_AVD_DIR)/ansible_collections/arista/avd/roles/eos_designs/python_modules/* $(EOS_DESIGNS_MODULES_DIR)/ mv $(VENDOR_DIR)/eos_designs_* $(EOS_DESIGNS_MODULES_DIR)/ $(SCRIPTS_DIR)/build-schemas.py @@ -101,7 +101,10 @@ fix-libs: ## Fix/remove various Ansible specifics things from python files find $(PACKAGE_DIR) -name '*.py' -exec sed -i -e 's/ansible_collections\.arista\.avd\.plugins\.filter.list_compress/$(PYAVD_FILTER_IMPORT)\.list_compress/g' {} + find $(PACKAGE_DIR) -name '*.py' -exec sed -i -e 's/ansible_collections\.arista\.avd\.plugins\.filter/$(VENDOR_IMPORT)\.j2\.filter/g' {} + - find $(PACKAGE_DIR) -name '*.py' -exec sed -i -e 's/ansible_collections\.arista\.avd\.roles\.eos_designs\.python_modules/$(VENDOR_IMPORT)\.eos_designs/g' {} + + +# Only remaining python_modules are ip_addressing and interface_descriptions referred in eos_designs_shared_utils. + find $(PACKAGE_DIR) -name '*.py' -exec sed -i -e 's/ansible_collections\.arista\.avd\.roles\.eos_designs\.python_modules/$(EOS_DESIGNS_IMPORT)/g' {} + + find $(PACKAGE_DIR) -name '*.py' -exec sed -i -e 's/from ansible\.utils\.display/from $(VENDOR_IMPORT)\.utils\.display/g' {} + cp -r $(CURRENT_DIR)/vendor_overrides/* $(VENDOR_DIR)/ diff --git a/python-avd/pyavd/_eos_designs/__init__.py b/python-avd/pyavd/_eos_designs/__init__.py new file mode 100644 index 00000000000..b17ca7c745d --- /dev/null +++ b/python-avd/pyavd/_eos_designs/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) 2024 Arista Networks, Inc. +# Use of this source code is governed by the Apache License 2.0 +# that can be found in the LICENSE file. diff --git a/python-avd/pyavd/_eos_designs/eos_designs_facts/__init__.py b/python-avd/pyavd/_eos_designs/eos_designs_facts/__init__.py index 669e37d1127..59544099a97 100644 --- a/python-avd/pyavd/_eos_designs/eos_designs_facts/__init__.py +++ b/python-avd/pyavd/_eos_designs/eos_designs_facts/__init__.py @@ -98,7 +98,8 @@ def evpn_multicast(self) -> bool | None: raise AristaAvdError( "'evpn_multicast: True' is only supported in combination with 'underlay_multicast: True' and 'igmp_snooping_enabled : True'" ) - elif self.shared_utils.mlag is True: + + if self.shared_utils.mlag is True: peer_eos_designs_facts: EosDesignsFacts = self.shared_utils.mlag_peer_facts if self.shared_utils.overlay_rd_type_admin_subfield == peer_eos_designs_facts.shared_utils.overlay_rd_type_admin_subfield: raise AristaAvdError( diff --git a/python-avd/pyavd/_eos_designs/eos_designs_facts/overlay.py b/python-avd/pyavd/_eos_designs/eos_designs_facts/overlay.py index c18bcc0ad63..9c62e952bdf 100644 --- a/python-avd/pyavd/_eos_designs/eos_designs_facts/overlay.py +++ b/python-avd/pyavd/_eos_designs/eos_designs_facts/overlay.py @@ -44,8 +44,7 @@ def evpn_route_servers(self: EosDesignsFacts) -> list: if self.shared_utils.underlay_router is True: if self.evpn_role == "client": return get(self.shared_utils.switch_data_combined, "evpn_route_servers", default=self.shared_utils.uplink_switches) - else: - return get(self.shared_utils.switch_data_combined, "evpn_route_servers") + return get(self.shared_utils.switch_data_combined, "evpn_route_servers") return [] @cached_property diff --git a/python-avd/pyavd/_eos_designs/eos_designs_facts/uplinks.py b/python-avd/pyavd/_eos_designs/eos_designs_facts/uplinks.py index a967dd9187c..4b706265f4a 100644 --- a/python-avd/pyavd/_eos_designs/eos_designs_facts/uplinks.py +++ b/python-avd/pyavd/_eos_designs/eos_designs_facts/uplinks.py @@ -70,7 +70,7 @@ def _uplink_port_channel_id(self: EosDesignsFacts) -> int: # produce an error if the switch is MLAG and port-channel ID is above 2000 if self.shared_utils.mlag: - if not (1 <= uplink_port_channel_id <= 2000): + if not 1 <= uplink_port_channel_id <= 2000: raise AristaAvdError( f"'uplink_port_channel_id' must be between 1 and 2000 for MLAG switches. Got '{uplink_port_channel_id}' on '{self.shared_utils.hostname}'." ) @@ -113,7 +113,7 @@ def _uplink_switch_port_channel_id(self: EosDesignsFacts) -> int: uplink_switch_facts: EosDesignsFacts = self.shared_utils.get_peer_facts(self.shared_utils.uplink_switches[0], required=True) if uplink_switch_facts.shared_utils.mlag: - if not (1 <= uplink_switch_port_channel_id <= 2000): + if not 1 <= uplink_switch_port_channel_id <= 2000: raise AristaAvdError( f"'uplink_switch_port_channel_id' must be between 1 and 2000 for MLAG switches. Got '{uplink_switch_port_channel_id}' on" f" '{self.shared_utils.hostname}'." @@ -250,7 +250,13 @@ def _get_port_channel_uplink(self: EosDesignsFacts, uplink_index: int, uplink_in return uplink - def _get_l2_uplink(self: EosDesignsFacts, uplink_index: int, uplink_interface: str, uplink_switch: str, uplink_switch_interface: str) -> dict: + def _get_l2_uplink( + self: EosDesignsFacts, + uplink_index: int, # pylint: disable=unused-argument + uplink_interface: str, + uplink_switch: str, + uplink_switch_interface: str, + ) -> dict: """ Return a single uplink dictionary for an L2 uplink. Reused for both uplink_type port-channel, lan and TODO lan-port-channel. """ diff --git a/python-avd/pyavd/_eos_designs/eos_designs_facts/vlans.py b/python-avd/pyavd/_eos_designs/eos_designs_facts/vlans.py index 5cb1315d39b..664207cbde0 100644 --- a/python-avd/pyavd/_eos_designs/eos_designs_facts/vlans.py +++ b/python-avd/pyavd/_eos_designs/eos_designs_facts/vlans.py @@ -178,11 +178,11 @@ def _endpoint_vlans(self: EosDesignsFacts) -> set[int]: if not self.shared_utils.filter_only_vlans_in_use: return set() - endpoint_vlans, endpoint_trunk_groups = self._endpoint_vlans_and_trunk_groups + endpoint_vlans, _ = self._endpoint_vlans_and_trunk_groups if not self.shared_utils.mlag: return endpoint_vlans - mlag_endpoint_vlans, mlag_endpoint_trunk_groups = self._mlag_peer_endpoint_vlans_and_trunk_groups + mlag_endpoint_vlans, _ = self._mlag_peer_endpoint_vlans_and_trunk_groups return endpoint_vlans.union(mlag_endpoint_vlans) @@ -205,11 +205,11 @@ def _endpoint_trunk_groups(self: EosDesignsFacts) -> set[str]: if not self.shared_utils.filter_only_vlans_in_use: return set() - endpoint_vlans, endpoint_trunk_groups = self._endpoint_vlans_and_trunk_groups + _, endpoint_trunk_groups = self._endpoint_vlans_and_trunk_groups if not self.shared_utils.mlag: return endpoint_trunk_groups - mlag_endpoint_vlans, mlag_endpoint_trunk_groups = self._mlag_peer_endpoint_vlans_and_trunk_groups + _, mlag_endpoint_trunk_groups = self._mlag_peer_endpoint_vlans_and_trunk_groups return endpoint_trunk_groups.union(mlag_endpoint_trunk_groups) @cached_property @@ -220,7 +220,7 @@ def local_endpoint_trunk_groups(self: EosDesignsFacts) -> list[str]: This is a subset of endpoint_trunk_groups which is used for filtering. """ if self.shared_utils.only_local_vlan_trunk_groups: - local_endpoint_vlans, local_endpoint_trunk_groups = self._local_endpoint_vlans_and_trunk_groups + _, local_endpoint_trunk_groups = self._local_endpoint_vlans_and_trunk_groups return list(local_endpoint_trunk_groups) return [] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/avdinterfacedescriptions.py b/python-avd/pyavd/_eos_designs/interface_descriptions/__init__.py similarity index 98% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/avdinterfacedescriptions.py rename to python-avd/pyavd/_eos_designs/interface_descriptions/__init__.py index b939859ac52..783dc2762e3 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/avdinterfacedescriptions.py +++ b/python-avd/pyavd/_eos_designs/interface_descriptions/__init__.py @@ -3,8 +3,7 @@ # that can be found in the LICENSE file. from collections import ChainMap -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts - +from ...vendor.avdfacts import AvdFacts from .models import InterfaceDescriptionData from .utils import UtilsMixin @@ -132,7 +131,10 @@ def mlag_ethernet_interfaces(self, mlag_interface: str) -> str: return f"MLAG_PEER_{self._mlag_peer}_{mlag_interface}" - def mlag_port_channel_interface(self, data: InterfaceDescriptionData) -> str: + def mlag_port_channel_interface( + self, + data: InterfaceDescriptionData, # pylint: disable=unused-argument + ) -> str: """ Available data: - mlag_peer diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/models.py b/python-avd/pyavd/_eos_designs/interface_descriptions/models.py similarity index 96% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/models.py rename to python-avd/pyavd/_eos_designs/interface_descriptions/models.py index 1697f44cf78..ffa0d05b0a8 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/models.py +++ b/python-avd/pyavd/_eos_designs/interface_descriptions/models.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils + from ...vendor.eos_designs.eos_designs_shared_utils import SharedUtils class InterfaceDescriptionData: diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/utils.py b/python-avd/pyavd/_eos_designs/interface_descriptions/utils.py similarity index 76% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/utils.py rename to python-avd/pyavd/_eos_designs/interface_descriptions/utils.py index 0d7f573f6bb..f3c2c0f82cf 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/interface_descriptions/utils.py +++ b/python-avd/pyavd/_eos_designs/interface_descriptions/utils.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils + from . import AvdInterfaceDescriptions class UtilsMixin: @@ -16,30 +16,27 @@ class UtilsMixin: Class should only be used as Mixin to an AvdInterfaceDescriptions class """ - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _mpls_overlay_role(self) -> str: + def _mpls_overlay_role(self: AvdInterfaceDescriptions) -> str: """TODO: AVD5.0.0 remove this since it has been replaced by DescriptionData.""" return self.shared_utils.mpls_overlay_role @cached_property - def _overlay_routing_protocol(self) -> str: + def _overlay_routing_protocol(self: AvdInterfaceDescriptions) -> str: """TODO: AVD5.0.0 remove this since it has been replaced by DescriptionData.""" return self.shared_utils.overlay_routing_protocol @cached_property - def _mlag_peer(self) -> str: + def _mlag_peer(self: AvdInterfaceDescriptions) -> str: """TODO: AVD5.0.0 remove this since it has been replaced by DescriptionData.""" return self.shared_utils.mlag_peer @cached_property - def _mlag_port_channel_id(self) -> str: + def _mlag_port_channel_id(self: AvdInterfaceDescriptions) -> str: """TODO: AVD5.0.0 remove this since it has been replaced by DescriptionData.""" return self.shared_utils.mlag_port_channel_id @cached_property - def _mpls_lsr(self) -> str: + def _mpls_lsr(self: AvdInterfaceDescriptions) -> str: """TODO: AVD5.0.0 remove this since it has been replaced by DescriptionData.""" return self.shared_utils.mpls_lsr diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/avdipaddressing.py b/python-avd/pyavd/_eos_designs/ip_addressing/__init__.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/avdipaddressing.py rename to python-avd/pyavd/_eos_designs/ip_addressing/__init__.py index 5506f870623..53765d6ffb3 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/avdipaddressing.py +++ b/python-avd/pyavd/_eos_designs/ip_addressing/__init__.py @@ -4,10 +4,9 @@ import ipaddress from collections import ChainMap -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get_ip_from_pool - +from ...vendor.avdfacts import AvdFacts +from ...vendor.errors import AristaAvdError +from ...vendor.utils import get_ip_from_pool from .utils import UtilsMixin @@ -99,16 +98,15 @@ def mlag_ip_primary(self) -> str: return self._mlag_ip(self._mlag_peer_ipv6_pool, 0, self.shared_utils.mlag_peer_address_family) - else: - if template_path := self.shared_utils.ip_addressing_templates.get("mlag_ip_primary"): - return self._template( - template_path, - mlag_primary_id=self._mlag_primary_id, - mlag_secondary_id=self._mlag_secondary_id, - switch_data={"combined": {"mlag_peer_ipv4_pool": self._mlag_peer_ipv4_pool}}, - ) + if template_path := self.shared_utils.ip_addressing_templates.get("mlag_ip_primary"): + return self._template( + template_path, + mlag_primary_id=self._mlag_primary_id, + mlag_secondary_id=self._mlag_secondary_id, + switch_data={"combined": {"mlag_peer_ipv4_pool": self._mlag_peer_ipv4_pool}}, + ) - return self._mlag_ip(self._mlag_peer_ipv4_pool, 0) + return self._mlag_ip(self._mlag_peer_ipv4_pool, 0) def mlag_ip_secondary(self) -> str: """ @@ -127,16 +125,15 @@ def mlag_ip_secondary(self) -> str: return self._mlag_ip(self._mlag_peer_ipv6_pool, 1, self.shared_utils.mlag_peer_address_family) - else: - if template_path := self.shared_utils.ip_addressing_templates.get("mlag_ip_secondary"): - return self._template( - template_path, - mlag_primary_id=self._mlag_primary_id, - mlag_secondary_id=self._mlag_secondary_id, - switch_data={"combined": {"mlag_peer_ipv4_pool": self._mlag_peer_ipv4_pool}}, - ) + if template_path := self.shared_utils.ip_addressing_templates.get("mlag_ip_secondary"): + return self._template( + template_path, + mlag_primary_id=self._mlag_primary_id, + mlag_secondary_id=self._mlag_secondary_id, + switch_data={"combined": {"mlag_peer_ipv4_pool": self._mlag_peer_ipv4_pool}}, + ) - return self._mlag_ip(self._mlag_peer_ipv4_pool, 1) + return self._mlag_ip(self._mlag_peer_ipv4_pool, 1) def mlag_l3_ip_primary(self) -> str: """ @@ -292,7 +289,7 @@ def evpn_underlay_l3_multicast_group( self, underlay_l3_multicast_group_ipv4_pool: str, vrf_vni: int, - vrf_id: int, + vrf_id: int, # pylint: disable=unused-argument evpn_underlay_l3_multicast_group_ipv4_pool_offset: int, ) -> str: """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/utils.py b/python-avd/pyavd/_eos_designs/ip_addressing/utils.py similarity index 78% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/utils.py rename to python-avd/pyavd/_eos_designs/ip_addressing/utils.py index b84658fe20c..ea2d0dd259b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/ip_addressing/utils.py +++ b/python-avd/pyavd/_eos_designs/ip_addressing/utils.py @@ -6,12 +6,12 @@ from functools import cached_property from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get +from ...vendor.errors import AristaAvdError, AristaAvdMissingVariableError +from ...vendor.j2.filter.range_expand import range_expand +from ...vendor.utils import get if TYPE_CHECKING: - from .avdipaddressing import AvdIpAddressing + from . import AvdIpAddressing class UtilsMixin: @@ -21,87 +21,87 @@ class UtilsMixin: """ @cached_property - def _mlag_primary_id(self: "AvdIpAddressing") -> int: + def _mlag_primary_id(self: AvdIpAddressing) -> int: if self.shared_utils.mlag_switch_ids is None or self.shared_utils.mlag_switch_ids.get("primary") is None: raise AristaAvdMissingVariableError("'mlag_switch_ids' is required to calculate MLAG IP addresses") return self.shared_utils.mlag_switch_ids["primary"] @cached_property - def _mlag_secondary_id(self: "AvdIpAddressing") -> int: + def _mlag_secondary_id(self: AvdIpAddressing) -> int: if self.shared_utils.mlag_switch_ids is None or self.shared_utils.mlag_switch_ids.get("secondary") is None: raise AristaAvdMissingVariableError("'mlag_switch_ids' is required to calculate MLAG IP addresses") return self.shared_utils.mlag_switch_ids["secondary"] @cached_property - def _fabric_ipaddress_mlag_algorithm(self: "AvdIpAddressing") -> str: + def _fabric_ipaddress_mlag_algorithm(self: AvdIpAddressing) -> str: return self.shared_utils.fabric_ip_addressing_mlag_algorithm @cached_property - def _fabric_ip_addressing_mlag_ipv4_prefix_length(self: "AvdIpAddressing") -> int: + def _fabric_ip_addressing_mlag_ipv4_prefix_length(self: AvdIpAddressing) -> int: return self.shared_utils.fabric_ip_addressing_mlag_ipv4_prefix_length @cached_property - def _fabric_ip_addressing_mlag_ipv6_prefix_length(self: "AvdIpAddressing") -> int: + def _fabric_ip_addressing_mlag_ipv6_prefix_length(self: AvdIpAddressing) -> int: return self.shared_utils.fabric_ip_addressing_mlag_ipv6_prefix_length @cached_property - def _fabric_ip_addressing_p2p_uplinks_ipv4_prefix_length(self: "AvdIpAddressing") -> int: + def _fabric_ip_addressing_p2p_uplinks_ipv4_prefix_length(self: AvdIpAddressing) -> int: return self.shared_utils.fabric_ip_addressing_p2p_uplinks_ipv4_prefix_length @cached_property - def _mlag_peer_ipv4_pool(self: "AvdIpAddressing") -> str: + def _mlag_peer_ipv4_pool(self: AvdIpAddressing) -> str: return self.shared_utils.mlag_peer_ipv4_pool @cached_property - def _mlag_peer_ipv6_pool(self: "AvdIpAddressing") -> str: + def _mlag_peer_ipv6_pool(self: AvdIpAddressing) -> str: return self.shared_utils.mlag_peer_ipv6_pool @cached_property - def _mlag_peer_l3_ipv4_pool(self: "AvdIpAddressing") -> str: + def _mlag_peer_l3_ipv4_pool(self: AvdIpAddressing) -> str: return self.shared_utils.mlag_peer_l3_ipv4_pool @cached_property - def _uplink_ipv4_pool(self: "AvdIpAddressing") -> str: + def _uplink_ipv4_pool(self: AvdIpAddressing) -> str: if self.shared_utils.uplink_ipv4_pool is None: raise AristaAvdMissingVariableError("'uplink_ipv4_pool' is required to calculate uplink IP addresses") return self.shared_utils.uplink_ipv4_pool @cached_property - def _id(self: "AvdIpAddressing") -> int: + def _id(self: AvdIpAddressing) -> int: if self.shared_utils.id is None: raise AristaAvdMissingVariableError("'id' is required to calculate IP addresses") return self.shared_utils.id @cached_property - def _max_uplink_switches(self: "AvdIpAddressing") -> int: + def _max_uplink_switches(self: AvdIpAddressing) -> int: return self.shared_utils.max_uplink_switches @cached_property - def _max_parallel_uplinks(self: "AvdIpAddressing") -> int: + def _max_parallel_uplinks(self: AvdIpAddressing) -> int: return self.shared_utils.max_parallel_uplinks @cached_property - def _loopback_ipv4_pool(self: "AvdIpAddressing") -> str: + def _loopback_ipv4_pool(self: AvdIpAddressing) -> str: return self.shared_utils.loopback_ipv4_pool @cached_property - def _loopback_ipv4_offset(self: "AvdIpAddressing") -> int: + def _loopback_ipv4_offset(self: AvdIpAddressing) -> int: return self.shared_utils.loopback_ipv4_offset @cached_property - def _loopback_ipv6_pool(self: "AvdIpAddressing") -> str: + def _loopback_ipv6_pool(self: AvdIpAddressing) -> str: return self.shared_utils.loopback_ipv6_pool @cached_property - def _loopback_ipv6_offset(self: "AvdIpAddressing") -> int: + def _loopback_ipv6_offset(self: AvdIpAddressing) -> int: return self.shared_utils.loopback_ipv6_offset @cached_property - def _vtep_loopback_ipv4_pool(self: "AvdIpAddressing") -> str: + def _vtep_loopback_ipv4_pool(self: AvdIpAddressing) -> str: return self.shared_utils.vtep_loopback_ipv4_pool @cached_property - def _mlag_odd_id_based_offset(self: "AvdIpAddressing") -> int: + def _mlag_odd_id_based_offset(self: AvdIpAddressing) -> int: """ Return the subnet offset for an MLAG pair based on odd id @@ -118,7 +118,7 @@ def _mlag_odd_id_based_offset(self: "AvdIpAddressing") -> int: return int((odd_id - 1) / 2) - def _get_downlink_ipv4_pool_and_offset(self: "AvdIpAddressing", uplink_switch_index: int) -> tuple[str, int]: + def _get_downlink_ipv4_pool_and_offset(self: AvdIpAddressing, uplink_switch_index: int) -> tuple[str, int]: """ Returns the downlink IP pool and offset as a tuple according to the uplink_switch_index @@ -147,7 +147,7 @@ def _get_downlink_ipv4_pool_and_offset(self: "AvdIpAddressing", uplink_switch_in "in the downlink_switch does not match any of the downlink_pools" ) - def _get_p2p_ipv4_pool_and_offset(self: "AvdIpAddressing", uplink_switch_index: int) -> tuple[str, int]: + def _get_p2p_ipv4_pool_and_offset(self: AvdIpAddressing, uplink_switch_index: int) -> tuple[str, int]: """ Returns IP pool and offset as a tuple according to the uplink_switch_index diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py b/python-avd/pyavd/_eos_designs/structured_config/__init__.py similarity index 74% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py rename to python-avd/pyavd/_eos_designs/structured_config/__init__.py index 811d2353e68..4062512798a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py +++ b/python-avd/pyavd/_eos_designs/structured_config/__init__.py @@ -5,23 +5,22 @@ from collections import ChainMap -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.merge import merge -from ansible_collections.arista.avd.plugins.plugin_utils.schema.avdschematools import AvdSchemaTools -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - -from ..base import AvdStructuredConfigBase -from ..connected_endpoints import AvdStructuredConfigConnectedEndpoints -from ..core_interfaces_and_l3_edge import AvdStructuredConfigCoreInterfacesAndL3Edge -from ..custom_structured_configuration import AvdStructuredConfigCustomStructuredConfiguration -from ..flows import AvdStructuredConfigFlows -from ..inband_management import AvdStructuredConfigInbandManagement -from ..metadata import AvdStructuredConfigMetadata -from ..mlag import AvdStructuredConfigMlag -from ..network_services import AvdStructuredConfigNetworkServices -from ..overlay import AvdStructuredConfigOverlay -from ..underlay import AvdStructuredConfigUnderlay +from ...avd_schema_tools import AvdSchemaTools +from ...vendor.avdfacts import AvdFacts +from ...vendor.eos_designs.eos_designs_shared_utils import SharedUtils +from ...vendor.merge import merge +from ...vendor.utils import get +from .base import AvdStructuredConfigBase +from .connected_endpoints import AvdStructuredConfigConnectedEndpoints +from .core_interfaces_and_l3_edge import AvdStructuredConfigCoreInterfacesAndL3Edge +from .custom_structured_configuration import AvdStructuredConfigCustomStructuredConfiguration +from .flows import AvdStructuredConfigFlows +from .inband_management import AvdStructuredConfigInbandManagement +from .metadata import AvdStructuredConfigMetadata +from .mlag import AvdStructuredConfigMlag +from .network_services import AvdStructuredConfigNetworkServices +from .overlay import AvdStructuredConfigOverlay +from .underlay import AvdStructuredConfigUnderlay AVD_STRUCTURED_CONFIG_CLASSES = [ AvdStructuredConfigBase, @@ -90,8 +89,8 @@ def get_structured_config( list_merge = get(module_vars, "custom_structured_configuration_list_merge", default="append_rp") # Only for structured config run conversion on the data in since we still have some structured config inputs without full schema validation. - for result in results: - output_schema_tools.convert_data(result) + for res in results: + output_schema_tools.convert_data(res) else: list_merge = "append" diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/base/__init__.py similarity index 97% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/base/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/base/__init__.py index 4bebb6671ac..9245bf41305 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/base/__init__.py @@ -5,13 +5,12 @@ from functools import cached_property -from ansible_collections.arista.avd.plugins.filter.convert_dicts import convert_dicts -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -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 get - +from ....j2filters.convert_dicts import convert_dicts +from ....j2filters.natural_sort import natural_sort +from ....vendor.avdfacts import AvdFacts +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import get from .ntp import NtpMixin from .snmp_server import SnmpServerMixin @@ -166,7 +165,7 @@ def service_routing_protocols_model(self) -> str: return "multi-agent" @cached_property - def ip_routing(self) -> bool: + def ip_routing(self) -> bool | None: """ For l3 devices, configure ip routing unless ip_routing_ipv6_interfaces is True. For other devices only configure if "always_configure_ip_routing" is True. @@ -279,7 +278,8 @@ def daemon_terminattr(self) -> dict | None: daemon_terminattr["cvaddrs"].append(f"{cvp_instance_ip}:443") daemon_terminattr["cvauth"] = { "method": "token-secure", - "token_file": get(self._hostvars, "cvp_token_file", "/tmp/cv-onboarding-token"), + # Ignoring sonar-lint false positive for tmp path since this is config for EOS + "token_file": get(self._hostvars, "cvp_token_file", "/tmp/cv-onboarding-token"), # NOSONAR } else: # updating for cvp_on_prem_ips @@ -293,7 +293,8 @@ def daemon_terminattr(self) -> dict | None: else: daemon_terminattr["cvauth"] = { "method": "token", - "token_file": get(self._hostvars, "cvp_token_file", "/tmp/token"), + # Ignoring sonar-lint false positive for tmp path since this is config for EOS + "token_file": get(self._hostvars, "cvp_token_file", "/tmp/token"), # NOSONAR } daemon_terminattr["cvvrf"] = self.shared_utils.mgmt_interface_vrf @@ -428,11 +429,9 @@ def spanning_tree(self) -> dict | None: if spanning_tree_mode is not None: spanning_tree["mode"] = spanning_tree_mode priority = get(self.shared_utils.switch_data_combined, "spanning_tree_priority", default=32768) + # "rapid-pvst" is not included below. Per vlan spanning-tree priorities are set under network-services. if spanning_tree_mode == "mstp": spanning_tree["mst_instances"] = [{"id": "0", "priority": priority}] - elif spanning_tree_mode == "rapid-pvst": - pass - # Per vlan spanning-tree priorities are set under network-services. elif spanning_tree_mode == "rstp": spanning_tree["rstp_priority"] = priority @@ -577,10 +576,12 @@ def mac_address_table(self) -> dict | None: def queue_monitor_streaming(self) -> dict | None: """ queue_monitor_streaming set based on queue_monitor_streaming data-model + """ enable = get(self._hostvars, "queue_monitor_streaming.enable") vrf = get(self._hostvars, "queue_monitor_streaming.vrf") if enable is not True or vrf is None: + # TODO: Fix bug where queue monitor enable without VRF will not return any config. return None queue_monitor = {} diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/ntp.py b/python-avd/pyavd/_eos_designs/structured_config/base/ntp.py similarity index 91% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/base/ntp.py rename to python-avd/pyavd/_eos_designs/structured_config/base/ntp.py index bbbe971cfd6..f7c55ddad1e 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/ntp.py +++ b/python-avd/pyavd/_eos_designs/structured_config/base/ntp.py @@ -4,13 +4,16 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -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 get - +from ....vendor.errors import AristaAvdError +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigBase + class NtpMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class NtpMixin(UtilsMixin): """ @cached_property - def ntp(self) -> dict | None: + def ntp(self: AvdStructuredConfigBase) -> dict | None: """ ntp set based on "ntp_settings" data-model. """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/snmp_server.py b/python-avd/pyavd/_eos_designs/structured_config/base/snmp_server.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/base/snmp_server.py rename to python-avd/pyavd/_eos_designs/structured_config/base/snmp_server.py index 7670beaae24..b1f3a357d08 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/snmp_server.py +++ b/python-avd/pyavd/_eos_designs/structured_config/base/snmp_server.py @@ -5,15 +5,18 @@ from functools import cached_property from hashlib import sha1 +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.filter.snmp_hash import hash_passphrase -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError -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 get, replace_or_append_item - +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdError, AristaAvdMissingVariableError +from ....vendor.j2.filter.snmp_hash import hash_passphrase +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import get, replace_or_append_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigBase + class SnmpServerMixin(UtilsMixin): """ @@ -22,7 +25,7 @@ class SnmpServerMixin(UtilsMixin): """ @cached_property - def snmp_server(self) -> dict | None: + def snmp_server(self: AvdStructuredConfigBase) -> dict | None: """ snmp_server set based on snmp_settings data-model, using various snmp_settings information. @@ -62,17 +65,18 @@ def snmp_server(self) -> dict | None: } ) - def _snmp_engine_ids(self, snmp_settings: dict) -> str | None: + def _snmp_engine_ids(self: AvdStructuredConfigBase, snmp_settings: dict) -> dict | None: """ - Return engine ids if "snmp_settings.compute_local_engineid" is True. + Return dict of engine ids if "snmp_settings.compute_local_engineid" is True. Otherwise return None """ - if not snmp_settings.get("compute_local_engineid") is True: + if snmp_settings.get("compute_local_engineid") is not True: return None compute_source = get(snmp_settings, "compute_local_engineid_source", default="hostname_and_ip") if compute_source == "hostname_and_ip": - local_engine_id = sha1(f"{self.shared_utils.hostname}{self.shared_utils.mgmt_ip}".encode("utf-8")).hexdigest() + # Accepting SonarLint issue: The weak sha1 is not used for encryption. Just to create a unique engine id. + local_engine_id = sha1(f"{self.shared_utils.hostname}{self.shared_utils.mgmt_ip}".encode("utf-8")).hexdigest() # NOSONAR elif compute_source == "system_mac": if self.shared_utils.system_mac_address is None: raise AristaAvdMissingVariableError("default_engine_id_from_system_mac: true requires system_mac_address to be set!") @@ -84,7 +88,7 @@ def _snmp_engine_ids(self, snmp_settings: dict) -> str | None: return {"local": local_engine_id} - def _snmp_location(self, snmp_settings: dict) -> str | None: + def _snmp_location(self: AvdStructuredConfigBase, snmp_settings: dict) -> str | None: """ Return location if "snmp_settings.location" is True. Otherwise return None @@ -102,7 +106,7 @@ def _snmp_location(self, snmp_settings: dict) -> str | None: location_elements = [location for location in location_elements if location not in [None, ""]] return " ".join(location_elements) - def _snmp_users(self, snmp_settings: dict, engine_ids: dict | None) -> list | None: + def _snmp_users(self: AvdStructuredConfigBase, snmp_settings: dict, engine_ids: dict | None) -> list | None: """ Return users if "snmp_settings.users" is set. Otherwise return None @@ -152,7 +156,7 @@ def _snmp_users(self, snmp_settings: dict, engine_ids: dict | None) -> list | No return snmp_users or None - def _snmp_hosts(self, snmp_settings) -> list | None: + def _snmp_hosts(self: AvdStructuredConfigBase, snmp_settings) -> list | None: """ Return hosts if "snmp_settings.hosts" is set. Otherwise return None @@ -195,7 +199,7 @@ def _snmp_hosts(self, snmp_settings) -> list | None: return snmp_hosts or None - def _snmp_local_interfaces(self, source_interfaces_inputs: dict | None) -> list | None: + def _snmp_local_interfaces(self: AvdStructuredConfigBase, source_interfaces_inputs: dict | None) -> list | None: """ Return local_interfaces if "source_interfaces.snmp" is set. Otherwise return None @@ -210,7 +214,7 @@ def _snmp_local_interfaces(self, source_interfaces_inputs: dict | None) -> list ) return local_interfaces or None - def _snmp_vrfs(self, snmp_settings: dict | None) -> list | None: + def _snmp_vrfs(self: AvdStructuredConfigBase, snmp_settings: dict | None) -> list | None: """ Return list of dicts for enabling/disabling SNMP for VRFs Requires one of the following options to be set under snmp_settings: diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/utils.py b/python-avd/pyavd/_eos_designs/structured_config/base/utils.py similarity index 83% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/base/utils.py rename to python-avd/pyavd/_eos_designs/structured_config/base/utils.py index 72a210a5310..1500552ab4b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/base/utils.py +++ b/python-avd/pyavd/_eos_designs/structured_config/base/utils.py @@ -4,10 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get +from ....vendor.errors import AristaAvdError, AristaAvdMissingVariableError +from ....vendor.utils import get + +if TYPE_CHECKING: + from . import AvdStructuredConfigBase class UtilsMixin: @@ -16,15 +19,11 @@ class UtilsMixin: Class should only be used as Mixin to a AvdStructuredConfig class or other Mixins. """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property def _source_interfaces(self) -> dict: return get(self._hostvars, "source_interfaces", default={}) - def _build_source_interfaces(self, include_mgmt_interface: bool, include_inband_mgmt_interface: bool, error_context: str) -> list: + def _build_source_interfaces(self: AvdStructuredConfigBase, include_mgmt_interface: bool, include_inband_mgmt_interface: bool, error_context: str) -> list: """ Return list of source interfaces with VRFs. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/__init__.py similarity index 94% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/__init__.py index 8086f815e13..272e6c3c82a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/__init__.py @@ -1,8 +1,7 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts - +from ....vendor.avdfacts import AvdFacts from .ethernet_interfaces import EthernetInterfacesMixin from .monitor_sessions import MonitorSessionsMixin from .port_channel_interfaces import PortChannelInterfacesMixin diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/ethernet_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/ethernet_interfaces.py similarity index 92% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/ethernet_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/ethernet_interfaces.py index f4b7c877079..2bd93b8399e 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/ethernet_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/ethernet_interfaces.py @@ -6,15 +6,18 @@ import re from collections import ChainMap from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError -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 ....vendor.errors import AristaAvdError, AristaAvdMissingVariableError +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import append_if_not_duplicate, default, get, replace_or_append_item +from ...interface_descriptions import InterfaceDescriptionData from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigConnectedEndpoints + class EthernetInterfacesMixin(UtilsMixin): """ @@ -23,7 +26,7 @@ class EthernetInterfacesMixin(UtilsMixin): """ @cached_property - def ethernet_interfaces(self) -> list | None: + def ethernet_interfaces(self: AvdStructuredConfigConnectedEndpoints) -> list | None: """ Return structured config for ethernet_interfaces @@ -78,7 +81,7 @@ def ethernet_interfaces(self) -> list | None: return None - def _update_ethernet_interface_cfg(self, adapter: dict, ethernet_interface: dict, connected_endpoint: dict) -> dict: + def _update_ethernet_interface_cfg(self: AvdStructuredConfigConnectedEndpoints, adapter: dict, ethernet_interface: dict, connected_endpoint: dict) -> dict: ethernet_interface.update( { "type": "switched", @@ -106,7 +109,7 @@ def _update_ethernet_interface_cfg(self, adapter: dict, ethernet_interface: dict ) return ethernet_interface - def _get_ethernet_interface_cfg(self, adapter: dict, node_index: int, connected_endpoint: dict) -> dict: + def _get_ethernet_interface_cfg(self: AvdStructuredConfigConnectedEndpoints, adapter: dict, node_index: int, connected_endpoint: dict) -> dict: """ Return structured_config for one ethernet_interface """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/monitor_sessions.py b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/monitor_sessions.py similarity index 91% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/monitor_sessions.py rename to python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/monitor_sessions.py index fd3ecc217af..a4c908d07b1 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/monitor_sessions.py +++ b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/monitor_sessions.py @@ -5,14 +5,17 @@ import re from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.merge import merge -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, groupby - +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.merge import merge +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import append_if_not_duplicate, get, groupby from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigConnectedEndpoints + class MonitorSessionsMixin(UtilsMixin): """ @@ -21,7 +24,7 @@ class MonitorSessionsMixin(UtilsMixin): """ @cached_property - def monitor_sessions(self) -> list | None: + def monitor_sessions(self: AvdStructuredConfigConnectedEndpoints) -> list | None: """ Return structured_config for monitor_sessions """ @@ -70,7 +73,7 @@ def monitor_sessions(self) -> list | None: return None @cached_property - def _monitor_session_configs(self) -> list: + def _monitor_session_configs(self: AvdStructuredConfigConnectedEndpoints) -> list: """ Return list of monitor session configs extracted from every interface """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/port_channel_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/port_channel_interfaces.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/port_channel_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/port_channel_interfaces.py index 88e4762f678..1b668325f05 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/port_channel_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/port_channel_interfaces.py @@ -6,17 +6,20 @@ import re from collections import ChainMap from functools import cached_property - -from ansible_collections.arista.avd.plugins.filter.generate_esi import generate_esi -from ansible_collections.arista.avd.plugins.filter.generate_lacp_id import generate_lacp_id -from ansible_collections.arista.avd.plugins.filter.generate_route_target import generate_route_target -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -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 typing import TYPE_CHECKING + +from ....j2filters.generate_esi import generate_esi +from ....j2filters.generate_route_target import generate_route_target +from ....vendor.j2.filter.generate_lacp_id import generate_lacp_id +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import append_if_not_duplicate, get +from ...interface_descriptions import InterfaceDescriptionData from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigConnectedEndpoints + class PortChannelInterfacesMixin(UtilsMixin): """ @@ -25,7 +28,7 @@ class PortChannelInterfacesMixin(UtilsMixin): """ @cached_property - def port_channel_interfaces(self) -> list | None: + def port_channel_interfaces(self: AvdStructuredConfigConnectedEndpoints) -> list | None: """ Return structured config for port_channel_interfaces @@ -110,7 +113,9 @@ def port_channel_interfaces(self) -> list | None: return None - def _get_port_channel_interface_cfg(self, adapter: dict, port_channel_interface_name: str, channel_group_id: int, connected_endpoint: dict) -> dict: + def _get_port_channel_interface_cfg( + self: AvdStructuredConfigConnectedEndpoints, adapter: dict, port_channel_interface_name: str, channel_group_id: int, connected_endpoint: dict + ) -> dict: """ Return structured_config for one port_channel_interface """ @@ -189,7 +194,9 @@ def _get_port_channel_interface_cfg(self, adapter: dict, port_channel_interface_ return strip_null_from_data(port_channel_interface, strip_values_tuple=(None, "")) - def _get_port_channel_subinterface_cfg(self, subinterface: dict, adapter: dict, port_channel_subinterface_name: str, channel_group_id: int) -> dict: + def _get_port_channel_subinterface_cfg( + self: AvdStructuredConfigConnectedEndpoints, subinterface: dict, adapter: dict, port_channel_subinterface_name: str, channel_group_id: int + ) -> dict: """ Return structured_config for one port_channel_interface (subinterface) """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/utils.py b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/utils.py similarity index 85% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/utils.py rename to python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/utils.py index a0d279b7d96..8a87eae63ff 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/connected_endpoints/utils.py +++ b/python-avd/pyavd/_eos_designs/structured_config/connected_endpoints/utils.py @@ -6,13 +6,16 @@ import re from functools import cached_property from hashlib import sha256 +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.convert_dicts import convert_dicts -from ansible_collections.arista.avd.plugins.filter.generate_esi import generate_esi -from ansible_collections.arista.avd.plugins.filter.generate_route_target import generate_route_target -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item +from ....j2filters.convert_dicts import convert_dicts +from ....j2filters.generate_esi import generate_esi +from ....j2filters.generate_route_target import generate_route_target +from ....vendor.errors import AristaAvdError +from ....vendor.utils import get, get_item + +if TYPE_CHECKING: + from . import AvdStructuredConfigConnectedEndpoints class UtilsMixin: @@ -21,12 +24,8 @@ class UtilsMixin: Class should only be used as Mixin to a AvdStructuredConfig class or other Mixins. """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _filtered_connected_endpoints(self) -> list: + def _filtered_connected_endpoints(self: AvdStructuredConfigConnectedEndpoints) -> list: """ Return list of endpoints defined under one of the keys in "connected_endpoints_keys" which are connected to this switch. @@ -71,7 +70,7 @@ def _filtered_connected_endpoints(self) -> list: return filtered_connected_endpoints @cached_property - def _filtered_network_ports(self) -> list: + def _filtered_network_ports(self: AvdStructuredConfigConnectedEndpoints) -> list: """ Return list of endpoints defined under "network_ports" which are connected to this switch. @@ -86,14 +85,16 @@ def _filtered_network_ports(self) -> list: return filtered_network_ports - def _match_regexes(self, regexes: list, value: str) -> bool: + def _match_regexes(self: AvdStructuredConfigConnectedEndpoints, regexes: list, value: str) -> bool: """ Match a list of regexes with the supplied value. Regex must match the full value to pass, so regex is wrapped in ^$ """ return any(re.match(rf"^{regex}$", value) for regex in regexes) - def _get_short_esi(self, adapter: dict, channel_group_id: int, short_esi: str = None, hash_extra_value: str = "") -> str | None: + def _get_short_esi( + self: AvdStructuredConfigConnectedEndpoints, adapter: dict, channel_group_id: int, short_esi: str = None, hash_extra_value: str = "" + ) -> str | None: """ Return short_esi for one adapter """ @@ -123,7 +124,7 @@ def _get_short_esi(self, adapter: dict, channel_group_id: int, short_esi: str = return short_esi - def _get_adapter_trunk_groups(self, adapter: dict, connected_endpoint: dict) -> dict | None: + def _get_adapter_trunk_groups(self: AvdStructuredConfigConnectedEndpoints, adapter: dict, connected_endpoint: dict) -> dict | None: """ Return trunk_groups for one adapter """ @@ -132,7 +133,7 @@ def _get_adapter_trunk_groups(self, adapter: dict, connected_endpoint: dict) -> return None - def _get_adapter_storm_control(self, adapter: dict) -> dict | None: + def _get_adapter_storm_control(self: AvdStructuredConfigConnectedEndpoints, adapter: dict) -> dict | None: """ Return storm_control for one adapter """ @@ -142,7 +143,7 @@ def _get_adapter_storm_control(self, adapter: dict) -> dict | None: return None def _get_adapter_evpn_ethernet_segment_cfg( - self, + self: AvdStructuredConfigConnectedEndpoints, adapter: dict, short_esi: str, node_index: int, @@ -192,7 +193,7 @@ def _get_adapter_evpn_ethernet_segment_cfg( return evpn_ethernet_segment - def _get_adapter_link_tracking_groups(self, adapter: dict) -> list | None: + def _get_adapter_link_tracking_groups(self: AvdStructuredConfigConnectedEndpoints, adapter: dict) -> list | None: """ Return link_tracking_groups for one adapter """ @@ -206,7 +207,7 @@ def _get_adapter_link_tracking_groups(self, adapter: dict) -> list | None: } ] - def _get_adapter_ptp(self, adapter: dict) -> dict | None: + def _get_adapter_ptp(self: AvdStructuredConfigConnectedEndpoints, adapter: dict) -> dict | None: """ Return ptp for one adapter """ @@ -228,7 +229,7 @@ def _get_adapter_ptp(self, adapter: dict) -> dict | None: return ptp_config - def _get_adapter_poe(self, adapter: dict) -> dict | None: + def _get_adapter_poe(self: AvdStructuredConfigConnectedEndpoints, adapter: dict) -> dict | None: """ Return poe settings for one adapter """ @@ -237,7 +238,7 @@ def _get_adapter_poe(self, adapter: dict) -> dict | None: return None - def _get_adapter_phone(self, adapter: dict, connected_endpoint: dict) -> dict | None: + def _get_adapter_phone(self: AvdStructuredConfigConnectedEndpoints, adapter: dict, connected_endpoint: dict) -> dict | None: """ Return phone settings for one adapter """ @@ -260,12 +261,12 @@ def _get_adapter_phone(self, adapter: dict, connected_endpoint: dict) -> dict | "trunk": get(adapter, "phone_trunk_mode"), } - def _get_adapter_sflow(self, adapter: dict) -> dict | None: + def _get_adapter_sflow(self: AvdStructuredConfigConnectedEndpoints, adapter: dict) -> dict | None: if (adapter_sflow := get(adapter, "sflow", default=self.shared_utils.fabric_sflow_endpoints)) is not None: return {"enable": adapter_sflow} return None - def _get_adapter_flow_tracking(self, adapter: dict) -> dict | None: + def _get_adapter_flow_tracking(self: AvdStructuredConfigConnectedEndpoints, adapter: dict) -> dict | None: # Adapter flow tracking variables will be validated in _filtered_connected_endpoints return self.shared_utils.get_flow_tracker(adapter, "endpoints") diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/__init__.py similarity index 95% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/__init__.py index 19adf05f58a..00e9c016d0e 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/__init__.py @@ -1,8 +1,7 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts - +from ....vendor.avdfacts import AvdFacts from .ethernet_interfaces import EthernetInterfacesMixin from .port_channel_interfaces import PortChannelInterfacesMixin from .router_bgp import RouterBgpMixin diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/ethernet_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/ethernet_interfaces.py similarity index 89% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/ethernet_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/ethernet_interfaces.py index 783b4c2b574..f208b705049 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/ethernet_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/ethernet_interfaces.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigCoreInterfacesAndL3Edge + class EthernetInterfacesMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class EthernetInterfacesMixin(UtilsMixin): """ @cached_property - def ethernet_interfaces(self) -> list | None: + def ethernet_interfaces(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> list | None: """ Return structured config for ethernet_interfaces """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/port_channel_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/port_channel_interfaces.py similarity index 84% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/port_channel_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/port_channel_interfaces.py index e6265443d18..3e2f36227ac 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/port_channel_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/port_channel_interfaces.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigCoreInterfacesAndL3Edge + class PortChannelInterfacesMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class PortChannelInterfacesMixin(UtilsMixin): """ @cached_property - def port_channel_interfaces(self) -> list | None: + def port_channel_interfaces(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> list | None: """ Return structured config for port_channel_interfaces """ @@ -31,7 +35,6 @@ def port_channel_interfaces(self) -> list | None: port_channel_interface = {key: value for key, value in port_channel_interface.items() if value is not None} port_channel_interfaces.append(port_channel_interface) - continue if port_channel_interfaces: return port_channel_interfaces diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/router_bgp.py b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/router_bgp.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/router_bgp.py rename to python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/router_bgp.py index aa9db455363..ed0170bab89 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/router_bgp.py +++ b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/router_bgp.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError - +from ....vendor.errors import AristaAvdMissingVariableError from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigCoreInterfacesAndL3Edge + class RouterBgpMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class RouterBgpMixin(UtilsMixin): """ @cached_property - def router_bgp(self) -> dict | None: + def router_bgp(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> dict | None: """ Return structured config for router_bgp """ @@ -28,7 +31,7 @@ def router_bgp(self) -> dict | None: neighbors = [] neighbor_interfaces = [] for p2p_link in self._filtered_p2p_links: - if not (p2p_link.get("include_in_underlay_protocol", True) is True): + if p2p_link.get("include_in_underlay_protocol", True) is not True: continue if p2p_link["data"]["bgp_as"] is None or p2p_link["data"]["peer_bgp_as"] is None: diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/router_ospf.py b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/router_ospf.py similarity index 85% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/router_ospf.py rename to python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/router_ospf.py index c861065532a..e8abeeb74b7 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/router_ospf.py +++ b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/router_ospf.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigCoreInterfacesAndL3Edge + class RouterOspfMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class RouterOspfMixin(UtilsMixin): """ @cached_property - def router_ospf(self) -> dict | None: + def router_ospf(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> dict | None: """ Return structured config for router_ospf """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/utils.py b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/utils.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/utils.py rename to python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/utils.py index 9415374fa02..6083674fe7a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/core_interfaces_and_l3_edge/utils.py +++ b/python-avd/pyavd/_eos_designs/structured_config/core_interfaces_and_l3_edge/utils.py @@ -8,12 +8,15 @@ from functools import cached_property from ipaddress import ip_network from itertools import islice +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.convert_dicts import convert_dicts -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.merge import merge -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get, get_item +from ....j2filters.convert_dicts import convert_dicts +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.merge import merge +from ....vendor.utils import default, get, get_item + +if TYPE_CHECKING: + from . import AvdStructuredConfigCoreInterfacesAndL3Edge class UtilsMixin: @@ -22,28 +25,24 @@ class UtilsMixin: Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _p2p_links_profiles(self) -> list: + def _p2p_links_profiles(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> list: return get(self._hostvars, f"{self.data_model}.p2p_links_profiles", default=[]) @cached_property - def _p2p_links_ip_pools(self) -> list: + def _p2p_links_ip_pools(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> list: return get(self._hostvars, f"{self.data_model}.p2p_links_ip_pools", default=[]) @cached_property - def _p2p_links(self) -> list: + def _p2p_links(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> list: return get(self._hostvars, f"{self.data_model}.p2p_links", default=[]) @cached_property - def _p2p_links_sflow(self) -> bool | None: + def _p2p_links_sflow(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> bool | None: return get(self._hostvars, f"fabric_sflow.{self.data_model}") @cached_property - def _filtered_p2p_links(self) -> list: + def _filtered_p2p_links(self: AvdStructuredConfigCoreInterfacesAndL3Edge) -> list: """ Returns a filtered list of p2p_links, which only contains links with our hostname. For each links any referenced profiles are applied and IP addresses are resolved @@ -70,7 +69,7 @@ def _filtered_p2p_links(self) -> list: return p2p_links - def _apply_p2p_links_profile(self, target_dict: dict) -> dict: + def _apply_p2p_links_profile(self: AvdStructuredConfigCoreInterfacesAndL3Edge, target_dict: dict) -> dict: """ Apply a profile to a p2p_link """ @@ -83,7 +82,7 @@ def _apply_p2p_links_profile(self, target_dict: dict) -> dict: merged_dict.pop("name", None) return merged_dict - def _resolve_p2p_ips(self, p2p_link: dict) -> dict: + def _resolve_p2p_ips(self: AvdStructuredConfigCoreInterfacesAndL3Edge, p2p_link: dict) -> dict: if "ip" in p2p_link: # ip already set, so nothing to do return p2p_link @@ -111,7 +110,7 @@ def _resolve_p2p_ips(self, p2p_link: dict) -> dict: p2p_link["ip"] = [f"{ip}/{subnet.prefixlen}" for ip in islice(subnet.hosts(), 2)] return p2p_link - def _get_p2p_data(self, p2p_link: dict) -> dict: + def _get_p2p_data(self: AvdStructuredConfigCoreInterfacesAndL3Edge, p2p_link: dict) -> dict: """ Parses p2p_link data model and extracts information which is easier to parse. Returns: @@ -206,7 +205,7 @@ def _get_p2p_data(self, p2p_link: dict) -> dict: raise AristaAvdMissingVariableError(f"{self.data_model}.p2p_links must have either 'interfaces' or 'port_channel' with correct members set.") - def _get_common_interface_cfg(self, p2p_link: dict) -> dict: + def _get_common_interface_cfg(self: AvdStructuredConfigCoreInterfacesAndL3Edge, p2p_link: dict) -> dict: """ Return partial structured_config for one p2p_link. Covers common config that is applicable to both port-channels and ethernet interfaces. @@ -288,7 +287,7 @@ def _get_common_interface_cfg(self, p2p_link: dict) -> dict: return interface_cfg - def _get_ethernet_cfg(self, p2p_link: dict) -> dict: + def _get_ethernet_cfg(self: AvdStructuredConfigCoreInterfacesAndL3Edge, p2p_link: dict) -> dict: """ Return partial structured_config for one p2p_link. Covers config that is only applicable to ethernet interfaces. @@ -312,7 +311,7 @@ def _get_ethernet_cfg(self, p2p_link: dict) -> dict: return ethernet_cfg - def _get_port_channel_member_cfg(self, p2p_link: dict, member: dict) -> dict: + def _get_port_channel_member_cfg(self: AvdStructuredConfigCoreInterfacesAndL3Edge, p2p_link: dict, member: dict) -> dict: """ Return partial structured_config for one p2p_link. Covers config for ethernet interfaces that are port-channel members. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/custom_structured_configuration/__init__.py similarity index 97% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/custom_structured_configuration/__init__.py index d0b7755a62f..36480a39a0a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/custom_structured_configuration/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/custom_structured_configuration/__init__.py @@ -5,8 +5,8 @@ from functools import cached_property -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get +from ....vendor.avdfacts import AvdFacts +from ....vendor.utils import get CUSTOM_STRUCTURED_CONFIGURATION_EXEMPT_KEYS = ["custom_structured_configuration_prefix", "custom_structured_configuration_list_merge"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/flows/__init__.py similarity index 95% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/flows/__init__.py index 394345b83d5..e76e998676b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/flows/__init__.py @@ -5,11 +5,11 @@ from functools import cached_property -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -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 get, get_item +from ....j2filters.natural_sort import natural_sort +from ....vendor.avdfacts import AvdFacts +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import get, get_item class AvdStructuredConfigFlows(AvdFacts): @@ -170,7 +170,7 @@ def flow_tracking(self) -> dict | None: Return structured config for flow_tracking """ configured_trackers = self._get_enabled_flow_trackers() - if not (configured_trackers): + if not configured_trackers: return None flow_tracking = {} diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/inband_management/__init__.py similarity index 94% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/inband_management/__init__.py index cd1f48b0370..817c4936264 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/inband_management/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/inband_management/__init__.py @@ -6,11 +6,11 @@ from functools import cached_property from ipaddress import ip_network -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.errors.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get +from ....j2filters.natural_sort import natural_sort +from ....vendor.avdfacts import AvdFacts +from ....vendor.errors.errors import AristaAvdMissingVariableError +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import get class AvdStructuredConfigInbandManagement(AvdFacts): @@ -49,7 +49,7 @@ def vlan_interfaces(self) -> list | None: @cached_property def _inband_mgmt_ipv6_parent(self) -> bool: if self._inband_management_parent_vlans: - for vlan, subnet in self._inband_management_parent_vlans.items(): + for subnet in self._inband_management_parent_vlans.values(): if subnet["ipv6"]: return True return False @@ -57,7 +57,7 @@ def _inband_mgmt_ipv6_parent(self) -> bool: @cached_property def _inband_mgmt_ipv4_parent(self) -> bool: if self._inband_management_parent_vlans: - for vlan, subnet in self._inband_management_parent_vlans.items(): + for subnet in self._inband_management_parent_vlans.values(): if subnet["ipv4"]: return True return False diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/metadata/__init__.py similarity index 93% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/metadata/__init__.py index 23ea3bce199..27c90b6fdcd 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/metadata/__init__.py @@ -5,9 +5,8 @@ from functools import cached_property -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict - +from ....vendor.avdfacts import AvdFacts +from ....vendor.strip_empties import strip_empties_from_dict from .cv_pathfinder import CvPathfinderMixin from .cv_tags import CvTagsMixin diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/cv_pathfinder.py b/python-avd/pyavd/_eos_designs/structured_config/metadata/cv_pathfinder.py similarity index 97% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/cv_pathfinder.py rename to python-avd/pyavd/_eos_designs/structured_config/metadata/cv_pathfinder.py index fde6bc5b586..fb2fb8db4b1 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/cv_pathfinder.py +++ b/python-avd/pyavd/_eos_designs/structured_config/metadata/cv_pathfinder.py @@ -6,11 +6,11 @@ from functools import cached_property from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item +from ....vendor.errors import AristaAvdError +from ....vendor.utils import get, get_item if TYPE_CHECKING: - from .avdstructuredconfig import AvdStructuredConfigMetadata + from . import AvdStructuredConfigMetadata class CvPathfinderMixin: diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/cv_tags.py b/python-avd/pyavd/_eos_designs/structured_config/metadata/cv_tags.py similarity index 96% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/cv_tags.py rename to python-avd/pyavd/_eos_designs/structured_config/metadata/cv_tags.py index 17b64784f0a..63add638449 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/metadata/cv_tags.py +++ b/python-avd/pyavd/_eos_designs/structured_config/metadata/cv_tags.py @@ -6,12 +6,12 @@ from functools import cached_property from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict, strip_empties_from_list -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get, get_item +from ....vendor.errors import AristaAvdError +from ....vendor.strip_empties import strip_empties_from_dict, strip_empties_from_list +from ....vendor.utils import default, get, get_item if TYPE_CHECKING: - from .avdstructuredconfig import AvdStructuredConfigMetadata + from . import AvdStructuredConfigMetadata INVALID_CUSTOM_DEVICE_TAGS = [ "topology_hint_type", diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/mlag/__init__.py similarity index 97% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/mlag/__init__.py index 4bedeea694a..f42b9c40472 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/mlag/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/mlag/__init__.py @@ -5,12 +5,11 @@ from functools import cached_property -from ansible_collections.arista.avd.plugins.filter.list_compress import list_compress -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get - -from ..interface_descriptions import InterfaceDescriptionData +from ....j2filters.list_compress import list_compress +from ....vendor.avdfacts import AvdFacts +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import default, get +from ...interface_descriptions import InterfaceDescriptionData class AvdStructuredConfigMlag(AvdFacts): diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/__init__.py similarity index 98% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/__init__.py index 55470fe971e..138762d6f60 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/__init__.py @@ -1,8 +1,7 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts - +from ....vendor.avdfacts import AvdFacts from .application_traffic_recognition import ApplicationTrafficRecognitionMixin from .dps_interfaces import DpsInterfacesMixin from .eos_cli import EosCliMixin diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/application_traffic_recognition.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/application_traffic_recognition.py similarity index 95% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/application_traffic_recognition.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/application_traffic_recognition.py index 6bd1a339729..76bcd5ddd42 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/application_traffic_recognition.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/application_traffic_recognition.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get, get_item - +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate, get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class ApplicationTrafficRecognitionMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class ApplicationTrafficRecognitionMixin(UtilsMixin): """ @cached_property - def application_traffic_recognition(self) -> dict | None: + def application_traffic_recognition(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for application_traffic_recognition if wan router """ @@ -33,15 +36,15 @@ def application_traffic_recognition(self) -> dict | None: # self._wan_control_plane_application_profile is defined in utils.py @cached_property - def _wan_control_plane_application(self) -> str: + def _wan_control_plane_application(self: AvdStructuredConfigNetworkServices) -> str: return "APP-CONTROL-PLANE" @cached_property - def _wan_cp_app_dst_prefix(self) -> str: + def _wan_cp_app_dst_prefix(self: AvdStructuredConfigNetworkServices) -> str: return "PFX-PATHFINDERS" @cached_property - def _wan_cp_app_src_prefix(self) -> str: + def _wan_cp_app_src_prefix(self: AvdStructuredConfigNetworkServices) -> str: return "PFX-LOCAL-VTEP-IP" def _generate_control_plane_application_profile(self, app_dict: dict) -> None: @@ -131,7 +134,7 @@ def _generate_control_plane_application_profile(self, app_dict: dict) -> None: {"name": self._wan_cp_app_src_prefix, "prefix_values": [f"{self.shared_utils.vtep_ip}/32"]} ) - def _filtered_application_classification(self) -> dict: + def _filtered_application_classification(self: AvdStructuredConfigNetworkServices) -> dict: """ Based on the filtered policies local to the device, filter which application profiles should be configured on the device. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/dps_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/dps_interfaces.py similarity index 78% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/dps_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/dps_interfaces.py index 444f9de10b9..5c7cf749e69 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/dps_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/dps_interfaces.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class DpsInterfacesMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class DpsInterfacesMixin(UtilsMixin): """ @cached_property - def dps_interfaces(self) -> list | None: + def dps_interfaces(self: AvdStructuredConfigNetworkServices) -> list | None: """ Returns structured config for dps_interfaces @@ -37,7 +41,7 @@ def dps_interfaces(self) -> list | None: # TODO do IPv6 when needed - for now no easy way in AVD to detect if this is needed # When needed - need a default value if different than IPv4 - if (dpsFlow := self.shared_utils.get_flow_tracker(None, "dps_interfaces")) is not None: - dps1["flow_tracker"] = dpsFlow + if (dps_flow := self.shared_utils.get_flow_tracker(None, "dps_interfaces")) is not None: + dps1["flow_tracker"] = dps_flow return [dps1] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/eos_cli.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/eos_cli.py similarity index 83% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/eos_cli.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/eos_cli.py index 6306712e50b..910f618b099 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/eos_cli.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/eos_cli.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class EosCliMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class EosCliMixin(UtilsMixin): """ @cached_property - def eos_cli(self) -> dict | None: + def eos_cli(self: AvdStructuredConfigNetworkServices) -> str | None: """ Return existing eos_cli plus any eos_cli from VRFs """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ethernet_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ethernet_interfaces.py similarity index 97% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ethernet_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ethernet_interfaces.py index 30b1579b570..71932109cb9 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ethernet_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ethernet_interfaces.py @@ -5,13 +5,16 @@ import re from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get - +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdError +from ....vendor.utils import append_if_not_duplicate, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class EthernetInterfacesMixin(UtilsMixin): """ @@ -20,7 +23,7 @@ class EthernetInterfacesMixin(UtilsMixin): """ @cached_property - def ethernet_interfaces(self) -> list | None: + def ethernet_interfaces(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for ethernet_interfaces diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_access_lists.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_access_lists.py similarity index 83% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_access_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ip_access_lists.py index e15c22191b9..4a7125ebb49 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_access_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_access_lists.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class IpAccesslistsMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class IpAccesslistsMixin(UtilsMixin): """ @cached_property - def ip_access_lists(self) -> list | None: + def ip_access_lists(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for ip_access_lists. """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_igmp_snooping.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_igmp_snooping.py similarity index 91% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_igmp_snooping.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ip_igmp_snooping.py index c0ad79a6dfa..337daac7bc6 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_igmp_snooping.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_igmp_snooping.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get - +from ....vendor.utils import append_if_not_duplicate, default, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class IpIgmpSnoopingMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class IpIgmpSnoopingMixin(UtilsMixin): """ @cached_property - def ip_igmp_snooping(self) -> dict | None: + def ip_igmp_snooping(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for ip_igmp_snooping """ @@ -28,7 +31,7 @@ def ip_igmp_snooping(self) -> dict | None: ip_igmp_snooping = {} igmp_snooping_enabled = self.shared_utils.igmp_snooping_enabled ip_igmp_snooping["globally_enabled"] = igmp_snooping_enabled - if not (igmp_snooping_enabled is True): + if igmp_snooping_enabled is not True: return ip_igmp_snooping vlans = [] @@ -59,7 +62,7 @@ def ip_igmp_snooping(self) -> dict | None: return ip_igmp_snooping - def _ip_igmp_snooping_vlan(self, vlan, tenant) -> dict: + def _ip_igmp_snooping_vlan(self: AvdStructuredConfigNetworkServices, vlan, tenant) -> dict: """ ip_igmp_snooping logic for one vlan diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_nat.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_nat.py similarity index 86% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_nat.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ip_nat.py index e276e1328c7..6ded30ba256 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_nat.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_nat.py @@ -5,9 +5,13 @@ from collections import defaultdict from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class IpNatMixin(UtilsMixin): """ @@ -16,7 +20,7 @@ class IpNatMixin(UtilsMixin): """ @cached_property - def ip_nat(self) -> dict | None: + def ip_nat(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Returns structured config for ip_nat """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_security.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_security.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_security.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ip_security.py index d9fc8af5b74..15994fc82e0 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_security.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_security.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -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 get - +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class IpSecurityMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class IpSecurityMixin(UtilsMixin): """ @cached_property - def ip_security(self) -> dict | None: + def ip_security(self: AvdStructuredConfigNetworkServices) -> dict | None: """ ip_security set based on cv_pathfinder_internet_exit_policies """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_virtual_router_mac_address.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_virtual_router_mac_address.py similarity index 80% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_virtual_router_mac_address.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ip_virtual_router_mac_address.py index ad706beeab9..315efa3d595 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ip_virtual_router_mac_address.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ip_virtual_router_mac_address.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class IpVirtualRouterMacAddressMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class IpVirtualRouterMacAddressMixin(UtilsMixin): """ @cached_property - def ip_virtual_router_mac_address(self) -> str | None: + def ip_virtual_router_mac_address(self: AvdStructuredConfigNetworkServices) -> str | None: """ Return structured config for ip_virtual_router_mac_address """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ipv6_static_routes.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/ipv6_static_routes.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ipv6_static_routes.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/ipv6_static_routes.py index cb43e32b285..1fe4e3ced9a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/ipv6_static_routes.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/ipv6_static_routes.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class Ipv6StaticRoutesMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class Ipv6StaticRoutesMixin(UtilsMixin): """ @cached_property - def ipv6_static_routes(self) -> list[dict] | None: + def ipv6_static_routes(self: AvdStructuredConfigNetworkServices) -> list[dict] | None: """ Returns structured config for ipv6_static_routes diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/loopback_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/loopback_interfaces.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/loopback_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/loopback_interfaces.py index 98f5b4c5350..ba619574c24 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/loopback_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/loopback_interfaces.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get, get_item - +from ....vendor.utils import append_if_not_duplicate, get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class LoopbackInterfacesMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class LoopbackInterfacesMixin(UtilsMixin): """ @cached_property - def loopback_interfaces(self) -> list | None: + def loopback_interfaces(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for loopback_interfaces @@ -25,7 +28,7 @@ def loopback_interfaces(self) -> list | None: This function is also called from virtual_source_nat_vrfs to avoid duplicate logic """ - if not (self.shared_utils.network_services_l3): + if not self.shared_utils.network_services_l3: return None loopback_interfaces = [] @@ -73,7 +76,7 @@ def loopback_interfaces(self) -> list | None: return None - def _get_vtep_diagnostic_loopback_for_vrf(self, vrf: dict) -> dict | None: + def _get_vtep_diagnostic_loopback_for_vrf(self: AvdStructuredConfigNetworkServices, vrf: dict) -> dict | None: if (loopback := get(vrf, "vtep_diagnostic.loopback")) is None: return None diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/metadata.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/metadata.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/metadata.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/metadata.py index a79fc2401a9..b2a2418f3f9 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/metadata.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/metadata.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_list -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.strip_empties import strip_empties_from_list +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class MetadataMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class MetadataMixin(UtilsMixin): """ @cached_property - def metadata(self) -> dict | None: + def metadata(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Generate metadata.cv_pathfinder.internet_exit_policies if available. """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/monitor_connectivity.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/monitor_connectivity.py similarity index 88% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/monitor_connectivity.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/monitor_connectivity.py index 250928a87db..6a1104a9b49 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/monitor_connectivity.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/monitor_connectivity.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class MonitorConnectivityMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class MonitorConnectivityMixin(UtilsMixin): """ @cached_property - def monitor_connectivity(self) -> dict | None: + def monitor_connectivity(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for monitor_connectivity diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/patch_panel.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/patch_panel.py similarity index 94% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/patch_panel.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/patch_panel.py index 9ec27ea8df1..7918e39df21 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/patch_panel.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/patch_panel.py @@ -5,12 +5,15 @@ import re from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get - +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import append_if_not_duplicate, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class PatchPanelMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class PatchPanelMixin(UtilsMixin): """ @cached_property - def patch_panel(self) -> dict | None: + def patch_panel(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for patch_panel """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/port_channel_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/port_channel_interfaces.py similarity index 92% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/port_channel_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/port_channel_interfaces.py index f41fce06f20..3bfb3f14f72 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/port_channel_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/port_channel_interfaces.py @@ -5,15 +5,18 @@ import re from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.generate_esi import generate_esi -from ansible_collections.arista.avd.plugins.filter.generate_lacp_id import generate_lacp_id -from ansible_collections.arista.avd.plugins.filter.generate_route_target import generate_route_target -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get - +from ....j2filters.generate_esi import generate_esi +from ....j2filters.generate_route_target import generate_route_target +from ....j2filters.natural_sort import natural_sort +from ....vendor.j2.filter.generate_lacp_id import generate_lacp_id +from ....vendor.utils import append_if_not_duplicate, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class PortChannelInterfacesMixin(UtilsMixin): """ @@ -22,7 +25,7 @@ class PortChannelInterfacesMixin(UtilsMixin): """ @cached_property - def port_channel_interfaces(self) -> list | None: + def port_channel_interfaces(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for port_channel_interfaces diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/prefix_lists.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/prefix_lists.py similarity index 89% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/prefix_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/prefix_lists.py index c8bf9c4097b..a796b98abd9 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/prefix_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/prefix_lists.py @@ -5,11 +5,14 @@ from functools import cached_property from ipaddress import IPv4Network +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort - +from ....j2filters.natural_sort import natural_sort from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class PrefixListsMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class PrefixListsMixin(UtilsMixin): """ @cached_property - def prefix_lists(self) -> list | None: + def prefix_lists(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for prefix_lists @@ -42,7 +45,7 @@ def prefix_lists(self) -> list | None: return None - def _prefix_lists_vrf_default(self) -> list: + def _prefix_lists_vrf_default(self: AvdStructuredConfigNetworkServices) -> list: """ prefix_lists for EVPN services in VRF "default" """ @@ -71,7 +74,7 @@ def _prefix_lists_vrf_default(self) -> list: return prefix_lists @cached_property - def _mlag_ibgp_peering_subnets_without_redistribution(self) -> list: + def _mlag_ibgp_peering_subnets_without_redistribution(self: AvdStructuredConfigNetworkServices) -> list: """ Return sorted list of MLAG peerings for VRFs where MLAG iBGP peering should not be redistributed """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/route_maps.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/route_maps.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/route_maps.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/route_maps.py index b0c7fdfdfe3..a3e6d47010a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/route_maps.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/route_maps.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_list -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.strip_empties import strip_empties_from_list +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouteMapsMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouteMapsMixin(UtilsMixin): """ @cached_property - def route_maps(self) -> list | None: + def route_maps(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for route_maps @@ -81,7 +84,7 @@ def route_maps(self) -> list | None: return None @cached_property - def _route_maps_vrf_default(self) -> list | None: + def _route_maps_vrf_default(self: AvdStructuredConfigNetworkServices) -> list | None: """ Route-maps for EVPN services in VRF "default" @@ -106,7 +109,7 @@ def _route_maps_vrf_default(self) -> list | None: return route_maps or None - def _bgp_mlag_peer_group_route_map(self) -> dict: + def _bgp_mlag_peer_group_route_map(self: AvdStructuredConfigNetworkServices) -> dict: """ Return dict with one route-map Origin Incomplete for MLAG iBGP learned routes @@ -125,7 +128,7 @@ def _bgp_mlag_peer_group_route_map(self) -> dict: ], } - def _connected_to_bgp_vrfs_route_map(self) -> dict: + def _connected_to_bgp_vrfs_route_map(self: AvdStructuredConfigNetworkServices) -> dict: """ Return dict with one route-map Filter MLAG peer subnets for redistribute connected for overlay VRFs @@ -145,7 +148,7 @@ def _connected_to_bgp_vrfs_route_map(self) -> dict: ], } - def _evpn_export_vrf_default_route_map(self) -> dict | None: + def _evpn_export_vrf_default_route_map(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Match the following prefixes to be exported in EVPN for VRF default: * SVI subnets in VRF default @@ -187,7 +190,7 @@ def _evpn_export_vrf_default_route_map(self) -> dict | None: return {"name": "RM-EVPN-EXPORT-VRF-DEFAULT", "sequence_numbers": sequence_numbers} - def _bgp_underlay_peers_route_map(self) -> dict | None: + def _bgp_underlay_peers_route_map(self: AvdStructuredConfigNetworkServices) -> dict | None: """ For non WAN routers filter EVPN routes away from underlay. @@ -229,7 +232,7 @@ def _bgp_underlay_peers_route_map(self) -> dict | None: return {"name": "RM-BGP-UNDERLAY-PEERS-OUT", "sequence_numbers": sequence_numbers} - def _redistribute_connected_to_bgp_route_map(self) -> dict | None: + def _redistribute_connected_to_bgp_route_map(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Append network services relevant entries to the route-map used to redistribute connected subnets in BGP @@ -257,7 +260,7 @@ def _redistribute_connected_to_bgp_route_map(self) -> dict | None: return {"name": "RM-CONN-2-BGP", "sequence_numbers": sequence_numbers} - def _redistribute_static_to_bgp_route_map(self) -> dict | None: + def _redistribute_static_to_bgp_route_map(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Append network services relevant entries to the route-map used to redistribute static routes to BGP """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_adaptive_virtual_topology.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_adaptive_virtual_topology.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_adaptive_virtual_topology.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_adaptive_virtual_topology.py index 266d95f3f0a..1e61f0263bc 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_adaptive_virtual_topology.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_adaptive_virtual_topology.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get, get_item - +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate, get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterAdaptiveVirtualTopologyMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouterAdaptiveVirtualTopologyMixin(UtilsMixin): """ @cached_property - def router_adaptive_virtual_topology(self) -> dict | None: + def router_adaptive_virtual_topology(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for profiles, policies and VRFs for router adaptive-virtual-topology (AVT) """ @@ -33,7 +36,7 @@ def router_adaptive_virtual_topology(self) -> dict | None: return strip_empties_from_dict(router_adaptive_virtual_topology) - def _cv_pathfinder_wan_vrfs(self) -> list: + def _cv_pathfinder_wan_vrfs(self: AvdStructuredConfigNetworkServices) -> list: """ Return a list of WAN VRFs based on filtered tenants and the AVT. """ @@ -71,7 +74,7 @@ def _cv_pathfinder_wan_vrfs(self) -> list: return wan_vrfs - def _cv_pathfinder_policies(self) -> list: + def _cv_pathfinder_policies(self: AvdStructuredConfigNetworkServices) -> list: """ Build and return the CV Pathfinder policies based on the computed _filtered_wan_policies. @@ -102,7 +105,7 @@ def _cv_pathfinder_policies(self) -> list: return policies - def _cv_pathfinder_profiles(self) -> list: + def _cv_pathfinder_profiles(self: AvdStructuredConfigNetworkServices) -> list: """ Return a list of router adaptive-virtual-topology profiles for this router. """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_bgp.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_bgp.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_bgp.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_bgp.py index abf09458330..16ded26c389 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_bgp.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_bgp.py @@ -7,16 +7,19 @@ from functools import cached_property from itertools import groupby as itertools_groupby from re import fullmatch as re_fullmatch - -from ansible_collections.arista.avd.plugins.filter.list_compress import list_compress -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.merge import merge -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get, get_item - +from typing import TYPE_CHECKING + +from ....j2filters.list_compress import list_compress +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.merge import merge +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate, default, get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterBgpMixin(UtilsMixin): """ @@ -25,7 +28,7 @@ class RouterBgpMixin(UtilsMixin): """ @cached_property - def router_bgp(self) -> dict | None: + def router_bgp(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return the structured config for router_bgp @@ -55,7 +58,7 @@ def router_bgp(self) -> dict | None: router_bgp = {key: value for key, value in router_bgp.items() if value is not None} return router_bgp - def _router_bgp_peer_groups(self) -> dict: + def _router_bgp_peer_groups(self: AvdStructuredConfigNetworkServices) -> dict: """ Return the structured config for router_bgp.peer_groups @@ -75,7 +78,7 @@ def _router_bgp_peer_groups(self) -> dict: if not (vrf["bgp_peers"] or vrf.get("bgp_peer_groups")): continue - vrf_peer_peergroups = set([peer["peer_group"] for peer in vrf["bgp_peers"] if "peer_group" in peer]) + vrf_peer_peergroups = set(peer["peer_group"] for peer in vrf["bgp_peers"] if "peer_group" in peer) peer_groups.extend( [ peer_group @@ -133,7 +136,7 @@ def _router_bgp_peer_groups(self) -> dict: return {} @cached_property - def _router_bgp_vrfs(self) -> list | None: + def _router_bgp_vrfs(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for router_bgp.vrfs @@ -252,7 +255,7 @@ def _router_bgp_vrfs(self) -> list | None: return vrfs or None - def _update_router_bgp_vrf_evpn_or_mpls_cfg(self, bgp_vrf: dict, vrf: dict, vrf_address_families: list) -> None: + def _update_router_bgp_vrf_evpn_or_mpls_cfg(self: AvdStructuredConfigNetworkServices, bgp_vrf: dict, vrf: dict, vrf_address_families: list) -> None: """ In-place update EVPN/MPLS part of structured config for *one* VRF under router_bgp.vrfs """ @@ -299,9 +302,7 @@ def _update_router_bgp_vrf_evpn_or_mpls_cfg(self, bgp_vrf: dict, vrf: dict, vrf_ if (evpn_multicast_transit_mode := get(vrf, "_evpn_l3_multicast_evpn_peg_transit")) is True: bgp_vrf["evpn_multicast_address_family"] = {"ipv4": {"transit": evpn_multicast_transit_mode}} - return - - def _update_router_bgp_vrf_mlag_neighbor_cfg(self, bgp_vrf: dict, vrf: dict, tenant: dict, vlan_id: int) -> None: + def _update_router_bgp_vrf_mlag_neighbor_cfg(self: AvdStructuredConfigNetworkServices, bgp_vrf: dict, vrf: dict, tenant: dict, vlan_id: int) -> None: """ In-place update MLAG neighbor part of structured config for *one* VRF under router_bgp.vrfs """ @@ -343,16 +344,15 @@ def _update_router_bgp_vrf_mlag_neighbor_cfg(self, bgp_vrf: dict, vrf: dict, ten }, } ) - return - def _router_bgp_sorted_vlans_and_svis_lists(self) -> dict: + def _router_bgp_sorted_vlans_and_svis_lists(self: AvdStructuredConfigNetworkServices) -> dict: tenant_svis_l2vlans_dict = {} for tenant in self.shared_utils.filtered_tenants: tenant_svis_l2vlans_dict[tenant["name"]] = {} # For L2VLANs l2vlans_bundle_dict = {} - l2vlans_nonBundle_list = {} + l2vlans_non_bundle_list = {} sorted_vlan_list = sorted(tenant["l2vlans"], key=self._get_vlan_aware_bundle_name_tuple_for_l2vlans) bundle_groups = itertools_groupby(sorted_vlan_list, self._get_vlan_aware_bundle_name_tuple_for_l2vlans) for vlan_aware_bundle_name_tuple, l2vlans in bundle_groups: @@ -362,13 +362,13 @@ def _router_bgp_sorted_vlans_and_svis_lists(self) -> dict: if is_evpn_vlan_bundle: l2vlans_bundle_dict[bundle_name] = l2vlans else: - l2vlans_nonBundle_list[bundle_name] = l2vlans + l2vlans_non_bundle_list[bundle_name] = l2vlans # For SVIs vrf_svis_bundle_dict = {} - vrf_svis_nonBundle_dict = {} + vrf_svis_non_bundle_dict = {} for vrf in tenant["vrfs"]: - vrf_svis_nonBundle_dict[vrf["name"]] = [] + vrf_svis_non_bundle_dict[vrf["name"]] = [] vrf_svis_bundle_dict[vrf["name"]] = {} sorted_svi_list = sorted(vrf["svis"], key=self._get_vlan_aware_bundle_name_tuple_for_svis) bundle_groups_svis = itertools_groupby(sorted_svi_list, self._get_vlan_aware_bundle_name_tuple_for_svis) @@ -379,16 +379,16 @@ def _router_bgp_sorted_vlans_and_svis_lists(self) -> dict: if is_evpn_vlan_bundle: vrf_svis_bundle_dict[vrf["name"]][bundle_name] = svis else: - vrf_svis_nonBundle_dict[vrf["name"]] = svis + vrf_svis_non_bundle_dict[vrf["name"]] = svis tenant_svis_l2vlans_dict[tenant["name"]]["svi_bundle"] = vrf_svis_bundle_dict - tenant_svis_l2vlans_dict[tenant["name"]]["svi_nonBundle"] = vrf_svis_nonBundle_dict + tenant_svis_l2vlans_dict[tenant["name"]]["svi_non_bundle"] = vrf_svis_non_bundle_dict tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_bundle"] = l2vlans_bundle_dict - tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_nonBundle"] = l2vlans_nonBundle_list + tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_non_bundle"] = l2vlans_non_bundle_list return tenant_svis_l2vlans_dict - def _router_bgp_vlans(self, tenant_svis_l2vlans_dict) -> list | None: + def _router_bgp_vlans(self: AvdStructuredConfigNetworkServices, tenant_svis_l2vlans_dict) -> list | None: """ Return structured config for router_bgp.vlans """ @@ -404,7 +404,7 @@ def _router_bgp_vlans(self, tenant_svis_l2vlans_dict) -> list | None: vlans = [] for tenant in self.shared_utils.filtered_tenants: for vrf in tenant["vrfs"]: - for svi in tenant_svis_l2vlans_dict[tenant["name"]]["svi_nonBundle"][vrf["name"]]: + for svi in tenant_svis_l2vlans_dict[tenant["name"]]["svi_non_bundle"][vrf["name"]]: if (vlan := self._router_bgp_vlans_vlan(svi, tenant, vrf)) is not None: vlan_id = int(svi["id"]) vlan = {"id": vlan_id, **vlan} @@ -418,7 +418,7 @@ def _router_bgp_vlans(self, tenant_svis_l2vlans_dict) -> list | None: ) # L2 Vlans per Tenant - for bundle_name, l2vlans in tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_nonBundle"].items(): + for l2vlans in tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_non_bundle"].values(): for l2vlan in l2vlans: if (vlan := self._router_bgp_vlans_vlan(l2vlan, tenant, vrf={})) is not None: vlan_id = int(l2vlan["id"]) @@ -434,7 +434,7 @@ def _router_bgp_vlans(self, tenant_svis_l2vlans_dict) -> list | None: return vlans or None - def _router_bgp_vlans_vlan(self, vlan, tenant, vrf) -> dict | None: + def _router_bgp_vlans_vlan(self: AvdStructuredConfigNetworkServices, vlan, tenant, vrf) -> dict | None: """ Return structured config for one given vlan under router_bgp.vlans """ @@ -475,7 +475,7 @@ def _evpn_vlan_bundles(self) -> list: def _evpn_vlan_aware_bundles(self) -> bool: return get(self._hostvars, "evpn_vlan_aware_bundles", default=False) - def _get_vlan_aware_bundle_name_tuple_for_l2vlans(self, vlan: dict) -> tuple[str, bool] | None: + def _get_vlan_aware_bundle_name_tuple_for_l2vlans(self: AvdStructuredConfigNetworkServices, vlan: dict) -> tuple[str, bool] | None: """ Return a tuple with string with the vlan-aware-bundle name for one VLAN and a boolean saying if this is a evpn_vlan_bundle. """ @@ -483,7 +483,7 @@ def _get_vlan_aware_bundle_name_tuple_for_l2vlans(self, vlan: dict) -> tuple[str return (str(vlan.get("evpn_vlan_bundle")), True) return (str(vlan.get("name")), False) - def _get_vlan_aware_bundle_name_tuple_for_svis(self, vlan: dict) -> tuple[str, bool] | None: + def _get_vlan_aware_bundle_name_tuple_for_svis(self: AvdStructuredConfigNetworkServices, vlan: dict) -> tuple[str, bool] | None: """ Return a tuple with string with the vlan-aware-bundle name for one VLAN and a boolean saying if this is a evpn_vlan_bundle. If no bundle is configured, it will return an empty string as name, since the calling function will then get all svis without bundle @@ -493,7 +493,7 @@ def _get_vlan_aware_bundle_name_tuple_for_svis(self, vlan: dict) -> tuple[str, b return (str(vlan.get("evpn_vlan_bundle")), True) return ("", False) - def _get_evpn_vlan_bundle(self, vlan: dict, bundle_name: str) -> dict: + def _get_evpn_vlan_bundle(self: AvdStructuredConfigNetworkServices, vlan: dict, bundle_name: str) -> dict: """ Return an evpn_vlan_bundle dict if it exists, else raise an exception. """ @@ -504,7 +504,7 @@ def _get_evpn_vlan_bundle(self, vlan: dict, bundle_name: str) -> dict: ) return evpn_vlan_bundle - def _get_svi_l2vlan_bundle(self, evpn_vlan_bundle: dict, tenant: dict, vlans: list) -> dict | None: + def _get_svi_l2vlan_bundle(self: AvdStructuredConfigNetworkServices, evpn_vlan_bundle: dict, tenant: dict, vlans: list) -> dict | None: """ Return an bundle config for a svi or l2vlan. """ @@ -527,10 +527,10 @@ def _get_svi_l2vlan_bundle(self, evpn_vlan_bundle: dict, tenant: dict, vlans: li if (eos_cli := get(evpn_vlan_bundle, "bgp.raw_eos_cli")) is not None: bundle["eos_cli"] = eos_cli return bundle - else: - return None - def _router_bgp_vlan_aware_bundles(self, tenant_svis_l2vlans_dict) -> list | None: + return None + + def _router_bgp_vlan_aware_bundles(self: AvdStructuredConfigNetworkServices, tenant_svis_l2vlans_dict) -> list | None: """ Return structured config for router_bgp.vlan_aware_bundles """ @@ -552,7 +552,7 @@ def _router_bgp_vlan_aware_bundles(self, tenant_svis_l2vlans_dict) -> list | Non l2vlan_svi_vlan_aware_bundles[bundle_name] = {"evpn_vlan_bundle": evpn_vlan_bundle, "l2vlan_svis": svis} if self._evpn_vlan_aware_bundles: - svis = tenant_svis_l2vlans_dict[tenant["name"]]["svi_nonBundle"][vrf["name"]] + svis = tenant_svis_l2vlans_dict[tenant["name"]]["svi_non_bundle"][vrf["name"]] # SVIs which don't have an evpn_vlan_bundle defined are included in the VRF vlan-aware-bundle if (bundle := self._router_bgp_vlan_aware_bundles_vrf(vrf, tenant, svis)) is not None: append_if_not_duplicate( @@ -574,7 +574,7 @@ def _router_bgp_vlan_aware_bundles(self, tenant_svis_l2vlans_dict) -> list | Non l2vlan_svi_vlan_aware_bundles[bundle_name] = {"evpn_vlan_bundle": evpn_vlan_bundle, "l2vlan_svis": l2vlans} if self._evpn_vlan_aware_bundles: - for bundle_name, l2vlans in tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_nonBundle"].items(): + for bundle_name, l2vlans in tenant_svis_l2vlans_dict[tenant["name"]]["l2vlan_non_bundle"].items(): # Without "evpn_vlan_bundle" we fall back to per-vlan behavior if (bundle := self._router_bgp_vlans_vlan(l2vlans[0], tenant, vrf={})) is None: # Skip bundle since no vlans were enabled for vxlan. @@ -616,7 +616,7 @@ def _router_bgp_vlan_aware_bundles(self, tenant_svis_l2vlans_dict) -> list | Non return bundles or None - def _router_bgp_vlan_aware_bundles_vrf(self, vrf: dict, tenant: dict, vlans: list[dict]) -> dict | None: + def _router_bgp_vlan_aware_bundles_vrf(self: AvdStructuredConfigNetworkServices, vrf: dict, tenant: dict, vlans: list[dict]) -> dict | None: """ Return structured config for one vrf under router_bgp.vlan_aware_bundles """ @@ -629,7 +629,9 @@ def _router_bgp_vlan_aware_bundles_vrf(self, vrf: dict, tenant: dict, vlans: lis tenant=tenant, ) - def _router_bgp_vlan_aware_bundle(self, name: str, vlans: list, rd: str, rt: str, evpn_l2_multi_domain: bool, tenant: dict) -> dict | None: + def _router_bgp_vlan_aware_bundle( + self: AvdStructuredConfigNetworkServices, name: str, vlans: list, rd: str, rt: str, evpn_l2_multi_domain: bool, tenant: dict + ) -> dict | None: """ Return structured config for one vlan-aware-bundle. Used for VRFs and bundles defined under "evpn_vlan_bundles" referred by l2vlans and SVIs @@ -657,7 +659,7 @@ def _router_bgp_vlan_aware_bundle(self, name: str, vlans: list, rd: str, rt: str return bundle @cached_property - def _rt_admin_subfield(self) -> str | None: + def _rt_admin_subfield(self: AvdStructuredConfigNetworkServices) -> str | None: """ Return a string with the route-target admin subfield unless set to "vrf_id" or "vrf_vni" or "id". Returns None if not set, since the calling functions will use @@ -670,12 +672,12 @@ def _rt_admin_subfield(self) -> str | None: if admin_subfield == "bgp_as": return self.shared_utils.bgp_as - if re_fullmatch(r"[0-9]+", str(admin_subfield)): + if re_fullmatch(r"\d+", str(admin_subfield)): return admin_subfield return None - def get_vlan_mac_vrf_id(self, vlan, tenant) -> int: + def get_vlan_mac_vrf_id(self: AvdStructuredConfigNetworkServices, vlan, tenant) -> int: mac_vrf_id_base = default(tenant.get("mac_vrf_id_base"), tenant.get("mac_vrf_vni_base")) if mac_vrf_id_base is None: raise AristaAvdMissingVariableError( @@ -684,7 +686,7 @@ def get_vlan_mac_vrf_id(self, vlan, tenant) -> int: ) return mac_vrf_id_base + int(vlan["id"]) - def get_vlan_mac_vrf_vni(self, vlan, tenant) -> int: + def get_vlan_mac_vrf_vni(self: AvdStructuredConfigNetworkServices, vlan, tenant) -> int: mac_vrf_vni_base = default(tenant.get("mac_vrf_vni_base"), tenant.get("mac_vrf_id_base")) if mac_vrf_vni_base is None: raise AristaAvdMissingVariableError( @@ -693,7 +695,7 @@ def get_vlan_mac_vrf_vni(self, vlan, tenant) -> int: ) return mac_vrf_vni_base + int(vlan["id"]) - def get_vlan_rd(self, vlan, tenant) -> str: + def get_vlan_rd(self: AvdStructuredConfigNetworkServices, vlan, tenant) -> str: """ Return a string with the route-destinguisher for one VLAN """ @@ -713,7 +715,7 @@ def get_vlan_rd(self, vlan, tenant) -> str: return f"{self.shared_utils.overlay_rd_type_admin_subfield}:{assigned_number_subfield}" - def get_vlan_rt(self, vlan: dict, tenant: dict) -> str: + def get_vlan_rt(self: AvdStructuredConfigNetworkServices, vlan: dict, tenant: dict) -> str: """ Return a string with the route-target for one VLAN """ @@ -745,7 +747,7 @@ def get_vlan_rt(self, vlan: dict, tenant: dict) -> str: return f"{admin_subfield}:{assigned_number_subfield}" @cached_property - def _vrf_rt_admin_subfield(self) -> str | None: + def _vrf_rt_admin_subfield(self: AvdStructuredConfigNetworkServices) -> str | None: """ Return a string with the VRF route-target admin subfield unless set to "vrf_id" or "vrf_vni" or "id". Returns None if not set, since the calling functions will use @@ -758,12 +760,12 @@ def _vrf_rt_admin_subfield(self) -> str | None: if admin_subfield == "bgp_as": return self.shared_utils.bgp_as - if re_fullmatch(r"[0-9]+", str(admin_subfield)): + if re_fullmatch(r"\d+", str(admin_subfield)): return admin_subfield return None - def get_vrf_rd(self, vrf) -> str: + def get_vrf_rd(self: AvdStructuredConfigNetworkServices, vrf) -> str: """ Return a string with the route-destinguisher for one VRF """ @@ -777,7 +779,7 @@ def get_vrf_rd(self, vrf) -> str: return f"{self.shared_utils.overlay_rd_type_vrf_admin_subfield}:{self.shared_utils.get_vrf_id(vrf)}" - def get_vrf_rt(self, vrf: dict) -> str: + def get_vrf_rt(self: AvdStructuredConfigNetworkServices, vrf: dict) -> str: """ Return a string with the route-target for one VRF """ @@ -799,7 +801,7 @@ def get_vrf_rt(self, vrf: dict) -> str: return f"{admin_subfield}:{self.shared_utils.get_vrf_id(vrf)}" - def get_vlan_aware_bundle_rd(self, id: int, tenant: dict, is_vrf: bool, rd_override: str = None) -> str: + def get_vlan_aware_bundle_rd(self: AvdStructuredConfigNetworkServices, id: int, tenant: dict, is_vrf: bool, rd_override: str | None = None) -> str: """ Return a string with the route-destinguisher for one VLAN Aware Bundle """ @@ -817,7 +819,9 @@ def get_vlan_aware_bundle_rd(self, id: int, tenant: dict, is_vrf: bool, rd_overr bundle_number = id + int(get(tenant, "vlan_aware_bundle_number_base", default=0)) return f"{admin_subfield}:{bundle_number}" - def get_vlan_aware_bundle_rt(self, id: int, vni: int, tenant: dict, is_vrf: bool, rt_override: str = None) -> str: + def get_vlan_aware_bundle_rt( + self: AvdStructuredConfigNetworkServices, id: int, vni: int, tenant: dict, is_vrf: bool, rt_override: str | None = None + ) -> str: """ Return a string with the route-target for one VLAN Aware Bundle """ @@ -840,7 +844,7 @@ def get_vlan_aware_bundle_rt(self, id: int, vni: int, tenant: dict, is_vrf: bool return f"{admin_subfield}:{bundle_number}" @cached_property - def _router_bgp_redistribute_routes(self) -> list | None: + def _router_bgp_redistribute_routes(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for router_bgp.redistribute_routes @@ -862,7 +866,7 @@ def _router_bgp_redistribute_routes(self) -> list | None: return [{"source_protocol": "static"}] @cached_property - def _router_bgp_vpws(self) -> list[dict] | None: + def _router_bgp_vpws(self: AvdStructuredConfigNetworkServices) -> list[dict] | None: """ Return structured config for router_bgp.vpws """ @@ -930,7 +934,7 @@ def _router_bgp_vpws(self) -> list[dict] | None: return None - def _router_bgp_mlag_peer_group(self) -> dict: + def _router_bgp_mlag_peer_group(self: AvdStructuredConfigNetworkServices) -> dict: """ Return a partial router_bgp structured_config covering the MLAG peer_group and associated address_family activations diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_internet_exit.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_internet_exit.py similarity index 91% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_internet_exit.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_internet_exit.py index 922af59a64d..dee3bc499b2 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_internet_exit.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_internet_exit.py @@ -5,11 +5,14 @@ from collections import defaultdict from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterInternetExitMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouterInternetExitMixin(UtilsMixin): """ @cached_property - def router_internet_exit(self) -> dict | None: + def router_internet_exit(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for router_internet_exit diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_isis.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_isis.py similarity index 85% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_isis.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_isis.py index 9ce3d0cca1f..c65f9734686 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_isis.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_isis.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterIsisMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class RouterIsisMixin(UtilsMixin): """ @cached_property - def router_isis(self) -> dict | None: + def router_isis(self: AvdStructuredConfigNetworkServices) -> dict | None: """ return structured config for router_isis diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_multicast.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_multicast.py similarity index 81% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_multicast.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_multicast.py index 59339855727..6f8d97ad4ba 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_multicast.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_multicast.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get -from ansible_collections.arista.avd.roles.eos_designs.python_modules.network_services.utils import UtilsMixin +from ....vendor.utils import append_if_not_duplicate, get +from .utils import UtilsMixin + +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices class RouterMulticastMixin(UtilsMixin): @@ -16,7 +20,7 @@ class RouterMulticastMixin(UtilsMixin): """ @cached_property - def router_multicast(self) -> dict | None: + def router_multicast(self: AvdStructuredConfigNetworkServices) -> dict | None: """ return structured config for router_multicast diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_ospf.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_ospf.py similarity index 93% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_ospf.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_ospf.py index 32b50ed12df..9b2ed154955 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_ospf.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_ospf.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get - +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.utils import append_if_not_duplicate, default, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterOspfMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouterOspfMixin(UtilsMixin): """ @cached_property - def router_ospf(self) -> dict | None: + def router_ospf(self: AvdStructuredConfigNetworkServices) -> dict | None: """ return structured config for router_ospf diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_path_selection.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_path_selection.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_path_selection.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_path_selection.py index 0470c8b60e8..b8175fe9844 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_path_selection.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_path_selection.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get - +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterPathSelectionMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouterPathSelectionMixin(UtilsMixin): """ @cached_property - def router_path_selection(self) -> dict | None: + def router_path_selection(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for router path-selection (DPS) """ @@ -44,7 +47,7 @@ def router_path_selection(self) -> dict | None: return strip_empties_from_dict(router_path_selection) - def _wan_load_balance_policies(self) -> list: + def _wan_load_balance_policies(self: AvdStructuredConfigNetworkServices) -> list: """ Return a list of load balance policies """ @@ -69,7 +72,7 @@ def _wan_load_balance_policies(self) -> list: return load_balance_policies - def _autovpn_policies(self) -> list: + def _autovpn_policies(self: AvdStructuredConfigNetworkServices) -> list: """ Return a list of policies for AutoVPN """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_pim_sparse_mode.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_pim_sparse_mode.py similarity index 82% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_pim_sparse_mode.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_pim_sparse_mode.py index 97739f9bcdf..4121611c3b4 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_pim_sparse_mode.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_pim_sparse_mode.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get -from ansible_collections.arista.avd.roles.eos_designs.python_modules.network_services.utils import UtilsMixin +from ....vendor.utils import append_if_not_duplicate, get +from .utils import UtilsMixin + +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices class RouterPimSparseModeMixin(UtilsMixin): @@ -16,7 +20,7 @@ class RouterPimSparseModeMixin(UtilsMixin): """ @cached_property - def router_pim_sparse_mode(self) -> dict | None: + def router_pim_sparse_mode(self: AvdStructuredConfigNetworkServices) -> dict | None: """ return structured config for router_pim diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_service_insertion.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_service_insertion.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_service_insertion.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/router_service_insertion.py index beffb6a8c4d..adb9e86127a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/router_service_insertion.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/router_service_insertion.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class RouterServiceInsertionMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class RouterServiceInsertionMixin(UtilsMixin): """ @cached_property - def router_service_insertion(self) -> dict | None: + def router_service_insertion(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Return structured config for router_service_insertion diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/spanning_tree.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/spanning_tree.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/spanning_tree.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/spanning_tree.py index 1e753721fb6..e02c0e60423 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/spanning_tree.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/spanning_tree.py @@ -4,10 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.list_compress import list_compress -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get -from ansible_collections.arista.avd.roles.eos_designs.python_modules.network_services.utils import UtilsMixin +from ....j2filters.list_compress import list_compress +from ....vendor.utils import get +from .utils import UtilsMixin + +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices class SpanningTreeMixin(UtilsMixin): @@ -17,7 +21,7 @@ class SpanningTreeMixin(UtilsMixin): """ @cached_property - def spanning_tree(self) -> dict | None: + def spanning_tree(self: AvdStructuredConfigNetworkServices) -> dict | None: """ spanning_tree priorities set per VLAN if spanning_tree mode is "rapid-pvst" """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/standard_access_lists.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/standard_access_lists.py similarity index 89% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/standard_access_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/standard_access_lists.py index 5676a6efd45..7e5f04f813d 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/standard_access_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/standard_access_lists.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get - +from ....vendor.utils import append_if_not_duplicate, default, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class StandardAccessListsMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class StandardAccessListsMixin(UtilsMixin): """ @cached_property - def standard_access_lists(self) -> list | None: + def standard_access_lists(self: AvdStructuredConfigNetworkServices) -> list | None: """ return structured config for standard_access_lists diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/static_routes.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/static_routes.py similarity index 94% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/static_routes.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/static_routes.py index ac1664de011..9ad652f9b8d 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/static_routes.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/static_routes.py @@ -5,9 +5,13 @@ import ipaddress from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class StaticRoutesMixin(UtilsMixin): """ @@ -16,7 +20,7 @@ class StaticRoutesMixin(UtilsMixin): """ @cached_property - def static_routes(self) -> list[dict] | None: + def static_routes(self: AvdStructuredConfigNetworkServices) -> list[dict] | None: """ Returns structured config for static_routes diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/struct_cfgs.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/struct_cfgs.py similarity index 86% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/struct_cfgs.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/struct_cfgs.py index 72b6abb2b8e..35da4316e53 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/struct_cfgs.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/struct_cfgs.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class StructCfgsMixin(UtilsMixin): """ @@ -16,11 +19,8 @@ class StructCfgsMixin(UtilsMixin): Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - @cached_property - def struct_cfgs(self) -> list | None: + def struct_cfgs(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return the combined structured config from VRFs """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/tunnel_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/tunnel_interfaces.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/tunnel_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/tunnel_interfaces.py index c8cade39ed4..86769421138 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/tunnel_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/tunnel_interfaces.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class TunnelInterfacesMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class TunnelInterfacesMixin(UtilsMixin): """ @cached_property - def tunnel_interfaces(self) -> list | None: + def tunnel_interfaces(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for tunnel_interfaces diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/utils.py similarity index 89% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/utils.py index bbc2a22aec9..ee66736c567 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/utils.py @@ -5,17 +5,18 @@ import ipaddress from functools import cached_property -from typing import Literal, Tuple - -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.password_utils.password import simple_7_encrypt -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get, get_item +from typing import TYPE_CHECKING, Literal, Tuple +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdError, AristaAvdMissingVariableError +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.password_utils.password import simple_7_encrypt +from ....vendor.utils import default, get, get_item from .utils_zscaler import UtilsZscalerMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class UtilsMixin(UtilsZscalerMixin): """ @@ -23,28 +24,24 @@ class UtilsMixin(UtilsZscalerMixin): Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _trunk_groups_mlag_name(self) -> str: + def _trunk_groups_mlag_name(self: AvdStructuredConfigNetworkServices) -> str: return get(self.shared_utils.trunk_groups, "mlag.name", required=True) @cached_property - def _trunk_groups_mlag_l3_name(self) -> str: + def _trunk_groups_mlag_l3_name(self: AvdStructuredConfigNetworkServices) -> str: return get(self.shared_utils.trunk_groups, "mlag_l3.name", required=True) @cached_property - def _trunk_groups_uplink_name(self) -> str: + def _trunk_groups_uplink_name(self: AvdStructuredConfigNetworkServices) -> str: return get(self.shared_utils.trunk_groups, "uplink.name", required=True) @cached_property - def _local_endpoint_trunk_groups(self) -> set: + def _local_endpoint_trunk_groups(self: AvdStructuredConfigNetworkServices) -> set: return set(get(self._hostvars, "switch.local_endpoint_trunk_groups", default=[])) @cached_property - def _vrf_default_evpn(self) -> bool: + def _vrf_default_evpn(self: AvdStructuredConfigNetworkServices) -> bool: """ Return boolean telling if VRF "default" is running EVPN or not. """ @@ -63,7 +60,7 @@ def _vrf_default_evpn(self) -> bool: return False @cached_property - def _vrf_default_ipv4_subnets(self) -> list[str]: + def _vrf_default_ipv4_subnets(self: AvdStructuredConfigNetworkServices) -> list[str]: """ Return list of ipv4 subnets in VRF "default" """ @@ -84,7 +81,7 @@ def _vrf_default_ipv4_subnets(self) -> list[str]: return subnets @cached_property - def _vrf_default_ipv4_static_routes(self) -> dict: + def _vrf_default_ipv4_static_routes(self: AvdStructuredConfigNetworkServices) -> dict: """ Finds static routes defined under VRF "default" and find out if they should be redistributed in underlay and/or overlay. @@ -131,7 +128,7 @@ def _vrf_default_ipv4_static_routes(self) -> dict: "redistribute_in_overlay": redistribute_in_overlay, } - def _mlag_ibgp_peering_enabled(self, vrf, tenant) -> bool: + def _mlag_ibgp_peering_enabled(self: AvdStructuredConfigNetworkServices, vrf, tenant) -> bool: """ Returns True if mlag ibgp_peering is enabled False otherwise @@ -142,7 +139,7 @@ def _mlag_ibgp_peering_enabled(self, vrf, tenant) -> bool: mlag_ibgp_peering: bool = default(vrf.get("enable_mlag_ibgp_peering_vrfs"), tenant.get("enable_mlag_ibgp_peering_vrfs"), True) return vrf["name"] != "default" and mlag_ibgp_peering - def _mlag_ibgp_peering_vlan_vrf(self, vrf, tenant) -> int | None: + def _mlag_ibgp_peering_vlan_vrf(self: AvdStructuredConfigNetworkServices, vrf, tenant) -> int | None: """ MLAG IBGP Peering VLANs per VRF @@ -165,7 +162,7 @@ def _mlag_ibgp_peering_vlan_vrf(self, vrf, tenant) -> int | None: return vlan_id - def _mlag_ibgp_peering_redistribute(self, vrf, tenant) -> bool: + def _mlag_ibgp_peering_redistribute(self: AvdStructuredConfigNetworkServices, vrf, tenant) -> bool: """ Returns True if MLAG IBGP Peering subnet should be redistributed for the given vrf/tenant. False otherwise. @@ -175,7 +172,7 @@ def _mlag_ibgp_peering_redistribute(self, vrf, tenant) -> bool: return default(vrf.get("redistribute_mlag_ibgp_peering_vrfs"), tenant.get("redistribute_mlag_ibgp_peering_vrfs"), True) is True @cached_property - def _configure_bgp_mlag_peer_group(self) -> bool: + def _configure_bgp_mlag_peer_group(self: AvdStructuredConfigNetworkServices) -> bool: """ Flag set during creating of BGP VRFs if an MLAG peering is needed. Decides if MLAG BGP peer-group should be configured. @@ -194,7 +191,7 @@ def _configure_bgp_mlag_peer_group(self) -> bool: return False @cached_property - def _filtered_wan_vrfs(self) -> list: + def _filtered_wan_vrfs(self: AvdStructuredConfigNetworkServices) -> list: """ Loop through all the VRFs defined under `wan_virtual_topologies.vrfs` and returns a list of mode """ @@ -230,7 +227,7 @@ def _filtered_wan_vrfs(self) -> list: return wan_vrfs @cached_property - def _wan_virtual_topologies_policies(self) -> list: + def _wan_virtual_topologies_policies(self: AvdStructuredConfigNetworkServices) -> list: """ This function parses the input data and append the default-policy if not already present """ @@ -242,7 +239,7 @@ def _wan_virtual_topologies_policies(self) -> list: return policies @cached_property - def _filtered_wan_policies(self) -> list: + def _filtered_wan_policies(self: AvdStructuredConfigNetworkServices) -> list: """ Loop through all the VRFs defined under `wan_virtual_topologies.vrfs` and returns a list of policies to configure on this device. @@ -286,7 +283,7 @@ def _filtered_wan_policies(self) -> list: return filtered_policies - def _update_policy_match_statements(self, policy: dict) -> None: + def _update_policy_match_statements(self: AvdStructuredConfigNetworkServices, policy: dict) -> None: """ Update the policy dict with two keys: `matches` and `default_match` For each match (or default_match), the load_balancing policy is resolved and if it is empty @@ -410,9 +407,7 @@ def _update_policy_match_statements(self, policy: dict) -> None: policy["matches"] = matches policy["default_match"] = default_match - return - - def _generate_wan_load_balance_policy(self, name: str, input_dict: dict, context_path: str) -> dict | None: + def _generate_wan_load_balance_policy(self: AvdStructuredConfigNetworkServices, name: str, input_dict: dict, context_path: str) -> dict | None: """ Generate and return a router path-selection load-balance policy. If HA is enabled, inject the HA path-group with priority 1. @@ -478,7 +473,7 @@ def _generate_wan_load_balance_policy(self, name: str, input_dict: dict, context return wan_load_balance_policy - def _path_group_preference_to_eos_priority(self, path_group_preference: int | str, context_path: str) -> int: + def _path_group_preference_to_eos_priority(self: AvdStructuredConfigNetworkServices, path_group_preference: int | str, context_path: str) -> int: """ Convert "preferred" to 1 and "alternate" to 2. Everything else is returned as is. @@ -498,7 +493,7 @@ def _path_group_preference_to_eos_priority(self, path_group_preference: int | st except ValueError: failed_conversion = True - if failed_conversion or not (1 <= priority <= 65535): + if failed_conversion or not 1 <= priority <= 65535: raise AristaAvdError( f"Invalid value '{path_group_preference}' for Path-Group preference - should be either 'preferred', " f"'alternate' or an integer[1-65535] for {context_path}." @@ -507,14 +502,14 @@ def _path_group_preference_to_eos_priority(self, path_group_preference: int | st return priority @cached_property - def _default_wan_policy_name(self) -> str: + def _default_wan_policy_name(self: AvdStructuredConfigNetworkServices) -> str: """ TODO make this configurable """ return "DEFAULT-POLICY" @cached_property - def _default_policy_path_group_names(self) -> list: + def _default_policy_path_group_names(self: AvdStructuredConfigNetworkServices) -> list: """ Return the list of path-groups to consider when generating a default policy with AVD whether for the default policy or the special Control-plane policy. @@ -532,7 +527,7 @@ def _default_policy_path_group_names(self) -> list: return natural_sort(path_group_names) @cached_property - def _default_wan_policy(self) -> dict: + def _default_wan_policy(self: AvdStructuredConfigNetworkServices) -> dict: """ If no policy is defined for a VRF under 'wan_virtual_topologies.vrfs', a default policy named DEFAULT-POLICY is used where all traffic is matched in the default category and distributed amongst all path-groups. @@ -545,7 +540,7 @@ def _default_wan_policy(self) -> dict: "default_virtual_topology": {"path_groups": [{"names": self._default_policy_path_group_names}]}, } - def _default_profile_name(self, profile_name: str, application_profile: str) -> str: + def _default_profile_name(self: AvdStructuredConfigNetworkServices, profile_name: str, application_profile: str) -> str: """ Helper function to consistently return the default name of a profile @@ -554,7 +549,7 @@ def _default_profile_name(self, profile_name: str, application_profile: str) -> return f"{profile_name}-{application_profile}" @cached_property - def _wan_control_plane_virtual_topology(self) -> dict: + def _wan_control_plane_virtual_topology(self: AvdStructuredConfigNetworkServices) -> dict: """ Return the Control plane virtual topology or the default one. @@ -569,7 +564,7 @@ def _wan_control_plane_virtual_topology(self) -> dict: return control_plane_virtual_topology @cached_property - def _wan_control_plane_profile_name(self) -> str: + def _wan_control_plane_profile_name(self: AvdStructuredConfigNetworkServices) -> str: """ Control plane profile name """ @@ -577,14 +572,14 @@ def _wan_control_plane_profile_name(self) -> str: return get(self._wan_control_plane_virtual_topology, "name", default=f"{vrf_default_policy_name}-CONTROL-PLANE") @cached_property - def _wan_control_plane_application_profile_name(self) -> str: + def _wan_control_plane_application_profile_name(self: AvdStructuredConfigNetworkServices) -> str: """ Control plane application profile name """ return get(self._hostvars, "wan_virtual_topologies.control_plane_virtual_topology.application_profile", default="APP-PROFILE-CONTROL-PLANE") @cached_property - def _local_path_groups_connected_to_pathfinder(self) -> list: + def _local_path_groups_connected_to_pathfinder(self: AvdStructuredConfigNetworkServices) -> list: """ Return list of names of local path_groups connected to pathfinder """ @@ -594,13 +589,15 @@ def _local_path_groups_connected_to_pathfinder(self) -> list: if any(wan_interface["connected_to_pathfinder"] for wan_interface in path_group["interfaces"]) ] - def get_internet_exit_nat_profile_name(self, internet_exit_policy_type: Literal["zscaler", "direct"]) -> str: + def get_internet_exit_nat_profile_name(self: AvdStructuredConfigNetworkServices, internet_exit_policy_type: Literal["zscaler", "direct"]) -> str: if internet_exit_policy_type == "zscaler": return "IE-ZSCALER-NAT" - else: - return "IE-DIRECT-NAT" - def get_internet_exit_nat_pool_and_profile(self, internet_exit_policy_type: Literal["zscaler", "direct"]) -> Tuple[dict | None, dict | None]: + return "IE-DIRECT-NAT" + + def get_internet_exit_nat_pool_and_profile( + self: AvdStructuredConfigNetworkServices, internet_exit_policy_type: Literal["zscaler", "direct"] + ) -> Tuple[dict | None, dict | None]: if internet_exit_policy_type == "zscaler": pool = { "name": "PORT-ONLY-POOL", @@ -626,7 +623,8 @@ def get_internet_exit_nat_pool_and_profile(self, internet_exit_policy_type: Lite }, } return pool, profile - elif internet_exit_policy_type == "direct": + + if internet_exit_policy_type == "direct": profile = { "name": self.get_internet_exit_nat_profile_name(internet_exit_policy_type), "source": { @@ -643,7 +641,7 @@ def get_internet_exit_nat_pool_and_profile(self, internet_exit_policy_type: Lite return None, None @cached_property - def _svi_acls(self) -> dict[str, dict[str, dict]]: + def _svi_acls(self: AvdStructuredConfigNetworkServices) -> dict[str, dict[str, dict]] | None: """ Returns a dict of : { @@ -686,7 +684,7 @@ def _svi_acls(self) -> dict[str, dict[str, dict]]: return svi_acls @cached_property - def _filtered_internet_exit_policies(self) -> list: + def _filtered_internet_exit_policies(self: AvdStructuredConfigNetworkServices) -> list: """ Only supported for CV Pathfinder Edge routers. Returns an empty list for pathfinders. @@ -754,7 +752,7 @@ def _filtered_internet_exit_policies(self) -> list: return internet_exit_policies - def get_internet_exit_connections(self, internet_exit_policy: dict) -> list: + def get_internet_exit_connections(self: AvdStructuredConfigNetworkServices, internet_exit_policy: dict) -> list: """ Return a list of connections (dicts) for the given internet_exit_policy. @@ -765,12 +763,13 @@ def get_internet_exit_connections(self, internet_exit_policy: dict) -> list: if policy_type == "direct": return self.get_direct_internet_exit_connections(internet_exit_policy) - elif policy_type == "zscaler": + + if policy_type == "zscaler": return self.get_zscaler_internet_exit_connections(internet_exit_policy) - else: - raise AristaAvdError(f"Unsupported type '{policy_type}' found in cv_pathfinder_internet_exit[name={policy_name}].") - def get_direct_internet_exit_connections(self, internet_exit_policy: dict) -> list: + raise AristaAvdError(f"Unsupported type '{policy_type}' found in cv_pathfinder_internet_exit[name={policy_name}].") + + def get_direct_internet_exit_connections(self: AvdStructuredConfigNetworkServices, internet_exit_policy: dict) -> list: """ Return a list of connections (dicts) for the given internet_exit_policy of type direct. """ @@ -806,7 +805,7 @@ def get_direct_internet_exit_connections(self, internet_exit_policy: dict) -> li return connections - def get_zscaler_internet_exit_connections(self, internet_exit_policy: dict) -> list: + def get_zscaler_internet_exit_connections(self: AvdStructuredConfigNetworkServices, internet_exit_policy: dict) -> list: """ Return a list of connections (dicts) for the given internet_exit_policy of type zscaler. """ @@ -879,7 +878,7 @@ def get_zscaler_internet_exit_connections(self, internet_exit_policy: dict) -> l return connections - def _get_ipsec_credentials(self, internet_exit_policy: dict) -> tuple[str, str]: + def _get_ipsec_credentials(self: AvdStructuredConfigNetworkServices, internet_exit_policy: dict) -> tuple[str, str]: """ Returns ufqdn, shared_key based on various details from the given internet_exit_policy. """ @@ -890,7 +889,7 @@ def _get_ipsec_credentials(self, internet_exit_policy: dict) -> tuple[str, str]: ufqdn = f"{self.shared_utils.hostname}_{policy_name}@{domain_name}" return ufqdn, ipsec_key - def _generate_ipsec_key(self, name: str, salt: str) -> str: + def _generate_ipsec_key(self: AvdStructuredConfigNetworkServices, name: str, salt: str) -> str: """ Build a secret containing various components for this policy and device. Run type-7 obfuscation using a algorithmic salt so we ensure the same key every time. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils_zscaler.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/utils_zscaler.py similarity index 80% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils_zscaler.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/utils_zscaler.py index 62c471b7955..63a34d85874 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/utils_zscaler.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/utils_zscaler.py @@ -8,15 +8,15 @@ from logging import getLogger from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.cv_client.client import CVClient -from ansible_collections.arista.avd.plugins.plugin_utils.cv_client.workflows.models import CVDevice -from ansible_collections.arista.avd.plugins.plugin_utils.cv_client.workflows.verify_devices_on_cv import verify_devices_in_cloudvision_inventory -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get +from ....vendor.cv_client.client import CVClient +from ....vendor.cv_client.workflows.models import CVDevice +from ....vendor.cv_client.workflows.verify_devices_on_cv import verify_devices_in_cloudvision_inventory +from ....vendor.errors import AristaAvdError +from ....vendor.utils import get if TYPE_CHECKING: - from ansible_collections.arista.avd.plugins.plugin_utils.cv_client.api.arista.swg.v1 import Location, VpnEndpoint + from ....vendor.cv_client.api.arista.swg.v1 import Location, VpnEndpoint + from . import AvdStructuredConfigNetworkServices LOGGER = getLogger(__name__) @@ -27,12 +27,8 @@ class UtilsZscalerMixin: Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _zscaler_endpoints(self) -> dict: + def _zscaler_endpoints(self: AvdStructuredConfigNetworkServices) -> dict: """ Returns zscaler_endpoints data model built via CloudVision API calls, unless they are provided in the input variables. @@ -44,7 +40,7 @@ def _zscaler_endpoints(self) -> dict: return asyncio.run(self._generate_zscaler_endpoints()) or {} - async def _generate_zscaler_endpoints(self): + async def _generate_zscaler_endpoints(self: AvdStructuredConfigNetworkServices): """ Call CloudVision SWG APIs to generate the zscaler_endpoints model. @@ -80,7 +76,7 @@ async def _generate_zscaler_endpoints(self): ) ) device_id: str = cv_inventory_devices[0].serial_number - request_time, cv_endpoint_config = await cv_client.set_swg_device(device_id=device_id, service="zscaler", location=wan_site_location) + request_time, _ = await cv_client.set_swg_device(device_id=device_id, service="zscaler", location=wan_site_location) cv_endpoint_status = await cv_client.wait_for_swg_endpoint_status(device_id=device_id, service="zscaler", start_time=request_time) device_location: Location = cv_endpoint_status.device_location diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/virtual_source_nat_vrfs.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/virtual_source_nat_vrfs.py similarity index 88% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/virtual_source_nat_vrfs.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/virtual_source_nat_vrfs.py index ba2ea924a30..2e247b31a0a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/virtual_source_nat_vrfs.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/virtual_source_nat_vrfs.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class VirtualSourceNatVrfsMixin(UtilsMixin): """ @@ -16,11 +19,8 @@ class VirtualSourceNatVrfsMixin(UtilsMixin): Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - loopback_interfaces: dict - @cached_property - def virtual_source_nat_vrfs(self) -> list | None: + def virtual_source_nat_vrfs(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for virtual_source_nat_vrfs diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vlan_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/vlan_interfaces.py similarity index 93% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vlan_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/vlan_interfaces.py index 319c4784e78..aa09c5a519e 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vlan_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/vlan_interfaces.py @@ -4,13 +4,16 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get - +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate, default, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class VlanInterfacesMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class VlanInterfacesMixin(UtilsMixin): """ @cached_property - def vlan_interfaces(self) -> list | None: + def vlan_interfaces(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for vlan_interfaces @@ -63,7 +66,7 @@ def vlan_interfaces(self) -> list | None: return None - def _get_vlan_interface_config_for_svi(self, svi, vrf) -> dict: + def _get_vlan_interface_config_for_svi(self: AvdStructuredConfigNetworkServices, svi, vrf) -> dict: def _check_virtual_router_mac_address(vlan_interface_config: dict, variables: list): """ Check if any variable in the list of variables is not None in vlan_interface_config @@ -151,7 +154,7 @@ def _check_virtual_router_mac_address(vlan_interface_config: dict, variables: li return strip_empties_from_dict(vlan_interface_config) - def _get_vlan_interface_config_for_mlag_peering(self, vrf) -> dict: + def _get_vlan_interface_config_for_mlag_peering(self: AvdStructuredConfigNetworkServices, vrf) -> dict: """ Build config for MLAG peering SVI for the given SVI. Called from vlan_interfaces and prefix_lists diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vlans.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/vlans.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vlans.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/vlans.py index a48b7b5a43c..50d71b15b34 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vlans.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/vlans.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class VlansMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class VlansMixin(UtilsMixin): """ @cached_property - def vlans(self) -> list | None: + def vlans(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for vlans. @@ -77,7 +80,7 @@ def vlans(self) -> list | None: return None - def _get_vlan_config(self, vlan) -> dict: + def _get_vlan_config(self: AvdStructuredConfigNetworkServices, vlan) -> dict: """ Return structured config for one given vlan diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vrfs.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/vrfs.py similarity index 89% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vrfs.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/vrfs.py index 7044b538520..f6faf22cf40 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vrfs.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/vrfs.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class VrfsMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class VrfsMixin(UtilsMixin): """ @cached_property - def vrfs(self) -> list | None: + def vrfs(self: AvdStructuredConfigNetworkServices) -> list | None: """ Return structured config for vrfs. @@ -69,7 +72,7 @@ def vrfs(self) -> list | None: return None - def _has_ipv6(self, vrf) -> bool: + def _has_ipv6(self: AvdStructuredConfigNetworkServices, vrf) -> bool: """ Return bool if IPv6 is configured in the given VRF. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py b/python-avd/pyavd/_eos_designs/structured_config/network_services/vxlan_interface.py similarity index 92% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py rename to python-avd/pyavd/_eos_designs/structured_config/network_services/vxlan_interface.py index 9b2e5c6eb49..a9eea70a2df 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/network_services/vxlan_interface.py +++ b/python-avd/pyavd/_eos_designs/structured_config/network_services/vxlan_interface.py @@ -4,15 +4,17 @@ from __future__ import annotations from functools import cached_property -from typing import NoReturn - -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError, AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, default, get, get_item, unique +from typing import TYPE_CHECKING, NoReturn +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdError, AristaAvdMissingVariableError +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.utils import append_if_not_duplicate, default, get, get_item, unique from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigNetworkServices + class VxlanInterfaceMixin(UtilsMixin): """ @@ -20,11 +22,8 @@ class VxlanInterfaceMixin(UtilsMixin): Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - @cached_property - def vxlan_interface(self) -> dict | None: + def vxlan_interface(self: AvdStructuredConfigNetworkServices) -> dict | None: """ Returns structured config for vxlan_interface @@ -122,7 +121,7 @@ def vxlan_interface(self) -> dict | None: } } - def _get_vxlan_interface_config_for_vrf(self, vrf: dict, tenant: dict, vrfs: list, vlans: list, vnis: list) -> None: + def _get_vxlan_interface_config_for_vrf(self: AvdStructuredConfigNetworkServices, vrf: dict, tenant: dict, vrfs: list, vlans: list, vnis: list) -> None: """ In place updates of the vlans, vnis and vrfs list """ @@ -210,7 +209,7 @@ def _get_vxlan_interface_config_for_vrf(self, vrf: dict, tenant: dict, vrfs: lis context_keys=["name", "vni"], ) - def _get_vxlan_interface_config_for_vlan(self, vlan, tenant) -> dict: + def _get_vxlan_interface_config_for_vlan(self: AvdStructuredConfigNetworkServices, vlan, tenant) -> dict: """ vxlan_interface logic for one vlan @@ -248,11 +247,11 @@ def _get_vxlan_interface_config_for_vlan(self, vlan, tenant) -> dict: return vxlan_interface_vlan @cached_property - def _overlay_her_flood_list_per_vni(self) -> bool: + def _overlay_her_flood_list_per_vni(self: AvdStructuredConfigNetworkServices) -> bool: return get(self._hostvars, "overlay_her_flood_list_per_vni") is True @cached_property - def _overlay_her_flood_lists(self) -> dict[list]: + def _overlay_her_flood_lists(self: AvdStructuredConfigNetworkServices) -> dict[list]: """ Returns a dict with HER Flood Lists. @@ -299,7 +298,7 @@ def _overlay_her_flood_lists(self) -> dict[list]: return overlay_her_flood_lists - def _raise_duplicate_vni_error(self, vni: int, context: str, tenant: str, duplicate_vni_tenant: str) -> NoReturn: + def _raise_duplicate_vni_error(self: AvdStructuredConfigNetworkServices, vni: int, context: str, tenant: str, duplicate_vni_tenant: str) -> NoReturn: msg = f"Duplicate VXLAN VNI '{vni}' found in Tenant(s) '{tenant}' during configuration of {context}." if duplicate_vni_tenant != tenant: msg = f"{msg} Other VNI is in Tenant(s) '{duplicate_vni_tenant}'." @@ -307,5 +306,5 @@ def _raise_duplicate_vni_error(self, vni: int, context: str, tenant: str, duplic raise AristaAvdError(msg) @cached_property - def _multi_vtep(self) -> bool: + def _multi_vtep(self: AvdStructuredConfigNetworkServices) -> bool: return self.shared_utils.mlag is True and self.shared_utils.evpn_multicast is True diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/__init__.py similarity index 96% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/__init__.py index ecd39deaf3d..518c83e81f0 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/__init__.py @@ -1,8 +1,7 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts - +from ....vendor.avdfacts import AvdFacts from .cvx import CvxMixin from .ip_extcommunity_lists import IpExtCommunityListsMixin from .ip_security import IpSecurityMixin diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/cvx.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/cvx.py similarity index 86% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/cvx.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/cvx.py index cffb61f44f7..2bd7aa7a219 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/cvx.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/cvx.py @@ -5,11 +5,14 @@ from functools import cached_property from ipaddress import ip_interface +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class CvxMixin(UtilsMixin): """ @@ -18,11 +21,11 @@ class CvxMixin(UtilsMixin): """ @cached_property - def cvx(self) -> dict | None: + def cvx(self: AvdStructuredConfigOverlay) -> dict | None: """ Detect if this is a CVX server for overlay and configure service & peer hosts accordingly. """ - if not (self.shared_utils.overlay_cvx): + if not self.shared_utils.overlay_cvx: return None overlay_cvx_servers = get(self._hostvars, "overlay_cvx_servers", default=[]) diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/ip_extcommunity_lists.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/ip_extcommunity_lists.py similarity index 86% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/ip_extcommunity_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/ip_extcommunity_lists.py index 0d1ea693337..7111bee46d4 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/ip_extcommunity_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/ip_extcommunity_lists.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class IpExtCommunityListsMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class IpExtCommunityListsMixin(UtilsMixin): """ @cached_property - def ip_extcommunity_lists(self) -> list | None: + def ip_extcommunity_lists(self: AvdStructuredConfigOverlay) -> list | None: """ Return structured config for ip_extcommunity_lists """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/ip_security.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/ip_security.py similarity index 84% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/ip_security.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/ip_security.py index b5de24805ab..22385a120b3 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/ip_security.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/ip_security.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -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 get - +from ....vendor.strip_empties import strip_null_from_data +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class IpSecurityMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class IpSecurityMixin(UtilsMixin): """ @cached_property - def ip_security(self) -> dict | None: + def ip_security(self: AvdStructuredConfigOverlay) -> dict | None: """ ip_security set based on wan_ipsec_profiles data_model @@ -42,7 +45,7 @@ def ip_security(self) -> dict | None: return strip_null_from_data(ip_security) - def _append_data_plane(self, ip_security: dict, data_plane_config: dict) -> None: + def _append_data_plane(self: AvdStructuredConfigOverlay, ip_security: dict, data_plane_config: dict) -> None: """ In place update of ip_security """ @@ -63,7 +66,7 @@ def _append_data_plane(self, ip_security: dict, data_plane_config: dict) -> None # For data plane, adding key_controller by default ip_security["key_controller"] = self._key_controller(profile_name) - def _append_control_plane(self, ip_security: dict, control_plane_config: dict) -> None: + def _append_control_plane(self: AvdStructuredConfigOverlay, ip_security: dict, control_plane_config: dict) -> None: """ In place update of ip_security for control plane data @@ -82,7 +85,7 @@ def _append_control_plane(self, ip_security: dict, control_plane_config: dict) - # If there is not data plane IPSec profile, use the control plane one for key controller ip_security["key_controller"] = self._key_controller(profile_name) - def _ike_policy(self, name: str) -> dict | None: + def _ike_policy(self: AvdStructuredConfigOverlay, name: str) -> dict | None: """ Return an IKE policy """ @@ -91,7 +94,7 @@ def _ike_policy(self, name: str) -> dict | None: "local_id": self.shared_utils.vtep_ip, } - def _sa_policy(self, name: str) -> dict | None: + def _sa_policy(self: AvdStructuredConfigOverlay, name: str) -> dict | None: """ Return an SA policy @@ -104,7 +107,7 @@ def _sa_policy(self, name: str) -> dict | None: sa_policy["pfs_dh_group"] = 14 return sa_policy - def _profile(self, profile_name: str, ike_policy_name: str | None, sa_policy_name: str, key: str) -> dict | None: + def _profile(self: AvdStructuredConfigOverlay, profile_name: str, ike_policy_name: str | None, sa_policy_name: str, key: str) -> dict | None: """ Return one IPsec Profile @@ -127,7 +130,7 @@ def _profile(self, profile_name: str, ike_policy_name: str | None, sa_policy_nam "mode": "transport", } - def _key_controller(self, profile_name: str) -> dict | None: + def _key_controller(self: AvdStructuredConfigOverlay, profile_name: str) -> dict | None: """ Return a key_controller structure if the device is not a RR or pathfinder """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/management_cvx.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/management_cvx.py similarity index 85% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/management_cvx.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/management_cvx.py index 14d875b0269..5867a25a4e3 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/management_cvx.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/management_cvx.py @@ -5,11 +5,14 @@ from functools import cached_property from ipaddress import ip_interface +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class ManagementCvxMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class ManagementCvxMixin(UtilsMixin): """ @cached_property - def management_cvx(self) -> dict | None: + def management_cvx(self: AvdStructuredConfigOverlay) -> dict | None: if not (self.shared_utils.overlay_cvx and self.shared_utils.overlay_vtep): return None diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/management_security.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/management_security.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/management_security.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/management_security.py index cb2bb43a29e..e309c209f2b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/management_security.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/management_security.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class ManagementSecurityMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class ManagementSecurityMixin(UtilsMixin): """ @cached_property - def management_security(self) -> dict | None: + def management_security(self: AvdStructuredConfigOverlay) -> dict | None: """ Return structured config for management_security. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/route_maps.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/route_maps.py similarity index 93% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/route_maps.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/route_maps.py index 304660c4d5e..b75fb98e172 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/route_maps.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/route_maps.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort - +from ....j2filters.natural_sort import natural_sort from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class RouteMapsMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class RouteMapsMixin(UtilsMixin): """ @cached_property - def route_maps(self) -> list | None: + def route_maps(self: AvdStructuredConfigOverlay) -> list | None: """ Return structured config for route_maps """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_adaptive_virtual_topology.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_adaptive_virtual_topology.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_adaptive_virtual_topology.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/router_adaptive_virtual_topology.py index daf91ad3905..fcaffb3db9b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_adaptive_virtual_topology.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_adaptive_virtual_topology.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class RouterAdaptiveVirtualTopologyMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class RouterAdaptiveVirtualTopologyMixin(UtilsMixin): """ @cached_property - def router_adaptive_virtual_topology(self) -> dict | None: + def router_adaptive_virtual_topology(self: AvdStructuredConfigOverlay) -> dict | None: """ Return structured config for router adaptive-virtual-topology (AVT) """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_bfd.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_bfd.py similarity index 77% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_bfd.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/router_bfd.py index 0267ef47dce..e34c08f02eb 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_bfd.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_bfd.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict - +from ....vendor.strip_empties import strip_empties_from_dict from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class RouterBfdMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class RouterBfdMixin(UtilsMixin): """ @cached_property - def router_bfd(self) -> dict | None: + def router_bfd(self: AvdStructuredConfigOverlay) -> dict | None: """ return structured config for router_bfd """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_bgp.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_bgp.py similarity index 93% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_bgp.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/router_bgp.py index aad0ecd82e6..86fc5b9dd80 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_bgp.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_bgp.py @@ -5,14 +5,17 @@ import ipaddress from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get, get_item - +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdError +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import default, get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class RouterBgpMixin(UtilsMixin): """ @@ -21,7 +24,7 @@ class RouterBgpMixin(UtilsMixin): """ @cached_property - def router_bgp(self) -> dict | None: + def router_bgp(self: AvdStructuredConfigOverlay) -> dict | None: """ Return the structured config for router_bgp """ @@ -47,13 +50,13 @@ def router_bgp(self) -> dict | None: # Need to keep potentially empty dict for redistribute_routes return strip_empties_from_dict(router_bgp, strip_values_tuple=(None, "")) - def _bgp_cluster_id(self) -> str | None: + def _bgp_cluster_id(self: AvdStructuredConfigOverlay) -> str | None: if self.shared_utils.overlay_routing_protocol == "ibgp": if self.shared_utils.evpn_role == "server" or self.shared_utils.mpls_overlay_role == "server": return get(self.shared_utils.switch_data_combined, "bgp_cluster_id", default=self.shared_utils.router_id) return None - def _bgp_listen_ranges(self) -> list | None: + def _bgp_listen_ranges(self: AvdStructuredConfigOverlay) -> list | None: """ Generate listen-ranges. Currently only supported for WAN RR. """ @@ -69,7 +72,9 @@ def _bgp_listen_ranges(self) -> list | None: for prefix in self.shared_utils.wan_listen_ranges ] or None - def _generate_base_peer_group(self, pg_type: str, pg_name: str, maximum_routes: int = 0, update_source: str = "Loopback0") -> dict: + def _generate_base_peer_group( + self: AvdStructuredConfigOverlay, pg_type: str, pg_name: str, maximum_routes: int = 0, update_source: str = "Loopback0" + ) -> dict: return { "name": self.shared_utils.bgp_peer_groups[pg_name]["name"], "type": pg_type, @@ -81,7 +86,7 @@ def _generate_base_peer_group(self, pg_type: str, pg_name: str, maximum_routes: "struct_cfg": self.shared_utils.bgp_peer_groups[pg_name]["structured_config"], } - def _peer_groups(self) -> list | None: + def _peer_groups(self: AvdStructuredConfigOverlay) -> list | None: """ """ peer_groups = [] @@ -171,7 +176,7 @@ def _peer_groups(self) -> list | None: return peer_groups - def _address_family_ipv4(self) -> dict: + def _address_family_ipv4(self: AvdStructuredConfigOverlay) -> dict: """ deactivate the relevant peer_groups in address_family_ipv4 """ @@ -203,7 +208,7 @@ def _address_family_ipv4(self) -> dict: return {"peer_groups": peer_groups} - def _address_family_evpn(self) -> dict: + def _address_family_evpn(self: AvdStructuredConfigOverlay) -> dict: """ """ address_family_evpn = {} @@ -282,7 +287,7 @@ def _address_family_evpn(self) -> dict: address_family_evpn["next_hop"] = {"resolution_disabled": True} return address_family_evpn - def _address_family_ipv4_sr_te(self) -> dict | None: + def _address_family_ipv4_sr_te(self: AvdStructuredConfigOverlay) -> dict | None: """Generate structured config for IPv4 SR-TE address family""" if not self.shared_utils.is_cv_pathfinder_router: return None @@ -301,7 +306,7 @@ def _address_family_ipv4_sr_te(self) -> dict | None: return address_family_ipv4_sr_te - def _address_family_link_state(self) -> dict | None: + def _address_family_link_state(self: AvdStructuredConfigOverlay) -> dict | None: """Generate structured config for link-state address family""" if not self.shared_utils.is_cv_pathfinder_router: return None @@ -332,7 +337,7 @@ def _address_family_link_state(self) -> dict | None: return address_family_link_state - def _address_family_path_selection(self) -> dict | None: + def _address_family_path_selection(self: AvdStructuredConfigOverlay) -> dict | None: """ """ if not self.shared_utils.is_wan_router: return None @@ -352,7 +357,7 @@ def _address_family_path_selection(self) -> dict | None: return address_family_path_selection - def _address_family_rtc(self) -> dict | None: + def _address_family_rtc(self: AvdStructuredConfigOverlay) -> dict | None: """ Activate EVPN OVERLAY peer group and EVPN OVERLAY CORE peer group (if present) in address_family_rtc @@ -398,7 +403,7 @@ def _address_family_rtc(self) -> dict | None: return address_family_rtc - def _address_family_vpn_ipvx(self, version: int) -> dict | None: + def _address_family_vpn_ipvx(self: AvdStructuredConfigOverlay, version: int) -> dict | None: if version not in [4, 6]: raise AristaAvdError("_address_family_vpn_ipvx should be called with version 4 or 6 only") @@ -430,7 +435,7 @@ def _address_family_vpn_ipvx(self, version: int) -> dict | None: return address_family_vpn_ipvx - def _create_neighbor(self, ip_address: str, name: str, peer_group: str, remote_as: str = None) -> dict: + def _create_neighbor(self: AvdStructuredConfigOverlay, ip_address: str, name: str, peer_group: str, remote_as: str = None) -> dict: """ """ neighbor = {"ip_address": ip_address, "peer_group": peer_group, "peer": name, "description": name} @@ -447,7 +452,7 @@ def _create_neighbor(self, ip_address: str, name: str, peer_group: str, remote_a return neighbor - def _neighbors(self) -> list | None: + def _neighbors(self: AvdStructuredConfigOverlay) -> list | None: """ """ neighbors = [] @@ -531,14 +536,14 @@ def _neighbors(self) -> list | None: return None - def _ip_in_listen_ranges(self, source_ip: str, listen_range_prefixes: list) -> bool: + def _ip_in_listen_ranges(self: AvdStructuredConfigOverlay, source_ip: str, listen_range_prefixes: list) -> bool: """ Check if our source IP is in any of the listen range prefixes """ source_ip = ipaddress.ip_address(source_ip) return any(source_ip in ipaddress.ip_network(prefix) for prefix in listen_range_prefixes) - def _bgp_overlay_dpath(self) -> dict | None: + def _bgp_overlay_dpath(self: AvdStructuredConfigOverlay) -> dict | None: if self.shared_utils.overlay_dpath is True: return { "bestpath": { diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_path_selection.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_path_selection.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_path_selection.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/router_path_selection.py index 8ccd9f510c1..ce49828e201 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_path_selection.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_path_selection.py @@ -4,13 +4,16 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item - +from ....vendor.errors import AristaAvdError +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class RouterPathSelectionMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class RouterPathSelectionMixin(UtilsMixin): """ @cached_property - def router_path_selection(self) -> dict | None: + def router_path_selection(self: AvdStructuredConfigOverlay) -> dict | None: """ Return structured config for router path-selection (DPS) """ @@ -38,21 +41,21 @@ def router_path_selection(self) -> dict | None: return strip_empties_from_dict(router_path_selection) @cached_property - def _cp_ipsec_profile_name(self) -> str: + def _cp_ipsec_profile_name(self: AvdStructuredConfigOverlay) -> str: """ Returns the IPsec profile name to use for Control-Plane """ return get(self._hostvars, "wan_ipsec_profiles.control_plane.profile_name", default="CP-PROFILE") @cached_property - def _dp_ipsec_profile_name(self) -> str: + def _dp_ipsec_profile_name(self: AvdStructuredConfigOverlay) -> str: """ Returns the IPsec profile name to use for Data-Plane """ # TODO need to use CP one if 'wan_ipsec_profiles.data_plane' not present return get(self._hostvars, "wan_ipsec_profiles.data_plane.profile_name", default="DP-PROFILE") - def _get_path_groups(self) -> list: + def _get_path_groups(self: AvdStructuredConfigOverlay) -> list: """ Generate the required path-groups locally """ @@ -108,7 +111,7 @@ def _get_path_groups(self) -> list: return path_groups - def _generate_ha_path_group(self) -> dict: + def _generate_ha_path_group(self: AvdStructuredConfigOverlay) -> dict: """ Called only when self.shared_utils.wan_ha is True or on Pathfinders """ @@ -139,18 +142,18 @@ def _generate_ha_path_group(self) -> dict: return ha_path_group - def _wan_ha_interfaces(self) -> list: + def _wan_ha_interfaces(self: AvdStructuredConfigOverlay) -> list: """ Return list of interfaces for HA """ return [uplink for uplink in self.shared_utils.get_switch_fact("uplinks") if get(uplink, "vrf") is None] - def _wan_ha_peer_vtep_ip(self) -> str: + def _wan_ha_peer_vtep_ip(self: AvdStructuredConfigOverlay) -> str: """ """ peer_facts = self.shared_utils.get_peer_facts(self.shared_utils.wan_ha_peer, required=True) return get(peer_facts, "vtep_ip", required=True) - def _get_path_group_id(self, path_group_name: str, config_id: int | None = None) -> int: + def _get_path_group_id(self: AvdStructuredConfigOverlay, path_group_name: str, config_id: int | None = None) -> int: """ TODO - implement algorithm to auto assign IDs - cf internal documentation TODO - also implement algorithm for cross connects on public path_groups @@ -161,7 +164,7 @@ def _get_path_group_id(self, path_group_name: str, config_id: int | None = None) return config_id return 500 - def _get_local_interfaces_for_path_group(self, path_group_name: str) -> list | None: + def _get_local_interfaces_for_path_group(self: AvdStructuredConfigOverlay, path_group_name: str) -> list | None: """ Generate the router_path_selection.local_interfaces list @@ -181,7 +184,7 @@ def _get_local_interfaces_for_path_group(self, path_group_name: str) -> list | N return local_interfaces - def _get_dynamic_peers(self, disable_ipsec: bool) -> dict | None: + def _get_dynamic_peers(self: AvdStructuredConfigOverlay, disable_ipsec: bool) -> dict | None: """ TODO support ip_local ? """ @@ -193,7 +196,7 @@ def _get_dynamic_peers(self, disable_ipsec: bool) -> dict | None: dynamic_peers["ipsec"] = False return dynamic_peers - def _get_static_peers_for_path_group(self, path_group_name: str) -> list | None: + def _get_static_peers_for_path_group(self: AvdStructuredConfigOverlay, path_group_name: str) -> list | None: """ Retrieves the static peers to configure for a given path-group based on the connected nodes. """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_traffic_engineering.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_traffic_engineering.py similarity index 78% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_traffic_engineering.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/router_traffic_engineering.py index a711d42d08b..ea55c939a7b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/router_traffic_engineering.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/router_traffic_engineering.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class RouterTrafficEngineering(UtilsMixin): """ @@ -15,7 +19,7 @@ class RouterTrafficEngineering(UtilsMixin): """ @cached_property - def router_traffic_engineering(self) -> dict | None: + def router_traffic_engineering(self: AvdStructuredConfigOverlay) -> dict | None: """ Return structured config for router traffic-engineering """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/stun.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/stun.py similarity index 84% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/stun.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/stun.py index e192d73cd35..31ba1954893 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/stun.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/stun.py @@ -5,11 +5,14 @@ import itertools from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict - +from ....vendor.strip_empties import strip_empties_from_dict from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay + class StunMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class StunMixin(UtilsMixin): """ @cached_property - def stun(self) -> dict | None: + def stun(self: AvdStructuredConfigOverlay) -> dict | None: """ Return structured config for stun """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/utils.py b/python-avd/pyavd/_eos_designs/structured_config/overlay/utils.py similarity index 85% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/utils.py rename to python-avd/pyavd/_eos_designs/structured_config/overlay/utils.py index 98119412d83..b5859e6f60e 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/overlay/utils.py +++ b/python-avd/pyavd/_eos_designs/structured_config/overlay/utils.py @@ -4,10 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils.shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import get + +if TYPE_CHECKING: + from . import AvdStructuredConfigOverlay class UtilsMixin: @@ -16,12 +19,8 @@ class UtilsMixin: Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _avd_overlay_peers(self) -> list: + def _avd_overlay_peers(self: AvdStructuredConfigOverlay) -> list: """ Returns a list of overlay peers for the device @@ -31,7 +30,7 @@ def _avd_overlay_peers(self) -> list: return get(self._hostvars, f"avd_overlay_peers..{self.shared_utils.hostname}", separator="..", default=[]) @cached_property - def _evpn_gateway_remote_peers(self) -> dict: + def _evpn_gateway_remote_peers(self: AvdStructuredConfigOverlay) -> dict: if not self.shared_utils.overlay_evpn: return {} @@ -62,7 +61,7 @@ def _evpn_gateway_remote_peers(self) -> dict: return evpn_gateway_remote_peers @cached_property - def _evpn_route_clients(self) -> dict: + def _evpn_route_clients(self: AvdStructuredConfigOverlay) -> dict: if not self.shared_utils.overlay_evpn: return {} @@ -76,14 +75,14 @@ def _evpn_route_clients(self) -> dict: if ( self.shared_utils.hostname in peer_facts.get("evpn_route_servers", []) and peer_facts.get("evpn_role") in ["server", "client"] - and avd_peer not in self._evpn_route_servers.keys() + and avd_peer not in self._evpn_route_servers ): self._append_peer(evpn_route_clients, avd_peer, peer_facts) return evpn_route_clients @cached_property - def _evpn_route_servers(self) -> dict: + def _evpn_route_servers(self: AvdStructuredConfigOverlay) -> dict: if not self.shared_utils.overlay_evpn: return {} @@ -100,29 +99,29 @@ def _evpn_route_servers(self) -> dict: # The next four should probably be moved to facts @cached_property - def _is_mpls_client(self) -> bool: + def _is_mpls_client(self: AvdStructuredConfigOverlay) -> bool: return self.shared_utils.mpls_overlay_role == "client" or (self.shared_utils.evpn_role == "client" and self.shared_utils.overlay_evpn_mpls) @cached_property - def _is_mpls_server(self) -> bool: + def _is_mpls_server(self: AvdStructuredConfigOverlay) -> bool: return self.shared_utils.mpls_overlay_role == "server" or (self.shared_utils.evpn_role == "server" and self.shared_utils.overlay_evpn_mpls) - def _is_peer_mpls_client(self, peer_facts: dict) -> bool: + def _is_peer_mpls_client(self: AvdStructuredConfigOverlay, peer_facts: dict) -> bool: return peer_facts.get("mpls_overlay_role", None) == "client" or ( peer_facts.get("evpn_role", None) == "client" and get(peer_facts, "overlay.evpn_mpls") is True ) - def _is_peer_mpls_server(self, peer_facts: dict) -> bool: + def _is_peer_mpls_server(self: AvdStructuredConfigOverlay, peer_facts: dict) -> bool: return peer_facts.get("mpls_overlay_role", None) == "server" or ( peer_facts.get("evpn_role", None) == "server" and get(peer_facts, "overlay.evpn_mpls") is True ) @cached_property - def _ipvpn_gateway_local_as(self) -> str | None: + def _ipvpn_gateway_local_as(self: AvdStructuredConfigOverlay) -> str | None: return str(_as) if (_as := get(self.shared_utils.switch_data_combined, "ipvpn_gateway.local_as")) is not None else None @cached_property - def _ipvpn_gateway_remote_peers(self) -> dict: + def _ipvpn_gateway_remote_peers(self: AvdStructuredConfigOverlay) -> dict: if self.shared_utils.overlay_ipvpn_gateway is not True: return {} @@ -148,7 +147,7 @@ def _ipvpn_gateway_remote_peers(self) -> dict: return ipvpn_gateway_remote_peers @cached_property - def _mpls_route_clients(self) -> dict: + def _mpls_route_clients(self: AvdStructuredConfigOverlay) -> dict: if self._is_mpls_server is not True: return {} @@ -159,13 +158,13 @@ def _mpls_route_clients(self) -> dict: if self._is_peer_mpls_client(peer_facts) is not True: continue - if self.shared_utils.hostname in peer_facts.get("mpls_route_reflectors", []) and avd_peer not in self._mpls_route_reflectors.keys(): + if self.shared_utils.hostname in peer_facts.get("mpls_route_reflectors", []) and avd_peer not in self._mpls_route_reflectors: self._append_peer(mpls_route_clients, avd_peer, peer_facts) return mpls_route_clients @cached_property - def _mpls_mesh_pe(self) -> dict: + def _mpls_mesh_pe(self: AvdStructuredConfigOverlay) -> dict: if self.shared_utils.overlay_mpls is not True: return {} @@ -189,7 +188,7 @@ def _mpls_mesh_pe(self) -> dict: return mpls_mesh_pe @cached_property - def _mpls_route_reflectors(self) -> dict: + def _mpls_route_reflectors(self: AvdStructuredConfigOverlay) -> dict: if self._is_mpls_client is not True: return {} @@ -208,7 +207,7 @@ def _mpls_route_reflectors(self) -> dict: return mpls_route_reflectors @cached_property - def _mpls_rr_peers(self) -> dict: + def _mpls_rr_peers(self: AvdStructuredConfigOverlay) -> dict: if self._is_mpls_server is not True: return {} @@ -236,7 +235,7 @@ def _mpls_rr_peers(self) -> dict: return mpls_rr_peers - def _append_peer(self, peers_dict: dict, peer_name: str, peer_facts: dict) -> None: + def _append_peer(self: AvdStructuredConfigOverlay, peers_dict: dict, peer_name: str, peer_facts: dict) -> None: """ Retrieve bgp_as and "overlay.peering_address" from peer_facts and append a new peer to peers_dict @@ -259,10 +258,10 @@ def _append_peer(self, peers_dict: dict, peer_name: str, peer_facts: dict) -> No } @cached_property - def _is_wan_server_with_peers(self) -> bool: + def _is_wan_server_with_peers(self: AvdStructuredConfigOverlay) -> bool: return self.shared_utils.is_wan_server and len(self.shared_utils.filtered_wan_route_servers) > 0 - def _stun_server_profile_name(self, wan_route_server_name: str, path_group_name: str, interface_name: str) -> str: + def _stun_server_profile_name(self: AvdStructuredConfigOverlay, wan_route_server_name: str, path_group_name: str, interface_name: str) -> str: """ Return a string to use as the name of the stun server_profile @@ -273,7 +272,7 @@ def _stun_server_profile_name(self, wan_route_server_name: str, path_group_name: return f"{path_group_name}-{wan_route_server_name}-{sanitized_interface_name}" @cached_property - def _stun_server_profiles(self) -> list: + def _stun_server_profiles(self: AvdStructuredConfigOverlay) -> dict: """ Return a dictionary of _stun_server_profiles with ip_address per local path_group """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/avdstructuredconfig.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/__init__.py similarity index 96% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/avdstructuredconfig.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/__init__.py index 9a8f7b3b69b..02f88169f6e 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/avdstructuredconfig.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/__init__.py @@ -1,8 +1,7 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from ansible_collections.arista.avd.plugins.plugin_utils.avdfacts import AvdFacts - +from ....vendor.avdfacts import AvdFacts from .agents import AgentsMixin from .as_path import AsPathMixin from .ethernet_interfaces import EthernetInterfacesMixin diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/agents.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/agents.py similarity index 82% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/agents.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/agents.py index 8fd9e344148..5b317cd3171 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/agents.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/agents.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class AgentsMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class AgentsMixin(UtilsMixin): """ @cached_property - def agents(self) -> dict | None: + def agents(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for agents """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/as_path.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/as_path.py similarity index 87% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/as_path.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/as_path.py index 506fdf94b19..65136fa108c 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/as_path.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/as_path.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class AsPathMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class AsPathMixin(UtilsMixin): """ @cached_property - def as_path(self) -> list | None: + def as_path(self: AvdStructuredConfigUnderlay) -> dict | None: """ Return structured config for as_path. """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/ethernet_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/ethernet_interfaces.py similarity index 96% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/ethernet_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/ethernet_interfaces.py index 6994f920c39..04570c02e2b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/ethernet_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/ethernet_interfaces.py @@ -4,13 +4,16 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get - -from ..interface_descriptions import InterfaceDescriptionData +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import append_if_not_duplicate, get +from ...interface_descriptions import InterfaceDescriptionData from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class EthernetInterfacesMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class EthernetInterfacesMixin(UtilsMixin): """ @cached_property - def ethernet_interfaces(self) -> list | None: + def ethernet_interfaces(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for ethernet_interfaces """ @@ -219,7 +222,7 @@ def ethernet_interfaces(self) -> list | None: interface_name = l3_interface["name"] if "." in interface_name: # This is a subinterface so we need to ensure that the parent is created - parent_interface_name, subif_id = interface_name.split(".", maxsplit=1) + parent_interface_name, _ = interface_name.split(".", maxsplit=1) subif_parent_interface_names.add(parent_interface_name) ethernet_interface = self._get_l3_interface_cfg(l3_interface) diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/ip_access_lists.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/ip_access_lists.py similarity index 78% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/ip_access_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/ip_access_lists.py index 988b459b545..967ac3f6a66 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/ip_access_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/ip_access_lists.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate - +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import append_if_not_duplicate from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class IpAccesslistsMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class IpAccesslistsMixin(UtilsMixin): """ @cached_property - def ip_access_lists(self) -> list | None: + def ip_access_lists(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for ip_access_lists. diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/loopback_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/loopback_interfaces.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/loopback_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/loopback_interfaces.py index 076a1d100ce..7918806008b 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/loopback_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/loopback_interfaces.py @@ -4,13 +4,16 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - -from ..interface_descriptions.models import InterfaceDescriptionData +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.utils import get +from ...interface_descriptions.models import InterfaceDescriptionData from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class LoopbackInterfacesMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class LoopbackInterfacesMixin(UtilsMixin): """ @cached_property - def loopback_interfaces(self) -> list | None: + def loopback_interfaces(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for loopback_interfaces """ @@ -93,7 +96,7 @@ def loopback_interfaces(self) -> list | None: return loopback_interfaces @cached_property - def _node_sid(self): + def _node_sid(self: AvdStructuredConfigUnderlay): if self.shared_utils.id is None: raise AristaAvdMissingVariableError(f"'id' is not set on '{self.shared_utils.hostname}' and is required to set node SID") node_sid_base = int(get(self.shared_utils.switch_data_combined, "node_sid_base", 0)) diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/mpls.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/mpls.py similarity index 86% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/mpls.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/mpls.py index 86ffc5d0177..390d4dd2433 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/mpls.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/mpls.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class MplsMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class MplsMixin(UtilsMixin): """ @cached_property - def mpls(self) -> dict | None: + def mpls(self: AvdStructuredConfigUnderlay) -> dict | None: """ Return structured config for mpls """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/port_channel_interfaces.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/port_channel_interfaces.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/port_channel_interfaces.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/port_channel_interfaces.py index bc9a09cf2eb..f9d9802c650 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/port_channel_interfaces.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/port_channel_interfaces.py @@ -4,15 +4,18 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.generate_esi import generate_esi -from ansible_collections.arista.avd.plugins.filter.generate_lacp_id import generate_lacp_id -from ansible_collections.arista.avd.plugins.filter.generate_route_target import generate_route_target -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - -from ..interface_descriptions.models import InterfaceDescriptionData +from ....j2filters.generate_esi import generate_esi +from ....j2filters.generate_route_target import generate_route_target +from ....vendor.j2.filter.generate_lacp_id import generate_lacp_id +from ....vendor.utils import get +from ...interface_descriptions.models import InterfaceDescriptionData from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class PortChannelInterfacesMixin(UtilsMixin): """ @@ -21,7 +24,7 @@ class PortChannelInterfacesMixin(UtilsMixin): """ @cached_property - def port_channel_interfaces(self) -> list | None: + def port_channel_interfaces(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for port_channel_interfaces """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/prefix_lists.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/prefix_lists.py similarity index 93% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/prefix_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/prefix_lists.py index db993f77fa6..53b3e6322df 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/prefix_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/prefix_lists.py @@ -5,9 +5,13 @@ import ipaddress from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class PrefixListsMixin(UtilsMixin): """ @@ -16,7 +20,7 @@ class PrefixListsMixin(UtilsMixin): """ @cached_property - def prefix_lists(self) -> list | None: + def prefix_lists(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for prefix_lists """ @@ -64,7 +68,7 @@ def prefix_lists(self) -> list | None: return prefix_lists @cached_property - def ipv6_prefix_lists(self) -> dict | None: + def ipv6_prefix_lists(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for IPv6 prefix_lists """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/route_maps.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/route_maps.py similarity index 96% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/route_maps.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/route_maps.py index ec865009302..46f47712807 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/route_maps.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/route_maps.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class RouteMapsMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class RouteMapsMixin(UtilsMixin): """ @cached_property - def route_maps(self) -> list | None: + def route_maps(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for route_maps diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_bgp.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_bgp.py similarity index 95% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_bgp.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/router_bgp.py index a6c08a903f1..94779dff120 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_bgp.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_bgp.py @@ -4,10 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import append_if_not_duplicate, get -from ansible_collections.arista.avd.roles.eos_designs.python_modules.underlay.utils import UtilsMixin +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import append_if_not_duplicate, get +from .utils import UtilsMixin + +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay class RouterBgpMixin(UtilsMixin): @@ -17,7 +21,7 @@ class RouterBgpMixin(UtilsMixin): """ @cached_property - def router_bgp(self) -> dict | None: + def router_bgp(self: AvdStructuredConfigUnderlay) -> dict | None: """ Return the structured config for router_bgp """ @@ -177,7 +181,7 @@ def router_bgp(self) -> dict | None: return strip_empties_from_dict(router_bgp, strip_values_tuple=(None, "")) @cached_property - def _router_bgp_redistribute_routes(self) -> list: + def _router_bgp_redistribute_routes(self: AvdStructuredConfigUnderlay) -> list: """ Return structured config for router_bgp.redistribute_routes """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_isis.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_isis.py similarity index 92% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_isis.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/router_isis.py index 23be82c1b22..fe38cb2ca02 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_isis.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_isis.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdMissingVariableError -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.errors import AristaAvdMissingVariableError +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class RouterIsisMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouterIsisMixin(UtilsMixin): """ @cached_property - def router_isis(self) -> dict | None: + def router_isis(self: AvdStructuredConfigUnderlay) -> dict | None: """ return structured config for router_isis """ @@ -72,7 +75,7 @@ def router_isis(self) -> dict | None: return router_isis @cached_property - def _isis_net(self) -> str | None: + def _isis_net(self: AvdStructuredConfigUnderlay) -> str | None: if get(self._hostvars, "isis_system_id_format", default="node_id") == "node_id": isis_system_id_prefix = get(self.shared_utils.switch_data_combined, "isis_system_id_prefix") if isis_system_id_prefix is None: @@ -91,7 +94,7 @@ def _isis_net(self) -> str | None: return f"{isis_area_id}.{system_id}.00" @cached_property - def _is_type(self) -> str: + def _is_type(self: AvdStructuredConfigUnderlay) -> str: default_is_type = get(self._hostvars, "isis_default_is_type", default="level-2") is_type = str(get(self.shared_utils.switch_data_combined, "is_type", default=default_is_type)).lower() if is_type not in ["level-1", "level-2", "level-1-2"]: diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_msdp.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_msdp.py similarity index 85% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_msdp.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/router_msdp.py index 81a0eaaf12b..5f2c572bd86 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_msdp.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_msdp.py @@ -4,12 +4,15 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item - +from ....j2filters.natural_sort import natural_sort +from ....vendor.utils import get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class RouterMsdpMixin(UtilsMixin): """ @@ -18,7 +21,7 @@ class RouterMsdpMixin(UtilsMixin): """ @cached_property - def router_msdp(self) -> dict | None: + def router_msdp(self: AvdStructuredConfigUnderlay) -> dict | None: """ return structured config for router_msdp @@ -52,7 +55,7 @@ def router_msdp(self) -> dict | None: "originator_id_local_interface": "Loopback0", "peers": [ { - "ipv4_address": get(self.shared_utils.get_peer_facts(node["name"]), "router_id", required=True), + "ipv4_address": get(self.shared_utils.get_peer_facts(peer), "router_id", required=True), "local_interface": "Loopback0", "description": peer, "mesh_groups": [{"name": "ANYCAST-RP"}], diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_ospf.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_ospf.py similarity index 90% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_ospf.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/router_ospf.py index d9bd7fee68b..8b7545c1209 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_ospf.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_ospf.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get - +from ....vendor.utils import default, get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class RouterOspfMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class RouterOspfMixin(UtilsMixin): """ @cached_property - def router_ospf(self) -> dict | None: + def router_ospf(self: AvdStructuredConfigUnderlay) -> dict | None: """ return structured config for router_ospf """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_pim_sparse_mode.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_pim_sparse_mode.py similarity index 91% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_pim_sparse_mode.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/router_pim_sparse_mode.py index 7cb134e7828..6956c4204b5 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/router_pim_sparse_mode.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/router_pim_sparse_mode.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item - +from ....vendor.utils import get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class RouterPimSparseModeMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class RouterPimSparseModeMixin(UtilsMixin): """ @cached_property - def router_pim_sparse_mode(self) -> dict | None: + def router_pim_sparse_mode(self: AvdStructuredConfigUnderlay) -> dict | None: """ return structured config for router_pim_sparse_mode diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/standard_access_lists.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/standard_access_lists.py similarity index 89% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/standard_access_lists.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/standard_access_lists.py index 95b70655b90..d777d802052 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/standard_access_lists.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/standard_access_lists.py @@ -4,9 +4,13 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class StandardAccessListsMixin(UtilsMixin): """ @@ -15,7 +19,7 @@ class StandardAccessListsMixin(UtilsMixin): """ @cached_property - def standard_access_lists(self) -> list | None: + def standard_access_lists(self: AvdStructuredConfigUnderlay) -> list | None: """ return structured config for standard_access_lists diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/static_routes.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/static_routes.py similarity index 88% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/static_routes.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/static_routes.py index 8cb8960b3af..e1878364059 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/static_routes.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/static_routes.py @@ -4,11 +4,14 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get - +from ....vendor.utils import get from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class StaticRoutesMixin(UtilsMixin): """ @@ -17,7 +20,7 @@ class StaticRoutesMixin(UtilsMixin): """ @cached_property - def static_routes(self) -> list[dict] | None: + def static_routes(self: AvdStructuredConfigUnderlay) -> list[dict] | None: """ Returns structured config for static_routes diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/utils.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/utils.py similarity index 92% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/utils.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/utils.py index 0366564ad63..326c80348b2 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/utils.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/utils.py @@ -4,15 +4,17 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.eos_designs_shared_utils.shared_utils import SharedUtils -from ansible_collections.arista.avd.plugins.plugin_utils.errors import AristaAvdError -from ansible_collections.arista.avd.plugins.plugin_utils.strip_empties import strip_empties_from_dict -from ansible_collections.arista.avd.plugins.plugin_utils.utils import default, get, get_item +from ....j2filters.natural_sort import natural_sort +from ....vendor.errors import AristaAvdError +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.strip_empties import strip_empties_from_dict +from ....vendor.utils import default, get, get_item +from ...interface_descriptions import InterfaceDescriptionData -from ..interface_descriptions import InterfaceDescriptionData +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay class UtilsMixin: @@ -21,12 +23,8 @@ class UtilsMixin: Class should only be used as Mixin to a AvdStructuredConfig class """ - # Set type hints for Attributes of the main class as needed - _hostvars: dict - shared_utils: SharedUtils - @cached_property - def _avd_peers(self) -> list: + def _avd_peers(self: AvdStructuredConfigUnderlay) -> list: """ Returns a list of peers @@ -36,7 +34,7 @@ def _avd_peers(self) -> list: return natural_sort(get(self._hostvars, f"avd_topology_peers..{self.shared_utils.hostname}", separator="..", default=[])) @cached_property - def _underlay_filter_peer_as_route_maps_asns(self) -> list: + def _underlay_filter_peer_as_route_maps_asns(self: AvdStructuredConfigUnderlay) -> list: """ Filtered ASNs """ @@ -47,7 +45,7 @@ def _underlay_filter_peer_as_route_maps_asns(self) -> list: return natural_sort({link["peer_bgp_as"] for link in self._underlay_links if link["type"] == "underlay_p2p"}) @cached_property - def _underlay_links(self) -> list: + def _underlay_links(self: AvdStructuredConfigUnderlay) -> list: """ Returns the list of underlay links for this device """ @@ -118,7 +116,7 @@ def _underlay_links(self) -> list: return natural_sort(underlay_links, "interface") @cached_property - def _underlay_vlan_trunk_groups(self) -> list: + def _underlay_vlan_trunk_groups(self: AvdStructuredConfigUnderlay) -> list: """ Returns a list of trunk groups to configure on the underlay link """ @@ -147,10 +145,10 @@ def _underlay_vlan_trunk_groups(self) -> list: return [] @cached_property - def _uplinks(self) -> list: + def _uplinks(self: AvdStructuredConfigUnderlay) -> list: return get(self._hostvars, "switch.uplinks") - def _get_l3_interface_cfg(self, l3_interface: dict) -> dict | None: + def _get_l3_interface_cfg(self: AvdStructuredConfigUnderlay, l3_interface: dict) -> dict | None: """ Returns structured_configuration for one L3 interface """ @@ -216,7 +214,7 @@ def _get_l3_interface_cfg(self, l3_interface: dict) -> dict | None: return strip_empties_from_dict(interface) - def _get_l3_uplink_with_l2_as_subint(self, link: dict) -> tuple[dict, list[dict]]: + def _get_l3_uplink_with_l2_as_subint(self: AvdStructuredConfigUnderlay, link: dict) -> tuple[dict, list[dict]]: """ Return a tuple with main uplink interface, list of subinterfaces representing each SVI. """ @@ -249,7 +247,7 @@ def _get_l3_uplink_with_l2_as_subint(self, link: dict) -> tuple[dict, list[dict] ) return main_interface, [interface for interface in interfaces if interface["name"] != link["interface"]] - def _get_l2_as_subint(self, link: dict, svi: dict, vrf: dict) -> dict: + def _get_l2_as_subint(self: AvdStructuredConfigUnderlay, link: dict, svi: dict, vrf: dict) -> dict: """ Return structured config for one subinterface representing the given SVI. Only supports static IPs or VRRP. @@ -298,7 +296,7 @@ def _get_l2_as_subint(self, link: dict, svi: dict, vrf: dict) -> dict: return strip_empties_from_dict(subinterface) @cached_property - def _l3_interface_acls(self) -> dict[str, dict[str, dict]]: + def _l3_interface_acls(self: AvdStructuredConfigUnderlay) -> dict[str, dict[str, dict]]: """ Returns a dict of : { diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/vlans.py b/python-avd/pyavd/_eos_designs/structured_config/underlay/vlans.py similarity index 88% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/vlans.py rename to python-avd/pyavd/_eos_designs/structured_config/underlay/vlans.py index 337bf1a4e67..d4634e9a8a5 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/underlay/vlans.py +++ b/python-avd/pyavd/_eos_designs/structured_config/underlay/vlans.py @@ -4,13 +4,16 @@ from __future__ import annotations from functools import cached_property +from typing import TYPE_CHECKING -from ansible_collections.arista.avd.plugins.filter.natural_sort import natural_sort -from ansible_collections.arista.avd.plugins.filter.range_expand import range_expand -from ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item - +from ....j2filters.natural_sort import natural_sort +from ....vendor.j2.filter.range_expand import range_expand +from ....vendor.utils import get, get_item from .utils import UtilsMixin +if TYPE_CHECKING: + from . import AvdStructuredConfigUnderlay + class VlansMixin(UtilsMixin): """ @@ -19,7 +22,7 @@ class VlansMixin(UtilsMixin): """ @cached_property - def vlans(self) -> dict | None: + def vlans(self: AvdStructuredConfigUnderlay) -> list | None: """ Return structured config for vlans diff --git a/python-avd/pyavd/get_device_structured_config.py b/python-avd/pyavd/get_device_structured_config.py index 1117809e95f..7f83631f730 100755 --- a/python-avd/pyavd/get_device_structured_config.py +++ b/python-avd/pyavd/get_device_structured_config.py @@ -3,6 +3,7 @@ # that can be found in the LICENSE file. from collections import ChainMap +from ._eos_designs.structured_config import get_structured_config from .avd_schema_tools import AvdSchemaTools from .constants import EOS_CLI_CONFIG_GEN_SCHEMA_ID @@ -21,7 +22,6 @@ def get_device_structured_config(hostname: str, inputs: dict, avd_facts: dict) - Device Structured Configuration as a dictionary """ # pylint: disable=import-outside-toplevel - from .vendor.eos_designs.get_structured_config import get_structured_config from .vendor.errors import AristaAvdError # pylint: enable=import-outside-toplevel diff --git a/python-avd/schema_tools/generate_docs/tablerowgen.py b/python-avd/schema_tools/generate_docs/tablerowgen.py index 3fbac50b2e6..37b13890232 100644 --- a/python-avd/schema_tools/generate_docs/tablerowgen.py +++ b/python-avd/schema_tools/generate_docs/tablerowgen.py @@ -93,8 +93,8 @@ def get_indentation(self) -> str: # TODO: Remove legacy output if LEGACY_OUTPUT: return i * (indentation_count - 2) + "-" + " " # Using space as last indentation to match legacy behavior - else: - return i * (indentation_count - 2) + "-" + i + + return i * (indentation_count - 2) + "-" + i return i * indentation_count diff --git a/python-avd/tests/pyavd/eos_cli_config_gen/test_validate_structured_config.py b/python-avd/tests/pyavd/eos_cli_config_gen/test_validate_structured_config.py index 87992a84075..b7751722437 100644 --- a/python-avd/tests/pyavd/eos_cli_config_gen/test_validate_structured_config.py +++ b/python-avd/tests/pyavd/eos_cli_config_gen/test_validate_structured_config.py @@ -3,7 +3,7 @@ # that can be found in the LICENSE file. from pyavd import validate_structured_config from pyavd.avd_schema_tools import AvdSchemaTools -from pyavd.vendor.errors import AvdValidationError +from pyavd.vendor.errors import AvdValidationError # pylint: disable=no-name-in-module SCHEMA = AvdSchemaTools(schema_id="eos_cli_config_gen").avdschema._schema diff --git a/python-avd/tests/pyavd/eos_designs/test_get_avd_facts.py b/python-avd/tests/pyavd/eos_designs/test_get_avd_facts.py index c04b547ee40..a0dddef8f95 100644 --- a/python-avd/tests/pyavd/eos_designs/test_get_avd_facts.py +++ b/python-avd/tests/pyavd/eos_designs/test_get_avd_facts.py @@ -11,10 +11,10 @@ def test_get_avd_facts(all_inputs: dict): avd_facts = get_avd_facts(all_inputs) assert isinstance(avd_facts, dict) - assert "avd_switch_facts" in avd_facts.keys() + assert "avd_switch_facts" in avd_facts assert isinstance(avd_facts["avd_switch_facts"], dict) assert len(avd_facts["avd_switch_facts"]) == len(all_inputs) - assert "avd_overlay_peers" in avd_facts.keys() + assert "avd_overlay_peers" in avd_facts assert isinstance(avd_facts["avd_overlay_peers"], dict) - assert "avd_topology_peers" in avd_facts.keys() + assert "avd_topology_peers" in avd_facts assert isinstance(avd_facts["avd_topology_peers"], dict) diff --git a/python-avd/tests/pyavd/eos_designs/test_validate_structured_config.py b/python-avd/tests/pyavd/eos_designs/test_validate_structured_config.py index 5282467e6e0..70e9a7c9a53 100644 --- a/python-avd/tests/pyavd/eos_designs/test_validate_structured_config.py +++ b/python-avd/tests/pyavd/eos_designs/test_validate_structured_config.py @@ -3,7 +3,7 @@ # that can be found in the LICENSE file. from pyavd import validate_structured_config from pyavd.avd_schema_tools import AvdSchemaTools -from pyavd.vendor.errors import AvdValidationError +from pyavd.vendor.errors import AvdValidationError # pylint: disable=no-name-in-module SCHEMA = AvdSchemaTools(schema_id="eos_cli_config_gen").avdschema._schema diff --git a/python-avd/tests/schema_tools/metaschema/test_meta_schema_model.py b/python-avd/tests/schema_tools/metaschema/test_meta_schema_model.py index ad89e0d45e1..fc2f6a07cd7 100644 --- a/python-avd/tests/schema_tools/metaschema/test_meta_schema_model.py +++ b/python-avd/tests/schema_tools/metaschema/test_meta_schema_model.py @@ -22,7 +22,7 @@ class NoAliasDumper(yaml.Dumper): """Dump YAML without generating aliases and anchors for reused ids""" - def ignore_aliases(self, data): + def ignore_aliases(self, _): return True diff --git a/python-avd/tests/utils.py b/python-avd/tests/utils.py index 10271b6916d..92c302a9bbf 100644 --- a/python-avd/tests/utils.py +++ b/python-avd/tests/utils.py @@ -45,7 +45,7 @@ def create_common_vars(common_varfiles): def get_files_in_folder(folder_path): files = [] - for root, dir, filenames in os.walk(folder_path): + for root, _, filenames in os.walk(folder_path): for filename in filenames: files.append(os.path.join(root, filename)) return files diff --git a/python-avd/vendor_overrides/schema/store.py b/python-avd/vendor_overrides/schema/store.py index 57f02cee92f..cf2ceb78961 100644 --- a/python-avd/vendor_overrides/schema/store.py +++ b/python-avd/vendor_overrides/schema/store.py @@ -4,7 +4,7 @@ from functools import lru_cache from pickle import load -from pyavd.vendor.schema.default_schemas import DEFAULT_PICKLED_SCHEMAS +from pyavd.vendor.schema.default_schemas import DEFAULT_PICKLED_SCHEMAS # pylint: disable=no-name-in-module @lru_cache diff --git a/python-avd/vendor_overrides/utils/template.py b/python-avd/vendor_overrides/utils/template.py deleted file mode 100644 index 1f307184389..00000000000 --- a/python-avd/vendor_overrides/utils/template.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2023-2024 Arista Networks, Inc. -# Use of this source code is governed by the Apache License 2.0 -# that can be found in the LICENSE file. -""" -Dummy. Not needed for pyavd, but is imported in __init__.py -""" - - -def template(*args) -> str: - raise NotImplementedError("Jinja Templating is not implemented in pyavd")