diff --git a/manila/api/v2/share_networks.py b/manila/api/v2/share_networks.py index 684a044b62..81f1271561 100644 --- a/manila/api/v2/share_networks.py +++ b/manila/api/v2/share_networks.py @@ -133,6 +133,19 @@ class ShareNetworkController(wsgi.Controller, wsgi.AdminActionsMixin): for share_server in subnet['share_servers']: self.share_rpcapi.delete_share_server(context, share_server) + for security_service in share_network['security_services']: + try: + db_api.share_network_remove_security_service( + context, + id, + security_service['id']) + except Exception: + LOG.exception( + "Failed to delete security association of network " + "{net_id} and security service " + "{sec_id}".format(net_id=id, + sec_id=security_service['id'])) + db_api.share_network_delete(context, id) try: diff --git a/manila/db/sqlalchemy/api.py b/manila/db/sqlalchemy/api.py index 5de660cfa4..b89f910e4a 100644 --- a/manila/db/sqlalchemy/api.py +++ b/manila/db/sqlalchemy/api.py @@ -5999,6 +5999,18 @@ def purge_deleted_records(context, age_in_days): metadata.reflect(get_engine()) deleted_age = timeutils.utcnow() - datetime.timedelta(days=age_in_days) + # Deleting rows in share_network_security_service_association + # related to deleted network or security service + sec_assoc_to_delete = context.session.query( + models.ShareNetworkSecurityServiceAssociation).join( + models.ShareNetwork).join(models.SecurityService).filter( + or_(models.ShareNetwork.deleted_at <= deleted_age, + models.SecurityService.deleted_at <= deleted_age)).all() + + for assoc in sec_assoc_to_delete: + with context.session.begin_nested(): + context.session.delete(assoc) + for table in reversed(metadata.sorted_tables): if 'deleted' not in table.columns.keys(): continue diff --git a/manila/tests/api/v2/test_share_networks.py b/manila/tests/api/v2/test_share_networks.py index 44eb123cf7..c9fa1c7c4d 100644 --- a/manila/tests/api/v2/test_share_networks.py +++ b/manila/tests/api/v2/test_share_networks.py @@ -1769,3 +1769,20 @@ class ShareNetworkAPITest(test.TestCase): self.assertRaises(exception_to_be_raised, self.controller.share_network_subnet_create_check, request, 'fake_net_id', body) + + def test_share_network_sec_service_delete(self): + self.mock_object(db_api, 'share_network_get', + mock.Mock(return_value=fake_share_network_with_ss)) + self.mock_object(db_api, 'share_network_delete') + self.mock_object(db_api, 'share_network_remove_security_service') + self.controller.delete(self.req, fake_share_network_with_ss['id']) + db_api.share_network_get.assert_called_once_with( + self.req.environ['manila.context'], + fake_share_network_with_ss['id']) + db_api.share_network_remove_security_service.assert_called_once_with( + self.req.environ['manila.context'], + fake_share_network_with_ss['id'], + fake_share_network_with_ss['security_services'][0]['id']) + db_api.share_network_delete.assert_called_once_with( + self.req.environ['manila.context'], + fake_share_network_with_ss['id']) diff --git a/releasenotes/notes/bug-2029366-network-deleted-without-security-associaton-ae56473f6d32c47e.yaml b/releasenotes/notes/bug-2029366-network-deleted-without-security-associaton-ae56473f6d32c47e.yaml new file mode 100644 index 0000000000..9b9e6b6a56 --- /dev/null +++ b/releasenotes/notes/bug-2029366-network-deleted-without-security-associaton-ae56473f6d32c47e.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed cleanup of share network security service associations at network delete. See `Launchpad bug 2029366 + ` for more details.