From 953a8945b80a2001dbbc432c2a5b3989f49db5d3 Mon Sep 17 00:00:00 2001 From: Jamie Reid Date: Wed, 11 Jun 2025 16:42:43 +1000 Subject: [PATCH 1/5] Adjusts parser for "show ap cdp neighbor" Resolves #723 Adjust regex to include the ap neighbor IP as it is output on 9800 platform v17.x --- ...ow_ap_cdp_neighbor_iosxe_2025061749625685170805.rst | 6 ++++++ src/genie/libs/parser/iosxe/show_ap.py | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 changelog/undistributed/changelog_show_ap_cdp_neighbor_iosxe_2025061749625685170805.rst diff --git a/changelog/undistributed/changelog_show_ap_cdp_neighbor_iosxe_2025061749625685170805.rst b/changelog/undistributed/changelog_show_ap_cdp_neighbor_iosxe_2025061749625685170805.rst new file mode 100644 index 0000000000..6f6e72f042 --- /dev/null +++ b/changelog/undistributed/changelog_show_ap_cdp_neighbor_iosxe_2025061749625685170805.rst @@ -0,0 +1,6 @@ +-------------------------------------------------------------------------------- + Fix +-------------------------------------------------------------------------------- +* IOSXE + * Modified ShowApCdpNeighbor: + * Updated regex pattern neighbor_info_capture to optionally capture the Neighbors IP if it exists diff --git a/src/genie/libs/parser/iosxe/show_ap.py b/src/genie/libs/parser/iosxe/show_ap.py index 81873de974..97e43a6659 100644 --- a/src/genie/libs/parser/iosxe/show_ap.py +++ b/src/genie/libs/parser/iosxe/show_ap.py @@ -1200,7 +1200,7 @@ def cli(self, output=None): neighbor_count_capture = re.compile(r"^Number\s+of\s+neighbors:\s+(?P\d+)$") # 0221-cap22 10.8.33.106 a02-21-sd-sw1.cisco.com TenGigabitEthernet3/0/47 neighbor_info_capture = re.compile( - r"^(?P\S+)\s+(?P\d+\.\d+\.\d+\.\d+)\s+(?P\S+)\s+(?P\S+)$") + r"^(?P\S+)\s+(?P\d+\.\d+\.\d+\.\d+)\s+(?P\S+)\s+((?P\S+))?\s+(?P\S+)$") # Neighbor IP Count: 1 neighbor_ip_count_capture = re.compile(r"^Neighbor\s+IP\s+Count:\s+(?P\d+)$") # 10.8.32.1 @@ -1235,6 +1235,12 @@ def cli(self, output=None): ap_cdp_neighbor_dict['ap_name'][ap_name]['ap_ip'] = ap_ip ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_name'] = neighbor_name ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_port'] = neighbor_port + if groups['neighbor_ip']: + neighbor_ip = groups['neighbor_ip'] + if not ap_cdp_neighbor_dict['ap_name'][ap_name].get('neighbor_ip_addresses', {}): + ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_ip_addresses'] = [] + ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_ip_addresses'].append(neighbor_ip) + # Neighbor IP Count: 1 elif neighbor_ip_count_capture.match(line): neighbor_ip_count_match = neighbor_ip_count_capture.match(line) @@ -3198,4 +3204,4 @@ def filter_lines(raw_output, remove_lines): ap_image_data = {} continue - return ap_image_dict \ No newline at end of file + return ap_image_dict From 203d3f2b9412c19d2c4cff6dd7dd70703f5111e8 Mon Sep 17 00:00:00 2001 From: Jamie Reid Date: Tue, 17 Jun 2025 11:36:53 +1000 Subject: [PATCH 2/5] Add comment to show match, and update schema --- src/genie/libs/parser/iosxe/show_ap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/genie/libs/parser/iosxe/show_ap.py b/src/genie/libs/parser/iosxe/show_ap.py index 97e43a6659..e7afa5d219 100644 --- a/src/genie/libs/parser/iosxe/show_ap.py +++ b/src/genie/libs/parser/iosxe/show_ap.py @@ -1149,7 +1149,7 @@ class ShowApCdpNeighborSchema(MetaParser): Optional("neighbor_name"): str, Optional("neighbor_port"): str, Optional("neighbor_ip_count"): int, - Optional("neighbor_ip_addresses"): list + Optional("neighbor_ip_addresses"): ListOf(str) } } } @@ -1199,6 +1199,7 @@ def cli(self, output=None): neighbor_count_capture = re.compile(r"^Number\s+of\s+neighbors:\s+(?P\d+)$") # 0221-cap22 10.8.33.106 a02-21-sd-sw1.cisco.com TenGigabitEthernet3/0/47 + # 0221-cap22 10.8.33.106 a02-21-sd-sw1.cisco.com 10.8.32.1 TenGigabitEthernet3/0/47 neighbor_info_capture = re.compile( r"^(?P\S+)\s+(?P\d+\.\d+\.\d+\.\d+)\s+(?P\S+)\s+((?P\S+))?\s+(?P\S+)$") # Neighbor IP Count: 1 From dac85b82afbe6bff554f368280f4d910e167fdb5 Mon Sep 17 00:00:00 2001 From: Jamie Reid Date: Tue, 17 Jun 2025 11:53:40 +1000 Subject: [PATCH 3/5] Clean up code as suggested by @ThomasJRyan in #984 --- src/genie/libs/parser/iosxe/show_ap.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/genie/libs/parser/iosxe/show_ap.py b/src/genie/libs/parser/iosxe/show_ap.py index e7afa5d219..4c18e95d75 100644 --- a/src/genie/libs/parser/iosxe/show_ap.py +++ b/src/genie/libs/parser/iosxe/show_ap.py @@ -1238,9 +1238,8 @@ def cli(self, output=None): ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_port'] = neighbor_port if groups['neighbor_ip']: neighbor_ip = groups['neighbor_ip'] - if not ap_cdp_neighbor_dict['ap_name'][ap_name].get('neighbor_ip_addresses', {}): - ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_ip_addresses'] = [] - ap_cdp_neighbor_dict['ap_name'][ap_name]['neighbor_ip_addresses'].append(neighbor_ip) + address_list = ap_cdp_neighbor_dict['ap_name'][ap_name].setdefault('neighbor_ip_addresses', []) + address_list.append(neighbor_ip) # Neighbor IP Count: 1 elif neighbor_ip_count_capture.match(line): From 58191fa6d30096d3418df3c43f288aa5f2f14d5f Mon Sep 17 00:00:00 2001 From: Jamie Reid Date: Tue, 17 Jun 2025 14:10:30 +1000 Subject: [PATCH 4/5] Add additional unittest for IOSXE ShowApCdpNeighbor parser --- .../cli/equal/golden_output_2_expected.py | 75 +++++++++++++++++++ .../cli/equal/golden_output_2_output.txt | 14 ++++ 2 files changed, 89 insertions(+) create mode 100644 src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_expected.py create mode 100644 src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_output.txt diff --git a/src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_expected.py b/src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_expected.py new file mode 100644 index 0000000000..6b8a897641 --- /dev/null +++ b/src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_expected.py @@ -0,0 +1,75 @@ +expected_output = { + "ap_cdp_neighbor_count": 149, + "ap_name": { + "0221-cap22": { + "ap_ip": "10.8.33.106", + "neighbor_name": "a02-21-sd-sw1.cisco.com", + "neighbor_port": "TenGigabitEthernet3/0/47", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0232-cap15": { + "ap_ip": "10.8.32.46", + "neighbor_name": "a02-32-sd-sw1.cisco.com", + "neighbor_port": "TenGigabitEthernet9/0/47", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0211-cap27": { + "ap_ip": "10.8.32.188", + "neighbor_name": "a02-11-sd-sw1.cisco.com", + "neighbor_port": "TenGigabitEthernet4/0/46", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0212-cap11": { + "ap_ip": "10.8.33.160", + "neighbor_name": "a02-12-sd-sw2.cisco.com", + "neighbor_port": "TenGigabitEthernet1/0/40", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0212-cap10": { + "ap_ip": "10.8.33.102", + "neighbor_name": "a02-12-sd-sw1.cisco.com", + "neighbor_port": "TenGigabitEthernet1/0/43", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0212-cap17": { + "ap_ip": "10.8.32.203", + "neighbor_name": "a02-12-sd-sw2.cisco.com", + "neighbor_port": "TenGigabitEthernet1/0/47", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0212-ca.4": { + "ap_ip": "10.8.32.202", + "neighbor_name": "a02-12-sd-sw1.cisco.com", + "neighbor_port": "TenGigabitEthernet1/0/48", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0222-cap09": { + "ap_ip": "10.8.33.33", + "neighbor_name": "a02-22-sd-sw2.cisco.com", + "neighbor_port": "TenGigabitEthernet8/0/48", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0231-cap43": { + "ap_ip": "10.8.33.93", + "neighbor_name": "a02-31-sd-sw1.cisco.com", + "neighbor_port": "TenGigabitEthernet4/0/47", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + }, + "0222-cap08": { + "ap_ip": "10.8.32.166", + "neighbor_name": "a02-22-sd-sw2.cisco.com", + "neighbor_port": "TenGigabitEthernet4/0/47", + "neighbor_ip_count": 1, + "neighbor_ip_addresses": ["10.8.32.1"] + } + } +} diff --git a/src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_output.txt b/src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_output.txt new file mode 100644 index 0000000000..e49035ca70 --- /dev/null +++ b/src/genie/libs/parser/iosxe/tests/ShowApCdpNeighbor/cli/equal/golden_output_2_output.txt @@ -0,0 +1,14 @@ +Number of neighbors: 149 + +AP Name AP IP Neighbor Name Neighbor IP Neighbor Port +------------------------------------------------------------------------------------------------------------------------------------------------------------- +0221-cap22 10.8.33.106 a02-21-sd-sw1.cisco.com 10.8.31.1 TenGigabitEthernet3/0/47 +0232-cap15 10.8.32.46 a02-32-sd-sw1.cisco.com 10.8.31.1 TenGigabitEthernet9/0/47 +0211-cap27 10.8.32.188 a02-11-sd-sw1.cisco.com 10.8.31.1 TenGigabitEthernet4/0/46 +0212-cap11 10.8.33.160 a02-12-sd-sw2.cisco.com 10.8.31.1 TenGigabitEthernet1/0/40 +0212-cap10 10.8.33.102 a02-12-sd-sw1.cisco.com 10.8.31.1 TenGigabitEthernet1/0/43 +0212-cap17 10.8.32.203 a02-12-sd-sw2.cisco.com 10.8.31.1 TenGigabitEthernet1/0/47 +0212-ca.4 10.8.32.202 a02-12-sd-sw1.cisco.com 10.8.31.1 TenGigabitEthernet1/0/48 +0222-cap09 10.8.33.33 a02-22-sd-sw2.cisco.com 10.8.31.1 TenGigabitEthernet8/0/48 +0231-cap43 10.8.33.93 a02-31-sd-sw1.cisco.com 10.8.31.1 TenGigabitEthernet4/0/47 +0222-cap08 10.8.32.166 a02-22-sd-sw2.cisco.com 10.8.31.1 TenGigabitEthernet4/0/47 From 20c01708070214b86745e2d402482e9f1fbb96e0 Mon Sep 17 00:00:00 2001 From: Jamie Reid Date: Tue, 17 Jun 2025 15:34:44 +1000 Subject: [PATCH 5/5] Add missing import --- src/genie/libs/parser/iosxe/show_ap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/genie/libs/parser/iosxe/show_ap.py b/src/genie/libs/parser/iosxe/show_ap.py index 4c18e95d75..a839e9e665 100644 --- a/src/genie/libs/parser/iosxe/show_ap.py +++ b/src/genie/libs/parser/iosxe/show_ap.py @@ -1,7 +1,7 @@ import re from genie.metaparser import MetaParser -from genie.metaparser.util.schemaengine import Any, Optional, Or +from genie.metaparser.util.schemaengine import Any, Optional, Or, ListOf # ====================