diff options
Diffstat (limited to 'networking_sfc/services/sfc/driver_manager.py')
-rw-r--r-- | networking_sfc/services/sfc/driver_manager.py | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/networking_sfc/services/sfc/driver_manager.py b/networking_sfc/services/sfc/driver_manager.py new file mode 100644 index 0000000..c8a212a --- /dev/null +++ b/networking_sfc/services/sfc/driver_manager.py @@ -0,0 +1,118 @@ +# Copyright 2015 Futurewei. All rights reserved. +# +# 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. + +from oslo_config import cfg +from oslo_log import log +import stevedore + +from neutron.i18n import _LE +from neutron.i18n import _LI + +from networking_sfc.services.sfc.common import exceptions as sfc_exc + + +LOG = log.getLogger(__name__) +cfg.CONF.import_opt('drivers', + 'networking_sfc.services.sfc.common.config', + group='sfc') + + +class SfcDriverManager(stevedore.named.NamedExtensionManager): + """Implementation of SFC drivers.""" + + def __init__(self): + # Registered sfc drivers, keyed by name. + self.drivers = {} + # Ordered list of sfc drivers, defining + # the order in which the drivers are called. + self.ordered_drivers = [] + LOG.info(_LI("Configured SFC drivers: %s"), + cfg.CONF.sfc.drivers) + super(SfcDriverManager, self).__init__('networking_sfc.sfc.drivers', + cfg.CONF.sfc.drivers, + invoke_on_load=True, + name_order=True) + LOG.info(_LI("Loaded SFC drivers: %s"), self.names()) + self._register_drivers() + + def _register_drivers(self): + """Register all SFC drivers. + + This method should only be called once in the SfcDriverManager + constructor. + """ + for ext in self: + self.drivers[ext.name] = ext + self.ordered_drivers.append(ext) + LOG.info(_LI("Registered SFC drivers: %s"), + [driver.name for driver in self.ordered_drivers]) + + def initialize(self): + # ServiceChain bulk operations requires each driver to support them + self.native_bulk_support = True + for driver in self.ordered_drivers: + LOG.info(_LI("Initializing SFC driver '%s'"), driver.name) + driver.obj.initialize() + self.native_bulk_support &= getattr(driver.obj, + 'native_bulk_support', True) + + def _call_drivers(self, method_name, context): + """Helper method for calling a method across all SFC drivers. + + :param method_name: name of the method to call + :param context: context parameter to pass to each method call + :param continue_on_failure: whether or not to continue to call + all SFC drivers once one has raised an exception + if any SFC driver call fails. + """ + for driver in self.ordered_drivers: + try: + getattr(driver.obj, method_name)(context) + except Exception as e: + # This is an internal failure. + LOG.exception(e) + LOG.error( + _LE("SFC driver '%(name)s' failed in %(method)s"), + {'name': driver.name, 'method': method_name} + ) + raise sfc_exc.SfcDriverError( + method=method_name + ) + + def create_port_chain(self, context): + self._call_drivers("create_port_chain", context) + + def update_port_chain(self, context): + self._call_drivers("update_port_chain", context) + + def delete_port_chain(self, context): + self._call_drivers("delete_port_chain", context) + + def create_port_pair(self, context): + self._call_drivers("create_port_pair", context) + + def update_port_pair(self, context): + self._call_drivers("update_port_pair", context) + + def delete_port_pair(self, context): + self._call_drivers("delete_port_pair", context) + + def create_port_pair_group(self, context): + self._call_drivers("create_port_pair_group", context) + + def update_port_pair_group(self, context): + self._call_drivers("update_port_pair_group", context) + + def delete_port_pair_group(self, context): + self._call_drivers("delete_port_pair_group", context) |