From 2f838556a845ca183d152c6d95c11dade9024cba Mon Sep 17 00:00:00 2001 From: Swaminathan Vasudevan Date: Thu, 11 Sep 2014 12:51:14 -0700 Subject: [PATCH] Deletes FIP agent gw port when last VM is deleted This patch deletes the FIP agent gateway port in the plugin, when the last VM with FIP using this FIP agent gw port on a Compute node gets deleted. Closes-bug: #1367588 Change-Id: I71a9fa48544fa4bbd08ac6d83c99e6542c818009 --- neutron/db/l3_dvr_db.py | 20 ++++++++++++++++++ neutron/tests/unit/db/test_l3_dvr_db.py | 27 ++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/neutron/db/l3_dvr_db.py b/neutron/db/l3_dvr_db.py index 695617192..b346ef3f2 100644 --- a/neutron/db/l3_dvr_db.py +++ b/neutron/db/l3_dvr_db.py @@ -181,6 +181,26 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin, super(L3_NAT_with_dvr_db_mixin, self).delete_floatingip(context, id) + def _get_floatingip_on_port(self, context, port_id=None): + """Helper function to retrieve the fip associated with port.""" + fip_qry = context.session.query(l3_db.FloatingIP) + floating_ip = fip_qry.filter_by(fixed_port_id=port_id) + return floating_ip.first() + + def disassociate_floatingips(self, context, port_id, do_notify=True): + """Override disassociate floatingips to delete fip agent gw port.""" + with context.session.begin(subtransactions=True): + fip = self._get_floatingip_on_port( + context, port_id=port_id) + if fip: + admin_ctx = context.elevated() + self.clear_unused_fip_agent_gw_port( + admin_ctx, fip, id) + return super(L3_NAT_with_dvr_db_mixin, + self).disassociate_floatingips(context, + port_id, + do_notify=do_notify) + def add_router_interface(self, context, router_id, interface_info): add_by_port, add_by_sub = self._validate_interface_info(interface_info) router = self._get_router(context, router_id) diff --git a/neutron/tests/unit/db/test_l3_dvr_db.py b/neutron/tests/unit/db/test_l3_dvr_db.py index be27ce9ca..6ef9b1a5b 100644 --- a/neutron/tests/unit/db/test_l3_dvr_db.py +++ b/neutron/tests/unit/db/test_l3_dvr_db.py @@ -23,7 +23,6 @@ from neutron import manager from neutron.openstack.common import uuidutils from neutron.tests.unit import testlib_api - _uuid = uuidutils.generate_uuid @@ -214,6 +213,32 @@ class L3DvrTestCase(testlib_api.SqlTestCase): self.mixin.delete_floatingip(self.ctx, fip_id) return vf + def _disassociate_floatingip_setup(self, port_id=None, floatingip=None): + with contextlib.nested( + mock.patch.object(self.mixin, '_get_floatingip_on_port'), + mock.patch.object(self.mixin, + 'clear_unused_fip_agent_gw_port'), + ) as (gf, vf): + gf.return_value = floatingip + self.mixin.disassociate_floatingips( + self.ctx, port_id, do_notify=False) + return vf + + def test_disassociate_floatingip_with_vm_port(self): + port_id = '1234' + floatingip = { + 'id': _uuid(), + 'fixed_port_id': 1234, + 'floating_network_id': _uuid() + } + mock_disassociate_fip = self._disassociate_floatingip_setup( + port_id=port_id, floatingip=floatingip) + self.assertTrue(mock_disassociate_fip.called) + + def test_disassociate_floatingip_with_no_vm_port(self): + mock_disassociate_fip = self._disassociate_floatingip_setup() + self.assertFalse(mock_disassociate_fip.called) + def test_delete_floatingip_without_internal_port(self): floatingip = { 'id': _uuid(), -- 2.45.2