summaryrefslogtreecommitdiffstats
path: root/networking_sfc/services/sfc/driver_manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'networking_sfc/services/sfc/driver_manager.py')
-rw-r--r--networking_sfc/services/sfc/driver_manager.py118
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)