From 9c9db24738161aef465489b320e6f54a94b4cac7 Mon Sep 17 00:00:00 2001 From: Swaminathan Vasudevan Date: Fri, 6 Feb 2015 15:07:40 -0800 Subject: [PATCH] Remove RPC dependency to create FIP agent gw port The Floatingip Agent Gateway port was initially created when the agent requests one through an RPC exchange. We are seeing more failures in this area of the code where there is delay in getting the agent gateway port from the plugin through RPC. Change-Id: Ieaa79c8bf2b1e03bc352f9252ce22286703e3715 Related-bug: #1415522 --- neutron/db/l3_dvr_db.py | 21 +++++++++++++++++- neutron/tests/unit/db/test_l3_dvr_db.py | 29 +++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/neutron/db/l3_dvr_db.py b/neutron/db/l3_dvr_db.py index 16b2fd828..47972ba75 100644 --- a/neutron/db/l3_dvr_db.py +++ b/neutron/db/l3_dvr_db.py @@ -191,8 +191,26 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin, ) def _update_fip_assoc(self, context, fip, floatingip_db, external_port): - """Override to delete the fip agent gw port on disassociate.""" + """Override to create and delete floating agent gw port for DVR. + + Floating IP Agent gateway port will be created when a + floatingIP association happens. + Floating IP Agent gateway port will be deleted when a + floatingIP disassociation happens. + """ fip_port = fip.get('port_id') + if fip_port and floatingip_db['id']: + vm_hostid = self.get_vm_port_hostid( + context, fip_port) + if vm_hostid: + # FIXME (Swami): This FIP Agent Gateway port should be + # created only once and there should not be a duplicate + # for the same host. Until we find a good solution for + # augmenting multiple server requests we should use the + # existing flow. + fip_agent_port = self.create_fip_agent_gw_port_if_not_exists( + context.elevated(), external_port['network_id'], vm_hostid) + LOG.debug("FIP Agent gateway port: %s", fip_agent_port) unused_fip_agent_gw_port = ( fip_port is None and floatingip_db['fixed_port_id']) if unused_fip_agent_gw_port: @@ -495,6 +513,7 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin, 'fixed_ips': attributes.ATTR_NOT_SPECIFIED, 'device_id': l3_agent_db['id'], 'device_owner': DEVICE_OWNER_AGENT_GW, + 'binding:host_id': host, 'admin_state_up': True, 'name': ''}}) if agent_port: diff --git a/neutron/tests/unit/db/test_l3_dvr_db.py b/neutron/tests/unit/db/test_l3_dvr_db.py index 943c62293..2e7316463 100644 --- a/neutron/tests/unit/db/test_l3_dvr_db.py +++ b/neutron/tests/unit/db/test_l3_dvr_db.py @@ -331,6 +331,35 @@ class L3DvrTestCase(testlib_api.SqlTestCase): self.ctx, fip, floatingip, mock.ANY) self.assertTrue(vf.called) + def test_create_floatingip_agent_gw_port(self): + fip = { + 'id': _uuid(), + 'port_id': _uuid(), + } + floatingip = { + 'id': _uuid(), + 'fixed_port_id': 1234, + } + port = { + 'id': _uuid(), + 'binding:host_id': 'myhost', + 'network_id': 'external_net' + } + with contextlib.nested( + mock.patch.object(self.mixin, + 'get_vm_port_hostid'), + mock.patch.object(self.mixin, + 'clear_unused_fip_agent_gw_port'), + mock.patch.object(self.mixin, + 'create_fip_agent_gw_port_if_not_exists'), + mock.patch.object(l3_dvr_db.l3_db.L3_NAT_db_mixin, + '_update_fip_assoc'), + ) as (vmp, vf, c_fip, cf): + vmp.return_value = 'my-host' + self.mixin._update_fip_assoc( + self.ctx, fip, floatingip, port) + self.assertTrue(c_fip.called) + def test__validate_router_migration_prevent_check_advanced_svc(self): router = {'name': 'foo_router', 'admin_state_up': True} router_db = self._create_router(router) -- 2.45.2