Merge "Add binding de-activation to OVS agent"

This commit is contained in:
Zuul 2018-07-23 13:06:40 +00:00 committed by Gerrit Code Review
commit 1deb0d9f7d
2 changed files with 55 additions and 1 deletions

View File

@ -124,7 +124,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
# 1.2 Support DVR (Distributed Virtual Router) RPC
# 1.3 Added param devices_to_update to security_groups_provider_updated
# 1.4 Added support for network_update
target = oslo_messaging.Target(version='1.4')
# 1.5 Added binding_deactivate
target = oslo_messaging.Target(version='1.5')
def __init__(self, bridge_classes, ext_manager, conf=None):
'''Constructor.
@ -174,6 +175,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
self.updated_ports = set()
# Stores port delete notifications
self.deleted_ports = set()
# Stores the port IDs whose binding has been deactivated
self.deactivated_bindings = set()
self.network_ports = collections.defaultdict(set)
# keeps association between ports and ofports to detect ofport change
@ -414,6 +417,12 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
{'network_id': network_id,
'ports': self.network_ports[network_id]})
def binding_deactivate(self, context, **kwargs):
if kwargs.get('host') != self.conf.host:
return
port_id = kwargs.get('port_id')
self.deactivated_bindings.add(port_id)
def _clean_network_ports(self, port_id):
for port_set in self.network_ports.values():
if port_id in port_set:
@ -444,6 +453,20 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
# more secure
self.sg_agent.remove_devices_filter(deleted_ports)
def process_deactivated_bindings(self, port_info):
# don't try to deactivate bindings for removed ports since they are
# already gone
if 'removed' in port_info:
self.deactivated_bindings -= port_info['removed']
while self.deactivated_bindings:
port_id = self.deactivated_bindings.pop()
port = self.int_br.get_vif_port_by_id(port_id)
if not port:
continue
self.int_br.delete_port(port.port_name)
LOG.debug(("Port id %s unplugged from integration bridge because "
"its binding was de-activated"), port_id)
def tunnel_update(self, context, **kwargs):
LOG.debug("tunnel_update received")
if not self.enable_tunneling:
@ -1786,6 +1809,7 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
return (polling_manager.is_polling_required or
self.updated_ports or
self.deleted_ports or
self.deactivated_bindings or
self.sg_agent.firewall_refresh_needed())
def _port_info_has_changes(self, port_info):
@ -2075,6 +2099,7 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
failed_devices, failed_ancillary_devices))
sync = False
self.process_deleted_ports(port_info)
self.process_deactivated_bindings(port_info)
ofport_changed_ports = self.update_stale_ofport_rules()
if ofport_changed_ports:
port_info.setdefault('updated', set()).update(

View File

@ -114,6 +114,7 @@ class TestOvsNeutronAgent(object):
group='SECURITYGROUP')
cfg.CONF.set_default('quitting_rpc_timeout', 10, 'AGENT')
cfg.CONF.set_default('local_ip', '127.0.0.1', 'OVS')
cfg.CONF.set_default('host', 'host')
mock.patch(
'neutron.agent.ovsdb.native.helpers.enable_connection_uri').start()
mock.patch(
@ -1218,6 +1219,34 @@ class TestOvsNeutronAgent(object):
self.assertFalse(int_br.set_db_attribute.called)
self.assertFalse(int_br.drop_port.called)
def test_binding_deactivate_not_for_host(self):
self.agent.binding_deactivate('unused_context', port_id='id',
host='other_host')
self.assertEqual(set(), self.agent.deactivated_bindings)
def test_binding_deactivate(self):
vif = FakeVif()
with mock.patch.object(self.agent, 'int_br') as int_br:
int_br.get_vif_port_by_id.return_value = vif
self.agent.binding_deactivate('unused_context', port_id='id',
host='host')
self.assertEqual(set(['id']), self.agent.deactivated_bindings)
self.agent.process_deactivated_bindings(port_info={})
int_br.get_vif_port_by_id.assert_called_once_with('id')
int_br.delete_port.assert_called_once_with(vif.port_name)
self.assertEqual(set(), self.agent.deactivated_bindings)
def test_binding_deactivate_removed_port(self):
with mock.patch.object(self.agent, 'int_br') as int_br:
self.agent.binding_deactivate('unused_context', port_id='id',
host='host')
self.assertEqual(set(['id']), self.agent.deactivated_bindings)
self.agent.process_deactivated_bindings(
port_info={'removed': {'id', }})
int_br.get_vif_port_by_id.assert_not_called()
int_br.delete_port.assert_not_called()
self.assertEqual(set(), self.agent.deactivated_bindings)
def _test_setup_physical_bridges(self, port_exists=False):
with mock.patch.object(ip_lib.IPDevice, "exists") as devex_fn,\
mock.patch.object(sys, "exit"),\