From 5483b978c287c788032dc8d3f595194f40bd6852 Mon Sep 17 00:00:00 2001 From: vitthalmagadum <122079046+vitthalmagadum@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:48:55 +0530 Subject: [PATCH] feat(anta): Added the test case to verify SNMP error counters (#836) --- anta/custom_types.py | 3 + anta/tests/snmp.py | 58 ++++++++++++++++++- examples/tests.yaml | 4 ++ tests/units/anta_tests/test_snmp.py | 86 ++++++++++++++++++++++++++++- 4 files changed, 149 insertions(+), 2 deletions(-) diff --git a/anta/custom_types.py b/anta/custom_types.py index e0bcdd3ea..c29811826 100644 --- a/anta/custom_types.py +++ b/anta/custom_types.py @@ -205,3 +205,6 @@ def validate_regex(value: str) -> str: BgpUpdateError = Literal["inUpdErrWithdraw", "inUpdErrIgnore", "inUpdErrDisableAfiSafi", "disabledAfiSafi", "lastUpdErrTime"] BfdProtocol = Literal["bgp", "isis", "lag", "ospf", "ospfv3", "pim", "route-input", "static-bfd", "static-route", "vrrp", "vxlan"] SnmpPdu = Literal["inGetPdus", "inGetNextPdus", "inSetPdus", "outGetResponsePdus", "outTrapPdus"] +SnmpErrorCounter = Literal[ + "inVersionErrs", "inBadCommunityNames", "inBadCommunityUses", "inParseErrs", "outTooBigErrs", "outNoSuchNameErrs", "outBadValueErrs", "outGeneralErrs" +] diff --git a/anta/tests/snmp.py b/anta/tests/snmp.py index ffbae1c02..217e32059 100644 --- a/anta/tests/snmp.py +++ b/anta/tests/snmp.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, ClassVar, get_args -from anta.custom_types import PositiveInteger, SnmpPdu +from anta.custom_types import PositiveInteger, SnmpErrorCounter, SnmpPdu from anta.models import AntaCommand, AntaTest from anta.tools import get_value @@ -294,3 +294,59 @@ def test(self) -> None: self.result.is_success() else: self.result.is_failure(f"The following SNMP PDU counters are not found or have zero PDU counters:\n{failures}") + + +class VerifySnmpErrorCounters(AntaTest): + """Verifies the SNMP error counters. + + By default, all error counters will be checked for any non-zero values. + An optional list of specific error counters can be provided for granular testing. + + Expected Results + ---------------- + * Success: The test will pass if the SNMP error counter(s) are zero/None. + * Failure: The test will fail if the SNMP error counter(s) are non-zero/not None/Not Found or is not configured. + + Examples + -------- + ```yaml + anta.tests.snmp: + - VerifySnmpErrorCounters: + error_counters: + - inVersionErrs + - inBadCommunityNames + """ + + name = "VerifySnmpErrorCounters" + description = "Verifies the SNMP error counters." + categories: ClassVar[list[str]] = ["snmp"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifySnmpErrorCounters test.""" + + error_counters: list[SnmpErrorCounter] | None = None + """Optional list of SNMP error counters to be verified. If not provided, test will verifies all error counters.""" + + @AntaTest.anta_test + def test(self) -> None: + """Main test function for VerifySnmpErrorCounters.""" + error_counters = self.inputs.error_counters + command_output = self.instance_commands[0].json_output + + # Verify SNMP PDU counters. + if not (snmp_counters := get_value(command_output, "counters")): + self.result.is_failure("SNMP counters not found.") + return + + # In case SNMP error counters not provided, It will check all the error counters. + if not error_counters: + error_counters = list(get_args(SnmpErrorCounter)) + + error_counters_not_ok = {counter: value for counter in error_counters if (value := snmp_counters.get(counter))} + + # Check if any failures + if not error_counters_not_ok: + self.result.is_success() + else: + self.result.is_failure(f"The following SNMP error counters are not found or have non-zero error counters:\n{error_counters_not_ok}") diff --git a/examples/tests.yaml b/examples/tests.yaml index cf961f8e5..d8f3332ae 100644 --- a/examples/tests.yaml +++ b/examples/tests.yaml @@ -401,6 +401,10 @@ anta.tests.snmp: - VerifySnmpPDUCounters: pdus: - outTrapPdus + - VerifySnmpErrorCounters: + error_counters: + - inVersionErrs + - inBadCommunityNames anta.tests.software: - VerifyEOSVersion: diff --git a/tests/units/anta_tests/test_snmp.py b/tests/units/anta_tests/test_snmp.py index 88f1bcddc..e7d8da8ba 100644 --- a/tests/units/anta_tests/test_snmp.py +++ b/tests/units/anta_tests/test_snmp.py @@ -7,7 +7,15 @@ from typing import Any -from anta.tests.snmp import VerifySnmpContact, VerifySnmpIPv4Acl, VerifySnmpIPv6Acl, VerifySnmpLocation, VerifySnmpPDUCounters, VerifySnmpStatus +from anta.tests.snmp import ( + VerifySnmpContact, + VerifySnmpErrorCounters, + VerifySnmpIPv4Acl, + VerifySnmpIPv6Acl, + VerifySnmpLocation, + VerifySnmpPDUCounters, + VerifySnmpStatus, +) from tests.units.anta_tests import test DATA: list[dict[str, Any]] = [ @@ -235,4 +243,80 @@ "messages": ["The following SNMP PDU counters are not found or have zero PDU counters:\n{'inGetPdus': 'Not Found', 'outTrapPdus': 'Not Found'}"], }, }, + { + "name": "success", + "test": VerifySnmpErrorCounters, + "eos_data": [ + { + "counters": { + "inVersionErrs": 0, + "inBadCommunityNames": 0, + "inBadCommunityUses": 0, + "inParseErrs": 0, + "outTooBigErrs": 0, + "outNoSuchNameErrs": 0, + "outBadValueErrs": 0, + "outGeneralErrs": 0, + }, + } + ], + "inputs": {}, + "expected": {"result": "success"}, + }, + { + "name": "success-specific-counters", + "test": VerifySnmpErrorCounters, + "eos_data": [ + { + "counters": { + "inVersionErrs": 0, + "inBadCommunityNames": 0, + "inBadCommunityUses": 0, + "inParseErrs": 0, + "outTooBigErrs": 5, + "outNoSuchNameErrs": 0, + "outBadValueErrs": 10, + "outGeneralErrs": 1, + }, + } + ], + "inputs": {"error_counters": ["inVersionErrs", "inParseErrs"]}, + "expected": {"result": "success"}, + }, + { + "name": "failure-counters-not-found", + "test": VerifySnmpErrorCounters, + "eos_data": [ + { + "counters": {}, + } + ], + "inputs": {}, + "expected": {"result": "failure", "messages": ["SNMP counters not found."]}, + }, + { + "name": "failure-incorrect-counters", + "test": VerifySnmpErrorCounters, + "eos_data": [ + { + "counters": { + "inVersionErrs": 1, + "inBadCommunityNames": 0, + "inBadCommunityUses": 0, + "inParseErrs": 2, + "outTooBigErrs": 0, + "outNoSuchNameErrs": 0, + "outBadValueErrs": 2, + "outGeneralErrs": 0, + }, + } + ], + "inputs": {}, + "expected": { + "result": "failure", + "messages": [ + "The following SNMP error counters are not found or have non-zero error counters:\n{'inVersionErrs': 1, 'inParseErrs': 2, 'outBadValueErrs': 2}" + ], + }, + }, ]