From 74b0c53da5d7e4305606c100becf34966d8af350 Mon Sep 17 00:00:00 2001 From: Oleg Bondarev Date: Thu, 11 Jun 2015 13:38:55 +0300 Subject: [PATCH] Fix l3 agent to not create already deleted router In case router is deleted during l3 agent resync, the "deleted" event is processed with higher priority, then resync event for the router may be processed which will recreate already deleted router. This happens due to timestamp not being properly updated for deleted router in router processor. The fix adds timestamp update for deleted router. Functional test will be updated in a follow-up patch Logging was improved to make debugging a bit easier. Closes-Bug: #1455439 Change-Id: I2d060064acccc10591a3d90be9011f116548cfce --- neutron/agent/l3/agent.py | 9 ++++++++- neutron/tests/unit/agent/l3/test_agent.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/neutron/agent/l3/agent.py b/neutron/agent/l3/agent.py index 6b25b9310..d9e4db8de 100644 --- a/neutron/agent/l3/agent.py +++ b/neutron/agent/l3/agent.py @@ -441,7 +441,8 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, def _process_router_update(self): for rp, update in self._queue.each_update_to_next_router(): - LOG.debug("Starting router update for %s", update.id) + LOG.debug("Starting router update for %s, action %s, priority %s", + update.id, update.action, update.priority) router = update.router if update.action != queue.DELETE_ROUTER and not router: try: @@ -464,6 +465,12 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, # one router by sticking the update at the end of the queue # at a lower priority. self.fullsync = True + else: + # need to update timestamp of removed router in case + # there are older events for the same router in the + # processing queue (like events from fullsync) in order to + # prevent deleted router re-creation + rp.fetched_and_processed(update.timestamp) continue try: diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py index 143c659dd..d10c30d8c 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -2090,6 +2090,23 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): agent._process_router_update() self.assertTrue(agent.fullsync) + def test_process_routers_update_router_deleted(self): + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + agent._queue = mock.Mock() + update = mock.Mock() + update.router = None + update.action = 1 # ROUTER_DELETED + router_info = mock.MagicMock() + agent.router_info[update.id] = router_info + router_processor = mock.Mock() + agent._queue.each_update_to_next_router.side_effect = [ + [(router_processor, update)]] + agent._process_router_update() + router_info.delete.assert_called_once_with(agent) + self.assertFalse(agent.router_info) + router_processor.fetched_and_processed.assert_called_once_with( + update.timestamp) + def test_process_router_if_compatible_with_no_ext_net_in_conf(self): agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) self.plugin_api.get_external_network_id.return_value = 'aaa' -- 2.45.2