Skip to content

Commit c976175

Browse files
authored
Improve NetBox filter functionality with comprehensive instance handling (#1843)
This commit enhances the --filter parameter for 'osism sync netbox' to properly filter both primary and secondary NetBox instances, providing better control and clearer output. Key improvements: 1. Apply filter to BOTH primary and secondary NetBox instances - Previously: primary was always tested regardless of filter - Now: only test instances matching the filter 2. Enhanced connectivity check messages - Show "Checking connectivity to..." for each instance individually - Consistent output format for filtered and non-filtered scenarios - Better visibility into connection testing process 3. Improved error handling - Error if no instances match the filter criteria - Error if no filtered instances are reachable - Prevent fallback to primary when filter targets specific instance 4. Accurate sync messaging - Show "(including secondaries)" only when secondaries are synced - Based on actual reachable_secondaries, not filter presence - Clear indication of sync scope Examples: - '--filter primary': only tests/syncs primary NetBox - '--filter manager': only tests/syncs secondary manager - No filter: tests/syncs all configured NetBox instances Fixes issue where filtered syncs would still test and sync to unintended NetBox instances. Signed-off-by: Christian Berendt <[email protected]>
1 parent 9970a78 commit c976175

File tree

1 file changed

+123
-49
lines changed

1 file changed

+123
-49
lines changed

osism/tasks/conductor/ironic.py

Lines changed: 123 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -435,42 +435,73 @@ def sync_netbox_from_ironic(request_id, node_name=None, netbox_filter=None):
435435
f"Starting Ironic to NetBox synchronisation{filter_msg}\n",
436436
)
437437

438-
# Check NetBox API connectivity
439-
try:
440-
osism_utils.push_task_output(
441-
request_id, "Checking NetBox API connectivity...\n"
442-
)
443-
osism_utils.nb.status()
444-
osism_utils.push_task_output(request_id, "NetBox API is reachable\n")
445-
except Exception as e:
446-
osism_utils.push_task_output(
447-
request_id, f"ERROR: NetBox API is not reachable: {e}\n"
448-
)
449-
osism_utils.finish_task_output(request_id, rc=1)
450-
return
451-
452-
# Check secondary NetBox instances connectivity
453-
# Apply filter BEFORE connectivity checks to avoid unnecessary network calls
438+
# Determine which NetBox instances to check based on filter
454439
reachable_secondaries = []
455-
if osism_utils.secondary_nb_list:
456-
# First filter the secondary instances based on netbox_filter
457-
filtered_secondaries = [
458-
nb
459-
for nb in osism_utils.secondary_nb_list
460-
if _matches_netbox_filter(nb, netbox_filter, is_primary=False)
461-
]
462440

463-
# Only check connectivity for filtered instances
464-
if filtered_secondaries:
441+
if netbox_filter:
442+
# When filter is set, only check NetBox instances that match the filter
443+
filtered_netboxes = []
444+
445+
# Check if primary matches filter
446+
if _matches_netbox_filter(osism_utils.nb, netbox_filter, is_primary=True):
447+
filtered_netboxes.append(("primary", osism_utils.nb))
448+
449+
# Check which secondaries match filter
450+
for nb in osism_utils.secondary_nb_list:
451+
if _matches_netbox_filter(nb, netbox_filter, is_primary=False):
452+
filtered_netboxes.append(("secondary", nb))
453+
454+
if not filtered_netboxes:
465455
osism_utils.push_task_output(
466-
request_id, "Checking secondary NetBox instances connectivity...\n"
456+
request_id,
457+
f"ERROR: No NetBox instances match filter: {netbox_filter}\n",
467458
)
468-
for nb in filtered_secondaries:
469-
try:
470-
nb.status()
471-
reachable_secondaries.append(nb)
459+
osism_utils.finish_task_output(request_id, rc=1)
460+
return
461+
462+
# Test connectivity for filtered instances only
463+
primary_reachable = False
464+
for nb_type, nb in filtered_netboxes:
465+
try:
466+
name = (
467+
getattr(nb, "netbox_name", None) if nb_type == "secondary" else None
468+
)
469+
site = (
470+
getattr(nb, "netbox_site", None) if nb_type == "secondary" else None
471+
)
472+
info_parts = []
473+
if name:
474+
info_parts.append(f"Name: {name}")
475+
if site:
476+
info_parts.append(f"Site: {site}")
477+
info = f" ({', '.join(info_parts)})" if info_parts else ""
478+
479+
osism_utils.push_task_output(
480+
request_id,
481+
f"Checking connectivity to filtered NetBox: {nb.base_url}{info}...\n",
482+
)
483+
nb.status()
472484

