Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(anta): Added test case to verify registered protocol for IPv4 BFD peers #773

Merged
merged 6 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions anta/custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,4 @@ def validate_regex(value: str) -> str:
"prefixRtMembershipDroppedMaxRouteLimitViolated",
]
BgpUpdateError = Literal["inUpdErrWithdraw", "inUpdErrIgnore", "inUpdErrDisableAfiSafi", "disabledAfiSafi", "lastUpdErrTime"]
BfdProtocol = Literal["bgp", "isis", "lag", "ospf", "ospfv3", "pim", "route-input", "static-bfd", "static-route", "vrrp", "vxlan"]
82 changes: 79 additions & 3 deletions anta/tests/bfd.py
carl-baillargeon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from pydantic import BaseModel, Field

from anta.custom_types import BfdInterval, BfdMultiplier
from anta.custom_types import BfdInterval, BfdMultiplier, BfdProtocol
from anta.models import AntaCommand, AntaTest
from anta.tools import get_value

Expand Down Expand Up @@ -45,7 +45,7 @@ class VerifyBFDSpecificPeers(AntaTest):
name = "VerifyBFDSpecificPeers"
description = "Verifies the IPv4 BFD peer's sessions and remote disc in the specified VRF."
categories: ClassVar[list[str]] = ["bfd"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers", revision=4)]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers", revision=1)]
carl-baillargeon marked this conversation as resolved.
Show resolved Hide resolved

class Input(AntaTest.Input):
"""Input model for the VerifyBFDSpecificPeers test."""
Expand Down Expand Up @@ -126,7 +126,7 @@ class VerifyBFDPeersIntervals(AntaTest):
name = "VerifyBFDPeersIntervals"
description = "Verifies the timers of the IPv4 BFD peers in the specified VRF."
categories: ClassVar[list[str]] = ["bfd"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers detail", revision=4)]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers detail", revision=1)]
carl-baillargeon marked this conversation as resolved.
Show resolved Hide resolved

class Input(AntaTest.Input):
"""Input model for the VerifyBFDPeersIntervals test."""
Expand Down Expand Up @@ -285,3 +285,79 @@ def test(self) -> None:
if up_failures:
up_failures_str = "\n".join(up_failures)
self.result.is_failure(f"\nFollowing BFD peers were down:\n{up_failures_str}")


class VerifyBFDPeersRegProtocols(AntaTest):
"""Verifies that IPv4 BFD peer(s) have the specified protocol(s) registered.

Expected Results
----------------
* Success: The test will pass if IPv4 BFD peers are registered with the specified protocol(s).
* Failure: The test will fail if IPv4 BFD peers are not found or the specified protocol(s) are not registered for the BFD peer(s).

Examples
--------
```yaml
anta.tests.bfd:
- VerifyBFDPeersRegProtocols:
bfd_peers:
- peer_address: 192.0.255.7
vrf: default
protocols:
- bgp
```
"""

name = "VerifyBFDPeersRegProtocols"
description = "Verifies that IPv4 BFD peer(s) have the specified protocol(s) registered."
categories: ClassVar[list[str]] = ["bfd"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers detail", revision=1)]

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

bfd_peers: list[BFDPeer]
"""List of IPv4 BFD peers."""

class BFDPeer(BaseModel):
"""Model for an IPv4 BFD peer."""

peer_address: IPv4Address
"""IPv4 address of a BFD peer."""
vrf: str = "default"
"""Optional VRF for BFD peer. If not provided, it defaults to `default`."""
protocols: list[BfdProtocol]
"""List of protocols to be verified."""

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyBFDPeersRegProtocols."""
# Initialize failure messages
failures: dict[Any, Any] = {}

# Iterating over BFD peers, extract the parameters and command output
for bfd_peer in self.inputs.bfd_peers:
peer = str(bfd_peer.peer_address)
vrf = bfd_peer.vrf
protocols = bfd_peer.protocols
bfd_output = get_value(
self.instance_commands[0].json_output,
f"vrfs..{vrf}..ipv4Neighbors..{peer}..peerStats..",
separator="..",
)

# Check if BFD peer configured
if not bfd_output:
failures[peer] = {vrf: "Not Configured"}
continue

# Check registered protocols
difference = set(protocols) - set(get_value(bfd_output, "peerStatsDetail.apps"))

if difference:
failures[peer] = {vrf: sorted(difference)}

if not failures:
self.result.is_success()
else:
self.result.is_failure(f"The following BFD peers are not configured or have non-registered protocol(s):\n{failures}")
7 changes: 7 additions & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ anta.tests.bfd:
multiplier: 3
- VerifyBFDPeersHealth:
down_threshold: 2
- VerifyBFDPeersRegProtocols:
bfd_peers:
- peer_address: 192.0.255.8
vrf: default
protocols:
- bgp
- isis

anta.tests.configuration:
- VerifyZeroTouch:
Expand Down
131 changes: 130 additions & 1 deletion tests/units/anta_tests/test_bfd.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# pylint: disable=C0413
# because of the patch above
from anta.tests.bfd import VerifyBFDPeersHealth, VerifyBFDPeersIntervals, VerifyBFDSpecificPeers
from anta.tests.bfd import VerifyBFDPeersHealth, VerifyBFDPeersIntervals, VerifyBFDPeersRegProtocols, VerifyBFDSpecificPeers
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611

DATA: list[dict[str, Any]] = [
Expand Down Expand Up @@ -519,4 +519,133 @@
],
},
},
{
"name": "success",
"test": VerifyBFDPeersRegProtocols,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 108328132,
"peerStatsDetail": {
"role": "active",
"apps": ["ospf"],
},
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.70": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 108328132,
"peerStatsDetail": {
"role": "active",
"apps": ["bgp"],
},
}
}
}
}
},
}
}
],
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "default", "protocols": ["ospf"]},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "protocols": ["bgp"]},
]
},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyBFDPeersRegProtocols,
"eos_data": [
{
"vrfs": {
"default": {
"ipv4Neighbors": {
"192.0.255.7": {
"peerStats": {
"": {
"status": "up",
"peerStatsDetail": {
"role": "active",
"apps": ["ospf"],
},
}
}
}
}
},
"MGMT": {
"ipv4Neighbors": {
"192.0.255.70": {
"peerStats": {
"": {
"status": "up",
"remoteDisc": 0,
"peerStatsDetail": {
"role": "active",
"apps": ["bgp"],
},
}
}
}
}
},
}
}
],
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "default", "protocols": ["isis"]},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "protocols": ["isis"]},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BFD peers are not configured or have non-registered protocol(s):\n"
"{'192.0.255.7': {'default': ['isis']}, "
"'192.0.255.70': {'MGMT': ['isis']}}"
],
},
},
{
"name": "failure-not-found",
"test": VerifyBFDPeersRegProtocols,
"eos_data": [
{
"vrfs": {
"default": {},
"MGMT": {},
}
}
],
"inputs": {
"bfd_peers": [
{"peer_address": "192.0.255.7", "vrf": "default", "protocols": ["isis"]},
{"peer_address": "192.0.255.70", "vrf": "MGMT", "protocols": ["isis"]},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BFD peers are not configured or have non-registered protocol(s):\n"
"{'192.0.255.7': {'default': 'Not Configured'}, '192.0.255.70': {'MGMT': 'Not Configured'}}"
],
},
},
]
Loading