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 strict check to VerifyBGPPeerMPCaps test to verify only mentioned multiprotocol capabilities of a BGP peer should be listed #783

Merged
merged 8 commits into from
Sep 4, 2024
20 changes: 17 additions & 3 deletions anta/tests/routing/bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,8 @@ def test(self) -> None:
class VerifyBGPPeerMPCaps(AntaTest):
"""Verifies the multiprotocol capabilities of a BGP peer in a specified VRF.

Supports `strict: True` to verify that only the specified capabilities are configured, requiring an exact match.

Expected Results
----------------
* Success: The test will pass if the BGP peer's multiprotocol capabilities are advertised, received, and enabled in the specified VRF.
Expand All @@ -699,6 +701,7 @@ class VerifyBGPPeerMPCaps(AntaTest):
bgp_peers:
- peer_address: 172.30.11.1
vrf: default
strict: False
capabilities:
- ipv4Unicast
```
Expand All @@ -722,6 +725,8 @@ class BgpPeer(BaseModel):
"""IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
strict: bool = False
"""If True, requires exact matching of provided capabilities. Defaults to False."""
capabilities: list[MultiProtocolCaps]
"""List of multiprotocol capabilities to be verified."""

Expand All @@ -730,14 +735,14 @@ def test(self) -> None:
"""Main test function for VerifyBGPPeerMPCaps."""
failures: dict[str, Any] = {"bgp_peers": {}}

# Iterate over each bgp peer
# Iterate over each bgp peer.
for bgp_peer in self.inputs.bgp_peers:
peer = str(bgp_peer.peer_address)
vrf = bgp_peer.vrf
capabilities = bgp_peer.capabilities
failure: dict[str, dict[str, dict[str, Any]]] = {"bgp_peers": {peer: {vrf: {}}}}

# Check if BGP output exists
# Check if BGP output exists.
if (
not (bgp_output := get_value(self.instance_commands[0].json_output, f"vrfs.{vrf}.peerList"))
or (bgp_output := get_item(bgp_output, "peerAddress", peer)) is None
Expand All @@ -746,8 +751,17 @@ def test(self) -> None:
failures = deep_update(failures, failure)
continue

# Check each capability
# Fetching the capabilities output.
bgp_output = get_value(bgp_output, "neighborCapabilities.multiprotocolCaps")

if bgp_peer.strict and sorted(capabilities) != sorted(bgp_output):
failure["bgp_peers"][peer][vrf] = {
"status": f"Expected only `{', '.join(capabilities)}` capabilities should be listed but found `{', '.join(bgp_output)}` instead."
}
failures = deep_update(failures, failure)
carl-baillargeon marked this conversation as resolved.
Show resolved Hide resolved
continue

# Check each capability
for capability in capabilities:
capability_output = bgp_output.get(capability)

Expand Down
1 change: 1 addition & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ anta.tests.routing:
bgp_peers:
- peer_address: 172.30.11.1
vrf: default
strict: False
capabilities:
- ipv4Unicast
- VerifyBGPPeerASNCap:
Expand Down
146 changes: 146 additions & 0 deletions tests/units/anta_tests/routing/test_bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,152 @@
],
},
},
{
"name": "success-strict",
"test": VerifyBGPPeerMPCaps,
"eos_data": [
{
"vrfs": {
"default": {
"peerList": [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
"multiprotocolCaps": {
"ipv4Unicast": {
"advertised": True,
"received": True,
"enabled": True,
},
"ipv4MplsLabels": {
"advertised": True,
"received": True,
"enabled": True,
},
}
},
}
]
},
"MGMT": {
"peerList": [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
"multiprotocolCaps": {
"ipv4Unicast": {
"advertised": True,
"received": True,
"enabled": True,
},
"ipv4MplsVpn": {
"advertised": True,
"received": True,
"enabled": True,
},
}
},
}
]
},
}
}
],
"inputs": {
"bgp_peers": [
{
"peer_address": "172.30.11.1",
"vrf": "default",
"strict": True,
"capabilities": ["Ipv4 Unicast", "ipv4 Mpls labels"],
},
{
"peer_address": "172.30.11.10",
"vrf": "MGMT",
"strict": True,
"capabilities": ["ipv4 Unicast", "ipv4 MplsVpn"],
},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-srict",
"test": VerifyBGPPeerMPCaps,
"eos_data": [
{
"vrfs": {
"default": {
"peerList": [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
"multiprotocolCaps": {
"ipv4Unicast": {
"advertised": True,
"received": True,
"enabled": True,
},
"ipv4MplsLabels": {
"advertised": True,
"received": True,
"enabled": True,
},
}
},
}
]
},
"MGMT": {
"peerList": [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
"multiprotocolCaps": {
"ipv4Unicast": {
"advertised": True,
"received": True,
"enabled": True,
},
"ipv4MplsVpn": {
"advertised": False,
"received": True,
"enabled": True,
},
}
},
}
]
},
}
}
],
"inputs": {
"bgp_peers": [
{
"peer_address": "172.30.11.1",
"vrf": "default",
"strict": True,
"capabilities": ["Ipv4 Unicast"],
},
{
"peer_address": "172.30.11.10",
"vrf": "MGMT",
"strict": True,
"capabilities": ["ipv4MplsVpn", "L2vpnEVPN"],
},
]
},
"expected": {
"result": "failure",
"messages": [
"Following BGP peer multiprotocol capabilities are not found or not ok:\n{'bgp_peers': {'172.30.11.1': "
"{'default': {'status': 'Expected only `ipv4Unicast` capabilities should be listed but found `ipv4Unicast, ipv4MplsLabels` instead.'}},"
" '172.30.11.10': {'MGMT': {'status': 'Expected only `ipv4MplsVpn, l2VpnEvpn` capabilities should be listed but found `ipv4Unicast, "
"ipv4MplsVpn` instead.'}}}}"
],
},
},
{
"name": "success",
"test": VerifyBGPPeerASNCap,
Expand Down
Loading