📦 ANTA version
📝 Details
Summary:
AntaDevice mutates the tags set object passed into the constructor by adding self.name directly to it. This becomes a real ANTA bug because inventory parsing reuses the same tags set when expanding a single networks or ranges entry into multiple devices.
As a result, devices created from the same inventory block can inherit each other’s names as tags.
Evidence:
device.py (line 168) stores the incoming tags set directly and mutates it with self.tags.add(self.name)
inventory/init.py (line 193) passes network.tags directly into each AsyncEOSDevice
inventory/init.py (line 244) passes range_def.tags directly into each AsyncEOSDevice
Impact:
Devices created from the same network or range can inherit each other’s names as tags, which can lead to incorrect device filtering, matching, and test selection.
Steps to Reproduce:
Use either ranges or networks.
Example using ranges:
anta_inventory:
ranges:
- start: 10.0.0.1
end: 10.0.0.2
tags: ["spine"]
from pathlib import Path
from anta.inventory import AntaInventory
inventory = AntaInventory.parse(
filename=Path("repro_inventory.yml"),
username="admin",
password="admin",
)
for device in inventory.devices:
print(device.name, sorted(device.tags))
Expected
10.0.0.1 ['10.0.0.1', 'spine']
10.0.0.2 ['10.0.0.2', 'spine']
Actual
10.0.0.1 ['10.0.0.1', '10.0.0.2', 'spine']
10.0.0.2 ['10.0.0.1', '10.0.0.2', 'spine']
The same issue also occurs with networks, for example:
anta_inventory:
networks:
- network: 10.0.0.0/31
tags: ["spine"]
Proposed fix
Make a defensive copy before mutating:
self.tags = set(tags) if tags is not None else set()
self.tags.add(self.name)
📦 ANTA version
anta version 1.9📝 Details
Summary:
AntaDevice mutates the tags set object passed into the constructor by adding self.name directly to it. This becomes a real ANTA bug because inventory parsing reuses the same tags set when expanding a single networks or ranges entry into multiple devices.
As a result, devices created from the same inventory block can inherit each other’s names as tags.
Evidence:
device.py (line 168) stores the incoming tags set directly and mutates it with self.tags.add(self.name)
inventory/init.py (line 193) passes network.tags directly into each AsyncEOSDevice
inventory/init.py (line 244) passes range_def.tags directly into each AsyncEOSDevice
Impact:
Devices created from the same network or range can inherit each other’s names as tags, which can lead to incorrect device filtering, matching, and test selection.
Steps to Reproduce:
Use either ranges or networks.
Example using ranges:
Expected
Actual
The same issue also occurs with networks, for example:
Proposed fix
Make a defensive copy before mutating: