From 3658c7155673077d712cd18fb99aa381bea9e843 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. 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 7b049d34bc9..5f27c417be1 100644 --- a/neutron/agent/l3/ha.py +++ b/neutron/agent/l3/ha.py @@ -150,7 +150,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 b1cb22c5115..88a653cb3b2 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -230,6 +230,45 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): agent.context, {'router_id': router.id, 'state': 'master'}) + 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)