Get rid of rpc to fetch fip agent port on agent.

This patch is dependent on the plugin side patch
Change-Id: Ieaa79c8bf2b1e03bc352f9252ce22286703e3715
for retrieving the fip agent port from the
router_update message.

This would reduce the wait time substantially.

Change-Id: I47bc43bab4bff59d14e2cdbce9f8b47826d392d9
Related-Bug: #1415522
This commit is contained in:
Swaminathan Vasudevan 2015-02-06 15:59:06 -08:00 committed by Carl Baldwin
parent c80b13f59f
commit 707890ef22
3 changed files with 130 additions and 15 deletions

View File

@ -580,8 +580,10 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
ri, ex_gw_port)
fip_statuses = self._configure_fip_addresses(ri, interface_name)
except (n_exc.FloatingIpSetupException, n_exc.IpTablesApplyException):
except (n_exc.FloatingIpSetupException,
n_exc.IpTablesApplyException) as e:
# All floating IPs must be put in error state
LOG.exception(e)
fip_statuses = self._put_fips_in_error_state(ri)
self._update_fip_statuses(ri, existing_floating_ips, fip_statuses)
@ -665,17 +667,18 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
def create_dvr_fip_interfaces(self, ri, ex_gw_port):
floating_ips = self.get_floating_ips(ri)
fip_agent_port = self.get_floating_agent_gw_interface(
ri, ex_gw_port['network_id'])
LOG.debug("FloatingIP agent gateway port received from the plugin: "
"%s", fip_agent_port)
if floating_ips:
is_first = ri.fip_ns.subscribe(ri.router_id)
if is_first:
agent_gateway_port = (
self.plugin_rpc.get_agent_gateway_port(
self.context, ex_gw_port['network_id']))
if 'subnet' not in agent_gateway_port:
if is_first and fip_agent_port:
if 'subnet' not in fip_agent_port:
LOG.error(_LE('Missing subnet/agent_gateway_port'))
else:
self._set_subnet_info(agent_gateway_port)
ri.fip_ns.create_gateway_port(agent_gateway_port)
self._set_subnet_info(fip_agent_port)
ri.fip_ns.create_gateway_port(fip_agent_port)
if ri.fip_ns.agent_gateway_port and floating_ips:
if ri.dist_fip_count == 0:
@ -802,6 +805,12 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
floating_ips = [i for i in floating_ips if i['host'] == self.host]
return floating_ips
def get_floating_agent_gw_interface(self, ri, ext_net_id):
"""Filter Floating Agent GW port for the external network."""
fip_ports = ri.router.get(l3_constants.FLOATINGIP_AGENT_INTF_KEY, [])
return next(
(p for p in fip_ports if p['network_id'] == ext_net_id), None)
def external_gateway_added(self, ri, ex_gw_port, interface_name):
if ri.router['distributed']:
ip_wrapr = ip_lib.IPWrapper(self.root_helper, namespace=ri.ns_name)

View File

@ -638,12 +638,42 @@ class TestDvrRouter(L3AgentTestFramework):
floating_ip['port_id'] = internal_ports[0]['id']
floating_ip['status'] = 'ACTIVE'
if not enable_snat:
return router
self._add_snat_port_info_to_router(router, internal_ports)
# FIP has a dependency on external gateway. So we need to create
# the snat_port info and fip_agent_gw_port_info irrespective of
# the agent type the dvr supports. The namespace creation is
# dependent on the agent_type.
external_gw_port = router['gw_port']
self._add_fip_agent_gw_port_info_to_router(router, external_gw_port)
return router
def _add_fip_agent_gw_port_info_to_router(self, router, external_gw_port):
# Add fip agent gateway port information to the router_info
fip_gw_port_list = router.get(
l3_constants.FLOATINGIP_AGENT_INTF_KEY, [])
if not fip_gw_port_list and external_gw_port:
# Get values from external gateway port
fixed_ip = external_gw_port['fixed_ips'][0]
float_subnet = external_gw_port['subnet']
port_ip = fixed_ip['ip_address']
# Pick an ip address which is not the same as port_ip
fip_gw_port_ip = str(netaddr.IPAddress(port_ip) + 5)
# Add floatingip agent gateway port info to router
router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = [
{'subnet':
{'cidr': float_subnet['cidr'],
'gateway_ip': float_subnet['gateway_ip'],
'id': fixed_ip['subnet_id']},
'network_id': external_gw_port['network_id'],
'device_owner': 'network:floatingip_agent_gateway',
'mac_address': 'fa:16:3e:80:8d:89',
'binding:host_id': self.agent.conf.host,
'fixed_ips': [{'subnet_id': fixed_ip['subnet_id'],
'ip_address': fip_gw_port_ip}],
'id': _uuid(),
'device_id': _uuid()}
]
def _add_snat_port_info_to_router(self, router, internal_ports):
# Add snat port information to the router
snat_port_list = router.get(l3_constants.SNAT_ROUTER_INTF_KEY, [])
@ -731,14 +761,19 @@ class TestDvrRouter(L3AgentTestFramework):
# is created with the ip address of the external gateway port
floating_ips = router.router[l3_constants.FLOATINGIP_KEY]
self.assertTrue(floating_ips)
# We need to fetch the floatingip agent gateway port info
# from the router_info
floating_agent_gw_port = (
router.router[l3_constants.FLOATINGIP_AGENT_INTF_KEY])
self.assertTrue(floating_agent_gw_port)
external_port = self.agent._get_ex_gw_port(router)
external_gw_port = floating_agent_gw_port[0]
fip_ns = self.agent.get_fip_ns(floating_ips[0]['floating_network_id'])
fip_ns_name = fip_ns.get_name()
fg_port_created_succesfully = ip_lib.device_exists_with_ip_mac(
fip_ns.get_ext_device_name(external_port['id']),
external_port['ip_cidr'],
external_port['mac_address'],
fip_ns.get_ext_device_name(external_gw_port['id']),
external_gw_port['ip_cidr'],
external_gw_port['mac_address'],
fip_ns_name, self.root_helper)
self.assertTrue(fg_port_created_succesfully)
# Check fpr-router device has been created

