From a9139be648d68eaa2469a9d70852c2b9383a63c1 Mon Sep 17 00:00:00 2001 From: VitthalMagadum Date: Wed, 4 Sep 2024 06:57:25 -0400 Subject: [PATCH 1/6] issue_810 Added TC for BGP peer-group --- anta/tests/routing/bgp.py | 74 ++++++ examples/tests.yaml | 17 ++ tests/units/anta_tests/routing/test_bgp.py | 289 +++++++++++++++++++++ 3 files changed, 380 insertions(+) diff --git a/anta/tests/routing/bgp.py b/anta/tests/routing/bgp.py index 3477fc8b2..cefb02b5b 100644 --- a/anta/tests/routing/bgp.py +++ b/anta/tests/routing/bgp.py @@ -1437,3 +1437,77 @@ 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 VerifyBGPPeerGroup(AntaTest): + """Verifies BGP peer group of the BGP IPv4 peer(s). + + Expected Results + ---------------- + * Success: The test will pass if the peer group is correctly assigned to the BGP peer(s). + * Failure: The test will fail if the BGP peer group not correctly assigned or peer is not configured. + + Examples + -------- + ```yaml + anta.tests.routing: + bgp: + - VerifyBGPPeerGroup: + bgp_peers: + - peer_address: 172.30.11.1 + vrf: default + peer_group: IPv4-UNDERLAY-PEERS + ``` + """ + + name = "VerifyBGPPeerGroup" + description = "Verifies BGP peer group of the 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 VerifyBGPPeerGroup 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`.""" + peer_group: str + """The name of the peer group, BGP neighbor is associated with.""" + + 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 VerifyBGPPeerGroup.""" + failures: dict[Any, Any] = {} + + for command, input_entry in zip(self.instance_commands, self.inputs.bgp_peers): + peer = command.params.peer + vrf = command.params.vrf + peer_group = input_entry.peer_group + + # 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 + + if (actual_peer_group := peer_detail.get("peerGroupName")) != peer_group: + failure_log = f"Expected `{peer_group}` as the configured peer-group, but found `{actual_peer_group}` instead." + if not actual_peer_group: + failure_log = "Peer-group not configured." + failures[peer] = failure_log + + # Check if any failures + if not failures: + self.result.is_success() + else: + self.result.is_failure(f"The following BGP peer(s) are not configured or have incorrect peer-group configured:\n{failures}") diff --git a/examples/tests.yaml b/examples/tests.yaml index bb7d3b0d6..e55bca58e 100644 --- a/examples/tests.yaml +++ b/examples/tests.yaml @@ -609,6 +609,23 @@ anta.tests.routing: update_errors: - inUpdErrWithdraw - inUpdErrIgnore + - VerifyBGPPeerGroup: + bgp_peers: + - peer_address: 10.100.0.8 + vrf: default + peer_group: IPv4-UNDERLAY-PEERS + - peer_address: 10.100.0.10 + vrf: MGMT + peer_group: IPv4-UNDERLAY-PEERS + - peer_address: 10.100.1.1 + vrf: default + peer_group: EVPN-OVERLAY-PEERS + - peer_address: 10.100.1.2 + vrf: MGMT + peer_group: EVPN-OVERLAY-PEERS + - peer_address: 10.100.4.5 + vrf: default + peer_group: MLAG-IPv4-UNDERLAY-PEER ospf: - VerifyOSPFNeighborState: - VerifyOSPFNeighborCount: diff --git a/tests/units/anta_tests/routing/test_bgp.py b/tests/units/anta_tests/routing/test_bgp.py index b76939bd5..859865873 100644 --- a/tests/units/anta_tests/routing/test_bgp.py +++ b/tests/units/anta_tests/routing/test_bgp.py @@ -16,6 +16,7 @@ VerifyBGPPeerASNCap, VerifyBGPPeerCount, VerifyBGPPeerDropStats, + VerifyBGPPeerGroup, VerifyBGPPeerMD5Auth, VerifyBGPPeerMPCaps, VerifyBGPPeerRouteRefreshCap, @@ -4503,4 +4504,292 @@ ], }, }, + { + "name": "success", + "test": VerifyBGPPeerGroup, + "eos_data": [ + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.0.8", + "peerGroupName": "IPv4-UNDERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "MGMT": { + "peerList": [ + { + "peerAddress": "10.100.0.10", + "peerGroupName": "IPv4-UNDERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.1.1", + "peerGroupName": "EVPN-OVERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "MGMT": { + "peerList": [ + { + "peerAddress": "10.100.1.2", + "peerGroupName": "EVPN-OVERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.4.5", + "peerGroupName": "MLAG-IPv4-UNDERLAY-PEER", + } + ] + }, + }, + }, + ], + "inputs": { + "bgp_peers": [ + {"peer_address": "10.100.0.8", "vrf": "default", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.0.10", "vrf": "MGMT", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.1.1", "vrf": "default", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.1.2", "vrf": "MGMT", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.4.5", "vrf": "default", "peer_group": "MLAG-IPv4-UNDERLAY-PEER"}, + ] + }, + "expected": {"result": "success"}, + }, + { + "name": "failure-incorrect-peer-group", + "test": VerifyBGPPeerGroup, + "eos_data": [ + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.0.8", + "peerGroupName": "UNDERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "MGMT": { + "peerList": [ + { + "peerAddress": "10.100.0.10", + "peerGroupName": "UNDERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.1.1", + "peerGroupName": "OVERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "MGMT": { + "peerList": [ + { + "peerAddress": "10.100.1.2", + "peerGroupName": "OVERLAY-PEERS", + } + ] + }, + }, + }, + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.4.5", + "peerGroupName": "UNDERLAY-PEER", + } + ] + }, + }, + }, + ], + "inputs": { + "bgp_peers": [ + {"peer_address": "10.100.0.8", "vrf": "default", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.0.10", "vrf": "MGMT", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.1.1", "vrf": "default", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.1.2", "vrf": "MGMT", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.4.5", "vrf": "default", "peer_group": "MLAG-IPv4-UNDERLAY-PEER"}, + ] + }, + "expected": { + "result": "failure", + "messages": [ + "The following BGP peer(s) are not configured or have incorrect peer-group configured:\n" + "{'10.100.0.8': 'Expected `IPv4-UNDERLAY-PEERS` as the configured peer-group, but found `UNDERLAY-PEERS` instead.', " + "'10.100.0.10': 'Expected `IPv4-UNDERLAY-PEERS` as the configured peer-group, but found `UNDERLAY-PEERS` instead.', " + "'10.100.1.1': 'Expected `EVPN-OVERLAY-PEERS` as the configured peer-group, but found `OVERLAY-PEERS` instead.', " + "'10.100.1.2': 'Expected `EVPN-OVERLAY-PEERS` as the configured peer-group, but found `OVERLAY-PEERS` instead.', " + "'10.100.4.5': 'Expected `MLAG-IPv4-UNDERLAY-PEER` as the configured peer-group, but found `UNDERLAY-PEER` instead.'}" + ], + }, + }, + { + "name": "failure-peers-not-found", + "test": VerifyBGPPeerGroup, + "eos_data": [ + { + "vrfs": { + "default": {"peerList": []}, + }, + }, + { + "vrfs": { + "MGMT": {"peerList": []}, + }, + }, + { + "vrfs": { + "default": {"peerList": []}, + }, + }, + { + "vrfs": { + "MGMT": {"peerList": []}, + }, + }, + { + "vrfs": { + "default": {"peerList": []}, + }, + }, + ], + "inputs": { + "bgp_peers": [ + {"peer_address": "10.100.0.8", "vrf": "default", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.0.10", "vrf": "MGMT", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.1.1", "vrf": "default", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.1.2", "vrf": "MGMT", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.4.5", "vrf": "default", "peer_group": "MLAG-IPv4-UNDERLAY-PEER"}, + ] + }, + "expected": { + "result": "failure", + "messages": [ + "The following BGP peer(s) are not configured or have incorrect peer-group configured:\n" + "{'10.100.0.8': {'default': 'Not configured'}, '10.100.0.10': {'MGMT': 'Not configured'}, '10.100.1.1': " + "{'default': 'Not configured'}, '10.100.1.2': {'MGMT': 'Not configured'}, '10.100.4.5': {'default': 'Not configured'}}" + ], + }, + }, + { + "name": "failure-peer-group-not-found", + "test": VerifyBGPPeerGroup, + "eos_data": [ + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.0.8", + } + ] + }, + }, + }, + { + "vrfs": { + "MGMT": { + "peerList": [ + { + "peerAddress": "10.100.0.10", + } + ] + }, + }, + }, + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.1.1", + } + ] + }, + }, + }, + { + "vrfs": { + "MGMT": { + "peerList": [ + { + "peerAddress": "10.100.1.2", + } + ] + }, + }, + }, + { + "vrfs": { + "default": { + "peerList": [ + { + "peerAddress": "10.100.4.5", + } + ] + }, + }, + }, + ], + "inputs": { + "bgp_peers": [ + {"peer_address": "10.100.0.8", "vrf": "default", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.0.10", "vrf": "MGMT", "peer_group": "IPv4-UNDERLAY-PEERS"}, + {"peer_address": "10.100.1.1", "vrf": "default", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.1.2", "vrf": "MGMT", "peer_group": "EVPN-OVERLAY-PEERS"}, + {"peer_address": "10.100.4.5", "vrf": "default", "peer_group": "MLAG-IPv4-UNDERLAY-PEER"}, + ] + }, + "expected": { + "result": "failure", + "messages": [ + "The following BGP peer(s) are not configured or have incorrect peer-group configured:\n" + "{'10.100.0.8': 'Peer-group not configured.', '10.100.0.10': 'Peer-group not configured.', '10.100.1.1': " + "'Peer-group not configured.', '10.100.1.2': 'Peer-group not configured.', '10.100.4.5': 'Peer-group not configured.'}" + ], + }, + }, ] From 07ae814e88e29ae66a6816a75903703771bc6da7 Mon Sep 17 00:00:00 2001 From: VitthalMagadum Date: Thu, 12 Sep 2024 00:38:24 -0400 Subject: [PATCH 2/6] issue_810 Handling review comments: updated failure messages --- anta/tests/routing/bgp.py | 6 +++--- tests/units/anta_tests/routing/test_bgp.py | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/anta/tests/routing/bgp.py b/anta/tests/routing/bgp.py index cefb02b5b..b18aa81ee 100644 --- a/anta/tests/routing/bgp.py +++ b/anta/tests/routing/bgp.py @@ -1491,8 +1491,8 @@ def test(self) -> None: failures: dict[Any, Any] = {} for command, input_entry in zip(self.instance_commands, self.inputs.bgp_peers): - peer = command.params.peer - vrf = command.params.vrf + peer = str(input_entry.peer_address) + vrf = input_entry.vrf peer_group = input_entry.peer_group # Verify BGP peer. @@ -1504,7 +1504,7 @@ def test(self) -> None: failure_log = f"Expected `{peer_group}` as the configured peer-group, but found `{actual_peer_group}` instead." if not actual_peer_group: failure_log = "Peer-group not configured." - failures[peer] = failure_log + failures[peer] = {vrf: failure_log} # Check if any failures if not failures: diff --git a/tests/units/anta_tests/routing/test_bgp.py b/tests/units/anta_tests/routing/test_bgp.py index 859865873..94bace16d 100644 --- a/tests/units/anta_tests/routing/test_bgp.py +++ b/tests/units/anta_tests/routing/test_bgp.py @@ -4658,11 +4658,11 @@ "result": "failure", "messages": [ "The following BGP peer(s) are not configured or have incorrect peer-group configured:\n" - "{'10.100.0.8': 'Expected `IPv4-UNDERLAY-PEERS` as the configured peer-group, but found `UNDERLAY-PEERS` instead.', " - "'10.100.0.10': 'Expected `IPv4-UNDERLAY-PEERS` as the configured peer-group, but found `UNDERLAY-PEERS` instead.', " - "'10.100.1.1': 'Expected `EVPN-OVERLAY-PEERS` as the configured peer-group, but found `OVERLAY-PEERS` instead.', " - "'10.100.1.2': 'Expected `EVPN-OVERLAY-PEERS` as the configured peer-group, but found `OVERLAY-PEERS` instead.', " - "'10.100.4.5': 'Expected `MLAG-IPv4-UNDERLAY-PEER` as the configured peer-group, but found `UNDERLAY-PEER` instead.'}" + "{'10.100.0.8': {'default': 'Expected `IPv4-UNDERLAY-PEERS` as the configured peer-group, but found `UNDERLAY-PEERS` instead.'}, " + "'10.100.0.10': {'MGMT': 'Expected `IPv4-UNDERLAY-PEERS` as the configured peer-group, but found `UNDERLAY-PEERS` instead.'}, " + "'10.100.1.1': {'default': 'Expected `EVPN-OVERLAY-PEERS` as the configured peer-group, but found `OVERLAY-PEERS` instead.'}, " + "'10.100.1.2': {'MGMT': 'Expected `EVPN-OVERLAY-PEERS` as the configured peer-group, but found `OVERLAY-PEERS` instead.'}, " + "'10.100.4.5': {'default': 'Expected `MLAG-IPv4-UNDERLAY-PEER` as the configured peer-group, but found `UNDERLAY-PEER` instead.'}}" ], }, }, @@ -4787,8 +4787,9 @@ "result": "failure", "messages": [ "The following BGP peer(s) are not configured or have incorrect peer-group configured:\n" - "{'10.100.0.8': 'Peer-group not configured.', '10.100.0.10': 'Peer-group not configured.', '10.100.1.1': " - "'Peer-group not configured.', '10.100.1.2': 'Peer-group not configured.', '10.100.4.5': 'Peer-group not configured.'}" + "{'10.100.0.8': {'default': 'Peer-group not configured.'}, '10.100.0.10': {'MGMT': 'Peer-group not configured.'}, '10.100.1.1': " + "{'default': 'Peer-group not configured.'}, '10.100.1.2': {'MGMT': 'Peer-group not configured.'}, " + "'10.100.4.5': {'default': 'Peer-group not configured.'}}" ], }, }, From 7529a1ddb1ff01583b89c47757683cf9041bd3c2 Mon Sep 17 00:00:00 2001 From: VitthalMagadum Date: Sun, 22 Sep 2024 12:23:10 -0400 Subject: [PATCH 3/6] CI fixes after conflicts removal --- tests/units/anta_tests/routing/test_bgp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/units/anta_tests/routing/test_bgp.py b/tests/units/anta_tests/routing/test_bgp.py index 8414c3811..63a622262 100644 --- a/tests/units/anta_tests/routing/test_bgp.py +++ b/tests/units/anta_tests/routing/test_bgp.py @@ -14,6 +14,7 @@ VerifyBGPPeerASNCap, VerifyBGPPeerCount, VerifyBGPPeerDropStats, + VerifyBGPPeerGroup, VerifyBGPPeerMD5Auth, VerifyBGPPeerMPCaps, VerifyBGPPeerRouteLimit, @@ -24,7 +25,6 @@ VerifyBGPSpecificPeers, VerifyBGPTimers, VerifyEVPNType2Route, - VerifyBGPPeerGroup, ) from tests.units.anta_tests import test @@ -5126,4 +5126,4 @@ ], }, }, -] \ No newline at end of file +] From fc9c42be17958b4c0ef3bcf6112541aaa0541bf0 Mon Sep 17 00:00:00 2001 From: VitthalMagadum Date: Wed, 25 Sep 2024 02:01:52 -0400 Subject: [PATCH 4/6] issue_810 Handling review comment: update new line --- examples/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tests.yaml b/examples/tests.yaml index fe49d560c..931c3627e 100644 --- a/examples/tests.yaml +++ b/examples/tests.yaml @@ -695,4 +695,4 @@ anta.tests.routing: - endpoint: 1.0.0.14/32 vias: - type: ip - nexthop: 1.1.1.1 \ No newline at end of file + nexthop: 1.1.1.1 From 459b4ff4827b2711401c18835906303e78201bb9 Mon Sep 17 00:00:00 2001 From: VitthalMagadum Date: Mon, 7 Oct 2024 07:01:03 -0400 Subject: [PATCH 5/6] issue_810 Added pylint disable check for no of line --- anta/tests/routing/bgp.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/anta/tests/routing/bgp.py b/anta/tests/routing/bgp.py index 82483d63a..5481fcc9a 100644 --- a/anta/tests/routing/bgp.py +++ b/anta/tests/routing/bgp.py @@ -26,6 +26,9 @@ else: from typing_extensions import Self +# pylint: disable=C0302 +# TODO: Refactor to reduce the number of lines in this module later + def _add_bgp_failures(failures: dict[tuple[str, str | None], dict[str, Any]], afi: Afi, safi: Safi | None, vrf: str, issue: str | dict[str, Any]) -> None: """Add a BGP failure entry to the given `failures` dictionary. From 87ae237d12ee8d69bdc086d3f87886051086a35d Mon Sep 17 00:00:00 2001 From: vitthalmagadum Date: Mon, 30 Dec 2024 23:32:40 -0500 Subject: [PATCH 6/6] Updated input model changes and unit tests for input --- anta/tests/routing/bgp.py | 14 +++++++++-- tests/units/input_models/routing/test_bgp.py | 26 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/anta/tests/routing/bgp.py b/anta/tests/routing/bgp.py index bfb91ffd3..50c9d1592 100644 --- a/anta/tests/routing/bgp.py +++ b/anta/tests/routing/bgp.py @@ -1277,10 +1277,20 @@ def test(self) -> None: class VerifyBGPPeerGroup(AntaTest): """Verifies BGP peer group of the IPv4 peer(s). + This test performs the following checks for each specified peer: + + 1. Confirms that the specified VRF is configured. + 2. Verifies that the peer exists in the BGP configuration. + 3. Confirms the peer group is correctly assigned to the specified BGP peer. + Expected Results ---------------- - * Success: The test will pass if the peer group is correctly assigned to the BGP peer(s). - * Failure: The test will fail if the BGP peer group not correctly assigned or peer is not configured. + * Success: If all of the following conditions are met: + - All specified peers are found in the BGP configuration. + - The peer group is correctly assigned to the specified BGP peer. + * Failure: If any of the following occur: + - A specified peer is not found in the BGP configuration. + - The peer group is not correctly assigned to the specified BGP peer. Examples -------- diff --git a/tests/units/input_models/routing/test_bgp.py b/tests/units/input_models/routing/test_bgp.py index 66c37af61..0f31cf587 100644 --- a/tests/units/input_models/routing/test_bgp.py +++ b/tests/units/input_models/routing/test_bgp.py @@ -15,6 +15,7 @@ from anta.tests.routing.bgp import ( VerifyBGPExchangedRoutes, VerifyBGPPeerCount, + VerifyBGPPeerGroup, VerifyBGPPeerMPCaps, VerifyBGPPeerRouteLimit, VerifyBgpRouteMaps, @@ -236,3 +237,28 @@ def test_invalid(self, bgp_peers: list[BgpPeer]) -> None: """Test VerifyBGPPeerRouteLimit.Input invalid inputs.""" with pytest.raises(ValidationError): VerifyBGPPeerRouteLimit.Input(bgp_peers=bgp_peers) + + +class TestVerifyBGPPeerGroupInput: + """Test anta.tests.routing.bgp.VerifyBGPPeerGroup.Input.""" + + @pytest.mark.parametrize( + ("bgp_peers"), + [ + pytest.param([{"peer_address": "172.30.255.5", "vrf": "default", "peer_group": "IPv4-UNDERLAY-PEERS"}], id="valid"), + ], + ) + def test_valid(self, bgp_peers: list[BgpPeer]) -> None: + """Test VerifyBGPPeerGroup.Input valid inputs.""" + VerifyBGPPeerGroup.Input(bgp_peers=bgp_peers) + + @pytest.mark.parametrize( + ("bgp_peers"), + [ + pytest.param([{"peer_address": "172.30.255.5", "vrf": "default"}], id="invalid"), + ], + ) + def test_invalid(self, bgp_peers: list[BgpPeer]) -> None: + """Test VerifyBGPPeerGroup.Input invalid inputs.""" + with pytest.raises(ValidationError): + VerifyBGPPeerGroup.Input(bgp_peers=bgp_peers)