Skip to content

Commit

Permalink
feat(anta): Added the test case to verify the SNMP source interface f…
Browse files Browse the repository at this point in the history
…or specified VRF (#870)

* Added TC for SNMP source interface

* issue_854 handling review comments: updated failure msgs

* Issue_854: Fixed pre-commit issues

* Issue_854: Refactored snmp source interface verification test with latest input model changes

* Issue_854: Fixed docstrings

* Minor fixes

---------

Co-authored-by: VitthalMagadum <[email protected]>
Co-authored-by: Geetanjali.mane <[email protected]>
Co-authored-by: Carl Baillargeon <[email protected]>
  • Loading branch information
4 people authored Jan 21, 2025
1 parent 3f76153 commit 995943a
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 2 deletions.
20 changes: 19 additions & 1 deletion anta/input_models/snmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from pydantic import BaseModel, ConfigDict

from anta.custom_types import Hostname, SnmpEncryptionAlgorithm, SnmpHashingAlgorithm, SnmpVersion
from anta.custom_types import Hostname, Interface, SnmpEncryptionAlgorithm, SnmpHashingAlgorithm, SnmpVersion


class SnmpHost(BaseModel):
Expand Down Expand Up @@ -54,3 +54,21 @@ def __str__(self) -> str:
- User: Test Group: Test_Group Version: v2c
"""
return f"User: {self.username} Group: {self.group_name} Version: {self.version}"


class SnmpSourceInterface(BaseModel):
"""Model for a SNMP source-interface."""

interface: Interface
"""Interface to use as the source IP address of SNMP messages."""
vrf: str = "default"
"""VRF of the source interface."""

def __str__(self) -> str:
"""Return a human-readable string representation of the SnmpSourceInterface for reporting.
Examples
--------
- Source Interface: Ethernet1 VRF: default
"""
return f"Source Interface: {self.interface} VRF: {self.vrf}"
56 changes: 55 additions & 1 deletion anta/tests/snmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pydantic import field_validator

from anta.custom_types import PositiveInteger, SnmpErrorCounter, SnmpPdu
from anta.input_models.snmp import SnmpHost, SnmpUser
from anta.input_models.snmp import SnmpHost, SnmpSourceInterface, SnmpUser
from anta.models import AntaCommand, AntaTest
from anta.tools import get_value

Expand Down Expand Up @@ -489,3 +489,57 @@ def test(self) -> None:

if user.priv_type and (act_encryption := get_value(user_details, "v3Params.privType", "Not Found")) != user.priv_type:
self.result.is_failure(f"{user} - Incorrect privacy type - Expected: {user.priv_type} Actual: {act_encryption}")


class VerifySnmpSourceInterface(AntaTest):
"""Verifies SNMP source interfaces.
This test performs the following checks:
1. Verifies that source interface(s) are configured for SNMP.
2. For each specified source interface:
- Interface is configured in the specified VRF.
Expected Results
----------------
* Success: The test will pass if the provided SNMP source interface(s) are configured in their specified VRF.
* Failure: The test will fail if any of the provided SNMP source interface(s) are NOT configured in their specified VRF.
Examples
--------
```yaml
anta.tests.snmp:
- VerifySnmpSourceInterface:
interfaces:
- interface: Ethernet1
vrf: default
- interface: Management0
vrf: MGMT
```
"""

categories: ClassVar[list[str]] = ["snmp"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp", revision=1)]

class Input(AntaTest.Input):
"""Input model for the VerifySnmpSourceInterface test."""

interfaces: list[SnmpSourceInterface]
"""List of source interfaces."""

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifySnmpSourceInterface."""
self.result.is_success()
command_output = self.instance_commands[0].json_output.get("srcIntf", {})

if not (interface_output := command_output.get("sourceInterfaces")):
self.result.is_failure("SNMP source interface(s) not configured")
return

for interface_details in self.inputs.interfaces:
# If the source interface is not configured, or if it does not match the expected value, the test fails.
if not (actual_interface := interface_output.get(interface_details.vrf)):
self.result.is_failure(f"{interface_details} - Not configured")
elif actual_interface != interface_details.interface:
self.result.is_failure(f"{interface_details} - Incorrect source interface - Actual: {actual_interface}")
7 changes: 7 additions & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,13 @@ anta.tests.snmp:
pdus:
- outTrapPdus
- inGetNextPdus
- VerifySnmpSourceInterface:
# Verifies SNMP source interfaces.
interfaces:
- interface: Ethernet1
vrf: default
- interface: Management0
vrf: MGMT
- VerifySnmpStatus:
# Verifies if the SNMP agent is enabled.
vrf: default
Expand Down
44 changes: 44 additions & 0 deletions tests/units/anta_tests/test_snmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
VerifySnmpIPv6Acl,
VerifySnmpLocation,
VerifySnmpPDUCounters,
VerifySnmpSourceInterface,
VerifySnmpStatus,
VerifySnmpUser,
)
Expand Down Expand Up @@ -536,4 +537,47 @@
],
},
},
{
"name": "success",
"test": VerifySnmpSourceInterface,
"eos_data": [
{
"srcIntf": {"sourceInterfaces": {"default": "Ethernet1", "MGMT": "Management0"}},
}
],
"inputs": {"interfaces": [{"interface": "Ethernet1", "vrf": "default"}, {"interface": "Management0", "vrf": "MGMT"}]},
"expected": {"result": "success"},
},
{
"name": "failure-not-configured",
"test": VerifySnmpSourceInterface,
"eos_data": [
{
"srcIntf": {},
}
],
"inputs": {"interfaces": [{"interface": "Ethernet1", "vrf": "default"}, {"interface": "Management0", "vrf": "MGMT"}]},
"expected": {"result": "failure", "messages": ["SNMP source interface(s) not configured"]},
},
{
"name": "failure-incorrect-interfaces",
"test": VerifySnmpSourceInterface,
"eos_data": [
{
"srcIntf": {
"sourceInterfaces": {
"default": "Management0",
}
},
}
],
"inputs": {"interfaces": [{"interface": "Ethernet1", "vrf": "default"}, {"interface": "Management0", "vrf": "MGMT"}]},
"expected": {
"result": "failure",
"messages": [
"Source Interface: Ethernet1 VRF: default - Incorrect source interface - Actual: Management0",
"Source Interface: Management0 VRF: MGMT - Not configured",
],
},
},
]

0 comments on commit 995943a

Please sign in to comment.