473-
# Build info message
485+
if nb_type == "primary":
486+
primary_reachable = True
487+
osism_utils.push_task_output(
488+
request_id,
489+
f"Filtered primary NetBox is reachable: {nb.base_url}\n",
490+
)
491+
else:
492+
reachable_secondaries.append(nb)
493+
osism_utils.push_task_output(
494+
request_id,
495+
f"Filtered secondary NetBox is reachable: {nb.base_url}{info}\n",
496+
)
497+
except Exception as e:
498+
# Build error message
499+
if nb_type == "primary":
500+
osism_utils.push_task_output(
501+
request_id,
502+
f"WARNING: Filtered primary NetBox not reachable: {nb.base_url}: {e}\n",
503+
)
504+
else:
474505
name = getattr(nb, "netbox_name", None)
475506
site = getattr(nb, "netbox_site", None)
476507
info_parts = []
@@ -479,22 +510,64 @@ def sync_netbox_from_ironic(request_id, node_name=None, netbox_filter=None):
479510
if site:
480511
info_parts.append(f"Site: {site}")
481512
info = f" ({', '.join(info_parts)})" if info_parts else ""
513+
osism_utils.push_task_output(
514+
request_id,
515+
f"WARNING: Filtered secondary NetBox not reachable: {nb.base_url}{info}: {e}\n",
516+
)
517+
518+
# If no filtered instances are reachable, error out
519+
if not primary_reachable and not reachable_secondaries:
520+
osism_utils.push_task_output(
521+
request_id,
522+
f"ERROR: No NetBox instances matching filter '{netbox_filter}' are reachable\n",
523+
)
524+
osism_utils.finish_task_output(request_id, rc=1)
525+
return
526+
else:
527+
# Original behavior when no filter is set: check primary and all secondaries
528+
# Check NetBox API connectivity
529+
try:
530+
osism_utils.push_task_output(
531+
request_id, "Checking NetBox API connectivity...\n"
532+
)
533+
osism_utils.nb.status()
534+
osism_utils.push_task_output(request_id, "NetBox API is reachable\n")
535+
except Exception as e:
536+
osism_utils.push_task_output(
537+
request_id, f"ERROR: NetBox API is not reachable: {e}\n"
538+
)
539+
osism_utils.finish_task_output(request_id, rc=1)
540+
return
541+
542+
# Check secondary NetBox instances connectivity
543+
if osism_utils.secondary_nb_list:
544+
osism_utils.push_task_output(
545+
request_id, "Checking secondary NetBox instances connectivity...\n"
546+
)
547+
for nb in osism_utils.secondary_nb_list:
548+
# Build info message
549+
name = getattr(nb, "netbox_name", None)
550+
site = getattr(nb, "netbox_site", None)
551+
info_parts = []
552+
if name:
553+
info_parts.append(f"Name: {name}")
554+
if site:
555+
info_parts.append(f"Site: {site}")
556+
info = f" ({', '.join(info_parts)})" if info_parts else ""
557+
558+
try:
559+
osism_utils.push_task_output(
560+
request_id,
561+
f"Checking connectivity to NetBox: {nb.base_url}{info}...\n",
562+
)
563+
nb.status()
564+
reachable_secondaries.append(nb)
482565

483566
osism_utils.push_task_output(
484567
request_id,
485568
f"Secondary NetBox is reachable: {nb.base_url}{info}\n",
486569
)
487570
except Exception as e:
488-
# Build warning message
489-
name = getattr(nb, "netbox_name", None)
490-
site = getattr(nb, "netbox_site", None)
491-
info_parts = []
492-
if name:
493-
info_parts.append(f"Name: {name}")
494-
if site:
495-
info_parts.append(f"Site: {site}")
496-
info = f" ({', '.join(info_parts)})" if info_parts else ""
497-
498571
osism_utils.push_task_output(
499572
request_id,
500573
f"WARNING: Secondary NetBox not reachable: {nb.base_url}{info}: {e}\n",
@@ -530,16 +603,17 @@ def sync_netbox_from_ironic(request_id, node_name=None, netbox_filter=None):
530603
osism_utils.finish_task_output(request_id, rc=1)
531604
return
532605

533-
# Determine if we have secondaries for messaging
534-
has_secondaries = len(reachable_secondaries) > 0
535-
secondary_msg = " (including secondaries)" if has_secondaries else ""
536-
537606
# Sync each node to NetBox
538607
for node in nodes:
539-
osism_utils.push_task_output(
540-
request_id,
541-
f"Syncing state of {node['name']} to NetBox{secondary_msg}\n",
542-
)
608+
# Adjust message based on whether secondaries are actually being synced
609+
if reachable_secondaries:
610+
sync_msg = (
611+
f"Syncing state of {node['name']} to NetBox (including secondaries)\n"
612+
)
613+
else:
614+
sync_msg = f"Syncing state of {node['name']} to NetBox\n"
615+
616+
osism_utils.push_task_output(request_id, sync_msg)
543617

544618
# Update all three states (each function handles primary + secondary NetBox instances)
545619
# Pass netbox_filter to only update matching NetBox instances

0 commit comments

Comments
 (0)