diff --git a/osism/commands/sonic.py b/osism/commands/sonic.py index 3cb1ff3b..54e02be6 100644 --- a/osism/commands/sonic.py +++ b/osism/commands/sonic.py @@ -12,12 +12,11 @@ from tabulate import tabulate from osism import utils -from osism.tasks import netbox +from osism.tasks import netbox, conductor from osism.tasks.conductor.netbox import ( - get_nb_device_query_list_sonic, get_device_oob_ip, ) -from osism.tasks.conductor.sonic.constants import DEFAULT_SONIC_ROLES, SUPPORTED_HWSKUS +from osism.tasks.conductor.sonic.constants import SUPPORTED_HWSKUS from osism.utils.ssh import ( cleanup_ssh_known_hosts_for_node, ensure_known_hosts_file, @@ -1068,6 +1067,7 @@ def get_parser(self, prog_name): parser.add_argument( "device", nargs="?", + default=None, type=str, help="Optional device name to filter by (same as sonic sync parameter)", ) @@ -1077,44 +1077,13 @@ def take_action(self, parsed_args): device_name = parsed_args.device try: - devices = [] - - if device_name: - # When specific device is requested, fetch it directly - try: - device = utils.nb.dcim.devices.get(name=device_name) - if device: - # Check if device role matches allowed roles - if device.role and device.role.slug in DEFAULT_SONIC_ROLES: - devices.append(device) - logger.debug( - f"Found device: {device.name} with role: {device.role.slug}" - ) - else: - logger.warning( - f"Device {device_name} has role '{device.role.slug if device.role else 'None'}' " - f"which is not in allowed SONiC roles: {', '.join(DEFAULT_SONIC_ROLES)}" - ) - return 1 - else: - logger.error(f"Device {device_name} not found in NetBox") - return 1 - except Exception as e: - logger.error(f"Error fetching device {device_name}: {e}") - return 1 - else: - # Get device query list from NETBOX_FILTER_CONDUCTOR_SONIC - nb_device_query_list = get_nb_device_query_list_sonic() - - for nb_device_query in nb_device_query_list: - # Query devices with the NETBOX_FILTER_CONDUCTOR_SONIC criteria - for device in utils.nb.dcim.devices.filter(**nb_device_query): - # Check if device role matches allowed roles - if device.role and device.role.slug in DEFAULT_SONIC_ROLES: - devices.append(device) - logger.debug( - f"Found device: {device.name} with role: {device.role.slug}" - ) + task = conductor.get_sonic_devices.delay(device_name=device_name) + devices = task.wait() + if isinstance(devices, type(None)): + logger.error( + "Error listing SONiC devices. Check the conductor log for details" + ) + return 1 logger.info(f"Found {len(devices)} devices matching criteria") diff --git a/osism/tasks/conductor/__init__.py b/osism/tasks/conductor/__init__.py index 94897d4d..8542a445 100644 --- a/osism/tasks/conductor/__init__.py +++ b/osism/tasks/conductor/__init__.py @@ -10,6 +10,7 @@ from osism.tasks.conductor.ironic import sync_ironic as _sync_ironic from osism.tasks.conductor.redfish import get_resources as _get_redfish_resources from osism.tasks.conductor.sonic import sync_sonic as _sync_sonic +from osism.tasks.conductor.sonic import get_devices as _get_sonic_devices # App configuration @@ -69,10 +70,16 @@ def get_redfish_resources(self, hostname, resource_type): return _get_redfish_resources(hostname, resource_type) +@app.task(bind=True, name="osism.tasks.conductor.get_sonic_devices") +def get_sonic_devices(self, device_name=None): + return _get_sonic_devices(device_name) + + __all__ = [ "app", "get_ironic_parameters", "get_redfish_resources", + "get_sonic_devices", "sync_netbox", "sync_ironic", "sync_sonic", diff --git a/osism/tasks/conductor/sonic/__init__.py b/osism/tasks/conductor/sonic/__init__.py index 3bb23cea..97a10b7d 100644 --- a/osism/tasks/conductor/sonic/__init__.py +++ b/osism/tasks/conductor/sonic/__init__.py @@ -5,6 +5,7 @@ from .config_generator import generate_sonic_config from .exporter import save_config_to_netbox, export_config_to_file from .sync import sync_sonic +from .device import get_devices from .connections import ( get_connected_interfaces, get_connected_device_for_sonic_interface, @@ -23,4 +24,5 @@ "get_connected_device_via_interface", "find_interconnected_devices", "get_device_bgp_neighbors_via_loopback", + "get_devices", ] diff --git a/osism/tasks/conductor/sonic/device.py b/osism/tasks/conductor/sonic/device.py index 03020e07..d092ce79 100644 --- a/osism/tasks/conductor/sonic/device.py +++ b/osism/tasks/conductor/sonic/device.py @@ -5,6 +5,8 @@ from loguru import logger from osism import utils +from osism.tasks.conductor.netbox import get_nb_device_query_list_sonic +from osism.tasks.conductor.sonic.constants import DEFAULT_SONIC_ROLES def get_device_platform(device, hwsku): @@ -80,3 +82,51 @@ def get_device_mac_address(device): logger.warning(f"Could not get MAC address for device {device.name}: {e}") return mac_address + + +def get_devices(self, device_name=None): + try: + devices = [] + + if device_name: + # When specific device is requested, fetch it directly + try: + device = utils.nb.dcim.devices.get(name=device_name) + if device: + # Check if device role matches allowed roles + if device.role and device.role.slug in DEFAULT_SONIC_ROLES: + devices.append(device) + logger.debug( + f"Found device: {device.name} with role: {device.role.slug}" + ) + else: + logger.warning( + f"Device {device_name} has role '{device.role.slug if device.role else 'None'}' " + f"which is not in allowed SONiC roles: {', '.join(DEFAULT_SONIC_ROLES)}" + ) + return 1 + else: + logger.error(f"Device {device_name} not found in NetBox") + return 1 + except Exception as e: + logger.error(f"Error fetching device {device_name}: {e}") + return 1 + else: + # Get device query list from NETBOX_FILTER_CONDUCTOR_SONIC + nb_device_query_list = get_nb_device_query_list_sonic() + + for nb_device_query in nb_device_query_list: + # Query devices with the NETBOX_FILTER_CONDUCTOR_SONIC criteria + for device in utils.nb.dcim.devices.filter(**nb_device_query): + # Check if device role matches allowed roles + if device.role and device.role.slug in DEFAULT_SONIC_ROLES: + devices.append(device) + logger.debug( + f"Found device: {device.name} with role: {device.role.slug}" + ) + + except Exception as e: + logger.error(f"Error retrieving SONiC devices from NetBox: {e}") + return None + + return devices