Move segment deletion back to PRECOMMIT_DELETE

This essentially reverts commit 12d24abba7.

Making the callback _delete_segments_for_network respond to
BEFORE_DELETE network event has created some bugs. In one of them,
it is not possible to delete a routed network, because the segments
cannot be deleted due to the fact that the associated subnets still
exist.

Making _delete_segments_for_network respond to PRECOMMIT_DELETE
introduces a StaleDataError with the standard attributes of the
deleted segments. To work around that, network_db is expired and
read again after notifying the PRECOMMIT_DELETE event in
delete_network in the DB core plug-in.

This also fixes an issue where we could delete the segment ID
of the l3-ha network when deleting a router, leaving all other
routers non-functioning.  Moving this to PRECOMMIT_DELETE fixes
it since it is done after we have checked that the network is
not in use and can be deleted.

Closes-Bug: #1697324
Closes-Bug: #1732543

Change-Id: I7c3c4654f183b317647a28d599a538fe460db68f
This commit is contained in:
Miguel Lavalle 2017-06-20 23:25:24 +00:00 committed by Brian Haley
parent f183196682
commit 9dff53ce65
3 changed files with 18 additions and 1 deletions

View File

@ -460,6 +460,11 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon,
network = self._make_network_dict(network_db, context=context)
registry.notify(resources.NETWORK, events.PRECOMMIT_DELETE,
self, context=context, network_id=id)
# We expire network_db here because precommit deletion
# might have left the relationship stale, for example,
# if we deleted a segment.
context.session.expire(network_db)
network_db = self._get_network(context, id)
context.session.delete(network_db)
registry.notify(resources.NETWORK, events.AFTER_DELETE,
self, context=context, network=network)

View File

@ -314,6 +314,6 @@ def subscribe():
resources.SEGMENT, events.PRECOMMIT_CREATE)
registry.subscribe(_delete_segments_for_network,
resources.NETWORK,
events.BEFORE_DELETE)
events.PRECOMMIT_DELETE)
subscribe()

View File

@ -365,6 +365,18 @@ class TestSegment(SegmentTestCase):
self._update('segments', segment['segment']['id'], segment,
expected_code=webob.exc.HTTPClientError.code)
def test_segment_notification_on_delete_network(self):
with mock.patch.object(db, '_delete_segments_for_network') as dsn:
db.subscribe()
with self.network() as network:
network = network['network']
self._delete('networks', network['id'])
dsn.assert_called_with(resources.NETWORK,
events.PRECOMMIT_DELETE,
mock.ANY,
context=mock.ANY,
network_id=mock.ANY)
class TestSegmentML2(SegmentTestCase):
def setUp(self):