DVR: Notify specific agent when update floatingip
The L3 agent was determined when update floatingip. So notify the specific agent rather than notify all agents. This will save some RPC resources. This is only for DVR routers. Legacy and HA routers notify only the relevant agents. Partial-Bug: #1486828 Change-Id: I12f61afdfaa944bc4b659cec61a8b5ff8c66ae76 Co-Authored-By: Oleg Bondarev <obondarev@mirantis.com>
This commit is contained in:
parent
7cc0f25e1a
commit
52e91f48f2
@ -685,11 +685,24 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
|
|||||||
initial_status=l3_const.FLOATINGIP_STATUS_ACTIVE):
|
initial_status=l3_const.FLOATINGIP_STATUS_ACTIVE):
|
||||||
floating_ip = self._create_floatingip(
|
floating_ip = self._create_floatingip(
|
||||||
context, floatingip, initial_status)
|
context, floatingip, initial_status)
|
||||||
|
self._notify_floating_ip_change(context, floating_ip)
|
||||||
|
return floating_ip
|
||||||
|
|
||||||
|
def _notify_floating_ip_change(self, context, floating_ip):
|
||||||
router_id = floating_ip['router_id']
|
router_id = floating_ip['router_id']
|
||||||
if not router_id:
|
if not router_id:
|
||||||
return floating_ip
|
return
|
||||||
|
|
||||||
router = self._get_router(context, router_id)
|
try:
|
||||||
|
router = self._get_router(context, router_id)
|
||||||
|
except l3.RouterNotFound:
|
||||||
|
# TODO(changzhi): this is present to avoid grenade failing on a
|
||||||
|
# race condition(<bug:1486828>). Can be removed when underlying
|
||||||
|
# race condition is cleaned up.
|
||||||
|
LOG.debug("Router %(router_id)s not found. "
|
||||||
|
"Just ingore this router. ",
|
||||||
|
{"router_id": router_id})
|
||||||
|
return
|
||||||
# we need to notify agents only in case Floating IP is associated
|
# we need to notify agents only in case Floating IP is associated
|
||||||
fixed_port_id = floating_ip['port_id']
|
fixed_port_id = floating_ip['port_id']
|
||||||
if fixed_port_id:
|
if fixed_port_id:
|
||||||
@ -698,9 +711,16 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
|
|||||||
self.l3_rpc_notifier.routers_updated_on_host(
|
self.l3_rpc_notifier.routers_updated_on_host(
|
||||||
context, [router_id], host)
|
context, [router_id], host)
|
||||||
else:
|
else:
|
||||||
self.notify_router_updated(context, router_id,
|
self.notify_router_updated(context, router_id)
|
||||||
'create_floatingip')
|
|
||||||
return floating_ip
|
def update_floatingip(self, context, id, floatingip):
|
||||||
|
old_floatingip, floatingip = self._update_floatingip(
|
||||||
|
context, id, floatingip)
|
||||||
|
self._notify_floating_ip_change(context, old_floatingip)
|
||||||
|
if (floatingip['router_id'] != old_floatingip['router_id'] or
|
||||||
|
floatingip['port_id'] != old_floatingip['port_id']):
|
||||||
|
self._notify_floating_ip_change(context, floatingip)
|
||||||
|
return floatingip
|
||||||
|
|
||||||
|
|
||||||
def is_distributed_router(router):
|
def is_distributed_router(router):
|
||||||
|
@ -257,7 +257,7 @@ class L3DvrTestCase(ml2_test_base.ML2TestFramework):
|
|||||||
self.assertFalse(l3_notif.routers_updated.called)
|
self.assertFalse(l3_notif.routers_updated.called)
|
||||||
else:
|
else:
|
||||||
l3_notif.routers_updated.assert_called_once_with(
|
l3_notif.routers_updated.assert_called_once_with(
|
||||||
self.context, [router['id']], 'create_floatingip')
|
self.context, [router['id']], None)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
l3_notif.routers_updated_on_host.called)
|
l3_notif.routers_updated_on_host.called)
|
||||||
|
|
||||||
@ -266,3 +266,82 @@ class L3DvrTestCase(ml2_test_base.ML2TestFramework):
|
|||||||
|
|
||||||
def test_create_floating_ip_agent_notification_non_dvr(self):
|
def test_create_floating_ip_agent_notification_non_dvr(self):
|
||||||
self._test_create_floating_ip_agent_notification(dvr=False)
|
self._test_create_floating_ip_agent_notification(dvr=False)
|
||||||
|
|
||||||
|
def _test_update_floating_ip_agent_notification(self, dvr=True):
|
||||||
|
with self.subnet() as ext_subnet,\
|
||||||
|
self.subnet(cidr='20.0.0.0/24') as int_subnet1,\
|
||||||
|
self.subnet(cidr='30.0.0.0/24') as int_subnet2,\
|
||||||
|
self.port(subnet=int_subnet1,
|
||||||
|
device_owner='compute:None') as int_port1,\
|
||||||
|
self.port(subnet=int_subnet2,
|
||||||
|
device_owner='compute:None') as int_port2:
|
||||||
|
# locate internal ports on different hosts
|
||||||
|
self.core_plugin.update_port(
|
||||||
|
self.context, int_port1['port']['id'],
|
||||||
|
{'port': {'binding:host_id': 'host1'}})
|
||||||
|
self.core_plugin.update_port(
|
||||||
|
self.context, int_port2['port']['id'],
|
||||||
|
{'port': {'binding:host_id': 'host2'}})
|
||||||
|
# and create l3 agents on corresponding hosts
|
||||||
|
helpers.register_l3_agent(host='host1',
|
||||||
|
agent_mode=l3_const.L3_AGENT_MODE_DVR)
|
||||||
|
helpers.register_l3_agent(host='host2',
|
||||||
|
agent_mode=l3_const.L3_AGENT_MODE_DVR)
|
||||||
|
|
||||||
|
# make net external
|
||||||
|
ext_net_id = ext_subnet['subnet']['network_id']
|
||||||
|
self._update('networks', ext_net_id,
|
||||||
|
{'network': {external_net.EXTERNAL: True}})
|
||||||
|
|
||||||
|
router1 = self._create_router(distributed=dvr)
|
||||||
|
router2 = self._create_router(distributed=dvr)
|
||||||
|
for router in (router1, router2):
|
||||||
|
self.l3_plugin.update_router(
|
||||||
|
self.context, router['id'],
|
||||||
|
{'router': {
|
||||||
|
'external_gateway_info': {'network_id': ext_net_id}}})
|
||||||
|
self.l3_plugin.add_router_interface(
|
||||||
|
self.context, router1['id'],
|
||||||
|
{'subnet_id': int_subnet1['subnet']['id']})
|
||||||
|
self.l3_plugin.add_router_interface(
|
||||||
|
self.context, router2['id'],
|
||||||
|
{'subnet_id': int_subnet2['subnet']['id']})
|
||||||
|
|
||||||
|
floating_ip = {'floating_network_id': ext_net_id,
|
||||||
|
'router_id': router1['id'],
|
||||||
|
'port_id': int_port1['port']['id'],
|
||||||
|
'tenant_id': int_port1['port']['tenant_id']}
|
||||||
|
floating_ip = self.l3_plugin.create_floatingip(
|
||||||
|
self.context, {'floatingip': floating_ip})
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
self.l3_plugin, '_l3_rpc_notifier') as l3_notif:
|
||||||
|
updated_floating_ip = {'router_id': router2['id'],
|
||||||
|
'port_id': int_port2['port']['id']}
|
||||||
|
self.l3_plugin.update_floatingip(
|
||||||
|
self.context, floating_ip['id'],
|
||||||
|
{'floatingip': updated_floating_ip})
|
||||||
|
if dvr:
|
||||||
|
self.assertEqual(
|
||||||
|
2, l3_notif.routers_updated_on_host.call_count)
|
||||||
|
expected_calls = [
|
||||||
|
mock.call(self.context, [router1['id']], 'host1'),
|
||||||
|
mock.call(self.context, [router2['id']], 'host2')]
|
||||||
|
l3_notif.routers_updated_on_host.assert_has_calls(
|
||||||
|
expected_calls)
|
||||||
|
self.assertFalse(l3_notif.routers_updated.called)
|
||||||
|
else:
|
||||||
|
self.assertEqual(
|
||||||
|
2, l3_notif.routers_updated.call_count)
|
||||||
|
expected_calls = [
|
||||||
|
mock.call(self.context, [router1['id']], None),
|
||||||
|
mock.call(self.context, [router2['id']], None)]
|
||||||
|
l3_notif.routers_updated.assert_has_calls(
|
||||||
|
expected_calls)
|
||||||
|
self.assertFalse(l3_notif.routers_updated_on_host.called)
|
||||||
|
|
||||||
|
def test_update_floating_ip_agent_notification(self):
|
||||||
|
self._test_update_floating_ip_agent_notification()
|
||||||
|
|
||||||
|
def test_update_floating_ip_agent_notification_non_dvr(self):
|
||||||
|
self._test_update_floating_ip_agent_notification(dvr=False)
|
||||||
|
Loading…
Reference in New Issue
Block a user