Skip to content

ANTA catalog for generic routing tests

Tests

VerifyIPv4RouteType

Verifies the route-type of the IPv4 prefixes.

This test performs the following checks for each IPv4 route: 1. Verifies that the specified VRF is configured. 2. Verifies that the specified IPv4 route is exists in the configuration. 3. Verifies that the the specified IPv4 route is of the expected type.

Expected Results
  • Success: If all of the following conditions are met:
    • All the specified VRFs are configured.
    • All the specified IPv4 routes are found.
    • All the specified IPv4 routes are of the expected type.
  • Failure: If any of the following occur:
    • A specified VRF is not configured.
    • A specified IPv4 route is not found.
    • Any specified IPv4 route is not of the expected type.
Examples
anta.tests.routing:
  generic:
    - VerifyIPv4RouteType:
        routes_entries:
          - prefix: 10.10.0.1/32
            vrf: default
            route_type: eBGP
          - prefix: 10.100.0.12/31
            vrf: default
            route_type: connected
          - prefix: 10.100.1.5/32
            vrf: default
            route_type: iBGP

Inputs

Name Type Description Default
Source code in anta/tests/routing/generic.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
class VerifyIPv4RouteType(AntaTest):
    """Verifies the route-type of the IPv4 prefixes.

    This test performs the following checks for each IPv4 route:
        1. Verifies that the specified VRF is configured.
        2. Verifies that the specified IPv4 route is exists in the configuration.
        3. Verifies that the the specified IPv4 route is of the expected type.

    Expected Results
    ----------------
    * Success: If all of the following conditions are met:
        - All the specified VRFs are configured.
        - All the specified IPv4 routes are found.
        - All the specified IPv4 routes are of the expected type.
    * Failure: If any of the following occur:
        - A specified VRF is not configured.
        - A specified IPv4 route is not found.
        - Any specified IPv4 route is not of the expected type.

    Examples
    --------
    ```yaml
    anta.tests.routing:
      generic:
        - VerifyIPv4RouteType:
            routes_entries:
              - prefix: 10.10.0.1/32
                vrf: default
                route_type: eBGP
              - prefix: 10.100.0.12/31
                vrf: default
                route_type: connected
              - prefix: 10.100.1.5/32
                vrf: default
                route_type: iBGP
    ```
    """

    categories: ClassVar[list[str]] = ["routing"]
    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip route vrf all", revision=4)]

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

        routes_entries: list[IPv4Routes]

    @AntaTest.anta_test
    def test(self) -> None:
        """Main test function for VerifyIPv4RouteType."""
        self.result.is_success()
        output = self.instance_commands[0].json_output

        # Iterating over the all routes entries mentioned in the inputs.
        for entry in self.inputs.routes_entries:
            prefix = str(entry.prefix)
            vrf = entry.vrf
            expected_route_type = entry.route_type

            # Verifying that on device, expected VRF is configured.
            if (routes_details := get_value(output, f"vrfs.{vrf}.routes")) is None:
                self.result.is_failure(f"{entry} - VRF not configured")
                continue

            # Verifying that the expected IPv4 route is present or not on the device
            if (route_data := routes_details.get(prefix)) is None:
                self.result.is_failure(f"{entry} - Route not found")
                continue

            # Verifying that the specified IPv4 routes are of the expected type.
            if expected_route_type != (actual_route_type := route_data.get("routeType")):
                self.result.is_failure(f"{entry} - Incorrect route type - Expected: {expected_route_type} Actual: {actual_route_type}")

VerifyRoutingProtocolModel

Verifies the configured routing protocol model.

Expected Results
  • Success: The test will pass if the configured routing protocol model is the one we expect.
  • Failure: The test will fail if the configured routing protocol model is not the one we expect.
Examples
anta.tests.routing:
  generic:
    - VerifyRoutingProtocolModel:
        model: multi-agent

Inputs

Name Type Description Default
model Literal['multi-agent', 'ribd']
Expected routing protocol model. Defaults to `multi-agent`.
'multi-agent'
Source code in anta/tests/routing/generic.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class VerifyRoutingProtocolModel(AntaTest):
    """Verifies the configured routing protocol model.

    Expected Results
    ----------------
    * Success: The test will pass if the configured routing protocol model is the one we expect.
    * Failure: The test will fail if the configured routing protocol model is not the one we expect.

    Examples
    --------
    ```yaml
    anta.tests.routing:
      generic:
        - VerifyRoutingProtocolModel:
            model: multi-agent
    ```
    """

    categories: ClassVar[list[str]] = ["routing"]
    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip route summary", revision=3)]

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

        model: Literal["multi-agent", "ribd"] = "multi-agent"
        """Expected routing protocol model. Defaults to `multi-agent`."""

    @AntaTest.anta_test
    def test(self) -> None:
        """Main test function for VerifyRoutingProtocolModel."""
        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}")

VerifyRoutingTableEntry

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.
Examples
anta.tests.routing:
  generic:
    - VerifyRoutingTableEntry:
        vrf: default
        routes:
          - 10.1.0.1
          - 10.1.0.2

Inputs

