From d181a85200de3805e0a245c003a9c7ea8568f747 Mon Sep 17 00:00:00 2001 From: Tong Liu Date: Mon, 13 Nov 2017 10:59:07 -0800 Subject: [PATCH] NSXv3: Add validation when attaching lbs to router To attach lb service to tenant router, router needs to connect to external gateway. This patch adds validation and raises exception if router doesn't connect to external gateway. Change-Id: I9379b6bf9283a3521ea3400f1db07ae696bc47f1 --- .../services/lbaas/nsx_v3/member_mgr.py | 5 +++ .../unit/services/lbaas/test_nsxv3_driver.py | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/vmware_nsx/services/lbaas/nsx_v3/member_mgr.py b/vmware_nsx/services/lbaas/nsx_v3/member_mgr.py index 9e06667d7f..cda8427b48 100644 --- a/vmware_nsx/services/lbaas/nsx_v3/member_mgr.py +++ b/vmware_nsx/services/lbaas/nsx_v3/member_mgr.py @@ -52,6 +52,11 @@ class EdgeMemberManager(base_mgr.Nsxv3LoadbalancerBaseManager): def _create_lb_service(self, context, service_client, tenant_id, router_id, nsx_router_id, lb_id, lb_size): router = self.core_plugin.get_router(context, router_id) + if not router.get('external_gateway_info'): + msg = (_('Tenant router %(router)s does not connect to ' + 'external gateway') % {'router': router['id']}) + raise n_exc.BadRequest(resource='lbaas-lbservice-create', + msg=msg) lb_name = utils.get_name_and_uuid(router['name'], router_id) tags = lb_utils.get_tags(self.core_plugin, router_id, diff --git a/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py b/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py index 58d4b5b004..f754697fca 100644 --- a/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py +++ b/vmware_nsx/tests/unit/services/lbaas/test_nsxv3_driver.py @@ -17,6 +17,7 @@ import mock from neutron.tests import base from neutron_lbaas.services.loadbalancer import data_models as lb_models from neutron_lib import context +from neutron_lib import exceptions as n_exc from vmware_nsx.db import db as nsx_db from vmware_nsx.services.lbaas import base_mgr @@ -514,6 +515,40 @@ class TestEdgeLbaasV2Member(BaseTestEdgeLbaasV2): mock_successful_completion.assert_called_with(self.context, self.member) + def test_create_lbs_no_router_gateway(self): + with mock.patch.object(lb_utils, 'validate_lb_subnet' + ) as mock_validate_lb_subnet, \ + mock.patch.object(self.lbv2_driver.plugin, 'get_pool_members' + ) as mock_get_pool_members, \ + mock.patch.object(lb_utils, 'get_network_from_subnet' + ) as mock_get_network, \ + mock.patch.object(lb_utils, 'get_router_from_network' + ) as mock_get_router_from_network, \ + mock.patch.object(nsx_db, 'get_nsx_lbaas_pool_binding' + ) as mock_get_pool_binding, \ + mock.patch.object(nsx_db, 'get_nsx_lbaas_loadbalancer_binding' + ) as mock_get_lb_binding, \ + mock.patch.object(nsx_db, 'get_nsx_router_id' + ) as mock_get_nsx_router_id, \ + mock.patch.object(self.service_client, 'get_router_lb_service' + ) as mock_get_lb_service, \ + mock.patch.object(self.core_plugin, 'get_router' + ) as mock_get_router: + mock_validate_lb_subnet.return_value = True + mock_get_pool_members.return_value = [self.member] + mock_get_network.return_value = LB_NETWORK + mock_get_router_from_network.return_value = LB_ROUTER_ID + mock_get_pool_binding.return_value = POOL_BINDING + mock_get_lb_binding.return_value = None + mock_get_nsx_router_id.return_value = LB_ROUTER_ID + mock_get_lb_service.return_value = None + mock_get_router.return_value = {'id': 'router1-xxx'} + + self.assertRaises(n_exc.BadRequest, + self.edge_driver.member.create, + self.context, + self.member) + def test_update(self): new_member = lb_models.Member(MEMBER_ID, LB_TENANT_ID, POOL_ID, MEMBER_ADDRESS, 80, 1, pool=self.pool,