View File

@ -883,6 +883,77 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
for chain, rule in rules:
nat.add_rule.assert_any_call(chain, rule, tag='floating_ip')
def test_get_floating_agent_gw_interfaces(self):
fake_network_id = _uuid()
agent_gateway_port = (
[{'fixed_ips': [{'ip_address': '20.0.0.30',
'subnet_id': _uuid()}],
'subnet': {'gateway_ip': '20.0.0.1'},
'id': _uuid(),
'binding:host_id': 'myhost',
'device_owner': 'network:floatingip_agent_gateway',
'network_id': fake_network_id,
'mac_address': 'ca:fe:de:ad:be:ef',
'ip_cidr': '20.0.0.30/24'}]
)
router = prepare_router_data(enable_snat=True)
router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = agent_gateway_port
router['distributed'] = True
ri = dvr_router.DvrRouter(router['id'], router, **self.ri_kwargs)
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
self.assertEqual(
agent_gateway_port[0],
agent.get_floating_agent_gw_interface(ri, fake_network_id))
def test_create_dvr_fip_interfaces(self):
fake_network_id = _uuid()
fake_floatingips = {'floatingips': [
{'id': _uuid(),
'floating_ip_address': '20.0.0.3',
'fixed_ip_address': '192.168.0.1',
'floating_network_id': _uuid(),
'port_id': _uuid(),
'host': HOSTNAME}]}
agent_gateway_port = (
[{'fixed_ips': [{'ip_address': '20.0.0.30',
'subnet_id': _uuid()}],
'subnet': {'gateway_ip': '20.0.0.1'},
'id': _uuid(),
'network_id': fake_network_id,
'mac_address': 'ca:fe:de:ad:be:ef',
'ip_cidr': '20.0.0.30/24'}]
)
router = prepare_router_data(enable_snat=True)
router[l3_constants.FLOATINGIP_KEY] = fake_floatingips['floatingips']
router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = agent_gateway_port
router['distributed'] = True
ri = dvr_router.DvrRouter(router['id'], router, **self.ri_kwargs)
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
ext_gw_port = ri.router.get('gw_port')
ri.fip_ns = agent.get_fip_ns(ext_gw_port['network_id'])
ri.dist_fip_count = 0
ri.fip_ns.subscribe = mock.Mock()
with contextlib.nested(mock.patch.object(agent,
'get_floating_ips'),
mock.patch.object(
agent, 'get_floating_agent_gw_interface'),
mock.patch.object(
agent, '_set_subnet_info')
) as (fips,
fip_gw_port,
sub_info):
fips.return_value = fake_floatingips
fip_gw_port.return_value = agent_gateway_port[0]
agent.create_dvr_fip_interfaces(ri, ext_gw_port)
self.assertTrue(fip_gw_port.called)
self.assertTrue(fips.called)
self.assertEqual(ri.fip_ns.agent_gateway_port,
agent_gateway_port[0])
def test_process_router_cent_floating_ip_add(self):
fake_floatingips = {'floatingips': [
{'id': _uuid(),