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.