From ce2866a4f6c6ee06e835f19394c1dd02ef83cff5 Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Fri, 5 Jun 2020 09:52:48 +0200 Subject: [PATCH] [OVN] Allow use of ovn-sync mechanism driver The ``neutron-ovn-db-sync-util`` replaces the ``ovn`` mechanism driver with the ``ovn-sync`` mechanism driver. Subsequently it makes calls into the OVN L3 service plugin. At present the OVN L3 service plugin assumes the ``ovn`` mechanism driver to be present and produces a Traceback when it is not. This patch fixes that by testing for both of the supported mechanism drivers. Change-Id: I1ac685a12f49119f5ef1428cbc504b639d783803 Closes-Bug: #1882202 Signed-off-by: Frode Nordahl (cherry picked from commit 206ce246768d6fb04b6bd92e189188f6702c74a7) --- neutron/services/ovn_l3/exceptions.py | 21 +++++++++++++++++++ neutron/services/ovn_l3/plugin.py | 14 ++++++++++++- .../tests/unit/services/ovn_l3/test_plugin.py | 17 +++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 neutron/services/ovn_l3/exceptions.py diff --git a/neutron/services/ovn_l3/exceptions.py b/neutron/services/ovn_l3/exceptions.py new file mode 100644 index 00000000000..72196785fb8 --- /dev/null +++ b/neutron/services/ovn_l3/exceptions.py @@ -0,0 +1,21 @@ +# Copyright 2020 Canonical Ltd. +# +# 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 neutron._i18n import _ +from neutron_lib import exceptions as n_exc + + +class MechanismDriverNotFound(n_exc.NotFound): + message = _("None of the supported mechanism drivers found: " + "%(mechanism_drivers)s. Check your configuration.") diff --git a/neutron/services/ovn_l3/plugin.py b/neutron/services/ovn_l3/plugin.py index dfa39a0b62b..e11462eda56 100644 --- a/neutron/services/ovn_l3/plugin.py +++ b/neutron/services/ovn_l3/plugin.py @@ -40,6 +40,8 @@ from neutron.db import ovn_revision_numbers_db as db_rev from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_client from neutron.scheduler import l3_ovn_scheduler +from neutron.services.ovn_l3 import exceptions as ovn_l3_exc + LOG = log.getLogger(__name__) @@ -105,7 +107,17 @@ class OVNL3RouterPlugin(service_base.ServicePluginBase, @property def _plugin_driver(self): if self._mech is None: - self._mech = self._plugin.mechanism_manager.mech_drivers['ovn'].obj + drivers = ('ovn', 'ovn-sync') + for driver in drivers: + try: + self._mech = self._plugin.mechanism_manager.mech_drivers[ + driver].obj + break + except KeyError: + pass + else: + raise ovn_l3_exc.MechanismDriverNotFound( + mechanism_drivers=drivers) return self._mech def get_plugin_type(self): diff --git a/neutron/tests/unit/services/ovn_l3/test_plugin.py b/neutron/tests/unit/services/ovn_l3/test_plugin.py index c9aa8f3c445..ebbcbe2b63a 100644 --- a/neutron/tests/unit/services/ovn_l3/test_plugin.py +++ b/neutron/tests/unit/services/ovn_l3/test_plugin.py @@ -284,6 +284,23 @@ class TestOVNL3RouterPlugin(test_mech_driver.Ml2PluginV2TestCase): return_value=False) self.mock_is_lb_member_fip.start() + def test__plugin_driver(self): + # No valid mech drivers should raise an exception. + self._mechanism_drivers = None + self.l3_inst._plugin.mechanism_manager.mech_drivers = {} + self.l3_inst._mech = None + self.assertRaises(n_exc.NotFound, lambda: self.l3_inst._plugin_driver) + # Populate the mechanism driver map with keys the code under test looks + # for and validate it finds them. + fake_mech_driver = mock.MagicMock() + for driver in ('ovn', 'ovn-sync'): + self.l3_inst._plugin.mechanism_manager.mech_drivers[ + driver] = fake_mech_driver + result = self.l3_inst._plugin_driver + self.l3_inst._plugin.mechanism_manager.mech_drivers.pop( + driver, None) + self.assertEqual(fake_mech_driver.obj, result) + @mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin.add_router_interface') def test_add_router_interface(self, func): router_id = 'router-id'