Skip to content

Commit

Permalink
feat(anta): Added test case to verify Inbound route map and Outbound …
Browse files Browse the repository at this point in the history
…route map in BGP neighbor details (#793)
  • Loading branch information
vitthalmagadum authored Sep 17, 2024
1 parent cff671e commit 900ebb7
Show file tree
Hide file tree
Showing 3 changed files with 305 additions and 0 deletions.
97 changes: 97 additions & 0 deletions anta/tests/routing/bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1437,3 +1437,100 @@ def test(self) -> None:
self.result.is_success()
else:
self.result.is_failure(f"The following BGP peers are not configured or have non-zero update error counters:\n{failures}")


class VerifyBgpRouteMaps(AntaTest):
"""Verifies BGP inbound and outbound route-maps of BGP IPv4 peer(s).
Expected Results
----------------
* Success: The test will pass if the correct route maps are applied in the correct direction (inbound or outbound) for IPv4 BGP peers in the specified VRF.
* Failure: The test will fail if BGP peers are not configured or any neighbor has an incorrect or missing route map in either the inbound or outbound direction.
Examples
--------
```yaml
anta.tests.routing:
bgp:
- VerifyBgpRouteMaps:
bgp_peers:
- peer_address: 172.30.11.1
vrf: default
inbound_route_map: RM-MLAG-PEER-IN
outbound_route_map: RM-MLAG-PEER-OUT
```
"""

name = "VerifyBgpRouteMaps"
description = "Verifies BGP inbound and outbound route-maps of BGP IPv4 peer(s)."
categories: ClassVar[list[str]] = ["bgp"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show bgp neighbors {peer} vrf {vrf}", revision=3)]

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

bgp_peers: list[BgpPeer]
"""List of BGP peers"""

class BgpPeer(BaseModel):
"""Model for a BGP peer."""

peer_address: IPv4Address
"""IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
inbound_route_map: str | None = None
"""Inbound route map applied, defaults to None."""
outbound_route_map: str | None = None
"""Outbound route map applied, defaults to None."""

@model_validator(mode="after")
def validate_inputs(self: BaseModel) -> BaseModel:
"""Validate the inputs provided to the BgpPeer class.
At least one of 'inbound' or 'outbound' route-map must be provided.
"""
if not (self.inbound_route_map or self.outbound_route_map):
msg = "At least one of 'inbound_route_map' or 'outbound_route_map' must be provided."
raise ValueError(msg)
return self

def render(self, template: AntaTemplate) -> list[AntaCommand]:
"""Render the template for each BGP peer in the input list."""
return [template.render(peer=str(bgp_peer.peer_address), vrf=bgp_peer.vrf) for bgp_peer in self.inputs.bgp_peers]

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

for command, input_entry in zip(self.instance_commands, self.inputs.bgp_peers):
peer = str(input_entry.peer_address)
vrf = input_entry.vrf
inbound_route_map = input_entry.inbound_route_map
outbound_route_map = input_entry.outbound_route_map
failure: dict[Any, Any] = {vrf: {}}

# Verify BGP peer.
if not (peer_list := get_value(command.json_output, f"vrfs.{vrf}.peerList")) or (peer_detail := get_item(peer_list, "peerAddress", peer)) is None:
failures[peer] = {vrf: "Not configured"}
continue

# Verify Inbound route-map
if inbound_route_map and (inbound_map := peer_detail.get("routeMapInbound", "Not Configured")) != inbound_route_map:
failure[vrf].update({"Inbound route-map": inbound_map})

# Verify Outbound route-map
if outbound_route_map and (outbound_map := peer_detail.get("routeMapOutbound", "Not Configured")) != outbound_route_map:
failure[vrf].update({"Outbound route-map": outbound_map})

if failure[vrf]:
failures[peer] = failure

# Check if any failures
if not failures:
self.result.is_success()
else:
self.result.is_failure(
f"The following BGP peers are not configured or has an incorrect or missing route map in either the inbound or outbound direction:\n{failures}"
)
6 changes: 6 additions & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,12 @@ anta.tests.routing:
update_errors:
- inUpdErrWithdraw
- inUpdErrIgnore
- VerifyBgpRouteMaps:
bgp_peers:
- peer_address: 10.100.4.1
vrf: default
inbound_route_map: RM-MLAG-PEER-IN
outbound_route_map: RM-MLAG-PEER-IN
ospf:
- VerifyOSPFNeighborState:
- VerifyOSPFNeighborCount:
Expand Down
202 changes: 202 additions & 0 deletions tests/units/anta_tests/routing/test_bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
VerifyBGPPeerRouteRefreshCap,
VerifyBGPPeersHealth,
VerifyBGPPeerUpdateErrors,
VerifyBgpRouteMaps,
VerifyBGPSpecificPeers,
VerifyBGPTimers,
VerifyEVPNType2Route,
Expand Down Expand Up @@ -4503,4 +4504,205 @@
],
},
},
{
"name": "success",
"test": VerifyBgpRouteMaps,
"eos_data": [
{
"vrfs": {
"default": {
"peerList": [
{
"peerAddress": "10.100.0.8",
"routeMapInbound": "RM-MLAG-PEER-IN",
"routeMapOutbound": "RM-MLAG-PEER-OUT",
}
]
},
},
},
{
"vrfs": {
"MGMT": {
"peerList": [
{
"peerAddress": "10.100.0.10",
"routeMapInbound": "RM-MLAG-PEER-IN",
"routeMapOutbound": "RM-MLAG-PEER-OUT",
}
]
},
},
},
],
"inputs": {
"bgp_peers": [
{"peer_address": "10.100.0.8", "vrf": "default", "inbound_route_map": "RM-MLAG-PEER-IN", "outbound_route_map": "RM-MLAG-PEER-OUT"},
{"peer_address": "10.100.0.10", "vrf": "MGMT", "inbound_route_map": "RM-MLAG-PEER-IN", "outbound_route_map": "RM-MLAG-PEER-OUT"},
]
},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-route-map",
"test": VerifyBgpRouteMaps,
"eos_data": [
{
"vrfs": {
"default": {
"peerList": [
{
"peerAddress": "10.100.0.8",
"routeMapInbound": "RM-MLAG-PEER",
"routeMapOutbound": "RM-MLAG-PEER",
}
]
},
},
},
{
"vrfs": {
"MGMT": {
"peerList": [
{
"peerAddress": "10.100.0.10",
"routeMapInbound": "RM-MLAG-PEER",
"routeMapOutbound": "RM-MLAG-PEER",
}
]
},
},
},
],
"inputs": {
"bgp_peers": [
{"peer_address": "10.100.0.8", "vrf": "default", "inbound_route_map": "RM-MLAG-PEER-IN", "outbound_route_map": "RM-MLAG-PEER-OUT"},
{"peer_address": "10.100.0.10", "vrf": "MGMT", "inbound_route_map": "RM-MLAG-PEER-IN", "outbound_route_map": "RM-MLAG-PEER-OUT"},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BGP peers are not configured or has an incorrect or missing route map in either the inbound or outbound direction:\n"
"{'10.100.0.8': {'default': {'Inbound route-map': 'RM-MLAG-PEER', 'Outbound route-map': 'RM-MLAG-PEER'}}, "
"'10.100.0.10': {'MGMT': {'Inbound route-map': 'RM-MLAG-PEER', 'Outbound route-map': 'RM-MLAG-PEER'}}}"
],
},
},
{
"name": "failure-incorrect-inbound-map",
"test": VerifyBgpRouteMaps,
"eos_data": [
{
"vrfs": {
"default": {
"peerList": [
{
"peerAddress": "10.100.0.8",
"routeMapInbound": "RM-MLAG-PEER",
"routeMapOutbound": "RM-MLAG-PEER",
}
]
},
},
},
{
"vrfs": {
"MGMT": {
"peerList": [
{
"peerAddress": "10.100.0.10",
"routeMapInbound": "RM-MLAG-PEER",
"routeMapOutbound": "RM-MLAG-PEER",
}
]
},
},
},
],
"inputs": {
"bgp_peers": [
{"peer_address": "10.100.0.8", "vrf": "default", "inbound_route_map": "RM-MLAG-PEER-IN"},
{"peer_address": "10.100.0.10", "vrf": "MGMT", "inbound_route_map": "RM-MLAG-PEER-IN"},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BGP peers are not configured or has an incorrect or missing route map in either the inbound or outbound direction:\n"
"{'10.100.0.8': {'default': {'Inbound route-map': 'RM-MLAG-PEER'}}, '10.100.0.10': {'MGMT': {'Inbound route-map': 'RM-MLAG-PEER'}}}"
],
},
},
{
"name": "failure-route-maps-not-configured",
"test": VerifyBgpRouteMaps,
"eos_data": [
{
"vrfs": {
"default": {
"peerList": [
{
"peerAddress": "10.100.0.8",
}
]
},
},
},
{
"vrfs": {
"MGMT": {
"peerList": [
{
"peerAddress": "10.100.0.10",
}
]
},
},
},
],
"inputs": {
"bgp_peers": [
{"peer_address": "10.100.0.8", "vrf": "default", "inbound_route_map": "RM-MLAG-PEER-IN", "outbound_route_map": "RM-MLAG-PEER-OUT"},
{"peer_address": "10.100.0.10", "vrf": "MGMT", "inbound_route_map": "RM-MLAG-PEER-IN", "outbound_route_map": "RM-MLAG-PEER-OUT"},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BGP peers are not configured or has an incorrect or missing route map in either the inbound or outbound direction:\n"
"{'10.100.0.8': {'default': {'Inbound route-map': 'Not Configured', 'Outbound route-map': 'Not Configured'}}, "
"'10.100.0.10': {'MGMT': {'Inbound route-map': 'Not Configured', 'Outbound route-map': 'Not Configured'}}}"
],
},
},
{
"name": "failure-peer-not-found",
"test": VerifyBgpRouteMaps,
"eos_data": [
{
"vrfs": {
"default": {"peerList": []},
},
},
{
"vrfs": {
"MGMT": {"peerList": []},
},
},
],
"inputs": {
"bgp_peers": [
{"peer_address": "10.100.0.8", "vrf": "default", "inbound_route_map": "RM-MLAG-PEER-IN"},
{"peer_address": "10.100.0.10", "vrf": "MGMT", "inbound_route_map": "RM-MLAG-PEER-IN"},
]
},
"expected": {
"result": "failure",
"messages": [
"The following BGP peers are not configured or has an incorrect or missing route map in either the inbound or outbound direction:\n"
"{'10.100.0.8': {'default': 'Not configured'}, '10.100.0.10': {'MGMT': 'Not configured'}}"
],
},
},
]

0 comments on commit 900ebb7

Please sign in to comment.