Name Type Description Default
vrf str
VRF context. Defaults to `default` VRF.
'default'
routes list[IPv4Address]
List of routes to verify.
-
collect Literal['one', 'all']
Route collect behavior: one=one route per command, all=all routes in vrf per command. Defaults to `one`
'one'

ip_interface_ip cached staticmethod

ip_interface_ip(route: str) -> IPv4Address

Return the IP address of the provided ip route with mask.

Source code in anta/tests/routing/generic.py
165
166
167
168
169
@staticmethod
@cache
def ip_interface_ip(route: str) -> IPv4Address:
    """Return the IP address of the provided ip route with mask."""
    return IPv4Interface(route).ip
Source code in anta/tests/routing/generic.py
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
class VerifyRoutingTableEntry(AntaTest):
    """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.

    Examples
    --------
    ```yaml
    anta.tests.routing:
      generic:
        - VerifyRoutingTableEntry:
            vrf: default
            routes:
              - 10.1.0.1
              - 10.1.0.2
    ```
    """

    categories: ClassVar[list[str]] = ["routing"]
    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
        AntaTemplate(template="show ip route vrf {vrf} {route}", revision=4),
        AntaTemplate(template="show ip route vrf {vrf}", revision=4),
    ]

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

        vrf: str = "default"
        """VRF context. Defaults to `default` VRF."""
        routes: list[IPv4Address]
        """List of routes to verify."""
        collect: Literal["one", "all"] = "one"
        """Route collect behavior: one=one route per command, all=all routes in vrf per command. Defaults to `one`"""

    def render(self, template: AntaTemplate) -> list[AntaCommand]:
        """Render the template for the input vrf."""
        if template == VerifyRoutingTableEntry.commands[0] and self.inputs.collect == "one":
            return [template.render(vrf=self.inputs.vrf, route=route) for route in self.inputs.routes]

        if template == VerifyRoutingTableEntry.commands[1] and self.inputs.collect == "all":
            return [template.render(vrf=self.inputs.vrf)]

        return []

    @staticmethod
    @cache
    def ip_interface_ip(route: str) -> IPv4Address:
        """Return the IP address of the provided ip route with mask."""
        return IPv4Interface(route).ip

    @AntaTest.anta_test
    def test(self) -> None:
        """Main test function for VerifyRoutingTableEntry."""
        commands_output_route_ips = set()

        for command in self.instance_commands:
            command_output_vrf = command.json_output["vrfs"][self.inputs.vrf]
            commands_output_route_ips |= {self.ip_interface_ip(route) for route in command_output_vrf["routes"]}

        missing_routes = [str(route) for route in self.inputs.routes if route not in commands_output_route_ips]

        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}")

VerifyRoutingTableSize

Verifies the size of the IP routing table of the default VRF.

Expected Results
  • Success: The test will pass if the routing table size is between the provided minimum and maximum values.
  • Failure: The test will fail if the routing table size is not between the provided minimum and maximum values.
Examples
anta.tests.routing:
  generic:
    - VerifyRoutingTableSize:
        minimum: 2
        maximum: 20

Inputs

Name Type Description Default
minimum PositiveInteger
Expected minimum routing table size.
-
maximum PositiveInteger
Expected maximum routing table size.
-
Source code in anta/tests/routing/generic.py
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 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
108
109
110
111
112
113
114
115
class VerifyRoutingTableSize(AntaTest):
    """Verifies the size of the IP routing table of the default VRF.

    Expected Results
    ----------------
    * Success: The test will pass if the routing table size is between the provided minimum and maximum values.
    * Failure: The test will fail if the routing table size is not between the provided minimum and maximum values.

    Examples
    --------
    ```yaml
    anta.tests.routing:
      generic:
        - VerifyRoutingTableSize:
            minimum: 2
            maximum: 20
    ```
    """

    categories: ClassVar[list[str]] = ["routing"]
    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip route summary", revision=3)]

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

        minimum: PositiveInteger
        """Expected minimum routing table size."""
        maximum: PositiveInteger
        """Expected maximum routing table size."""

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

    @AntaTest.anta_test
    def test(self) -> None:
        """Main test function for VerifyRoutingTableSize."""
        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 models

IPv4Routes

Model for a list of IPV4 route entries.

Name Type Description Default
prefix IPv4Network
The IPV4 network to validate the route type.
-
vrf str
VRF context. Defaults to `default` VRF.
'default'
route_type IPv4RouteType
List of IPV4 Route type to validate the valid rout type.
-
Source code in anta/input_models/routing/generic.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class IPv4Routes(BaseModel):
    """Model for a list of IPV4 route entries."""

    model_config = ConfigDict(extra="forbid")
    prefix: IPv4Network
    """The IPV4 network to validate the route type."""
    vrf: str = "default"
    """VRF context. Defaults to `default` VRF."""
    route_type: IPv4RouteType
    """List of IPV4 Route type to validate the valid rout type."""

    def __str__(self) -> str:
        """Return a human-readable string representation of the IPv4RouteType for reporting."""
        return f"Prefix: {self.prefix} VRF: {self.vrf}"