]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Allow CIDRs with non-zero masked portions
authorKevin Benton <blak111@gmail.com>
Tue, 18 Mar 2014 00:06:46 +0000 (17:06 -0700)
committerKevin Benton <blak111@gmail.com>
Wed, 19 Mar 2014 02:07:12 +0000 (19:07 -0700)
Allow users to specify CIDRs with bits other
than zeros in the masked portion of the subnet.
e.g. 192.168.1.5/24 is accepted and converted
to 192.168.1.0/24.

Closes-Bug: #1204173
Change-Id: I7ddff41e6988feb6e2a87e40a4d99db7174415b1

neutron/api/v2/attributes.py
neutron/db/db_base_plugin_v2.py
neutron/tests/unit/test_attributes.py
neutron/tests/unit/test_db_plugin.py

index 1b90bb73ad71cc107b8a26aacb7ae9505a198ad4..8a2f74cf2b83bb29ce4aa946cbdfeef20a137e1a 100644 (file)
@@ -291,7 +291,7 @@ def _validate_subnet(data, valid_values=None):
     msg = None
     try:
         net = netaddr.IPNetwork(_validate_no_whitespace(data))
-        if ('/' not in data or net.network != net.ip):
+        if '/' not in data:
             msg = _("'%(data)s' isn't a recognized IP subnet cidr,"
                     " '%(cidr)s' is recommended") % {"data": data,
                                                      "cidr": net.cidr}
index b7ad1ecff602fd250e614cb868c69d1fa257de31..875582f15f945960bbc127ee39b5ab34a21dbe9a 100644 (file)
@@ -1062,8 +1062,11 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
 
     def create_subnet(self, context, subnet):
 
+        net = netaddr.IPNetwork(subnet['subnet']['cidr'])
+        # turn the CIDR into a proper subnet
+        subnet['subnet']['cidr'] = '%s/%s' % (net.network, net.prefixlen)
+
         s = subnet['subnet']
-        net = netaddr.IPNetwork(s['cidr'])
 
         if s['gateway_ip'] is attributes.ATTR_NOT_SPECIFIED:
             s['gateway_ip'] = str(netaddr.IPAddress(net.first + 1))
index b4a44a6eda68a5d6f05f72743bbd04ca67566448..53edc26933bca7eeb97997e23776d7661a82c688 100644 (file)
@@ -459,13 +459,11 @@ class TestAttributes(base.BaseTestCase):
                                                    "cidr": "10.0.2.0/32"}
         self.assertEqual(msg, error)
 
-        # Invalid - IPv4 with final octets
-        cidr = "192.168.1.1/24"
-        msg = validator(cidr, None)
-        error = _("'%(data)s' isn't a recognized IP subnet cidr,"
-                  " '%(cidr)s' is recommended") % {"data": cidr,
-                                                   "cidr": "192.168.1.0/24"}
-        self.assertEqual(msg, error)
+        # Valid - IPv4 with non-zero masked bits is ok
+        for i in range(1, 255):
+            cidr = "192.168.1.%s/24" % i
+            msg = validator(cidr, None)
+            self.assertIsNone(msg)
 
         # Invalid - IPv6 without final octets, missing mask
         cidr = "fe80::"
index c7e780ac069df913a53db0a7aa463f2661274d1b..0194c1716587b2b57f3a39583ef71c77d3072307 100644 (file)
@@ -2503,16 +2503,26 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
                                 device_owner='fake_owner',
                                 set_context=False)
 
-    def test_create_subnet_bad_cidr(self):
-        with self.network() as network:
-            data = {'subnet': {'network_id': network['network']['id'],
-                               'cidr': '10.0.2.5/24',
-                               'ip_version': 4,
-                               'tenant_id': network['network']['tenant_id']}}
-
-            subnet_req = self.new_create_request('subnets', data)
-            res = subnet_req.get_response(self.api)
-            self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code)
+    def test_create_subnet_nonzero_cidr(self):
+        with contextlib.nested(
+            self.subnet(cidr='10.129.122.5/8'),
+            self.subnet(cidr='11.129.122.5/15'),
+            self.subnet(cidr='12.129.122.5/16'),
+            self.subnet(cidr='13.129.122.5/18'),
+            self.subnet(cidr='14.129.122.5/22'),
+            self.subnet(cidr='15.129.122.5/24'),
+            self.subnet(cidr='16.129.122.5/28'),
+            self.subnet(cidr='17.129.122.5/32')
+        ) as subs:
+            # the API should accept and correct these for users
+            self.assertEqual(subs[0]['subnet']['cidr'], '10.0.0.0/8')
+            self.assertEqual(subs[1]['subnet']['cidr'], '11.128.0.0/15')
+            self.assertEqual(subs[2]['subnet']['cidr'], '12.129.0.0/16')
+            self.assertEqual(subs[3]['subnet']['cidr'], '13.129.64.0/18')
+            self.assertEqual(subs[4]['subnet']['cidr'], '14.129.120.0/22')
+            self.assertEqual(subs[5]['subnet']['cidr'], '15.129.122.0/24')
+            self.assertEqual(subs[6]['subnet']['cidr'], '16.129.122.0/28')
+            self.assertEqual(subs[7]['subnet']['cidr'], '17.129.122.5/32')
 
     def test_create_subnet_bad_ip_version(self):
         with self.network() as network: