Merge "Use revision to discard stale DHCP updates"

This commit is contained in:
Jenkins 2016-09-02 02:51:42 +00:00 committed by Gerrit Code Review
commit 903eb250bc
2 changed files with 31 additions and 0 deletions

View File

@ -374,6 +374,9 @@ class DhcpAgent(manager.Manager):
def port_update_end(self, context, payload):
"""Handle the port.update.end notification event."""
updated_port = dhcp.DictModel(payload['port'])
if self.cache.is_port_message_stale(payload['port']):
LOG.debug("Discarding stale port update: %s", updated_port)
return
network = self.cache.get_network_by_id(updated_port.network_id)
if network:
LOG.info(_LI("Trigger reload_allocations for port %s"),
@ -402,6 +405,7 @@ class DhcpAgent(manager.Manager):
def port_delete_end(self, context, payload):
"""Handle the port.delete.end notification event."""
port = self.cache.get_port_by_id(payload['port_id'])
self.cache.deleted_ports.add(payload['port_id'])
if port:
network = self.cache.get_network_by_id(port.network_id)
self.cache.remove_port(port)
@ -534,6 +538,15 @@ class NetworkCache(object):
self.cache = {}
self.subnet_lookup = {}
self.port_lookup = {}
self.deleted_ports = set()
def is_port_message_stale(self, payload):
orig = self.get_port_by_id(payload['id'])
if orig and orig.get('revision', 0) > payload.get('revision', 0):
return True
if payload['id'] in self.deleted_ports:
return True
return False
def get_port_ids(self):
return self.port_lookup.keys()

View File

@ -115,6 +115,7 @@ fake_port2 = dhcp.DictModel(dict(id='12345678-1234-aaaa-123456789000',
device_owner='',
mac_address='aa:bb:cc:dd:ee:99',
network_id='12345678-1234-5678-1234567890ab',
revision=77,
fixed_ips=[fake_fixed_ip2]))
fake_ipv6_port = dhcp.DictModel(dict(id='12345678-1234-aaaa-123456789000',
@ -625,6 +626,7 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
self.cache_p = mock.patch('neutron.agent.dhcp.agent.NetworkCache')
cache_cls = self.cache_p.start()
self.cache = mock.Mock()
self.cache.is_port_message_stale.return_value = False
cache_cls.return_value = self.cache
self.mock_makedirs_p = mock.patch("os.makedirs")
self.mock_makedirs = self.mock_makedirs_p.start()
@ -1069,6 +1071,7 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
self.dhcp.port_delete_end(None, payload)
self.cache.assert_has_calls(
[mock.call.get_port_by_id(fake_port2.id),
mock.call.deleted_ports.add(fake_port2.id),
mock.call.get_network_by_id(fake_network.id),
mock.call.remove_port(fake_port2)])
self.call_driver.assert_has_calls(
@ -1125,6 +1128,21 @@ class TestDhcpPluginApiProxy(base.BaseTestCase):
class TestNetworkCache(base.BaseTestCase):
def test_update_of_deleted_port_ignored(self):
nc = dhcp_agent.NetworkCache()
nc.put(fake_network)
nc.deleted_ports.add(fake_port2['id'])
self.assertTrue(nc.is_port_message_stale(fake_port2))
def test_stale_update_ignored(self):
nc = dhcp_agent.NetworkCache()
nc.put(fake_network)
nc.put_port(fake_port2)
stale = copy.copy(fake_port2)
stale['revision'] = 2
self.assertTrue(nc.is_port_message_stale(stale))
def test_put_network(self):
nc = dhcp_agent.NetworkCache()
nc.put(fake_network)