Merge "Fix FloatingIP Namespace creation in DVR for Late Binding"

This commit is contained in:
Jenkins 2015-06-26 17:33:09 +00:00 committed by Gerrit Code Review
commit 210d4e5bbf
3 changed files with 99 additions and 0 deletions

View File

@ -417,6 +417,17 @@ class DvrLocalRouter(router.RouterInfo):
is_first = False
if floating_ips:
is_first = self.fip_ns.subscribe(self.router_id)
if is_first and not fip_agent_port:
LOG.debug("No FloatingIP agent gateway port possibly due to "
"late binding of the private port to the host, "
"requesting agent gateway port for 'network-id' :"
"%s", ex_gw_port['network_id'])
fip_agent_port = self.agent.plugin_rpc.get_agent_gateway_port(
self.agent.context, ex_gw_port['network_id'])
if not fip_agent_port:
LOG.error(_LE("No FloatingIP agent gateway port "
"returned from server for 'network-id': "
"%s"), ex_gw_port['network_id'])
if is_first and fip_agent_port:
if 'subnets' not in fip_agent_port:
LOG.error(_LE('Missing subnet/agent_gateway_port'))

View File

@ -1265,3 +1265,47 @@ class TestDvrRouter(L3AgentTestFramework):
router.router_id, router.fip_ns.get_int_device_name,
router.fip_ns.get_name())
self.assertEqual(expected_mtu, dev_mtu)
def test_dvr_router_fip_agent_mismatch(self):
"""Test to validate the floatingip agent mismatch.
This test validates the condition where floatingip agent
gateway port host mismatches with the agent and so the
binding will not be there.
"""
self.agent.conf.agent_mode = 'dvr'
router_info = self.generate_dvr_router_info()
floating_ip = router_info['_floatingips'][0]
floating_ip['host'] = 'my_new_host'
# In this case the floatingip binding is different and so it
# should not create the floatingip namespace on the given agent.
# This is also like there is no current binding.
router1 = self.manage_router(self.agent, router_info)
fip_ns = router1.fip_ns.get_name()
self.assertTrue(self._namespace_exists(router1.ns_name))
self.assertFalse(self._namespace_exists(fip_ns))
self._assert_snat_namespace_does_not_exist(router1)
def test_dvr_router_fip_late_binding(self):
"""Test to validate the floatingip migration or latebinding.
This test validates the condition where floatingip private
port changes while migration or when the private port host
binding is done later after floatingip association.
"""
self.agent.conf.agent_mode = 'dvr'
router_info = self.generate_dvr_router_info()
fip_agent_gw_port = router_info[l3_constants.FLOATINGIP_AGENT_INTF_KEY]
# Now let us not pass the FLOATINGIP_AGENT_INTF_KEY, to emulate
# that the server did not create the port, since there was no valid
# host binding.
router_info[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = []
self.mock_plugin_api.get_agent_gateway_port.return_value = (
fip_agent_gw_port[0])
router1 = self.manage_router(self.agent, router_info)
fip_ns = router1.fip_ns.get_name()
self.assertTrue(self._namespace_exists(router1.ns_name))
self.assertTrue(self._namespace_exists(fip_ns))
self._assert_snat_namespace_does_not_exist(router1)

View File

@ -841,6 +841,50 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
ri.add_floating_ip.assert_called_once_with(
floating_ips[0], mock.sentinel.interface_name, device)
@mock.patch.object(lla.LinkLocalAllocator, '_write')
def test_create_dvr_fip_interfaces_for_late_binding(self, lla_write):
fake_network_id = _uuid()
fake_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(),
'host': HOSTNAME}]}
agent_gateway_port = (
{'fixed_ips': [
{'ip_address': '20.0.0.30',
'prefixlen': 24,
'subnet_id': fake_subnet_id}],
'subnets': [
{'id': fake_subnet_id,
'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[l3_constants.FLOATINGIP_KEY] = fake_floatingips['floatingips']
router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = []
router['distributed'] = True
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
ri = dvr_router.DvrEdgeRouter(
agent, HOSTNAME, router['id'], router, **self.ri_kwargs)
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 mock.patch.object(agent.plugin_rpc,
'get_agent_gateway_port') as fip_gw_port:
fip_gw_port.return_value = agent_gateway_port
ri.create_dvr_fip_interfaces(ext_gw_port)
self.assertTrue(fip_gw_port.called)
self.assertEqual(agent_gateway_port,
ri.fip_ns.agent_gateway_port)
@mock.patch.object(lla.LinkLocalAllocator, '_write')
def test_create_dvr_fip_interfaces(self, lla_write):
fake_network_id = _uuid()