Merge "Check for provisioning blocks before updating port up"

This commit is contained in:
Jenkins 2016-07-12 01:12:35 +00:00 committed by Gerrit Code Review
commit c3ee77b787
4 changed files with 49 additions and 0 deletions

View File

@ -152,6 +152,22 @@ def provisioning_complete(context, object_id, object_type, entity):
context=context, object_id=object_id)
def is_object_blocked(context, object_id, object_type):
"""Return boolean indicating if object has a provisioning block.
:param context: neutron api request context
:param object_id: ID of object that has been provisioned
:param object_type: callback resource type of the object
"""
standard_attr_id = _get_standard_attr_id(context, object_id,
object_type)
if not standard_attr_id:
# object doesn't exist so it has no blocks
return False
return bool(context.session.query(ProvisioningBlock).filter_by(
standard_attr_id=standard_attr_id).count())
def _get_standard_attr_id(context, object_id, object_type):
model = _RESOURCE_TO_MODEL_MAP.get(object_type)
if not model:

View File

@ -215,6 +215,16 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
LOG.debug("Port %s cannot update to ACTIVE because it "
"is not bound.", port_id)
return
else:
# port is bound, but we have to check for new provisioning blocks
# one last time to detect the case where we were triggered by an
# unbound port and the port became bound with new provisioning
# blocks before 'get_port' was called above
if provisioning_blocks.is_object_blocked(context, port_id,
resources.PORT):
LOG.debug("Port %s had new provisioning blocks added so it "
"will not transition to active.", port_id)
return
self.update_port_status(context, port_id, const.PORT_STATUS_ACTIVE)
@property

View File

@ -94,6 +94,18 @@ class TestStatusBarriers(testlib_api.SqlTestCase):
resources.PORT, 'entity2')
self.assertFalse(self.provisioned.called)
def test_is_object_blocked(self):
pb.add_provisioning_component(self.ctx, self.port.id, resources.PORT,
'e1')
self.assertTrue(pb.is_object_blocked(self.ctx, self.port.id,
resources.PORT))
self.assertFalse(pb.is_object_blocked(self.ctx, 'xyz',
resources.PORT))
pb.provisioning_complete(self.ctx, self.port.id,
resources.PORT, 'e1')
self.assertFalse(pb.is_object_blocked(self.ctx, self.port.id,
resources.PORT))
def test_remove_provisioning_component(self):
pb.add_provisioning_component(self.ctx, self.port.id, resources.PORT,
'e1')

View File

@ -512,6 +512,17 @@ class TestMl2DbOperationBoundsTenant(TestMl2DbOperationBounds):
class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
def test__port_provisioned_with_blocks(self):
plugin = manager.NeutronManager.get_plugin()
ups = mock.patch.object(plugin, 'update_port_status').start()
with self.port() as port:
mock.patch('neutron.plugins.ml2.plugin.db.get_port').start()
provisioning_blocks.add_provisioning_component(
self.context, port['port']['id'], 'port', 'DHCP')
plugin._port_provisioned('port', 'evt', 'trigger',
self.context, port['port']['id'])
self.assertFalse(ups.called)
def test__port_provisioned_no_binding(self):
plugin = manager.NeutronManager.get_plugin()
with self.network() as net: