diff options
Diffstat (limited to 'anta/tests/aaa.py')
-rw-r--r-- | anta/tests/aaa.py | 310 |
1 files changed, 210 insertions, 100 deletions
diff --git a/anta/tests/aaa.py b/anta/tests/aaa.py index 84298cf..d6d0689 100644 --- a/anta/tests/aaa.py +++ b/anta/tests/aaa.py @@ -1,44 +1,56 @@ # Copyright (c) 2023-2024 Arista Networks, Inc. # Use of this source code is governed by the Apache License 2.0 # that can be found in the LICENSE file. -""" -Test functions related to the EOS various AAA settings -""" +"""Module related to the EOS various AAA tests.""" + # Mypy does not understand AntaTest.Input typing # mypy: disable-error-code=attr-defined from __future__ import annotations from ipaddress import IPv4Address - -# Need to keep List and Set for pydantic in python 3.8 -from typing import List, Literal, Set +from typing import TYPE_CHECKING, ClassVar, Literal from anta.custom_types import AAAAuthMethod from anta.models import AntaCommand, AntaTest +if TYPE_CHECKING: + from anta.models import AntaTemplate -class VerifyTacacsSourceIntf(AntaTest): - """ - Verifies TACACS source-interface for a specified VRF. - Expected Results: - * success: The test will pass if the provided TACACS source-interface is configured in the specified VRF. - * failure: The test will fail if the provided TACACS source-interface is NOT configured in the specified VRF. +class VerifyTacacsSourceIntf(AntaTest): + """Verifies TACACS source-interface for a specified VRF. + + Expected Results + ---------------- + * Success: The test will pass if the provided TACACS source-interface is configured in the specified VRF. + * Failure: The test will fail if the provided TACACS source-interface is NOT configured in the specified VRF. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyTacacsSourceIntf: + intf: Management0 + vrf: MGMT + ``` """ name = "VerifyTacacsSourceIntf" description = "Verifies TACACS source-interface for a specified VRF." - categories = ["aaa"] - commands = [AntaCommand(command="show tacacs")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show tacacs", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifyTacacsSourceIntf test.""" - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring intf: str - """Source-interface to use as source IP of TACACS messages""" + """Source-interface to use as source IP of TACACS messages.""" vrf: str = "default" - """The name of the VRF to transport TACACS messages""" + """The name of the VRF to transport TACACS messages. Defaults to `default`.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyTacacsSourceIntf.""" command_output = self.instance_commands[0].json_output try: if command_output["srcIntf"][self.inputs.vrf] == self.inputs.intf: @@ -50,27 +62,41 @@ class VerifyTacacsSourceIntf(AntaTest): class VerifyTacacsServers(AntaTest): - """ - Verifies TACACS servers are configured for a specified VRF. - - Expected Results: - * success: The test will pass if the provided TACACS servers are configured in the specified VRF. - * failure: The test will fail if the provided TACACS servers are NOT configured in the specified VRF. + """Verifies TACACS servers are configured for a specified VRF. + + Expected Results + ---------------- + * Success: The test will pass if the provided TACACS servers are configured in the specified VRF. + * Failure: The test will fail if the provided TACACS servers are NOT configured in the specified VRF. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyTacacsServers: + servers: + - 10.10.10.21 + - 10.10.10.22 + vrf: MGMT + ``` """ name = "VerifyTacacsServers" description = "Verifies TACACS servers are configured for a specified VRF." - categories = ["aaa"] - commands = [AntaCommand(command="show tacacs")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show tacacs", revision=1)] - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring - servers: List[IPv4Address] - """List of TACACS servers""" + class Input(AntaTest.Input): + """Input model for the VerifyTacacsServers test.""" + + servers: list[IPv4Address] + """List of TACACS servers.""" vrf: str = "default" - """The name of the VRF to transport TACACS messages""" + """The name of the VRF to transport TACACS messages. Defaults to `default`.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyTacacsServers.""" command_output = self.instance_commands[0].json_output tacacs_servers = command_output["tacacsServers"] if not tacacs_servers: @@ -90,25 +116,38 @@ class VerifyTacacsServers(AntaTest): class VerifyTacacsServerGroups(AntaTest): - """ - Verifies if the provided TACACS server group(s) are configured. - - Expected Results: - * success: The test will pass if the provided TACACS server group(s) are configured. - * failure: The test will fail if one or all the provided TACACS server group(s) are NOT configured. + """Verifies if the provided TACACS server group(s) are configured. + + Expected Results + ---------------- + * Success: The test will pass if the provided TACACS server group(s) are configured. + * Failure: The test will fail if one or all the provided TACACS server group(s) are NOT configured. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyTacacsServerGroups: + groups: + - TACACS-GROUP1 + - TACACS-GROUP2 + ``` """ name = "VerifyTacacsServerGroups" description = "Verifies if the provided TACACS server group(s) are configured." - categories = ["aaa"] - commands = [AntaCommand(command="show tacacs")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show tacacs", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifyTacacsServerGroups test.""" - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring - groups: List[str] - """List of TACACS server group""" + groups: list[str] + """List of TACACS server groups.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyTacacsServerGroups.""" command_output = self.instance_commands[0].json_output tacacs_groups = command_output["groups"] if not tacacs_groups: @@ -122,29 +161,47 @@ class VerifyTacacsServerGroups(AntaTest): class VerifyAuthenMethods(AntaTest): - """ - Verifies the AAA authentication method lists for different authentication types (login, enable, dot1x). - - Expected Results: - * success: The test will pass if the provided AAA authentication method list is matching in the configured authentication types. - * failure: The test will fail if the provided AAA authentication method list is NOT matching in the configured authentication types. + """Verifies the AAA authentication method lists for different authentication types (login, enable, dot1x). + + Expected Results + ---------------- + * Success: The test will pass if the provided AAA authentication method list is matching in the configured authentication types. + * Failure: The test will fail if the provided AAA authentication method list is NOT matching in the configured authentication types. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyAuthenMethods: + methods: + - local + - none + - logging + types: + - login + - enable + - dot1x + ``` """ name = "VerifyAuthenMethods" description = "Verifies the AAA authentication method lists for different authentication types (login, enable, dot1x)." - categories = ["aaa"] - commands = [AntaCommand(command="show aaa methods authentication")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods authentication", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifyAuthenMethods test.""" - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring - methods: List[AAAAuthMethod] - """List of AAA authentication methods. Methods should be in the right order""" - types: Set[Literal["login", "enable", "dot1x"]] - """List of authentication types to verify""" + methods: list[AAAAuthMethod] + """List of AAA authentication methods. Methods should be in the right order.""" + types: set[Literal["login", "enable", "dot1x"]] + """List of authentication types to verify.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyAuthenMethods.""" command_output = self.instance_commands[0].json_output - not_matching = [] + not_matching: list[str] = [] for k, v in command_output.items(): auth_type = k.replace("AuthenMethods", "") if auth_type not in self.inputs.types: @@ -157,9 +214,8 @@ class VerifyAuthenMethods(AntaTest): if v["login"]["methods"] != self.inputs.methods: self.result.is_failure(f"AAA authentication methods {self.inputs.methods} are not matching for login console") return - for methods in v.values(): - if methods["methods"] != self.inputs.methods: - not_matching.append(auth_type) + not_matching.extend(auth_type for methods in v.values() if methods["methods"] != self.inputs.methods) + if not not_matching: self.result.is_success() else: @@ -167,37 +223,53 @@ class VerifyAuthenMethods(AntaTest): class VerifyAuthzMethods(AntaTest): - """ - Verifies the AAA authorization method lists for different authorization types (commands, exec). - - Expected Results: - * success: The test will pass if the provided AAA authorization method list is matching in the configured authorization types. - * failure: The test will fail if the provided AAA authorization method list is NOT matching in the configured authorization types. + """Verifies the AAA authorization method lists for different authorization types (commands, exec). + + Expected Results + ---------------- + * Success: The test will pass if the provided AAA authorization method list is matching in the configured authorization types. + * Failure: The test will fail if the provided AAA authorization method list is NOT matching in the configured authorization types. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyAuthzMethods: + methods: + - local + - none + - logging + types: + - commands + - exec + ``` """ name = "VerifyAuthzMethods" description = "Verifies the AAA authorization method lists for different authorization types (commands, exec)." - categories = ["aaa"] - commands = [AntaCommand(command="show aaa methods authorization")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods authorization", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifyAuthzMethods test.""" - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring - methods: List[AAAAuthMethod] - """List of AAA authorization methods. Methods should be in the right order""" - types: Set[Literal["commands", "exec"]] - """List of authorization types to verify""" + methods: list[AAAAuthMethod] + """List of AAA authorization methods. Methods should be in the right order.""" + types: set[Literal["commands", "exec"]] + """List of authorization types to verify.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyAuthzMethods.""" command_output = self.instance_commands[0].json_output - not_matching = [] + not_matching: list[str] = [] for k, v in command_output.items(): authz_type = k.replace("AuthzMethods", "") if authz_type not in self.inputs.types: # We do not need to verify this accounting type continue - for methods in v.values(): - if methods["methods"] != self.inputs.methods: - not_matching.append(authz_type) + not_matching.extend(authz_type for methods in v.values() if methods["methods"] != self.inputs.methods) + if not not_matching: self.result.is_success() else: @@ -205,27 +277,46 @@ class VerifyAuthzMethods(AntaTest): class VerifyAcctDefaultMethods(AntaTest): - """ - Verifies the AAA accounting default method lists for different accounting types (system, exec, commands, dot1x). - - Expected Results: - * success: The test will pass if the provided AAA accounting default method list is matching in the configured accounting types. - * failure: The test will fail if the provided AAA accounting default method list is NOT matching in the configured accounting types. + """Verifies the AAA accounting default method lists for different accounting types (system, exec, commands, dot1x). + + Expected Results + ---------------- + * Success: The test will pass if the provided AAA accounting default method list is matching in the configured accounting types. + * Failure: The test will fail if the provided AAA accounting default method list is NOT matching in the configured accounting types. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyAcctDefaultMethods: + methods: + - local + - none + - logging + types: + - system + - exec + - commands + - dot1x + ``` """ name = "VerifyAcctDefaultMethods" description = "Verifies the AAA accounting default method lists for different accounting types (system, exec, commands, dot1x)." - categories = ["aaa"] - commands = [AntaCommand(command="show aaa methods accounting")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods accounting", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifyAcctDefaultMethods test.""" - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring - methods: List[AAAAuthMethod] - """List of AAA accounting methods. Methods should be in the right order""" - types: Set[Literal["commands", "exec", "system", "dot1x"]] - """List of accounting types to verify""" + methods: list[AAAAuthMethod] + """List of AAA accounting methods. Methods should be in the right order.""" + types: set[Literal["commands", "exec", "system", "dot1x"]] + """List of accounting types to verify.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyAcctDefaultMethods.""" command_output = self.instance_commands[0].json_output not_matching = [] not_configured = [] @@ -249,27 +340,46 @@ class VerifyAcctDefaultMethods(AntaTest): class VerifyAcctConsoleMethods(AntaTest): - """ - Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x). - - Expected Results: - * success: The test will pass if the provided AAA accounting console method list is matching in the configured accounting types. - * failure: The test will fail if the provided AAA accounting console method list is NOT matching in the configured accounting types. + """Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x). + + Expected Results + ---------------- + * Success: The test will pass if the provided AAA accounting console method list is matching in the configured accounting types. + * Failure: The test will fail if the provided AAA accounting console method list is NOT matching in the configured accounting types. + + Examples + -------- + ```yaml + anta.tests.aaa: + - VerifyAcctConsoleMethods: + methods: + - local + - none + - logging + types: + - system + - exec + - commands + - dot1x + ``` """ name = "VerifyAcctConsoleMethods" description = "Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x)." - categories = ["aaa"] - commands = [AntaCommand(command="show aaa methods accounting")] + categories: ClassVar[list[str]] = ["aaa"] + commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods accounting", revision=1)] + + class Input(AntaTest.Input): + """Input model for the VerifyAcctConsoleMethods test.""" - class Input(AntaTest.Input): # pylint: disable=missing-class-docstring - methods: List[AAAAuthMethod] - """List of AAA accounting console methods. Methods should be in the right order""" - types: Set[Literal["commands", "exec", "system", "dot1x"]] - """List of accounting console types to verify""" + methods: list[AAAAuthMethod] + """List of AAA accounting console methods. Methods should be in the right order.""" + types: set[Literal["commands", "exec", "system", "dot1x"]] + """List of accounting console types to verify.""" @AntaTest.anta_test def test(self) -> None: + """Main test function for VerifyAcctConsoleMethods.""" command_output = self.instance_commands[0].json_output not_matching = [] not_configured = [] |