Skip to content

Generic

ANTA catalog for routing-generic tests

Generic routing test functions

VerifyBFD

Bases: AntaTest

Verifies there is no BFD peer in down state (all VRF, IPv4 neighbors).

Source code in anta/tests/routing/generic.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
class VerifyBFD(AntaTest):
    """
    Verifies there is no BFD peer in down state (all VRF, IPv4 neighbors).
    """

    name = "VerifyBFD"
    description = "Verifies there is no BFD peer in down state (all VRF, IPv4 neighbors)."
    categories = ["routing", "generic"]
    # revision 1 as later revision introduce additional nesting for type
    commands = [AntaCommand(command="show bfd peers", revision=1)]

    @AntaTest.anta_test
    def test(self) -> None:
        """Run VerifyBFD validation"""

        command_output = self.instance_commands[0].json_output

        self.result.is_success()

        for _, vrf_data in command_output["vrfs"].items():
            for _, neighbor_data in vrf_data["ipv4Neighbors"].items():
                for peer, peer_data in neighbor_data["peerStats"].items():
                    if (peer_status := peer_data["status"]) != "up":
                        failure_message = f"bfd state for peer '{peer}' is {peer_status} (expected up)."
                        if (peer_l3intf := peer_data.get("l3intf")) is not None and peer_l3intf != "":
                            failure_message += f" Interface: {peer_l3intf}."
                        self.result.is_failure(failure_message)

test

test() -> None

Run VerifyBFD validation

Source code in anta/tests/routing/generic.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
@AntaTest.anta_test
def test(self) -> None:
    """Run VerifyBFD validation"""

    command_output = self.instance_commands[0].json_output

    self.result.is_success()

    for _, vrf_data in command_output["vrfs"].items():
        for _, neighbor_data in vrf_data["ipv4Neighbors"].items():
            for peer, peer_data in neighbor_data["peerStats"].items():
                if (peer_status := peer_data["status"]) != "up":
                    failure_message = f"bfd state for peer '{peer}' is {peer_status} (expected up)."
                    if (peer_l3intf := peer_data.get("l3intf")) is not None and peer_l3intf != "":
                        failure_message += f" Interface: {peer_l3intf}."
                    self.result.is_failure(failure_message)

VerifyRoutingProtocolModel

Bases: AntaTest

Verifies the configured routing protocol model is the one we expect. And if there is no mismatch between the configured and operating routing protocol model.

model(str): Expected routing protocol model (multi-agent or ribd). Default is multi-agent
Source code in anta/tests/routing/generic.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class VerifyRoutingProtocolModel(AntaTest):
    """
    Verifies the configured routing protocol model is the one we expect.
    And if there is no mismatch between the configured and operating routing protocol model.

        model(str): Expected routing protocol model (multi-agent or ribd). Default is multi-agent
    """

    name = "VerifyRoutingProtocolModel"
    description = (
        "Verifies the configured routing protocol model is the expected one and if there is no mismatch between the configured and operating routing protocol model."
    )
    categories = ["routing", "generic"]
    # "revision": 3
    commands = [AntaCommand(command="show ip route summary")]

    @AntaTest.anta_test
    def test(self, model: Optional[str] = "multi-agent") -> None:
        """Run VerifyRoutingProtocolModel validation"""

        if not model:
            self.result.is_skipped("VerifyRoutingProtocolModel was not run as no model was given")
            return
        command_output = self.instance_commands[0].json_output

        configured_model = command_output["protoModelStatus"]["configuredProtoModel"]
        operating_model = command_output["protoModelStatus"]["operatingProtoModel"]
        if configured_model == operating_model == model:
            self.result.is_success()
        else:
            self.result.is_failure(f"routing model is misconfigured: configured: {configured_model} - operating: {operating_model} - expected: {model}")

test

test(model: Optional[str] = 'multi-agent') -> None

Run VerifyRoutingProtocolModel validation

