Source code for ironic.networking.switch_drivers.driver_factory

#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""
Networking service driver factory for loading switch drivers.

This module provides a driver factory system for the networking service,
allowing dynamic loading of switch drivers from external projects via
entry points.
"""

import collections

from oslo_log import log

from ironic.common import driver_factory
from ironic.common import exception
from ironic.common.i18n import _
from ironic.conf import CONF

LOG = log.getLogger(__name__)


[docs] class BaseSwitchDriverFactory(driver_factory.BaseDriverFactory): """Base factory for discovering, loading and managing switch drivers. This factory loads switch drivers from entry points and manages their lifecycle. Switch drivers are loaded from external projects and provide vendor-specific implementations for network switch management. Inherits from common.BaseDriverFactory to ensure consistency with Ironic's standard driver factory pattern. """ # Entry point namespace for switch drivers _entrypoint_name = "ironic.networking.switch_drivers" # Configuration option containing enabled drivers list _enabled_driver_list_config_option = "enabled_switch_drivers" # Template for logging loaded drivers _logging_template = "Loaded the following switch drivers: %s" # Use two-phase initialization: load classes first, initialize later # This allows config preprocessing before driver initialization _invoke_on_load = False @classmethod def _set_enabled_drivers(cls): """Set the list of enabled drivers from configuration. Overrides the base implementation to read from the networking configuration group instead of the default group. """ enabled_drivers = getattr( CONF.ironic_networking, cls._enabled_driver_list_config_option, [] ) # Check for duplicated driver entries and warn about them counter = collections.Counter(enabled_drivers).items() duplicated_drivers = [] cls._enabled_driver_list = [] for item, cnt in counter: if not item: raise exception.ConfigInvalid( error_msg=_( 'An empty switch driver was specified in the "%s" ' 'configuration option. Please fix your ironic.conf ' 'file.') % cls._enabled_driver_list_config_option ) if cnt > 1: duplicated_drivers.append(item) cls._enabled_driver_list.append(item) if duplicated_drivers: raise exception.ConfigInvalid( error_msg=_( 'The switch driver(s) "%s" is/are duplicated in the ' 'list of enabled drivers. Please check your ' 'configuration file.') % ", ".join(duplicated_drivers) ) @classmethod def _init_extension_manager(cls): """Initialize the extension manager for loading switch drivers. Extends the base implementation to handle the case where no switch drivers are enabled. """ # Set enabled drivers first cls._set_enabled_drivers() # Only proceed if we have enabled drivers if not cls._enabled_driver_list: LOG.info("No switch drivers enabled in configuration") return # Call parent implementation try: super()._init_extension_manager() except RuntimeError as e: if "No suitable drivers found" in str(e): LOG.warning( "No switch drivers could be loaded. Check that " "the specified drivers are installed and their " "entry points are correctly defined." ) cls._extension_manager = None else: raise
def _warn_if_unsupported(ext): """Warn if a driver is marked as unsupported.""" if hasattr(ext.obj, "supported") and not ext.obj.supported: LOG.warning( 'Switch driver "%s" is UNSUPPORTED. It has been ' "deprecated and may be removed in a future release.", ext.name, )
[docs] class SwitchDriverFactory(BaseSwitchDriverFactory): """Factory for loading switch drivers from entry points.""" pass
# Global factory instance _switch_driver_factory = None
[docs] def get_switch_driver_factory(): """Get the global switch driver factory instance.""" global _switch_driver_factory if _switch_driver_factory is None: _switch_driver_factory = SwitchDriverFactory() return _switch_driver_factory
[docs] def get_switch_driver(driver_name): """Get a switch driver instance by name. :param driver_name: Name of the switch driver to retrieve. :returns: Instance of the switch driver. :raises: DriverNotFound if the driver is not found. """ factory = get_switch_driver_factory() return factory.get_driver(driver_name)
[docs] def list_switch_drivers(): """Get a list of all available switch driver names. :returns: List of switch driver names. """ factory = get_switch_driver_factory() return factory.names
[docs] def switch_drivers(): """Get all switch drivers as a dictionary. :returns: Dictionary mapping driver name to driver instance. """ factory = get_switch_driver_factory() return dict(factory.items())