From db5ea5c705757ca20a5789839f96518877c91820 Mon Sep 17 00:00:00 2001 From: berlin Date: Mon, 17 Feb 2014 11:04:08 +0800 Subject: [PATCH] Fix duplicate name of NVP LBaaS objs not allowed on vShield Edge Duplicate name of LBaaS objs such as pool/vip/app_profile is not allowed on vShield Edge, so here a name convention is needed to ensure name uniqueness on the edge side. Closes-Bug: #1257225 Change-Id: I953610d0389a78aa01f378c2ff4931d8c74413ea --- .../vmware/vshield/common/constants.py | 2 ++ .../vshield/edge_loadbalancer_driver.py | 10 +++++--- .../tests/unit/vmware/vshield/fake_vcns.py | 16 ++++++++++-- .../unit/vmware/vshield/test_lbaas_plugin.py | 25 +++++++++++++++++++ .../vshield/test_loadbalancer_driver.py | 23 +++++++++++++++++ 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/neutron/plugins/vmware/vshield/common/constants.py b/neutron/plugins/vmware/vshield/common/constants.py index 8d8ace05f12..1c2aa25db15 100644 --- a/neutron/plugins/vmware/vshield/common/constants.py +++ b/neutron/plugins/vmware/vshield/common/constants.py @@ -33,6 +33,8 @@ APPEND = -1 # error code VCNS_ERROR_CODE_EDGE_NOT_RUNNING = 10013 +SUFFIX_LENGTH = 8 + # router status by number class RouterStatus(object): diff --git a/neutron/plugins/vmware/vshield/edge_loadbalancer_driver.py b/neutron/plugins/vmware/vshield/edge_loadbalancer_driver.py index 63f0bccd954..cb9e24eaa72 100644 --- a/neutron/plugins/vmware/vshield/edge_loadbalancer_driver.py +++ b/neutron/plugins/vmware/vshield/edge_loadbalancer_driver.py @@ -57,7 +57,8 @@ class EdgeLbDriver(): context.session, pool_id, edge_id) pool_vseid = poolid_map['pool_vseid'] return { - 'name': vip.get('name'), + 'name': vip.get( + 'name', '') + vip['id'][-vcns_const.SUFFIX_LENGTH:], 'description': vip.get('description'), 'ipAddress': vip.get('address'), 'protocol': vip.get('protocol'), @@ -74,7 +75,7 @@ class EdgeLbDriver(): vip_vse['defaultPoolId']) return { - 'name': vip_vse['name'], + 'name': vip_vse['name'][:-vcns_const.SUFFIX_LENGTH], 'address': vip_vse['ipAddress'], 'protocol': vip_vse['protocol'], 'protocol_port': vip_vse['port'], @@ -83,7 +84,8 @@ class EdgeLbDriver(): def _convert_lb_pool(self, context, edge_id, pool, members): vsepool = { - 'name': pool.get('name'), + 'name': pool.get( + 'name', '') + pool['id'][-vcns_const.SUFFIX_LENGTH:], 'description': pool.get('description'), 'algorithm': BALANCE_MAP.get( pool.get('lb_method'), @@ -112,7 +114,7 @@ class EdgeLbDriver(): def _restore_lb_pool(self, context, edge_id, pool_vse): #TODO(linb): Get more usefule info return { - 'name': pool_vse['name'], + 'name': pool_vse['name'][:-vcns_const.SUFFIX_LENGTH], } def _convert_lb_monitor(self, context, monitor): diff --git a/neutron/tests/unit/vmware/vshield/fake_vcns.py b/neutron/tests/unit/vmware/vshield/fake_vcns.py index 2e097e89c66..37dcbf53657 100644 --- a/neutron/tests/unit/vmware/vshield/fake_vcns.py +++ b/neutron/tests/unit/vmware/vshield/fake_vcns.py @@ -369,16 +369,24 @@ class FakeVcns(object): break return self.return_helper(header, response) + def is_name_unique(self, objs_dict, name): + return name not in [obj_dict['name'] + for obj_dict in objs_dict.values()] + def create_vip(self, edge_id, vip_new): + header = {'status': 403} + response = "" if not self._fake_virtualservers_dict.get(edge_id): self._fake_virtualservers_dict[edge_id] = {} + if not self.is_name_unique(self._fake_virtualservers_dict[edge_id], + vip_new['name']): + return self.return_helper(header, response) vip_vseid = uuidutils.generate_uuid() self._fake_virtualservers_dict[edge_id][vip_vseid] = vip_new header = { 'status': 204, 'location': "https://host/api/4.0/edges/edge_id" "/loadbalancer/config/%s" % vip_vseid} - response = "" return self.return_helper(header, response) def get_vip(self, edge_id, vip_vseid): @@ -413,15 +421,19 @@ class FakeVcns(object): return self.return_helper(header, response) def create_pool(self, edge_id, pool_new): + header = {'status': 403} + response = "" if not self._fake_pools_dict.get(edge_id): self._fake_pools_dict[edge_id] = {} + if not self.is_name_unique(self._fake_pools_dict[edge_id], + pool_new['name']): + return self.return_helper(header, response) pool_vseid = uuidutils.generate_uuid() self._fake_pools_dict[edge_id][pool_vseid] = pool_new header = { 'status': 204, 'location': "https://host/api/4.0/edges/edge_id" "/loadbalancer/config/%s" % pool_vseid} - response = "" return self.return_helper(header, response) def get_pool(self, edge_id, pool_vseid): diff --git a/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py b/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py index 1b1b67be907..221c41154e8 100644 --- a/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py +++ b/neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py @@ -201,6 +201,31 @@ class TestLoadbalancerPlugin( protocol='TCP', session_persistence={'type': 'HTTP_COOKIE'}) + def test_create_vips_with_same_names(self): + new_router_id = self._create_and_get_router() + with self.subnet() as subnet: + net_id = subnet['subnet']['network_id'] + self._set_net_external(net_id) + with contextlib.nested( + self.vip( + name='vip', + router_id=new_router_id, + subnet=subnet, protocol_port=80), + self.vip( + name='vip', + router_id=new_router_id, + subnet=subnet, protocol_port=81), + self.vip( + name='vip', + router_id=new_router_id, + subnet=subnet, protocol_port=82), + ) as (vip1, vip2, vip3): + req = self.new_list_request('vips') + res = self.deserialize( + self.fmt, req.get_response(self.ext_api)) + for index in range(len(res['vips'])): + self.assertEqual(res['vips'][index]['name'], 'vip') + def test_update_vip(self): name = 'new_vip' router_id = self._create_and_get_router() diff --git a/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py b/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py index 7ff53f32483..db0a7728312 100644 --- a/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py +++ b/neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py @@ -109,6 +109,19 @@ class TestEdgeLbDriver(VcnsDriverTestCase): for k, v in vip_get.iteritems(): self.assertEqual(vip_create[k], v) + def test_create_two_vips_with_same_name(self): + ctx = context.get_admin_context() + with self.pool(no_delete=True) as pool: + self.pool_id = pool['pool']['id'] + POOL_MAP_INFO['pool_id'] = pool['pool']['id'] + vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO) + with self.vip(pool=pool) as res: + vip_create = res['vip'] + self.driver.create_vip(ctx, VSE_ID, vip_create) + self.assertRaises(vcns_exc.Forbidden, + self.driver.create_vip, + ctx, VSE_ID, vip_create) + def test_convert_app_profile(self): app_profile_name = 'app_profile_name' sess_persist1 = {'type': "SOURCE_IP"} @@ -246,6 +259,16 @@ class TestEdgeLbDriver(VcnsDriverTestCase): for k, v in pool_get.iteritems(): self.assertEqual(pool_create[k], v) + def test_create_two_pools_with_same_name(self): + ctx = context.get_admin_context() + with self.pool(no_delete=True) as p: + self.pool_id = p['pool']['id'] + pool_create = p['pool'] + self.driver.create_pool(ctx, VSE_ID, pool_create, []) + self.assertRaises(vcns_exc.Forbidden, + self.driver.create_pool, + ctx, VSE_ID, pool_create, []) + def test_update_pool(self): ctx = context.get_admin_context() with self.pool(no_delete=True) as p: