diff --git a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/SFLOW_TESTS.yml b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/SFLOW_TESTS.yml index 7d9910f15ad..64fdc7199bf 100644 --- a/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/SFLOW_TESTS.yml +++ b/ansible_collections/arista/avd/molecule/eos_designs_unit_tests/inventory/group_vars/SFLOW_TESTS.yml @@ -15,10 +15,9 @@ sflow_settings: - destination: 10.10.10.12 vrf: sflowvrf port: 1234 - structured_config: - vrfs: - - name: sflowvrf - source_interface: Loopback321 + vrfs: + - name: sflowvrf + source_interface: Loopback321 fabric_sflow: uplinks: true diff --git a/ansible_collections/arista/avd/roles/eos_designs/docs/tables/management-sflow-settings.md b/ansible_collections/arista/avd/roles/eos_designs/docs/tables/management-sflow-settings.md index 9d2bb1cfbd5..3d10ecdfbab 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/docs/tables/management-sflow-settings.md +++ b/ansible_collections/arista/avd/roles/eos_designs/docs/tables/management-sflow-settings.md @@ -18,8 +18,10 @@ | [  destinations](## "sflow_settings.destinations") | List, items: Dictionary | | | | | | [    - destination](## "sflow_settings.destinations.[].destination") | String | Required | | | sFlow destination name or IP address. | | [      port](## "sflow_settings.destinations.[].port") | Integer | | | Min: 1
Max: 65535 | UDP Port number. The default port number for sFlow is 6343. | - | [      vrf](## "sflow_settings.destinations.[].vrf") | String | | | | If not set, the VRF is automatically picked up from the global setting `default_mgmt_method`.
The value of `vrf` will be interpreted according to these rules:
- `use_mgmt_interface_vrf` will configure the sFlow destination under the VRF set with `mgmt_interface_vrf` and set the `mgmt_interface` as sFlow source-interface.
An error will be raised if `mgmt_ip` or `ipv6_mgmt_ip` are not configured for the device.
- `use_inband_mgmt_vrf` will configure the sFlow destination under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface.
An error will be raised if inband management is not configured for the device.
- Any other string will be used directly as the VRF name but source interface must be set with `sflow.structured_config` as needed. | - | [  structured_config](## "sflow_settings.structured_config") | Dictionary | | | | Custom structured config added under `sflow` for `eos_cli_config_gen`. | + | [      vrf](## "sflow_settings.destinations.[].vrf") | String | | | | If not set, the VRF is automatically picked up from the global setting `default_mgmt_method`.
The value of `vrf` will be interpreted according to these rules:
- `use_mgmt_interface_vrf` will configure the sFlow destination under the VRF set with `mgmt_interface_vrf` and set the `mgmt_interface` as sFlow source-interface.
An error will be raised if `mgmt_ip` or `ipv6_mgmt_ip` are not configured for the device.
- `use_inband_mgmt_vrf` will configure the sFlow destination under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface.
An error will be raised if inband management is not configured for the device.
- Any other string will be used directly as the VRF name. Remember to set the `sflow_settings.vrfs[].source_interface` if needed. | + | [  vrfs](## "sflow_settings.vrfs") | List, items: Dictionary | | | | | + | [    - name](## "sflow_settings.vrfs.[].name") | String | Required, Unique | | | VRF name. | + | [      source_interface](## "sflow_settings.vrfs.[].source_interface") | String | | | | Source interface to use for sFlow destinations in this VRF.
If set for the VRFs defined by `mgmt_interface_vrf` or `inband_mgmt_vrf`, this setting will take precedence. | === "YAML" @@ -65,9 +67,14 @@ # An error will be raised if `mgmt_ip` or `ipv6_mgmt_ip` are not configured for the device. # - `use_inband_mgmt_vrf` will configure the sFlow destination under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface. # An error will be raised if inband management is not configured for the device. - # - Any other string will be used directly as the VRF name but source interface must be set with `sflow.structured_config` as needed. + # - Any other string will be used directly as the VRF name. Remember to set the `sflow_settings.vrfs[].source_interface` if needed. vrf: + vrfs: - # Custom structured config added under `sflow` for `eos_cli_config_gen`. - structured_config: + # VRF name. + - name: + + # Source interface to use for sFlow destinations in this VRF. + # If set for the VRFs defined by `mgmt_interface_vrf` or `inband_mgmt_vrf`, this setting will take precedence. + source_interface: ``` diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/sflow/__init__.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py similarity index 60% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/sflow/__init__.py rename to ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py index d803f00f4c1..d8047b8e2dc 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/sflow/__init__.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) 2023 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -from .avdstructuredconfig import AvdStructuredConfigSflow +from .avdstructuredconfig import AvdStructuredConfigFlows -__all__ = ["AvdStructuredConfigSflow"] +__all__ = ["AvdStructuredConfigFlows"] diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/sflow/avdstructuredconfig.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py similarity index 86% rename from ansible_collections/arista/avd/roles/eos_designs/python_modules/sflow/avdstructuredconfig.py rename to ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py index b8f816e3b11..bcd3fd4ea2f 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/sflow/avdstructuredconfig.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/flows/avdstructuredconfig.py @@ -9,10 +9,10 @@ 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 ansible_collections.arista.avd.plugins.plugin_utils.utils import get, get_item -class AvdStructuredConfigSflow(AvdFacts): +class AvdStructuredConfigFlows(AvdFacts): """ This class must be rendered after all other eos_designs modules since it relies on detecting sflow from the interface structured config generated by the other modules. @@ -41,6 +41,8 @@ def sflow(self) -> dict | None: # This cannot be implemented today since it would be breaking for already released support for sflow on interfaces. return None + sflow_settings_vrfs = get(self._hostvars, "sflow_settings.vrfs", default=[]) + # At this point we have at least one interface with sFlow enabled # and at least one destination. sflow = {"run": True} @@ -61,7 +63,7 @@ def sflow(self) -> dict | None: ) vrf = self.shared_utils.mgmt_interface_vrf - source_interface = self.shared_utils.mgmt_interface + source_interface = get(get_item(sflow_settings_vrfs, "name", vrf, default={}), "source_interface", default=self.shared_utils.mgmt_interface) elif vrf == "use_inband_mgmt_vrf": # Check for missing interface @@ -72,7 +74,13 @@ def sflow(self) -> dict | None: # self.shared_utils.inband_mgmt_vrf returns None for the default VRF, but here we need "default" to avoid duplicates. vrf = self.shared_utils.inband_mgmt_vrf or "default" - source_interface = self.shared_utils.inband_mgmt_interface + source_interface = get( + get_item(sflow_settings_vrfs, "name", vrf, default={}), "source_interface", default=self.shared_utils.inband_mgmt_interface + ) + + else: + # Default is none, meaning we will not configure a source interface for this VRF. + source_interface = get(get_item(sflow_settings_vrfs, "name", vrf, default={}), "source_interface") if vrf in [None, "default"]: # Add destination without VRF field @@ -100,20 +108,6 @@ def sflow(self) -> dict | None: return strip_null_from_data(sflow) - @cached_property - def struct_cfgs(self) -> list[dict] | None: - """ - Various structured_config keys. - - Covers: - - sflow_settings.structured_config inserted under sflow.* - """ - struct_cfgs = [] - if (struct_cfg := get(self._hostvars, "sflow_settings.structured_config")) is not None: - struct_cfgs.append({"sflow": struct_cfg}) - - return struct_cfgs or None - @cached_property def _enable_sflow(self) -> bool: """ diff --git a/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py b/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py index a291fa0caa6..7a7fddf5488 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py +++ b/ansible_collections/arista/avd/roles/eos_designs/python_modules/get_structured_config/get_structured_config.py @@ -15,12 +15,12 @@ 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 ..sflow import AvdStructuredConfigSflow from ..underlay import AvdStructuredConfigUnderlay AVD_STRUCTURED_CONFIG_CLASSES = [ @@ -32,11 +32,11 @@ AvdStructuredConfigNetworkServices, AvdStructuredConfigConnectedEndpoints, AvdStructuredConfigInbandManagement, - # The sFlow module must be rendered after others contributing interfaces, - # since it parses those interfaces for sFlow config. - AvdStructuredConfigSflow, # Metadata must be after anything else that can generate structured config, since CV tags can consume from structured config. AvdStructuredConfigMetadata, + # The Flows module must be rendered after others contributing interfaces, + # since it parses those interfaces for sFlow or flow tracking (ipfix) config. + AvdStructuredConfigFlows, # The Custom Structured Configuration module must be rendered last, # since it parses all supported object looking for `struct_cfg`. AvdStructuredConfigCustomStructuredConfiguration, diff --git a/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.jsonschema.json b/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.jsonschema.json index 5f55b6415cd..cd319c76284 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.jsonschema.json +++ b/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.jsonschema.json @@ -20600,7 +20600,7 @@ }, "vrf": { "type": "string", - "description": "If not set, the VRF is automatically picked up from the global setting `default_mgmt_method`.\nThe value of `vrf` will be interpreted according to these rules:\n- `use_mgmt_interface_vrf` will configure the sFlow destination under the VRF set with `mgmt_interface_vrf` and set the `mgmt_interface` as sFlow source-interface.\n An error will be raised if `mgmt_ip` or `ipv6_mgmt_ip` are not configured for the device.\n- `use_inband_mgmt_vrf` will configure the sFlow destination under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface.\n An error will be raised if inband management is not configured for the device.\n- Any other string will be used directly as the VRF name but source interface must be set with `sflow.structured_config` as needed.", + "description": "If not set, the VRF is automatically picked up from the global setting `default_mgmt_method`.\nThe value of `vrf` will be interpreted according to these rules:\n- `use_mgmt_interface_vrf` will configure the sFlow destination under the VRF set with `mgmt_interface_vrf` and set the `mgmt_interface` as sFlow source-interface.\n An error will be raised if `mgmt_ip` or `ipv6_mgmt_ip` are not configured for the device.\n- `use_inband_mgmt_vrf` will configure the sFlow destination under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface.\n An error will be raised if inband management is not configured for the device.\n- Any other string will be used directly as the VRF name. Remember to set the `sflow_settings.vrfs[].source_interface` if needed.", "title": "VRF" } }, @@ -20614,10 +20614,31 @@ }, "title": "Destinations" }, - "structured_config": { - "type": "object", - "description": "Custom structured config added under `sflow` for `eos_cli_config_gen`.", - "title": "Structured Config" + "vrfs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "VRF name.", + "title": "Name" + }, + "source_interface": { + "type": "string", + "description": "Source interface to use for sFlow destinations in this VRF.\nIf set for the VRFs defined by `mgmt_interface_vrf` or `inband_mgmt_vrf`, this setting will take precedence.", + "title": "Source Interface" + } + }, + "additionalProperties": false, + "patternProperties": { + "^_.+$": {} + }, + "required": [ + "name" + ] + }, + "title": "VRFs" } }, "additionalProperties": false, diff --git a/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.schema.yml b/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.schema.yml index af33be01f2f..9ae4c7fda61 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.schema.yml +++ b/ansible_collections/arista/avd/roles/eos_designs/schemas/eos_designs.schema.yml @@ -2913,13 +2913,28 @@ keys: under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface.\n An error will be raised if inband management is not configured for the device.\n- Any other string will be used - directly as the VRF name but source interface must be set with `sflow.structured_config` - as needed." + directly as the VRF name. Remember to set the `sflow_settings.vrfs[].source_interface` + if needed." convert_types: - int - structured_config: - type: dict - description: Custom structured config added under `sflow` for `eos_cli_config_gen`. + vrfs: + type: list + primary_key: name + items: + type: dict + keys: + name: + type: str + convert_types: + - int + description: VRF name. + source_interface: + type: str + description: 'Source interface to use for sFlow destinations in this + VRF. + + If set for the VRFs defined by `mgmt_interface_vrf` or `inband_mgmt_vrf`, + this setting will take precedence.' shutdown_interfaces_towards_undeployed_peers: documentation_options: table: fabric-settings diff --git a/ansible_collections/arista/avd/roles/eos_designs/schemas/schema_fragments/sflow_settings.schema.yml b/ansible_collections/arista/avd/roles/eos_designs/schemas/schema_fragments/sflow_settings.schema.yml index b414e7cc781..77f85bd795a 100644 --- a/ansible_collections/arista/avd/roles/eos_designs/schemas/schema_fragments/sflow_settings.schema.yml +++ b/ansible_collections/arista/avd/roles/eos_designs/schemas/schema_fragments/sflow_settings.schema.yml @@ -40,9 +40,22 @@ keys: An error will be raised if `mgmt_ip` or `ipv6_mgmt_ip` are not configured for the device. - `use_inband_mgmt_vrf` will configure the sFlow destination under the VRF set with `inband_mgmt_vrf` and set the `inband_mgmt_interface` as sFlow source-interface. An error will be raised if inband management is not configured for the device. - - Any other string will be used directly as the VRF name but source interface must be set with `sflow.structured_config` as needed. + - Any other string will be used directly as the VRF name. Remember to set the `sflow_settings.vrfs[].source_interface` if needed. convert_types: - int - structured_config: - type: dict - description: Custom structured config added under `sflow` for `eos_cli_config_gen`. + vrfs: + type: list + primary_key: name + items: + type: dict + keys: + name: + type: str + convert_types: + - int + description: VRF name. + source_interface: + type: str + description: |- + Source interface to use for sFlow destinations in this VRF. + If set for the VRFs defined by `mgmt_interface_vrf` or `inband_mgmt_vrf`, this setting will take precedence.