]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Verify ML2 type driver exists before calling del
authorKevin Benton <blak111@gmail.com>
Sun, 6 Apr 2014 11:57:36 +0000 (04:57 -0700)
committerGerrit Code Review <review@openstack.org>
Sun, 13 Apr 2014 09:21:28 +0000 (09:21 +0000)
Verifies that an ML2 type driver exists for a given
segment type before attempting to call the release_segment
method on it. Logs an error if a type driver is not
found.

This covers the case where a segment is created with
a given type and then ML2 is reconfigured without
support for that type.

DocImpact
The ML2 documentation should be updated with a warning
that disabling a network type driver and re-enabling
it later may lead to possible DB inconsistencies.

Closes-Bug: #1292102
Change-Id: I65a35abf3ed57347bb6e8fee228f8c0697217c00

neutron/plugins/ml2/managers.py
neutron/tests/unit/ml2/test_ml2_plugin.py

index 7421e4b0f66ee8b639b7a5cfd612aa069a5f905e..a5feb70408f7ded5e5d6f277f9a7b15115c5d66c 100644 (file)
@@ -98,6 +98,16 @@ class TypeManager(stevedore.named.NamedExtensionManager):
     def release_segment(self, session, segment):
         network_type = segment.get(api.NETWORK_TYPE)
         driver = self.drivers.get(network_type)
+        # ML2 may have been reconfigured since the segment was created,
+        # so a driver may no longer exist for this network_type.
+        # REVISIT: network_type-specific db entries may become orphaned
+        # if a network is deleted and the driver isn't available to release
+        # the segment. This may be fixed with explicit foreign-key references
+        # or consistency checks on driver initialization.
+        if not driver:
+            LOG.error(_("Failed to release segment '%s' because "
+                        "network type is not supported."), segment)
+            return
         driver.obj.release_segment(session, segment)
 
 
index 408c7ea5b9f9f7a5d5afeadb845b9392a9049e96..da878b4152bf9f4f8a77a5473084bbef86c8a395 100644 (file)
@@ -25,6 +25,7 @@ from neutron.extensions import providernet as pnet
 from neutron import manager
 from neutron.plugins.ml2.common import exceptions as ml2_exc
 from neutron.plugins.ml2 import config
+from neutron.plugins.ml2 import driver_api
 from neutron.plugins.ml2 import plugin as ml2_plugin
 from neutron.tests.unit import _test_extension_portbindings as test_bindings
 from neutron.tests.unit.ml2.drivers import mechanism_logger as mech_logger
@@ -289,6 +290,17 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
         res = network_req.get_response(self.api)
         self.assertEqual(res.status_int, 400)
 
+    def test_release_segment_no_type_driver(self):
+        segment = {driver_api.NETWORK_TYPE: 'faketype',
+                   driver_api.PHYSICAL_NETWORK: 'physnet1',
+                   driver_api.ID: 1}
+        with mock.patch('neutron.plugins.ml2.managers.LOG') as log:
+            self.driver.type_manager.release_segment(session=None,
+                                                     segment=segment)
+        log.error.assert_called_once_with(
+            "Failed to release segment '%s' because "
+            "network type is not supported.", segment)
+
     def test_create_provider_fail(self):
         segment = {pnet.NETWORK_TYPE: None,
                    pnet.PHYSICAL_NETWORK: 'phys_net',