Skip to content

Commit 92bc259

Browse files
authored
Merge pull request #14 from cisco-en-programmability/private/vivekraj2000/CSCwu46556
Added logic to filter devices having multiple serial numbers in sda_host_port_onboarding_playbook_config_generator
2 parents 92a5bb4 + 9e69d96 commit 92bc259

1 file changed

Lines changed: 54 additions & 12 deletions

File tree

plugins/modules/sda_host_port_onboarding_playbook_config_generator.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,10 @@ def get_port_assignments_configuration(self, network_element, filters):
13901390
# The device must pass ALL specified filters to be included.
13911391
# Evaluation order: device_ips → serial_numbers → hostnames.
13921392
# Within each filter type, matching is OR (any value match).
1393+
# Note: 'serial_numbers' additionally handles stack switches.
1394+
# Catalyst Center returns 'serialNumber' as a comma-separated
1395+
# string for stacks; the device matches if ANY member serial
1396+
# is in the filter set.
13931397
# Omitted/empty filter type → no restriction on that attribute.
13941398
# ----------------------------------------------------------
13951399

@@ -1407,13 +1411,16 @@ def get_port_assignments_configuration(self, network_element, filters):
14071411

14081412
if fabric_site_name_serial_number_mapping:
14091413
expected_serials = fabric_site_name_serial_number_mapping.get(fabric_site_name, set())
1410-
if expected_serials and serial_number not in expected_serials:
1414+
matched, device_serials = self._device_matches_serial_filter(
1415+
serial_number, expected_serials
1416+
)
1417+
if expected_serials and not matched:
14111418
self.log(
1412-
f"Warning: Resolved serial number '{serial_number}' for "
1413-
f"device ID '{network_device_id}' does not match expected "
1414-
f"serial numbers {expected_serials} from filters for "
1415-
f"fabric site '{fabric_site_name}'.",
1416-
"DEBUG"
1419+
f"Resolved serial number(s) {device_serials or repr(serial_number)} "
1420+
f"for device ID '{network_device_id}' do not match expected "
1421+
f"serial numbers {expected_serials} from filters for fabric site "
1422+
f"'{fabric_site_name}'.",
1423+
"DEBUG",
14171424
)
14181425
continue
14191426

@@ -1753,6 +1760,10 @@ def get_port_channels_configuration(self, network_element, filters):
17531760
# The device must pass ALL specified filters to be included.
17541761
# Evaluation order: device_ips → serial_numbers → hostnames.
17551762
# Within each filter type, matching is OR (any value match).
1763+
# Note: 'serial_numbers' additionally handles stack switches.
1764+
# Catalyst Center returns 'serialNumber' as a comma-separated
1765+
# string for stacks; the device matches if ANY member serial
1766+
# is in the filter set.
17561767
# Omitted/empty filter type → no restriction on that attribute.
17571768
# ----------------------------------------------------------
17581769

@@ -1770,13 +1781,16 @@ def get_port_channels_configuration(self, network_element, filters):
17701781

17711782
if fabric_site_name_serial_number_mapping:
17721783
expected_serials = fabric_site_name_serial_number_mapping.get(fabric_site_name, set())
1773-
if expected_serials and serial_number not in expected_serials:
1784+
matched, device_serials = self._device_matches_serial_filter(
1785+
serial_number, expected_serials
1786+
)
1787+
if expected_serials and not matched:
17741788
self.log(
1775-
f"Warning: Resolved serial number '{serial_number}' for "
1776-
f"device ID '{network_device_id}' does not match expected "
1777-
f"serial numbers {expected_serials} from filters for "
1778-
f"fabric site '{fabric_site_name}'.",
1779-
"DEBUG"
1789+
f"Resolved serial number(s) {device_serials or repr(serial_number)} "
1790+
f"for device ID '{network_device_id}' do not match expected "
1791+
f"serial numbers {expected_serials} from filters for fabric site "
1792+
f"'{fabric_site_name}'.",
1793+
"DEBUG",
17801794
)
17811795
continue
17821796

@@ -1819,6 +1833,34 @@ def get_port_channels_configuration(self, network_element, filters):
18191833
)
18201834
return all_fabric_port_channels_details
18211835

1836+
def _device_matches_serial_filter(self, serial_number, expected_serials):
1837+
"""
1838+
Check whether a device's serial number passes the expected-serials filter.
1839+
1840+
Catalyst Center returns 'serialNumber' as a comma-separated string for
1841+
stacked devices (e.g. 'FCW2415C14A, FCW2415C147'). The device is treated
1842+
as matching if ANY of its stack-member serials is in the expected set.
1843+
1844+
Args:
1845+
serial_number (str | None): Raw 'serialNumber' value from the device
1846+
response. May be None, empty, or comma-separated.
1847+
expected_serials (set[str]): Expected serial numbers for this device's
1848+
fabric site. An empty set means no restriction.
1849+
1850+
Returns:
1851+
tuple[bool, set[str]]: (matched, parsed_device_serials). When
1852+
expected_serials is empty, matched is True and parsed_device_serials
1853+
is the parsed set (useful for logging).
1854+
"""
1855+
device_serials = {
1856+
s.strip() for s in (serial_number or "").split(",") if s.strip()
1857+
}
1858+
1859+
if not expected_serials:
1860+
return True, device_serials
1861+
1862+
return bool(device_serials & expected_serials), device_serials
1863+
18221864
def get_wireless_ssids_configuration(self, network_element, filters):
18231865
"""
18241866
Retrieves and transforms wireless SSID configurations from Catalyst Center.

0 commit comments

Comments
 (0)