]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Validate maximum limit for quota
authorliyingjun <yingjun.li@kylin-cloud.com>
Mon, 29 Jun 2015 01:49:34 +0000 (09:49 +0800)
committerliyingjun <yingjun.li@kylin-cloud.com>
Thu, 2 Jul 2015 01:07:12 +0000 (09:07 +0800)
Currently, when updating quota using limit larger than 0x7FFFFFFF,
there will be a DBError. The maximum limit needs to be validated.
And the maximum value is defined by SQL integer type INT, which
is a general value:
http://dev.mysql.com/doc/refman/5.0/en/integer-types.html
http://www.postgresql.org/docs/9.1/static/datatype-numeric.html

Change-Id: I3b4bd3badb84224bd8196c4fdd523c68310809de
Closes-bug: #1433052

cinder/api/contrib/quotas.py
cinder/db/api.py
cinder/tests/unit/api/contrib/test_quotas.py

index ec0536957795daf29c25f16bea2da3e44b1a10cb..937ce86cd8d40cec42522dd11fb9582959c1c334 100644 (file)
@@ -63,9 +63,15 @@ class QuotaSetsController(wsgi.Controller):
             msg = _("Quota limit must be specified as an integer value.")
             raise webob.exc.HTTPBadRequest(explanation=msg)
 
-        # NOTE: -1 is a flag value for unlimited
-        if limit < -1:
-            msg = _("Quota limit must be -1 or greater.")
+        # NOTE: -1 is a flag value for unlimited, maximum value is limited
+        # by SQL standard integer type `INT` which is `0x7FFFFFFF`, it's a
+        # general value for SQL, using a hardcoded value here is not a
+        # `nice` way, but it seems like the only way for now:
+        # http://dev.mysql.com/doc/refman/5.0/en/integer-types.html
+        # http://www.postgresql.org/docs/9.1/static/datatype-numeric.html
+        if limit < -1 or limit > db.MAX_INT:
+            msg = _("Quota limit must be in the range of -1 "
+                    "to %s.") % db.MAX_INT
             raise webob.exc.HTTPBadRequest(explanation=msg)
 
         return limit
index 45a63b318c0823caab4e455181998ff7a6981ff6..60c975c1adb82a0fe0fb8060e6d4c844a4e46794 100644 (file)
@@ -66,6 +66,9 @@ _BACKEND_MAPPING = {'sqlalchemy': 'cinder.db.sqlalchemy.api'}
 
 IMPL = db_concurrency.TpoolDbapiWrapper(CONF, _BACKEND_MAPPING)
 
+# The maximum value a signed INT type may have
+MAX_INT = 0x7FFFFFFF
+
 
 ###################
 
index 591389650cb6d77740eba603c7b9add5d73b55ad..318386676ab27fbd33d5abc2ced059522b6cc231 100644 (file)
@@ -84,6 +84,10 @@ class QuotaSetsControllerTest(test.TestCase):
         result = self.controller.update(self.req, 'foo', body)
         self.assertDictMatch(result, body)
 
+        body = make_body(gigabytes=db.MAX_INT, tenant_id=None)
+        result = self.controller.update(self.req, 'foo', body)
+        self.assertDictMatch(result, body)
+
     def test_update_wrong_key(self):
         body = {'quota_set': {'bad': 'bad'}}
         self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
@@ -113,6 +117,9 @@ class QuotaSetsControllerTest(test.TestCase):
         body = {'quota_set': {'gigabytes': -1000}}
         self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
                           self.req, 'foo', body)
+        body = {'quota_set': {'gigabytes': db.MAX_INT + 1}}
+        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
+                          self.req, 'foo', body)
 
     def test_update_no_admin(self):
         self.req.environ['cinder.context'].is_admin = False