]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix duplicate name of NVP LBaaS objs not allowed on vShield Edge
authorberlin <linb@vmware.com>
Mon, 17 Feb 2014 03:04:08 +0000 (11:04 +0800)
committerberlin <linb@vmware.com>
Thu, 20 Mar 2014 06:26:24 +0000 (14:26 +0800)
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

neutron/plugins/vmware/vshield/common/constants.py
neutron/plugins/vmware/vshield/edge_loadbalancer_driver.py
neutron/tests/unit/vmware/vshield/fake_vcns.py
neutron/tests/unit/vmware/vshield/test_lbaas_plugin.py
neutron/tests/unit/vmware/vshield/test_loadbalancer_driver.py

index 8d8ace05f1210ad9ce14ce3a6454e1c4a7344a10..1c2aa25db151b94821ad95d236e7d6c96ce3e75a 100644 (file)
@@ -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):
index 63f0bccd9544a24afdcb15718b6255b4087a2bd0..cb9e24eaa725e75612be9bf2a957b214517ea738 100644 (file)
@@ -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):
index 2e097e89c66537809288a9069c46626fc3835652..37dcbf536571f07f1d39051c362885b91458cc3a 100644 (file)
@@ -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):
index 1b1b67be907fc20fcb5f535ec4ee211f1b1add95..221c41154e8abbffd000b04ea45f79d62037df20 100644 (file)
@@ -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()
index 7ff53f324837cbecdf63a4b95b76c79929d8eb5f..db0a77283129dfc8f1604af342c1ff690af6f8ce 100644 (file)
@@ -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: