Clear associated tap resources on port delete

Change-Id: Ifdaa08734825dd5fe9ded2ce13d16cad699d0737
Closes-Bug: #1814937
This commit is contained in:
Deepak Tiwari 2019-02-06 11:57:12 -06:00
parent 97bb1b3383
commit 080ef1661f
3 changed files with 113 additions and 22 deletions

View File

@ -17,6 +17,9 @@
from neutron.db import servicetype_db as st_db
from neutron.services import provider_configuration as pconf
from neutron.services import service_base
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import exceptions as n_exc
from neutron_taas.common import constants
@ -37,6 +40,7 @@ def add_provider_configuration(type_manager, service_type):
pconf.ProviderConfiguration('neutron_taas'))
@registry.has_registry_receivers
class TaasPlugin(taas_db.Taas_db_Mixin):
supported_extension_aliases = ["taas"]
@ -174,3 +178,34 @@ class TaasPlugin(taas_db.Taas_db_Mixin):
with excutils.save_and_reraise_exception():
LOG.error("Failed to delete tap flow on driver. "
"tap_flow: %s", id)
@registry.receives(resources.PORT, [events.PRECOMMIT_DELETE])
def handle_delete_port(self, resource, event, trigger, context, **kwargs):
deleted_port = kwargs['port']
if not deleted_port:
LOG.error("TaaS: Handle Delete Port: Invalid port object received")
return
deleted_port_id = deleted_port['id']
LOG.info("TaaS: Handle Delete Port: %s", deleted_port_id)
# Get list of configured tap-services
t_s_collection = self.get_tap_services(
context,
filters={'port_id': [deleted_port_id]}, fields=['id'])
for t_s in t_s_collection:
try:
self.delete_tap_service(context, t_s['id'])
except taas_ex.TapServiceNotFound:
LOG.debug("Not found tap_service: %s", t_s['id'])
t_f_collection = self.get_tap_flows(
context,
filters={'source_port': [deleted_port_id]}, fields=['id'])
for t_f in t_f_collection:
try:
self.delete_tap_flow(context, t_f['id'])
except taas_ex.TapFlowNotFound:
LOG.debug("Not found tap_flow: %s", t_f['id'])

View File

@ -1,3 +1,4 @@
# Copyright (c) 2018 AT&T Intellectual Property. All other rights reserved.
# Copyright (c) 2015 Midokura SARL
# All Rights Reserved.
#
@ -16,6 +17,7 @@
from tempest.common import utils
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from neutron_taas.tests.tempest_plugin.tests.api import base
@ -24,48 +26,93 @@ CONF = config.CONF
class TaaSExtensionTestJSON(base.BaseTaaSTest):
@classmethod
@utils.requires_ext(extension='taas', service='network')
def skip_checks(cls):
super(TaaSExtensionTestJSON, cls).skip_checks()
@classmethod
def resource_setup(cls):
super(TaaSExtensionTestJSON, cls).resource_setup()
if not utils.is_extension_enabled('taas', 'network'):
msg = "TaaS Extension not enabled."
raise cls.skipException(msg)
cls.network = cls.create_network()
cls.ts_port = cls.create_port(cls.network)
cls.tf_port = cls.create_port(cls.network)
cls.tf2_port = cls.create_port(cls.network)
@decorators.idempotent_id('b993c14e-797a-4c91-b4da-8cb1a450aa2f')
def test_create_tap_service_and_flow(self):
network = self.create_network()
port = self.create_port(network)
tap_service = self.create_tap_service(port_id=port['id'])
"""create tap service adn tap flow
Test create tap service and flow.
"""
tap_service = self.create_tap_service(port_id=self.ts_port['id'])
self.create_tap_flow(tap_service_id=tap_service['id'],
direction='BOTH', source_port=port['id'])
direction='BOTH', source_port=self.tf_port['id'])
@decorators.idempotent_id('d7a2115d-16b4-41cf-95a6-dcebc3682b24')
def test_delete_tap_service_after_delete_port(self):
network = self.create_network()
port = self.create_port(network)
tap_service = self.create_tap_service(port_id=port['id'])
# delete port
self.ports_client.delete_port(port['id'])
def test_delete_tap_resources_after_ts_port_delete(self):
"""delete tap resources after ts port delete
Test delete tap resources after deletion of ts port.
"""
tap_service = self.create_tap_service(port_id=self.ts_port['id'])
tap_flow = self.create_tap_flow(tap_service_id=tap_service['id'],
direction='BOTH',
source_port=self.tf2_port['id'])
# delete ts_port; it shall also delete the associated tap-service and
# subsequently the tap-flow as well
self.ports_client.delete_port(self.ts_port['id'])
# Attempt tap-service deletion; it should throw not found exception.
self.assertRaises(lib_exc.NotFound,
self.tap_services_client.delete_tap_service,
tap_service['id'])
# Attempt tap-flow deletion; it should throw not found exception.
self.assertRaises(lib_exc.NotFound,
self.tap_flows_client.delete_tap_flow,
tap_flow['id'])
@decorators.idempotent_id('9ba4edfd-4002-4c44-b02b-6c4f71b40a92')
def test_delete_tap_resources_after_tf_port_delete(self):
"""delete tap resources after tf port delete
Test delete tap service after deletion of tf port.
"""
tap_service = self.create_tap_service(port_id=self.ts_port['id'])
tap_flow = self.create_tap_flow(tap_service_id=tap_service['id'],
direction='BOTH',
source_port=self.tf_port['id'])
# delete tf port; it shall also delete the associated tap-flow
self.ports_client.delete_port(self.tf_port['id'])
# Attempt tap-flow deletion; it should throw not found exception.
self.assertRaises(lib_exc.NotFound,
self.tap_flows_client.delete_tap_flow,
tap_flow['id'])
# delete tap service; it shall go fine
self.tap_services_client.delete_tap_service(tap_service['id'])
@decorators.idempotent_id('687089b8-b045-496d-86bf-030b380039d1')
def test_update_tap_service(self):
network = self.create_network()
port = self.create_port(network)
tap_service = self.create_tap_service(port_id=port['id'])
def test_create_and_update_tap_service(self):
"""create and update tap service
Test update tap service - update description.
"""
tap_service = self.create_tap_service(port_id=self.ts_port['id'])
# Update description of the tap service
self.update_tap_service(
tap_service['id'],
description='Tap Service Description Updated')
@decorators.idempotent_id('bb4d5482-37fc-46b5-85a5-5867e9adbfae')
def test_update_tap_flow(self):
network = self.create_network()
port = self.create_port(network)
tap_service = self.create_tap_service(port_id=port['id'])
def test_create_and_update_tap_flow(self):
"""create and update tap flow
Test update tap flow - update description.
"""
tap_service = self.create_tap_service(port_id=self.ts_port['id'])
tap_flow = self.create_tap_flow(
tap_service_id=tap_service['id'],
direction='BOTH', source_port=port['id'])
direction='BOTH', source_port=self.tf_port['id'])
# Update description of the tap flow
self.update_tap_flow(
tap_flow['id'],

View File

@ -0,0 +1,9 @@
---
prelude: >
Deleting a port associated with some tap resources (tap service or tap
flow) shall now cascade delete those associated tap resources as well.
It should be noted that this change alters the API behaviour in the sense
that earlier deleting a port did not clear the associated tap resources.
issues:
- |
Fixes bug `1814937 <https://bugs.launchpad.net/tap-as-a-service/+bug/1814937>`_.