Merge "Use revision to discard stale DHCP updates"
This commit is contained in:
commit
903eb250bc
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue