From 8815e9e86755d2b253642949faec5de39e92f991 Mon Sep 17 00:00:00 2001 From: Quan Tian Date: Sun, 22 Jan 2017 16:49:24 +0800 Subject: [PATCH] Don't add duplicate metadata rules after router update For a HA router, when it's updated, the l3 agents which are standby always call the after_router_added method, then duplicate metadata rules are added to iptables table. Althrough these rules will not be applied to system because of the _weed_out_duplicates method, they will grow linearly with router update operations. Because these metadata rules are added once router is added to the agent and will not be cleaned until router is removed, calling the add_rule method in after_router_updated is a waste. This patch removes adding metadata rules in after_router_updated. Conflicts: neutron/tests/unit/agent/metadata/test_driver.py Change-Id: I6650f1071499ed6cabd936bb0fb36b32a4b60bca Closes-Bug: #1658460 --- neutron/agent/metadata/driver.py | 10 ++++++++-- .../tests/unit/agent/metadata/test_driver.py | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/neutron/agent/metadata/driver.py b/neutron/agent/metadata/driver.py index 92e4ba287be..71337254348 100644 --- a/neutron/agent/metadata/driver.py +++ b/neutron/agent/metadata/driver.py @@ -170,8 +170,14 @@ def after_router_added(resource, event, l3_agent, **kwargs): def after_router_updated(resource, event, l3_agent, **kwargs): router = kwargs['router'] proxy = l3_agent.metadata_driver - if not proxy.monitors.get(router.router_id): - after_router_added(resource, event, l3_agent, **kwargs) + if (not proxy.monitors.get(router.router_id) and + not isinstance(router, ha_router.HaRouter)): + proxy.spawn_monitored_metadata_proxy( + l3_agent.process_monitor, + router.ns_name, + proxy.metadata_port, + l3_agent.conf, + router_id=router.router_id) def before_router_removed(resource, event, l3_agent, **kwargs): diff --git a/neutron/tests/unit/agent/metadata/test_driver.py b/neutron/tests/unit/agent/metadata/test_driver.py index 35b951e4b5c..96993aa190a 100644 --- a/neutron/tests/unit/agent/metadata/test_driver.py +++ b/neutron/tests/unit/agent/metadata/test_driver.py @@ -20,6 +20,7 @@ from oslo_utils import uuidutils from neutron.agent.common import config as agent_config from neutron.agent.l3 import agent as l3_agent from neutron.agent.l3 import router_info +from neutron.agent.linux import iptables_manager from neutron.agent.metadata import driver as metadata_driver from neutron.common import constants from neutron.conf.agent.l3 import config as l3_config @@ -93,6 +94,24 @@ class TestMetadataDriverProcess(base.BaseTestCase): f.assert_called_once_with( 'router', 'after_update', agent, router=ri) + def test_after_router_updated_should_not_call_add_metadata_rules(self): + with mock.patch.object(iptables_manager.IptablesTable, + 'add_rule') as f,\ + mock.patch.object(iptables_manager.IptablesManager, + 'apply'),\ + mock.patch.object(metadata_driver.MetadataDriver, + 'spawn_monitored_metadata_proxy'),\ + mock.patch.object(router_info.RouterInfo, 'process'): + agent = l3_agent.L3NATAgent('localhost') + router_id = _uuid() + router = {'id': router_id} + ri = router_info.RouterInfo(mock.Mock(), router_id, router, + agent.conf, mock.ANY) + agent.router_info[router_id] = ri + f.reset_mock() + agent._process_updated_router(router) + f.assert_not_called() + def _test_spawn_metadata_proxy(self, expected_user, expected_group, user='', group='', watch_log=True): router_id = _uuid()