diff --git a/nova/api/openstack/compute/contrib/quotas.py b/nova/api/openstack/compute/contrib/quotas.py index bdf82ea86e13..728c3fad64da 100644 --- a/nova/api/openstack/compute/contrib/quotas.py +++ b/nova/api/openstack/compute/contrib/quotas.py @@ -23,10 +23,12 @@ from nova.api.openstack import xmlutil from nova import db from nova.db.sqlalchemy import api as sqlalchemy_api from nova import exception +from nova.openstack.common import log as logging from nova import quota QUOTAS = quota.QUOTAS +LOG = logging.getLogger(__name__) authorize_update = extensions.extension_authorizer('compute', 'quotas:update') @@ -88,7 +90,14 @@ class QuotaSetsController(object): project_id = id for key in body['quota_set'].keys(): if key in QUOTAS: - value = int(body['quota_set'][key]) + try: + value = int(body['quota_set'][key]) + except (ValueError, TypeError): + LOG.warn(_("Quota for %s should be integer.") % key) + # NOTE(hzzhoushaoyu): Do not prevent valid value to be + # updated. If raise BadRequest, some may be updated and + # others may be not. + continue self._validate_quota_limit(value) try: db.quota_update(context, project_id, key, value) diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py index 8d518b8159bc..6636824fd723 100644 --- a/nova/tests/api/openstack/compute/contrib/test_quotas.py +++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py @@ -143,6 +143,45 @@ class QuotaSetsTest(test.TestCase): self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, req, 'update_me', body) + def test_quotas_update_invalid_value(self): + expected_resp = {'quota_set': { + 'instances': 50, 'cores': 50, + 'ram': 51200, 'floating_ips': 10, + 'metadata_items': 128, 'injected_files': 5, + 'injected_file_content_bytes': 10240, + 'injected_file_path_bytes': 255, + 'security_groups': 10, + 'security_group_rules': 20, + 'key_pairs': 100}} + + # when PUT JSON format with empty string for quota + body = {'quota_set': {'instances': 50, 'cores': 50, + 'ram': '', 'floating_ips': 10, + 'metadata_items': 128, 'injected_files': 5, + 'injected_file_content_bytes': 10240, + 'injected_file_path_bytes': 255, + 'security_groups': 10, + 'security_group_rules': 20, + 'key_pairs': 100}} + req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me', + use_admin_context=True) + res_dict = self.controller.update(req, 'update_me', body) + self.assertEqual(res_dict, expected_resp) + + # when PUT XML format with empty string for quota + body = {'quota_set': {'instances': 50, 'cores': 50, + 'ram': {}, 'floating_ips': 10, + 'metadata_items': 128, 'injected_files': 5, + 'injected_file_content_bytes': 10240, + 'injected_file_path_bytes': 255, + 'security_groups': 10, + 'security_group_rules': 20, + 'key_pairs': 100}} + req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me', + use_admin_context=True) + res_dict = self.controller.update(req, 'update_me', body) + self.assertEqual(res_dict, expected_resp) + class QuotaXMLSerializerTest(test.TestCase): def setUp(self):