self.rpc_loop.start(interval=RPC_LOOP_INTERVAL)
super(L3NATAgent, self).__init__(conf=self.conf)
+ self.target_ex_net_id = None
+
def _check_config_params(self):
"""Check items in configuration files.
ip_wrapper = ip_wrapper_root.ensure_namespace(ri.ns_name())
ip_wrapper.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
- def _fetch_external_net_id(self):
+ def _fetch_external_net_id(self, force=False):
"""Find UUID of single external network for this agent."""
if self.conf.gateway_external_network_id:
return self.conf.gateway_external_network_id
if not self.conf.external_network_bridge:
return
+ if not force and self.target_ex_net_id:
+ return self.target_ex_net_id
+
try:
- return self.plugin_rpc.get_external_network_id(self.context)
+ self.target_ex_net_id = self.plugin_rpc.get_external_network_id(
+ self.context)
+ return self.target_ex_net_id
except rpc_common.RemoteError as e:
with excutils.save_and_reraise_exception():
if e.exc_type == 'TooManyExternalNetworks':
continue
if (target_ex_net_id and ex_net_id and
ex_net_id != target_ex_net_id):
- continue
+ # Double check that our single external_net_id has not changed
+ # by forcing a check by RPC.
+ if (ex_net_id != self._fetch_external_net_id(force=True)):
+ continue
cur_router_ids.add(r['id'])
if r['id'] not in self.router_info:
self._router_added(r['id'], r)
agent._process_routers(routers)
self.assertIn(routers[0]['id'], agent.router_info)
+ self.plugin_api.get_external_network_id.assert_called_with(
+ agent.context)
+
+ def test_process_routers_with_cached_ext_net(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+ self.plugin_api.get_external_network_id.return_value = 'aaa'
+ agent.target_ex_net_id = 'aaa'
+
+ routers = [
+ {'id': _uuid(),
+ 'routes': [],
+ 'admin_state_up': True,
+ 'external_gateway_info': {'network_id': 'aaa'}}]
+
+ agent._process_routers(routers)
+ self.assertIn(routers[0]['id'], agent.router_info)
+ self.assertFalse(self.plugin_api.get_external_network_id.called)
+
+ def test_process_routers_with_stale_cached_ext_net(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+ self.plugin_api.get_external_network_id.return_value = 'aaa'
+ agent.target_ex_net_id = 'bbb'
+
+ routers = [
+ {'id': _uuid(),
+ 'routes': [],
+ 'admin_state_up': True,
+ 'external_gateway_info': {'network_id': 'aaa'}}]
+
+ agent._process_routers(routers)
+ self.assertIn(routers[0]['id'], agent.router_info)
+ self.plugin_api.get_external_network_id.assert_called_with(
+ agent.context)
def test_process_routers_with_no_ext_net_in_conf_and_two_net_plugin(self):
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)