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
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
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:
        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.

Source code in anta/tests/routing/generic.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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.
    """

    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"]
    commands = [AntaCommand(command="show ip route summary", revision=3)]

    class Input(AntaTest.Input):  # pylint: disable=missing-class-docstring
        model: Literal["multi-agent", "ribd"] = "multi-agent"
        """Expected routing protocol model"""

    @AntaTest.anta_test
    def test(self) -> None:
        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 == self.inputs.model:
            self.result.is_success()
        else:
            self.result.is_failure(f"routing model is misconfigured: configured: {configured_model} - operating: {operating_model} - expected: {self.inputs.model}")

Input

Bases: Input

Source code in anta/tests/routing/generic.py
35
36
37
class Input(AntaTest.Input):  # pylint: disable=missing-class-docstring
    model: Literal["multi-agent", "ribd"] = "multi-agent"
    """Expected routing protocol model"""

model class-attribute instance-attribute

model: Literal['multi-agent', 'ribd'] = 'multi-agent'

Expected routing protocol model

VerifyRoutingTableEntry

Bases: AntaTest

This test verifies that the provided routes are present in the routing table of a specified VRF.

Expected Results
  • success: The test will pass if the provided routes are present in the routing table.
  • failure: The test will fail if one or many provided routes are missing from the routing table.
Source code in anta/tests/routing/generic.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
class VerifyRoutingTableEntry(AntaTest):
    """
    This test verifies that the provided routes are present in the routing table of a specified VRF.

    Expected Results:
        * success: The test will pass if the provided routes are present in the routing table.
        * failure: The test will fail if one or many provided routes are missing from the routing table.
    """

    name = "VerifyRoutingTableEntry"
    description = "Verifies that the provided routes are present in the routing table of a specified VRF."
    categories = ["routing", "generic"]
    commands = [AntaTemplate(template="show ip route vrf {vrf} {route}")]

    class Input(AntaTest.Input):  # pylint: disable=missing-class-docstring
        vrf: str = "default"
        """VRF context"""
        routes: List[IPv4Address]
        """Routes to verify"""

    def render(self, template: AntaTemplate) -> list[AntaCommand]:
        return [template.render(vrf=self.inputs.vrf, route=route) for route in self.inputs.routes]

    @AntaTest.anta_test
    def test(self) -> None:
        missing_routes = []

        for command in self.instance_commands:
            if "vrf" in command.params and "route" in command.params:
                vrf, route = command.params["vrf"], command.params["route"]
                if len(routes := command.json_output["vrfs"][vrf]["routes"]) == 0 or route != ip_interface(list(routes)[0]).ip:
                    missing_routes.append(str(route))

        if not missing_routes:
            self.result.is_success()
        else:
            self.result.is_failure(f"The following route(s) are missing from the routing table of VRF {self.inputs.vrf}: {missing_routes}")

Input

Bases: Input

Source code in anta/tests/routing/generic.py
123
124
125
126
127
class Input(AntaTest.Input):  # pylint: disable=missing-class-docstring
    vrf: str = "default"
    """VRF context"""
    routes: List[IPv4Address]
    """Routes to verify"""

routes instance-attribute

routes: List[IPv4Address]

Routes to verify

vrf class-attribute instance-attribute

vrf: str = 'default'

VRF context

VerifyRoutingTableSize

Bases: AntaTest

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

Source code in anta/tests/routing/generic.py
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
79
80
81
class VerifyRoutingTableSize(AntaTest):
    """
    Verifies the size of the IP routing table (default VRF).
    Should be between the two provided thresholds.
    """

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

    class Input(AntaTest.Input):  # pylint: disable=missing-class-docstring
        minimum: int
        """Expected minimum routing table (default VRF) size"""
        maximum: int
        """Expected maximum routing table (default VRF) size"""

        @model_validator(mode="after")  # type: ignore
        def check_min_max(self) -> AntaTest.Input:
            """Validate that maximum is greater than minimum"""
            if self.minimum > self.maximum:
                raise ValueError(f"Minimum {self.minimum} is greater than maximum {self.maximum}")
            return self

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

Input

Bases: Input

Source code in anta/tests/routing/generic.py
61
62
63
64
65
66
67
68
69
70
71
72
class Input(AntaTest.Input):  # pylint: disable=missing-class-docstring
    minimum: int
    """Expected minimum routing table (default VRF) size"""
    maximum: int
    """Expected maximum routing table (default VRF) size"""

    @model_validator(mode="after")  # type: ignore
    def check_min_max(self) -> AntaTest.Input:
        """Validate that maximum is greater than minimum"""
        if self.minimum > self.maximum:
            raise ValueError(f"Minimum {self.minimum} is greater than maximum {self.maximum}")
        return self

maximum instance-attribute

maximum: int

Expected maximum routing table (default VRF) size

minimum instance-attribute

minimum: int

Expected minimum routing table (default VRF) size

check_min_max

check_min_max() -> AntaTest.Input

Validate that maximum is greater than minimum

Source code in anta/tests/routing/generic.py
67
68
69
70
71
72
@model_validator(mode="after")  # type: ignore
def check_min_max(self) -> AntaTest.Input:
    """Validate that maximum is greater than minimum"""
    if self.minimum > self.maximum:
        raise ValueError(f"Minimum {self.minimum} is greater than maximum {self.maximum}")
    return self

Last update: August 18, 2023