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)