DVR: Fix agent to process only floatingips that have a host match
The agent is not currently checking for the host bound
before configuring the floatingip. That leads to
floatingips being configured on multiple hosts.
This is a partial fix on the agent side to prevent
configuring a floatingip ip that is not bound to
this host.
Related-Bug: #1712412
Related-Bug: #1713927
Change-Id: I1bc8c42425f97234f56412a2f109a996d9f896de
(cherry picked from commit afd1995d91
)
This commit is contained in:
parent
93d2e76391
commit
2e6654067a
|
@ -100,6 +100,16 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
if floating_ip_status == lib_constants.FLOATINGIP_STATUS_ACTIVE:
|
||||
self.centralized_floatingips_set.add(fip_cidr)
|
||||
return floating_ip_status
|
||||
if not self._check_if_floatingip_bound_to_host(fip):
|
||||
# TODO(Swami): Need to figure out what status
|
||||
# should be returned when the floating IP is
|
||||
# not destined for this agent and if the floating
|
||||
# IP is configured in a different compute host.
|
||||
# This should not happen once we fix the server
|
||||
# side code, but still a check to make sure if
|
||||
# the floating IP is intended for this host should
|
||||
# be done.
|
||||
return
|
||||
floating_ip = fip['floating_ip_address']
|
||||
fixed_ip = fip['fixed_ip_address']
|
||||
self._add_floating_ip_rule(floating_ip, fixed_ip)
|
||||
|
@ -440,9 +450,6 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
pass
|
||||
|
||||
def get_external_device_interface_name(self, ex_gw_port):
|
||||
floating_ips = self.get_floating_ips()
|
||||
if not self._get_floatingips_bound_to_host(floating_ips):
|
||||
return self.get_snat_external_device_interface_name(ex_gw_port)
|
||||
fip_int = self.fip_ns.get_int_device_name(self.router_id)
|
||||
if ip_lib.device_exists(fip_int, namespace=self.fip_ns.get_name()):
|
||||
return self.fip_ns.get_rtr_ext_device_name(self.router_id)
|
||||
|
@ -544,10 +551,9 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
ext_scope_mark)
|
||||
return ports_scopemark
|
||||
|
||||
def _get_floatingips_bound_to_host(self, floating_ips):
|
||||
"""Filter Floating IPs to be hosted on this agent."""
|
||||
return [fip for fip in floating_ips
|
||||
if self.host in (fip.get('host'), fip.get('dest_host'))]
|
||||
def _check_if_floatingip_bound_to_host(self, fip):
|
||||
"""Check if the floating IP is bound to this host."""
|
||||
return self.host in (fip.get('host'), fip.get('dest_host'))
|
||||
|
||||
def process_external(self):
|
||||
if self.agent_conf.agent_mode != (
|
||||
|
|
|
@ -1191,8 +1191,6 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
fip_gw_port.return_value = agent_gateway_port[0]
|
||||
ri.create_dvr_external_gateway_on_agent(ext_gw_port)
|
||||
ri.connect_rtr_2_fip()
|
||||
ri._get_floatingips_bound_to_host = mock.Mock(
|
||||
return_value=True)
|
||||
self.assertTrue(fip_gw_port.called)
|
||||
self.assertTrue(create_fip.called)
|
||||
self.assertEqual(agent_gateway_port[0],
|
||||
|
@ -1211,6 +1209,64 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
create_fip.assert_called_once_with()
|
||||
self.assertEqual(1, ri.fip_ns.create_rtr_2_fip_link.call_count)
|
||||
|
||||
@mock.patch.object(lla.LinkLocalAllocator, '_write')
|
||||
def test_floating_ip_not_configured_if_no_host_or_dest_host(
|
||||
self, lla_write):
|
||||
fake_network_id = _uuid()
|
||||
subnet_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()}]}
|
||||
agent_gateway_port = (
|
||||
[{'fixed_ips': [
|
||||
{'ip_address': '20.0.0.30',
|
||||
'prefixlen': 24,
|
||||
'subnet_id': subnet_id}],
|
||||
'subnets': [
|
||||
{'id': subnet_id,
|
||||
'cidr': '20.0.0.0/24',
|
||||
'gateway_ip': '20.0.0.1'}],
|
||||
'id': _uuid(),
|
||||
'network_id': fake_network_id,
|
||||
'mac_address': 'ca:fe:de:ad:be:ef'}]
|
||||
)
|
||||
|
||||
router = l3_test_common.prepare_router_data(enable_snat=True)
|
||||
router[lib_constants.FLOATINGIP_KEY] = fake_floatingips['floatingips']
|
||||
router[n_const.FLOATINGIP_AGENT_INTF_KEY] = agent_gateway_port
|
||||
router['distributed'] = True
|
||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||
self._set_ri_kwargs(agent, router['id'], router)
|
||||
ri = dvr_router.DvrEdgeRouter(HOSTNAME, **self.ri_kwargs)
|
||||
ext_gw_port = ri.router.get('gw_port')
|
||||
ri.fip_ns = agent.get_fip_ns(ext_gw_port['network_id'])
|
||||
agent.process_router_add = mock.Mock()
|
||||
ri.fip_ns.create_rtr_2_fip_link = mock.Mock()
|
||||
with mock.patch.object(ri, 'get_floating_ips') as fips, \
|
||||
mock.patch.object(ri, 'get_floating_agent_gw_interface'
|
||||
) as fip_gw_port, \
|
||||
mock.patch.object(ri,
|
||||
'_add_floating_ip_rule') as add_rule, \
|
||||
mock.patch.object(ri.fip_ns,
|
||||
'create') as create_fip:
|
||||
fips.return_value = fake_floatingips
|
||||
fip_gw_port.return_value = agent_gateway_port[0]
|
||||
ri.create_dvr_external_gateway_on_agent(ext_gw_port)
|
||||
ri.connect_rtr_2_fip()
|
||||
self.assertTrue(fip_gw_port.called)
|
||||
self.assertTrue(create_fip.called)
|
||||
self.assertEqual(agent_gateway_port[0],
|
||||
ri.fip_ns.agent_gateway_port)
|
||||
self.assertTrue(ri.rtr_fip_connect)
|
||||
# Now let us associate the fip to the router
|
||||
status = ri.floating_ip_added_dist(fips, "192.168.0.1/32")
|
||||
self.assertIsNone(status)
|
||||
self.assertEqual(0, self.send_adv_notif.call_count)
|
||||
self.assertFalse(add_rule.called)
|
||||
|
||||
@mock.patch.object(lla.LinkLocalAllocator, '_write')
|
||||
def test_floating_ip_centralized(self, lla_write):
|
||||
fake_network_id = _uuid()
|
||||
|
@ -1370,8 +1426,6 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
fip_gw_port.return_value = agent_gateway_port[0]
|
||||
ri.create_dvr_external_gateway_on_agent(ext_gw_port)
|
||||
ri.connect_rtr_2_fip()
|
||||
ri._get_floatingips_bound_to_host = mock.Mock(
|
||||
return_value=True)
|
||||
self.assertTrue(fip_gw_port.called)
|
||||
self.assertEqual(agent_gateway_port[0],
|
||||
ri.fip_ns.agent_gateway_port)
|
||||
|
@ -1421,8 +1475,6 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
fip_gw_port.return_value = agent_gateway_port[0]
|
||||
ri.create_dvr_external_gateway_on_agent(ext_gw_port)
|
||||
ri.connect_rtr_2_fip()
|
||||
ri._get_floatingips_bound_to_host = mock.Mock(
|
||||
return_value=True)
|
||||
self.assertTrue(fip_gw_port.called)
|
||||
self.assertEqual(agent_gateway_port[0],
|
||||
ri.fip_ns.agent_gateway_port)
|
||||
|
|
|
@ -179,7 +179,6 @@ class TestDvrRouterOperations(base.BaseTestCase):
|
|||
ri.rtr_fip_connect = True
|
||||
ex_gw_port = {'network_id': 'fake_net_id'}
|
||||
ri.create_dvr_external_gateway_on_agent(ex_gw_port)
|
||||
ri._get_floatingips_bound_to_host = mock.Mock(return_value=True)
|
||||
ri.fip_ns.create_or_update_gateway_port.assert_called_once_with(
|
||||
fip_agent_port)
|
||||
|
||||
|
|
Loading…
Reference in New Issue