From: Swaminathan Vasudevan Date: Tue, 29 Jul 2014 23:34:58 +0000 (-0700) Subject: Fix-DVR Gateway clear doesn't delete csnat port X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=86a0adefe326116ae42c0e01a8fa2c2849bfa2c2;p=openstack-build%2Fneutron-build.git Fix-DVR Gateway clear doesn't delete csnat port When a gateway is set to a distributed router, the router checks for the interfaces associated with the router and based on the number of interfaces the router creates "csnat" interface ports that would be used by the SNAT service in the Service Node. When a gateway is cleared, the plugin should delete the "csnat" interface ports. In the current code, it is deleting the port and re-creating the port with a different id. A check need to be made before it creates a new port to make sure that the router has a valid gateway port. This is a bug and this patch fixes this issue. Change-Id: I84f1795360b3693a025b5fa3454bf9efc7e503ae Closes-Bug: #1350089 --- diff --git a/neutron/db/l3_dvr_db.py b/neutron/db/l3_dvr_db.py index 2024b0d98..a77252de5 100644 --- a/neutron/db/l3_dvr_db.py +++ b/neutron/db/l3_dvr_db.py @@ -116,7 +116,7 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin, super(L3_NAT_with_dvr_db_mixin, self)._create_gw_port(context, router_id, router, new_network) - if router.extra_attributes.distributed: + if router.extra_attributes.distributed and router.gw_port: snat_p_list = self.create_snat_intf_ports_if_not_exists( context.elevated(), router['id']) if not snat_p_list: diff --git a/neutron/tests/unit/db/test_l3_dvr_db.py b/neutron/tests/unit/db/test_l3_dvr_db.py index caa288412..c0329ee6f 100644 --- a/neutron/tests/unit/db/test_l3_dvr_db.py +++ b/neutron/tests/unit/db/test_l3_dvr_db.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import contextlib import mock from neutron.common import constants as l3_const @@ -147,3 +148,22 @@ class L3DvrTestCase(base.BaseTestCase): 'network_id': ['network_id'], 'device_id': ['agent_id'], 'device_owner': [l3_const.DEVICE_OWNER_AGENT_GW]}) + + def test__create_gw_port_with_no_gateway(self): + router = { + 'name': 'foo_router', + 'admin_state_up': True, + 'distributed': True, + } + router_db = self._create_router(router) + router_id = router_db['id'] + self.assertTrue(router_db.extra_attributes.distributed) + with contextlib.nested( + mock.patch.object(l3_dvr_db.l3_db.L3_NAT_db_mixin, + '_create_gw_port'), + mock.patch.object(self.mixin, + 'create_snat_intf_ports_if_not_exists') + ) as (cw, cs): + self.mixin._create_gw_port( + self.ctx, router_id, router_db, mock.ANY) + self.assertFalse(cs.call_count)