Refresh router objects after port binding

Post-binding information about router ports is missing in results of RPC
calls made by l3 agents. sync_routers code ensures that bindings are
present, however, it does not refresh router objects before returning
them - for RPC clients ports remain unbound before the next sync and
there is no necessary address scope information present to create routes
from fip namespaces to qrouter namespaces.

 Conflicts:
	neutron/api/rpc/handlers/l3_rpc.py

Change-Id: Ia135f0ed7ca99887d5208fa78fe4df1ff6412c26
Closes-Bug: #1759971
(cherry picked from commit ff5e8d7d6c)
This commit is contained in:
Dmitrii Shcherbakov 2018-04-01 21:02:10 -04:00 committed by Brian Haley
parent 01c67ac1cb
commit 29e0c7629f
2 changed files with 20 additions and 7 deletions

View File

@ -117,6 +117,15 @@ class L3RpcCallback(object):
router_ids = kwargs.get('router_ids')
host = kwargs.get('host')
context = neutron_context.get_admin_context()
routers = self._routers_to_sync(context, router_ids, host)
if utils.is_extension_supported(
self.plugin, constants.PORT_BINDING_EXT_ALIAS):
self._ensure_host_set_on_ports(context, host, routers)
# refresh the data structure after ports are bound
routers = self._routers_to_sync(context, router_ids, host)
return routers
def _routers_to_sync(self, context, router_ids, host=None):
if utils.is_extension_supported(
self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
routers = (
@ -124,9 +133,6 @@ class L3RpcCallback(object):
context, host, router_ids))
else:
routers = self.l3plugin.get_sync_data(context, router_ids)
if utils.is_extension_supported(
self.plugin, constants.PORT_BINDING_EXT_ALIAS):
self._ensure_host_set_on_ports(context, host, routers)
return routers
def _ensure_host_set_on_ports(self, context, host, routers):

View File

@ -1546,9 +1546,6 @@ class TestDvrRouter(framework.L3AgentTestFramework):
self.agent.conf.agent_mode = 'dvr'
router_info = self.generate_dvr_router_info(
enable_snat=True, enable_gw=True, enable_floating_ip=True)
fip_agent_gw_port = router_info[n_const.FLOATINGIP_AGENT_INTF_KEY]
self.mock_plugin_api.get_agent_gateway_port.return_value = (
fip_agent_gw_port[0])
router_info[lib_constants.FLOATINGIP_KEY] = []
if address_scopes:
address_scope1 = {
@ -1566,6 +1563,12 @@ class TestDvrRouter(framework.L3AgentTestFramework):
address_scope1)
router_info[lib_constants.INTERFACE_KEY][1]['address_scopes'] = (
address_scope2)
# should have the same address_scopes as gw_port
fip_agent_gw_ports = router_info[n_const.FLOATINGIP_AGENT_INTF_KEY]
fip_agent_gw_ports[0]['address_scopes'] = (
router_info['gw_port']['address_scopes'])
self.mock_plugin_api.get_agent_gateway_port.return_value = (
fip_agent_gw_ports[0])
router1 = self.manage_router(self.agent, router_info)
fip_ns_name = router1.fip_ns.get_name()
self.assertTrue(self._namespace_exists(router1.ns_name))
@ -1600,7 +1603,7 @@ class TestDvrRouter(framework.L3AgentTestFramework):
# Now remove the gateway and validate if the respective interface
# routes in router namespace is deleted respectively.
self. _assert_interface_rules_on_gateway_remove(
router1, self.agent, address_scopes, fip_agent_gw_port[0],
router1, self.agent, address_scopes, fip_agent_gw_ports[0],
rfp_device, fpr_device)
def test_dvr_fip_and_router_namespace_rules_with_address_scopes_match(
@ -1668,6 +1671,10 @@ class TestDvrRouter(framework.L3AgentTestFramework):
if gw_address_scope:
router_info['gw_port']['address_scopes'] = {
str(lib_constants.IP_VERSION_4): gw_address_scope}
fip_agent_gw_ports = router_info[
n_const.FLOATINGIP_AGENT_INTF_KEY]
fip_agent_gw_ports[0]['address_scopes'] = router_info['gw_port'][
'address_scopes']
router_info[lib_constants.INTERFACE_KEY][0]['address_scopes'] = (
address_scope1)
router_info[lib_constants.INTERFACE_KEY][1]['address_scopes'] = (