From 5aa1c315fcd904bd66cd07980124d7213a960d26 Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Thu, 28 Feb 2019 11:35:07 +0100 Subject: [PATCH] Spawn metadata proxy on dvr ha standby routers In case when L3 agent is running in dvr_snat mode on compute node, it is like that e.g. in some of the gate jobs, it may happen that same router is scheduled to be in standby mode on compute node and on same compute node there is instance connected to it. So in such case metadata proxy needs to be spawned in router namespace even if it is in standby mode. Conflicts: neutron/tests/unit/agent/l3/test_agent.py Change-Id: Id646ab2c184c7a1d5ac38286a0162dd37d72df6e Closes-Bug: #1817956 Closes-Bug: #1606741 (cherry picked from commit 6ae228cc2e75504d9a8f35e3480a66707f9d7246) --- neutron/agent/l3/ha.py | 5 ++- neutron/tests/unit/agent/l3/test_agent.py | 39 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/neutron/agent/l3/ha.py b/neutron/agent/l3/ha.py index 795e271964e..a21c0921e89 100644 --- a/neutron/agent/l3/ha.py +++ b/neutron/agent/l3/ha.py @@ -149,7 +149,10 @@ class AgentMixin(object): interface_name, enable) def _update_metadata_proxy(self, ri, router_id, state): - if state == 'master': + # NOTE(slaweq): Since the metadata proxy is spawned in the qrouter + # namespace and not in the snat namespace, even standby DVR-HA + # routers needs to serve metadata requests to local ports. + if state == 'master' or ri.router.get('distributed', False): LOG.debug('Spawning metadata proxy for router %s', router_id) self.metadata_driver.spawn_monitored_metadata_proxy( self.process_monitor, ri.ns_name, self.conf.metadata_port, diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py index 6b9bdc24e24..fbdfac881e6 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -214,6 +214,45 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): agent.enqueue_state_change(router.id, 'master') self.assertFalse(agent._update_metadata_proxy.call_count) + def test_enqueue_state_change_router_active_ha(self): + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + router = {'distributed': False} + router_info = mock.MagicMock(router=router) + with mock.patch.object( + agent.metadata_driver, 'spawn_monitored_metadata_proxy' + ) as spawn_metadata_proxy, mock.patch.object( + agent.metadata_driver, 'destroy_monitored_metadata_proxy' + ) as destroy_metadata_proxy: + agent._update_metadata_proxy(router_info, "router_id", "master") + spawn_metadata_proxy.assert_called() + destroy_metadata_proxy.assert_not_called() + + def test_enqueue_state_change_router_standby_ha(self): + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + router = {'distributed': False} + router_info = mock.MagicMock(router=router) + with mock.patch.object( + agent.metadata_driver, 'spawn_monitored_metadata_proxy' + ) as spawn_metadata_proxy, mock.patch.object( + agent.metadata_driver, 'destroy_monitored_metadata_proxy' + ) as destroy_metadata_proxy: + agent._update_metadata_proxy(router_info, "router_id", "standby") + spawn_metadata_proxy.assert_not_called() + destroy_metadata_proxy.assert_called() + + def test_enqueue_state_change_router_standby_ha_dvr(self): + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + router = {'distributed': True} + router_info = mock.MagicMock(router=router) + with mock.patch.object( + agent.metadata_driver, 'spawn_monitored_metadata_proxy' + ) as spawn_metadata_proxy, mock.patch.object( + agent.metadata_driver, 'destroy_monitored_metadata_proxy' + ) as destroy_metadata_proxy: + agent._update_metadata_proxy(router_info, "router_id", "standby") + spawn_metadata_proxy.assert_called() + destroy_metadata_proxy.assert_not_called() + def _test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper( self, state, enable_expected): agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)