Source code in anta/tests/routing/generic.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@AntaTest.anta_test
def test(self, model: Optional[str] = "multi-agent") -> None:
    """Run VerifyRoutingProtocolModel validation"""

    if not model:
        self.result.is_skipped("VerifyRoutingProtocolModel was not run as no model was given")
        return
    command_output = self.instance_commands[0].json_output

    configured_model = command_output["protoModelStatus"]["configuredProtoModel"]
    operating_model = command_output["protoModelStatus"]["operatingProtoModel"]
    if configured_model == operating_model == model:
        self.result.is_success()
    else:
        self.result.is_failure(f"routing model is misconfigured: configured: {configured_model} - operating: {operating_model} - expected: {model}")

VerifyRoutingTableSize

Bases: AntaTest

Verifies the size of the IP routing table (default VRF). Should be between the two provided thresholds.

Parameters:

Name Type Description Default
minimum(int)

Expected minimum routing table (default VRF) size.

required
maximum(int)

Expected maximum routing table (default VRF) size.

required
Source code in anta/tests/routing/generic.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class VerifyRoutingTableSize(AntaTest):
    """
    Verifies the size of the IP routing table (default VRF).
    Should be between the two provided thresholds.

    Args:
        minimum(int): Expected minimum routing table (default VRF) size.
        maximum(int): Expected maximum routing table (default VRF) size.
    """

    name = "VerifyRoutingTableSize"
    description = "Verifies the size of the IP routing table (default VRF). Should be between the two provided thresholds."
    categories = ["routing", "generic"]
    # "revision": 3
    commands = [AntaCommand(command="show ip route summary")]

    @AntaTest.anta_test
    def test(self, minimum: Optional[int] = None, maximum: Optional[int] = None) -> None:
        """Run VerifyRoutingTableSize validation"""

        if not minimum or not maximum:
            self.result.is_skipped(f"VerifyRoutingTableSize was not run as either minimum {minimum} or maximum {maximum} was not provided")
            return
        if not isinstance(minimum, int) or not isinstance(maximum, int):
            self.result.is_error(f"VerifyRoutingTableSize was not run as either minimum {minimum} or maximum {maximum} is not a valid value (integer)")
            return
        if maximum < minimum:
            self.result.is_error(f"VerifyRoutingTableSize was not run as minimum {minimum} is greate than maximum {maximum}.")
            return

        command_output = self.instance_commands[0].json_output
        total_routes = int(command_output["vrfs"]["default"]["totalRoutes"])
        if minimum <= total_routes <= maximum:
            self.result.is_success()
        else:
            self.result.is_failure(f"routing-table has {total_routes} routes and not between min ({minimum}) and maximum ({maximum})")

test

test(minimum: Optional[int] = None, maximum: Optional[int] = None) -> None

Run VerifyRoutingTableSize validation

Source code in anta/tests/routing/generic.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@AntaTest.anta_test
def test(self, minimum: Optional[int] = None, maximum: Optional[int] = None) -> None:
    """Run VerifyRoutingTableSize validation"""

    if not minimum or not maximum:
        self.result.is_skipped(f"VerifyRoutingTableSize was not run as either minimum {minimum} or maximum {maximum} was not provided")
        return
    if not isinstance(minimum, int) or not isinstance(maximum, int):
        self.result.is_error(f"VerifyRoutingTableSize was not run as either minimum {minimum} or maximum {maximum} is not a valid value (integer)")
        return
    if maximum < minimum:
        self.result.is_error(f"VerifyRoutingTableSize was not run as minimum {minimum} is greate than maximum {maximum}.")
        return

    command_output = self.instance_commands[0].json_output
    total_routes = int(command_output["vrfs"]["default"]["totalRoutes"])
    if minimum <= total_routes <= maximum:
        self.result.is_success()
    else:
        self.result.is_failure(f"routing-table has {total_routes} routes and not between min ({minimum}) and maximum ({maximum})")

Last update: July 19, 2023