Remove port from ovsdb after its deletion

When port is being deleted via API it is not removed
from ovsdb and corresponding iptables chains remain
even though the port does not exist.

This patch adds a notification for the ovs neutron agent,
upon which the port is deleted from ovsdb.

Co-Authored-By: Akash Gangil <akashg1611@gmail.com>
Closes-Bug: #1333365
Change-Id: Iccda3bee98d561ef3a06d0317d3d68d6b1dfb76b
This commit is contained in:
Elena Ezhova 2014-12-24 17:09:32 +03:00
parent 874dd6db8a
commit d6a55c1736
5 changed files with 42 additions and 0 deletions

View File

@ -1172,6 +1172,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
# fact that an error occurred.
LOG.error(_LE("mechanism_manager.delete_port_postcommit failed for"
" port %s"), id)
self.notifier.port_delete(context, id)
self.notify_security_groups_member_updated(context, port)
def get_bound_port_context(self, plugin_context, port_id, host=None):

View File

@ -198,6 +198,10 @@ class AgentNotifierApi(dvr_rpc.DVRAgentRpcApiMixin,
self.topic_port_update = topics.get_topic_name(topic,
topics.PORT,
topics.UPDATE)
self.topic_port_delete = topics.get_topic_name(topic,
topics.PORT,
topics.DELETE)
target = oslo_messaging.Target(topic=topic, version='1.0')
self.client = n_rpc.get_client(target)
@ -213,3 +217,8 @@ class AgentNotifierApi(dvr_rpc.DVRAgentRpcApiMixin,
cctxt.cast(context, 'port_update', port=port,
network_type=network_type, segmentation_id=segmentation_id,
physical_network=physical_network)
def port_delete(self, context, port_id):
cctxt = self.client.prepare(topic=self.topic_port_delete,
fanout=True)
cctxt.cast(context, 'port_delete', port_id=port_id)

View File

@ -294,6 +294,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
self.endpoints = [self]
# Define the listening consumers for the agent
consumers = [[topics.PORT, topics.UPDATE],
[topics.PORT, topics.DELETE],
[topics.NETWORK, topics.DELETE],
[constants.TUNNEL, topics.UPDATE],
[topics.SECURITY_GROUP, topics.UPDATE],
@ -331,6 +332,13 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
self.updated_ports.add(port['id'])
LOG.debug("port_update message processed for port %s", port['id'])
def port_delete(self, context, **kwargs):
port_id = kwargs.get('port_id')
port = self.int_br.get_vif_port_by_id(port_id)
# If port exists, delete it
if port:
self.int_br.delete_port(port.port_name)
def tunnel_update(self, context, **kwargs):
LOG.debug("tunnel_update received")
if not self.enable_tunneling:

View File

@ -223,6 +223,16 @@ class RpcApiTestCase(base.BaseTestCase):
segmentation_id='fake_segmentation_id',
physical_network='fake_physical_network')
def test_port_delete(self):
rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT)
self._test_rpc_api(
rpcapi,
topics.get_topic_name(topics.AGENT,
topics.PORT,
topics.DELETE),
'port_delete', rpc_method='cast',
fanout=True, port_id='fake_port')
def test_tunnel_update(self):
rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT)
self._test_rpc_api(

View File

@ -498,6 +498,20 @@ class TestOvsNeutronAgent(base.BaseTestCase):
physical_network="physnet")
self.assertEqual(set(['123']), self.agent.updated_ports)
def test_port_delete(self):
port_id = "123"
port_name = "foo"
with contextlib.nested(
mock.patch.object(self.agent.int_br, 'get_vif_port_by_id',
return_value=mock.MagicMock(
port_name=port_name)),
mock.patch.object(self.agent.int_br, "delete_port")
) as (get_vif_func, del_port_func):
self.agent.port_delete("unused_context",
port_id=port_id)
self.assertTrue(get_vif_func.called)
del_port_func.assert_called_once_with(port_name)
def test_setup_physical_bridges(self):
with contextlib.nested(
mock.patch.object(ip_lib, "device_exists"),