Fix empty BGP route false positives and add batch alias UX.

Skip Dest/Network headers when Total routes is 0; capture direction from match groups; expose workbook compare/data/sheet stats and prefer batch aliases in compare/cutover pickers.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-22 10:58:57 +08:00
parent f321413dbf
commit 1fcd613bc6
16 changed files with 327 additions and 39 deletions

View file

@ -108,6 +108,29 @@ Routes Learned From This Neighbor:
* 10.2.0.0/24 10.0.0.1 20 65001 65009 ?
"""
_BGP_ROUTE_EMPTY_DEST = """
Current AS: 100. Other AS: 24208, 3.45420
Routes Learned From This Neighbor:
Status codes: * valid, < last valid, i - internal, s - stale
Origin codes: i - IGP, e - EGP, ? - incomplete
Local router ID 1.11.1.1, Local AS 100, Local port 0
Remote router ID 0.0.0.0, Remote AS 100, Remote port 0
Total number of routes: 0
Valid routes : 0
Invalid routes : 0
Dest Next Hop Metric LocPrf InTag Path
"""
_BGP_ROUTE_EMPTY_OUT = """
Current AS: 100. Other AS: 24208, 3.45420
Routes Sent To This Neighbor:
Origin codes: i - IGP, e - EGP, ? - incomplete
Total number of routes: 0
Network Next Hop From Metric LocPrf Tag Path
"""
_IP_ROUTE = """
Dest Gw Interface Owner Pri Metric
*> 0.0.0.0/0 10.0.0.1 smartgroup1 BGP 200 1
@ -371,6 +394,48 @@ class ZteExtendedParserTests(unittest.TestCase):
)
self.assertEqual(ra.command, "show bgp vpnv4 unicast vrf CUST_A summary | one-line")
def test_bgp_route_empty_total_skips_header(self) -> None:
empty_in = normalize_bgp_route(
raw_text=_BGP_ROUTE_EMPTY_DEST,
command="show bgp vpnv4 unicast neighbor in 10.22.9.2 | one-line",
params={"neighbor": "10.22.9.2", "direction": "in"},
)
self.assertEqual(empty_in, [])
empty_out = normalize_bgp_route(
raw_text=_BGP_ROUTE_EMPTY_OUT,
command="show bgp vpnv4 unicast neighbor out 10.22.9.2 | one-line",
)
self.assertEqual(empty_out, [])
hit_in = match_command(
vendor_key="zte",
command="show bgp vpnv4 unicast neighbor in 10.22.9.2 | one-line",
)
self.assertIsNotNone(hit_in)
assert hit_in is not None
self.assertEqual(hit_in.profile.profile_id, "zte.bgp_vpnv4_neighbor_in")
self.assertEqual(hit_in.params.get("direction"), "in")
self.assertEqual(hit_in.params.get("neighbor"), "10.22.9.2")
hit_out = match_command(
vendor_key="zte",
command="show bgp vpnv4 unicast neighbor out 10.22.9.2 | one-line",
)
self.assertIsNotNone(hit_out)
assert hit_out is not None
self.assertEqual(hit_out.profile.profile_id, "zte.bgp_vpnv4_neighbor_out")
self.assertEqual(hit_out.params.get("direction"), "out")
self.assertEqual(hit_out.params.get("neighbor"), "10.22.9.2")
# Direction detected from command when params omit it
parsed = normalize_bgp_route(
raw_text=_BGP_ROUTE_IN,
command="show bgp vpnv4 unicast neighbor out 10.0.0.1",
)
self.assertEqual(parsed[0]["direction"], "out")
self.assertEqual(parsed[0]["neighbor"], "10.0.0.1")
def test_ip_ipv6_route_and_pw(self) -> None:
ip = normalize_ip_route(
raw_text=_IP_ROUTE,
@ -705,6 +770,7 @@ gei-0/0/0/2 is up, ifindex: 2
assert hit6 is not None
self.assertEqual(hit6.profile.profile_id, "zte.bgp_vpnv6_neighbor_in")
self.assertEqual(hit6.params.get("neighbor"), "FC00:1::1")
self.assertEqual(hit6.params.get("direction"), "in")
routes = normalize_bgp_route(
raw_text=_BGP_ROUTE_IN,