Verify ML2 type driver exists before calling del

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
This commit is contained in:
Kevin Benton 2014-04-06 04:57:36 -07:00 committed by Gerrit Code Review
parent 405fa193ce
commit af89d74d29
2 changed files with 22 additions and 0 deletions

View 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)

View 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',