Merge "Delete tunnel endpoints if endpoint agent is deleted"

This commit is contained in:
Zuul
2025-08-29 17:32:31 +00:00
committed by Gerrit Code Review
3 changed files with 89 additions and 1 deletions

View File

@@ -917,7 +917,7 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
@profiler.trace("rpc")
def tunnel_delete(self, context, **kwargs):
LOG.debug("tunnel_delete received")
LOG.debug("tunnel_delete received: %s", kwargs)
if not self.enable_tunneling:
return
tunnel_ip = kwargs.get('tunnel_ip')

View File

@@ -492,6 +492,34 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
return True
return False
@registry.receives(resources.AGENT, [events.AFTER_DELETE])
def delete_agent_notified(self, resource, event, trigger,
payload=None):
context = payload.context
agent = payload.states[0]
if agent.binary != const.AGENT_PROCESS_OVS:
return
tunnel_id = payload.resource_id
tunnel_ip = agent.configurations.get('tunneling_ip')
tunnel_types = agent.configurations.get('tunnel_types')
if not tunnel_ip or not tunnel_types:
return
LOG.debug('Deleting tunnel id %s, and endpoints associated with '
'it (tunnel_ip: %s tunnel_types: %s)',
tunnel_id, tunnel_ip, tunnel_types)
for t_type in tunnel_types:
self.notifier.tunnel_delete(
context=context,
tunnel_ip=tunnel_ip,
tunnel_type=t_type)
try:
driver = self.type_manager.drivers.get(t_type)
except KeyError:
LOG.warning('Tunnel type %s is not registered, cannot '
'delete tunnel endpoint for it.', t_type)
else:
driver.obj.delete_endpoint(tunnel_ip)
@registry.receives(resources.AGENT, [events.AFTER_UPDATE])
def _retry_binding_revived_agents(self, resource, event, trigger,
payload=None):

View File

@@ -43,6 +43,7 @@ from neutron_lib.plugins import utils as p_utils
from oslo_config import cfg
from oslo_db import exception as db_exc
from oslo_utils import netutils
from oslo_utils import timeutils
from oslo_utils import uuidutils
import testtools
import webob
@@ -64,6 +65,7 @@ from neutron.plugins.ml2.common import constants as ml2_consts
from neutron.plugins.ml2.common import exceptions as ml2_exc
from neutron.plugins.ml2 import db as ml2_db
from neutron.plugins.ml2 import driver_context
from neutron.plugins.ml2.drivers import type_tunnel
from neutron.plugins.ml2.drivers import type_vlan
from neutron.plugins.ml2 import managers
from neutron.plugins.ml2 import models
@@ -595,6 +597,64 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
self.assertIn("network", res.json['NeutronError']['message'])
class TestMl2AgentNotifications(Ml2PluginV2TestCase):
class Agent:
def __init__(self, agent_dict):
for field in agent_dict:
setattr(self, field, agent_dict[field])
def test_delete_agent_notified(self):
agent_status = {'agent_type': constants.AGENT_TYPE_OVS,
'binary': constants.AGENT_PROCESS_OVS,
'host': 'AHOST',
'topic': 'N/A',
'configurations': {'tunnel_types': ['vxlan'],
'tunneling_ip': '100.101.2.3'}}
agent = self.plugin.create_or_update_agent(self.context,
dict(agent_status),
timeutils.utcnow())
agnt = self.Agent(agent[1])
with mock.patch.object(
self.plugin.notifier, 'tunnel_delete') as m_t_del:
with mock.patch.object(
type_tunnel.EndpointTunnelTypeDriver,
'delete_endpoint') as m_del_ep:
self.plugin.delete_agent_notified(
resource='agent', event='after_delete', trigger=None,
payload=events.DBEventPayload(
self.context, states=(agnt,),
resource_id=agent[1]['id']))
m_t_del.assert_called_once_with(
context=mock.ANY,
tunnel_ip='100.101.2.3', tunnel_type='vxlan')
m_del_ep.assert_called_once_with('100.101.2.3')
def test_delete_agent_notified_non_ovs(self):
agent_status = {'agent_type': constants.AGENT_TYPE_NIC_SWITCH,
'binary': constants.AGENT_PROCESS_NIC_SWITCH,
'host': 'AHOST',
'topic': 'N/A',
'configurations': {'tunnel_types': ['vxlan'],
'tunneling_ip': '100.101.2.3'}}
agent = self.plugin.create_or_update_agent(self.context,
dict(agent_status),
timeutils.utcnow())
agnt = self.Agent(agent[1])
with mock.patch.object(
self.plugin.notifier, 'tunnel_delete') as m_t_del:
with mock.patch.object(
type_tunnel.EndpointTunnelTypeDriver,
'delete_endpoint') as m_del_ep:
self.plugin.delete_agent_notified(
resource='agent', event='after_delete', trigger=None,
payload=events.DBEventPayload(
self.context, states=(agnt,),
resource_id=agent[1]['id']))
m_t_del.assert_not_called()
m_del_ep.assert_not_called()
class TestMl2NetworksV2AgentMechDrivers(Ml2PluginV2TestCase):
_mechanism_drivers = ['logger', 'test', 'test_with_agent']