Skip to content

Commit

Permalink
feat(anta.tests): Add OSPF Max LSA Test (#602)
Browse files Browse the repository at this point in the history
* feat(anta.tests): Add OSPF Max LSA Test

---------

Co-authored-by: Matthieu Tâche <[email protected]>
  • Loading branch information
klorfevre and mtache authored Mar 25, 2024
1 parent 8028df0 commit 1ef4ab7
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 1 deletion.
66 changes: 66 additions & 0 deletions anta/tests/routing/ospf.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,31 @@ def _get_not_full_ospf_neighbors(ospf_neighbor_json: dict[str, Any]) -> list[dic
]


def _get_ospf_max_lsa_info(ospf_process_json: dict[str, Any]) -> list[dict[str, Any]]:
"""Return information about OSPF instances and their LSAs.
Args:
----
ospf_process_json (dict[str, Any]): OSPF process information in JSON format.
Returns
-------
list[dict[str, Any]]: A list of dictionaries containing OSPF LSAs information.
"""
return [
{
"vrf": vrf,
"instance": instance,
"maxLsa": instance_data.get("maxLsaInformation", {}).get("maxLsa"),
"maxLsaThreshold": instance_data.get("maxLsaInformation", {}).get("maxLsaThreshold"),
"numLsa": instance_data.get("lsaInformation", {}).get("numLsa"),
}
for vrf, vrf_data in ospf_process_json.get("vrfs", {}).items()
for instance, instance_data in vrf_data.get("instList", {}).items()
]


class VerifyOSPFNeighborState(AntaTest):
"""Verifies all OSPF neighbors are in FULL state.
Expand Down Expand Up @@ -139,3 +164,44 @@ def test(self) -> None:
not_full_neighbors = _get_not_full_ospf_neighbors(command_output)
if not_full_neighbors:
self.result.is_failure(f"Some neighbors are not correctly configured: {not_full_neighbors}.")


class VerifyOSPFMaxLSA(AntaTest):
"""Verifies LSAs present in the OSPF link state database did not cross the maximum LSA Threshold.
Expected Results
----------------
* Success: The test will pass if all OSPF instances did not cross the maximum LSA Threshold.
* Failure: The test will fail if some OSPF instances crossed the maximum LSA Threshold.
* Skipped: The test will be skipped if no OSPF instance is found.
Examples
--------
```yaml
anta.tests.routing:
ospf:
- VerifyOSPFMaxLSA:
```
"""

name = "VerifyOSPFMaxLSA"
description = "Verifies all OSPF instances did not cross the maximum LSA threshold."
categories: ClassVar[list[str]] = ["ospf"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip ospf")]

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyOSPFMaxLSA."""
command_output = self.instance_commands[0].json_output
ospf_instance_info = _get_ospf_max_lsa_info(command_output)
if not ospf_instance_info:
self.result.is_skipped("No OSPF instance found.")
return
all_instances_within_threshold = all(instance["numLsa"] <= instance["maxLsa"] * (instance["maxLsaThreshold"] / 100) for instance in ospf_instance_info)
if all_instances_within_threshold:
self.result.is_success()
else:
exceeded_instances = [
instance["instance"] for instance in ospf_instance_info if instance["numLsa"] > instance["maxLsa"] * (instance["maxLsaThreshold"] / 100)
]
self.result.is_failure(f"OSPF Instances {exceeded_instances} crossed the maximum LSA threshold.")
1 change: 1 addition & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -491,3 +491,4 @@ anta.tests.routing:
- VerifyOSPFNeighborState:
- VerifyOSPFNeighborCount:
number: 3
- VerifyOSPFMaxLSA:
116 changes: 115 additions & 1 deletion tests/units/anta_tests/routing/test_ospf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from typing import Any

from anta.tests.routing.ospf import VerifyOSPFNeighborCount, VerifyOSPFNeighborState
from anta.tests.routing.ospf import VerifyOSPFMaxLSA, VerifyOSPFNeighborCount, VerifyOSPFNeighborState
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611

DATA: list[dict[str, Any]] = [
Expand Down Expand Up @@ -294,4 +294,118 @@
"inputs": {"number": 3},
"expected": {"result": "skipped", "messages": ["no OSPF neighbor found"]},
},
{
"name": "success",
"test": VerifyOSPFMaxLSA,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"1": {
"instanceId": 1,
"maxLsaInformation": {
"maxLsa": 12000,
"maxLsaThreshold": 75,
},
"routerId": "1.1.1.1",
"lsaInformation": {
"lsaArrivalInterval": 1000,
"lsaStartInterval": 1000,
"lsaHoldInterval": 5000,
"lsaMaxWaitInterval": 5000,
"numLsa": 9,
},
},
},
},
"TEST": {
"instList": {
"10": {
"instanceId": 10,
"maxLsaInformation": {
"maxLsa": 1000,
"maxLsaThreshold": 75,
},
"routerId": "20.20.20.20",
"lsaInformation": {
"lsaArrivalInterval": 1000,
"lsaStartInterval": 1000,
"lsaHoldInterval": 5000,
"lsaMaxWaitInterval": 5000,
"numLsa": 5,
},
},
},
},
},
},
],
"inputs": None,
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyOSPFMaxLSA,
"eos_data": [
{
"vrfs": {
"default": {
"instList": {
"1": {
"instanceId": 1,
"maxLsaInformation": {
"maxLsa": 12000,
"maxLsaThreshold": 75,
},
"routerId": "1.1.1.1",
"lsaInformation": {
"lsaArrivalInterval": 1000,
"lsaStartInterval": 1000,
"lsaHoldInterval": 5000,
"lsaMaxWaitInterval": 5000,
"numLsa": 11500,
},
},
},
},
"TEST": {
"instList": {
"10": {
"instanceId": 10,
"maxLsaInformation": {
"maxLsa": 1000,
"maxLsaThreshold": 75,
},
"routerId": "20.20.20.20",
"lsaInformation": {
"lsaArrivalInterval": 1000,
"lsaStartInterval": 1000,
"lsaHoldInterval": 5000,
"lsaMaxWaitInterval": 5000,
"numLsa": 1500,
},
},
},
},
},
},
],
"inputs": None,
"expected": {
"result": "failure",
"messages": ["OSPF Instances ['1', '10'] crossed the maximum LSA threshold."],
},
},
{
"name": "skipped",
"test": VerifyOSPFMaxLSA,
"eos_data": [
{
"vrfs": {},
},
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["No OSPF instance found."]},
},
]

0 comments on commit 1ef4ab7

Please sign in to comment.