def quota(self, project_id, key=None, value=None): """ Create, update or display quotas for project If no quota key is provided, the quota will be displayed. If a valid quota key is provided and it does not exist, it will be created. Otherwise, it will be updated. """ ctxt = context.get_admin_context() project_quota = QUOTAS.get_project_quotas(ctxt, project_id) # if key is None, that means we need to show the quotas instead # of updating them if key: if key in project_quota: if value.lower() == "unlimited": value = -1 try: db.quota_update(ctxt, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(ctxt, project_id, key, value) else: print _("%(key)s is not a valid quota key. Valid options are: " "%(options)s.") % { "key": key, "options": ", ".join(project_quota), } return 2 print_format = "%-36s %-10s %-10s %-10s" print print_format % (_("Quota"), _("Limit"), _("In Use"), _("Reserved")) # Retrieve the quota after update project_quota = QUOTAS.get_project_quotas(ctxt, project_id) for key, value in project_quota.iteritems(): if value["limit"] < 0 or value["limit"] is None: value["limit"] = "unlimited" print print_format % (key, value["limit"], value["in_use"], value["reserved"])
def test_quota_overrides(self): """Make sure overriding a projects quotas works""" num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 2) db.quota_create(self.context, {'project_id': self.project.id, 'instances': 10}) num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 10) # metadata_items too_many_items = FLAGS.quota_metadata_items + 1000 num_metadata_items = quota.allowed_metadata_items(self.context, too_many_items) self.assertEqual(num_metadata_items, FLAGS.quota_metadata_items) db.quota_update(self.context, self.project.id, {'metadata_items': 5}) num_metadata_items = quota.allowed_metadata_items(self.context, too_many_items) self.assertEqual(num_metadata_items, 5) # Cleanup db.quota_destroy(self.context, self.project.id)
def test_quota_overrides(self): """Make sure overriding a projects quotas works""" num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 2) db.quota_create(self.context, { 'project_id': self.project.id, 'instances': 10 }) num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 10) # metadata_items too_many_items = FLAGS.quota_metadata_items + 1000 num_metadata_items = quota.allowed_metadata_items( self.context, too_many_items) self.assertEqual(num_metadata_items, FLAGS.quota_metadata_items) db.quota_update(self.context, self.project.id, {'metadata_items': 5}) num_metadata_items = quota.allowed_metadata_items( self.context, too_many_items) self.assertEqual(num_metadata_items, 5) # Cleanup db.quota_destroy(self.context, self.project.id)
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id bad_keys = [] for key in body['quota_set'].keys(): if (key not in QUOTAS and key != 'tenant_id' and key != 'id'): bad_keys.append(key) if len(bad_keys) > 0: msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys) raise webob.exc.HTTPBadRequest(explanation=msg) for key in body['quota_set'].keys(): 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) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id)}
def test_unlimited_metadata_items(self): FLAGS.quota_metadata_items = 10 items = quota.allowed_metadata_items(self.context, 100) self.assertEqual(items, 10) db.quota_create(self.context, self.project_id, 'metadata_items', None) items = quota.allowed_metadata_items(self.context, 100) self.assertEqual(items, 100) items = quota.allowed_metadata_items(self.context, 101) self.assertEqual(items, 101)
def test_unlimited_floating_ips(self): FLAGS.quota_floating_ips = 10 floating_ips = quota.allowed_floating_ips(self.context, 100) self.assertEqual(floating_ips, 10) db.quota_create(self.context, self.project_id, 'floating_ips', None) floating_ips = quota.allowed_floating_ips(self.context, 100) self.assertEqual(floating_ips, 100) floating_ips = quota.allowed_floating_ips(self.context, 101) self.assertEqual(floating_ips, 101)
def test_unlimited_gigabytes(self): self.flags(quota_volumes=-1, quota_gigabytes=10) volumes = quota.allowed_volumes(self.context, 100, 1) self.assertEqual(volumes, 10) db.quota_create(self.context, self.project_id, "gigabytes", None) volumes = quota.allowed_volumes(self.context, 100, 1) self.assertEqual(volumes, 100) volumes = quota.allowed_volumes(self.context, 101, 1) self.assertEqual(volumes, 101)
def test_unlimited_floating_ips(self): self.flags(quota_floating_ips=10) floating_ips = quota.allowed_floating_ips(self.context, 100) self.assertEqual(floating_ips, 10) db.quota_create(self.context, self.project_id, "floating_ips", None) floating_ips = quota.allowed_floating_ips(self.context, 100) self.assertEqual(floating_ips, 100) floating_ips = quota.allowed_floating_ips(self.context, 101) self.assertEqual(floating_ips, 101)
def test_unlimited_key_pairs(self): self.flags(quota_key_pairs=10) key_pairs = quota.allowed_key_pairs(self.context, 100) self.assertEqual(key_pairs, 10) db.quota_create(self.context, self.project_id, 'key_pairs', -1) key_pairs = quota.allowed_key_pairs(self.context, 100) self.assertEqual(key_pairs, 100) key_pairs = quota.allowed_key_pairs(self.context, 101) self.assertEqual(key_pairs, 101)
def test_unlimited_security_groups(self): self.flags(quota_security_groups=10) security_groups = quota.allowed_security_groups(self.context, 100) self.assertEqual(security_groups, 10) db.quota_create(self.context, self.project_id, 'security_groups', None) security_groups = quota.allowed_security_groups(self.context, 100) self.assertEqual(security_groups, 100) security_groups = quota.allowed_security_groups(self.context, 101) self.assertEqual(security_groups, 101)
def test_unlimited_metadata_items(self): self.flags(quota_metadata_items=10) items = quota.allowed_metadata_items(self.context, 100) self.assertEqual(items, 10) db.quota_create(self.context, self.project_id, "metadata_items", None) items = quota.allowed_metadata_items(self.context, 100) self.assertEqual(items, 100) items = quota.allowed_metadata_items(self.context, 101) self.assertEqual(items, 101)
def test_unlimited_floating_ips(self): self.flags(quota_floating_ips=10) floating_ips = quota.allowed_floating_ips(self.context, 100) self.assertEqual(floating_ips, 10) db.quota_create(self.context, self.project_id, 'floating_ips', None) floating_ips = quota.allowed_floating_ips(self.context, 100) self.assertEqual(floating_ips, 100) floating_ips = quota.allowed_floating_ips(self.context, 101) self.assertEqual(floating_ips, 101)
def test_unlimited_gigabytes(self): self.flags(quota_volumes=-1, quota_gigabytes=10) volumes = quota.allowed_volumes(self.context, 100, 1) self.assertEqual(volumes, 10) db.quota_create(self.context, self.project_id, 'gigabytes', None) volumes = quota.allowed_volumes(self.context, 100, 1) self.assertEqual(volumes, 100) volumes = quota.allowed_volumes(self.context, 101, 1) self.assertEqual(volumes, 101)
def test_unlimited_metadata_items(self): self.flags(quota_metadata_items=10) items = quota.allowed_metadata_items(self.context, 100) self.assertEqual(items, 10) db.quota_create(self.context, self.project_id, 'metadata_items', None) items = quota.allowed_metadata_items(self.context, 100) self.assertEqual(items, 100) items = quota.allowed_metadata_items(self.context, 101) self.assertEqual(items, 101)
def test_unlimited_cores(self): self.flags(quota_instances=-1, quota_ram=-1, quota_cores=2) instance_type = self._get_instance_type("m1.small") num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, "cores", None) num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 100) num_instances = quota.allowed_instances(self.context, 101, instance_type) self.assertEqual(num_instances, 101)
def test_unlimited_gigabytes(self): FLAGS.quota_volumes = -1 FLAGS.quota_gigabytes = 10 volumes = quota.allowed_volumes(self.context, 100, 1) self.assertEqual(volumes, 10) db.quota_create(self.context, self.project_id, 'gigabytes', None) volumes = quota.allowed_volumes(self.context, 100, 1) self.assertEqual(volumes, 100) volumes = quota.allowed_volumes(self.context, 101, 1) self.assertEqual(volumes, 101)
def test_unlimited_cores(self): FLAGS.quota_instances = 1000 FLAGS.quota_cores = 2 instance_type = self._get_instance_type("m1.small") num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project.id, "cores", None) num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 100) num_instances = quota.allowed_instances(self.context, 101, instance_type) self.assertEqual(num_instances, 101)
def test_bless_quota(self): def assert_quotas(expected_increased): _pre_usages = dict(pre_usages) _pre_usages.pop('project_id', None) post_usages = sqlalchemy_db.quota_usage_get_all_by_project(self.context, self.context.project_id) # Need to assert something about the quota consumption for quota_key in ['instances', 'ram', 'cores']: pre_usage = _pre_usages.pop(quota_key) self.assertEquals(pre_usage.get('in_use',0) + expected_increased[quota_key], post_usages[quota_key].get('in_use',0)) self.assertEquals(pre_usage.get('reserved',0), post_usages[quota_key].get('reserved',0)) for key, quota_usage in _pre_usages.iteritems(): self.assertEquals(quota_usage.get('reserved', 0), post_usages[key].get('reserved', 0)) self.assertEquals(quota_usage.get('in_use', 0), post_usages[key].get('in_use', 0)) instance_uuid = utils.create_instance(self.context) instance = db.instance_get_by_uuid(self.context, instance_uuid) # Set the quota so that we can have two blessed instances (+ the instance we are blessing). db.quota_create(self.context, self.context.project_id, 'ram', 3 * instance['memory_mb']) pre_usages = sqlalchemy_db.quota_usage_get_all_by_project(self.context, self.context.project_id) # The amount of resources a blessed instance consumes. blessed_uuids = [] for i in range(1, 3): blessed_uuids.append( self.cobalt_api.bless_instance(self.context, instance_uuid)['uuid']) expected = dict(zip(['instances', 'ram', 'cores'], map(lambda x: i * x, [1, instance['memory_mb'], instance['vcpus']]))) assert_quotas(expected) try: self.cobalt_api.bless_instance(self.context, instance_uuid) self.fail("We should not have the quota to bless one more instance.") except exception.TooManyInstances: pass # Discard the blessed uuid and ensure that the quota increases. remaining = len(blessed_uuids) for blessed_uuid in blessed_uuids: self.cobalt_api.discard_instance(self.context, blessed_uuid) remaining -= 1 expected = dict(zip(['instances', 'ram', 'cores'], map(lambda x: remaining * x, [1, instance['memory_mb'], instance['vcpus']]))) assert_quotas(expected)
def test_unlimited_ram(self): self.flags(quota_instances=-1, quota_ram=2 * 2048, quota_cores=-1) instance_type = self._get_instance_type('m1.small') num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, 'ram', -1) num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 100) num_instances = quota.allowed_instances(self.context, 101, instance_type) self.assertEqual(num_instances, 101)
def test_unlimited_cores(self): self.flags(quota_instances=-1, quota_ram=-1, quota_cores=2) instance_type = self._get_instance_type('m1.small') num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, 'cores', None) num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 100) num_instances = quota.allowed_instances(self.context, 101, instance_type) self.assertEqual(num_instances, 101)
def update(self, req, id, body): context = req.environ['nova.context'] project_id = id for key in body['quota_set'].keys(): if key in quota_resources: value = int(body['quota_set'][key]) try: db.quota_update(context, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': quota.get_project_quotas(context, project_id)}
def test_quota_overrides(self): """Make sure overriding a projects quotas works""" num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, 'instances', 10) num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 4) db.quota_create(self.context, self.project_id, 'cores', 100) num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 10) db.quota_create(self.context, self.project_id, 'ram', 3 * 2048) num_instances = quota.allowed_instances(self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 3) # metadata_items too_many_items = FLAGS.quota_metadata_items + 1000 num_metadata_items = quota.allowed_metadata_items(self.context, too_many_items) self.assertEqual(num_metadata_items, FLAGS.quota_metadata_items) db.quota_create(self.context, self.project_id, 'metadata_items', 5) num_metadata_items = quota.allowed_metadata_items(self.context, too_many_items) self.assertEqual(num_metadata_items, 5) # Cleanup db.quota_destroy_all_by_project(self.context, self.project_id)
def test_quota_overrides(self): """Make sure overriding a projects quotas works""" num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, 'instances', 10) num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 4) db.quota_create(self.context, self.project_id, 'cores', 100) num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 10) db.quota_create(self.context, self.project_id, 'ram', 3 * 2048) num_instances = quota.allowed_instances( self.context, 100, self._get_instance_type('m1.small')) self.assertEqual(num_instances, 3) # metadata_items too_many_items = FLAGS.quota_metadata_items + 1000 num_metadata_items = quota.allowed_metadata_items( self.context, too_many_items) self.assertEqual(num_metadata_items, FLAGS.quota_metadata_items) db.quota_create(self.context, self.project_id, 'metadata_items', 5) num_metadata_items = quota.allowed_metadata_items( self.context, too_many_items) self.assertEqual(num_metadata_items, 5) # Cleanup db.quota_destroy_all_by_project(self.context, self.project_id)
def update(self, req, id, body): context = req.environ['nova.context'] project_id = id resources = ['metadata_items', 'injected_file_content_bytes', 'volumes', 'gigabytes', 'ram', 'floating_ips', 'instances', 'injected_files', 'cores'] for key in body['quota_set'].keys(): if key in resources: value = int(body['quota_set'][key]) try: db.quota_update(context, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) return {'quota_set': quota.get_project_quotas(context, project_id)}
def test_quota_overrides(self): """Make sure overriding a projects quotas works""" num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 2) db.quota_create(self.context, {'project_id': self.project.id, 'instances': 10}) num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 4) db.quota_update(self.context, self.project.id, {'cores': 100}) num_instances = quota.allowed_instances(self.context, 100, instance_types.INSTANCE_TYPES['m1.small']) self.assertEqual(num_instances, 10) db.quota_destroy(self.context, self.project.id)
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id for key in body['quota_set'].keys(): if key in QUOTAS: value = int(body['quota_set'][key]) self._validate_quota_limit(value) try: db.quota_update(context, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id)}
def test_unlimited_cores(self): FLAGS.quota_instances = -1 FLAGS.quota_ram = -1 FLAGS.quota_cores = 2 instance_type = self._get_instance_type('m1.small') num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, 'cores', None) num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 100) num_instances = quota.allowed_instances(self.context, 101, instance_type) self.assertEqual(num_instances, 101)
def test_unlimited_ram(self): FLAGS.quota_instances = -1 FLAGS.quota_ram = 2 * 2048 FLAGS.quota_cores = -1 instance_type = self._get_instance_type('m1.small') num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 2) db.quota_create(self.context, self.project_id, 'ram', None) num_instances = quota.allowed_instances(self.context, 100, instance_type) self.assertEqual(num_instances, 100) num_instances = quota.allowed_instances(self.context, 101, instance_type) self.assertEqual(num_instances, 101)
def test_unlimited_security_group_rules(self): def fake_security_group_rule_count_by_group(context, sec_group_id): return 0 self.stubs.Set(db, 'security_group_rule_count_by_group', fake_security_group_rule_count_by_group) self.flags(quota_security_group_rules=20) rules = quota.allowed_security_group_rules(self.context, 1234, 100) self.assertEqual(rules, 20) db.quota_create(self.context, self.project_id, 'security_group_rules', None) rules = quota.allowed_security_group_rules(self.context, 1234, 100) self.assertEqual(rules, 100) rules = quota.allowed_security_group_rules(self.context, 1234, 101) self.assertEqual(rules, 101)
def quota(self, project_id, key=None, value=None): """ Create, update or display quotas for project If no quota key is provided, the quota will be displayed. If a valid quota key is provided and it does not exist, it will be created. Otherwise, it will be updated. """ ctxt = context.get_admin_context() project_quota = QUOTAS.get_project_quotas(ctxt, project_id) # if key is None, that means we need to show the quotas instead # of updating them if key: if key in project_quota: if value.lower() == 'unlimited': value = -1 try: db.quota_update(ctxt, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(ctxt, project_id, key, value) else: print _('%(key)s is not a valid quota key. Valid options are: ' '%(options)s.') % {'key': key, 'options': ', '.join(project_quota)} return(2) print_format = "%-36s %-10s %-10s %-10s" print print_format % ( _('Quota'), _('Limit'), _('In Use'), _('Reserved')) # Retrieve the quota after update project_quota = QUOTAS.get_project_quotas(ctxt, project_id) for key, value in project_quota.iteritems(): if value['limit'] < 0 or value['limit'] is None: value['limit'] = 'unlimited' print print_format % (key, value['limit'], value['in_use'], value['reserved'])
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id for key in body['quota_set'].keys(): if key in QUOTAS: 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) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id)}
def update(self, req, id, body): context = req.environ['nova.context'] params = self._request_params(req) project_id = id user_id = None remains = {} quotas = {} if 'user_id' in params: # Project admins are able to modify per-user quotas. authorize_action(context, 'update_for_user') user_id = params["user_id"][0] remains = self._get_quotas(context, project_id, remaining=True) quotas = db.quota_get_all_by_user(context, user_id, project_id) else: # Only admins are able to modify per-project quotas. authorize_action(context, 'update_for_project') for key in body['quota_set'].keys(): if key in QUOTAS: value = int(body['quota_set'][key]) try: if user_id: self._validate_quota_limit(value, remains.get(key, 0), quotas.get(key, 0)) db.quota_update_for_user(context, user_id, project_id, key, value) else: self._validate_quota_limit(value, remains.get(key, -1), quotas.get(key, 0)) db.quota_update(context, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) except exception.UserQuotaNotFound: db.quota_create_for_user(context, user_id, project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id, user_id)}
def update(self, req, id, body): context = req.environ["nova.context"] project_id = id resources = [ "metadata_items", "injected_file_content_bytes", "volumes", "gigabytes", "ram", "floating_ips", "instances", "injected_files", "cores", ] for key in body["quota_set"].keys(): if key in resources: value = int(body["quota_set"][key]) try: db.quota_update(context, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) return {"quota_set": quota.get_project_quotas(context, project_id)}
def _do_test_volume_quota(self, resource): def _validate(result, request, quota, allow): overs = result['overs'] usages = result['usages'] quotas = result['quotas'] allowed = result['allowed'] self.assertEquals(request > allow, resource in overs) self.assertEquals(usages[resource], 0) self.assertEquals(quotas[resource], quota) self.assertEquals(allowed[resource], allow) quota_volumes = 10 if resource == 'volumes' else -1 quota_gigabytes = 10 if resource == 'gigabytes' else -1 self.flags(quota_volumes=quota_volumes, quota_gigabytes=quota_gigabytes) _validate(quota.allowed_volumes(self.context, 100, 1), 100, 10, 10) db.quota_create(self.context, self.project_id, resource, None) _validate(quota.allowed_volumes(self.context, 100, 1), 100, None, 100) db.quota_create(self.context, self.project_id, resource, -1) _validate(quota.allowed_volumes(self.context, 100, 1), 100, None, 100) _validate(quota.allowed_volumes(self.context, 101, 1), 101, None, 101)
def test_unlimited_db_allowed_injected_files(self): self.flags(quota_max_injected_files=5) db.quota_create(self.context, self.project_id, "injected_files", None) self.assertEqual(quota.allowed_injected_files(self.context, 100), 100)
def test_overridden_allowed_injected_files(self): self.flags(quota_max_injected_files=5) db.quota_create(self.context, self.project_id, "injected_files", 77) self.assertEqual(quota.allowed_injected_files(self.context, 100), 77)
def test_overridden_allowed_injected_file_content_bytes(self): FLAGS.quota_max_injected_file_content_bytes = 12345 db.quota_create(self.context, self.project_id, 'injected_file_content_bytes', 5678) limit = quota.allowed_injected_file_content_bytes(self.context, 23456) self.assertEqual(limit, 5678)
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id bad_keys = [] # By default, we can force update the quota if the extended # is not loaded force_update = True extended_loaded = False if self.ext_mgr.is_loaded('os-extended-quotas'): # force optional has been enabled, the default value of # force_update need to be changed to False extended_loaded = True force_update = False user_id = None if self.ext_mgr.is_loaded('os-user-quotas'): # Update user quotas only if the extended is loaded params = urlparse.parse_qs(req.environ.get('QUERY_STRING', '')) user_id = params.get('user_id', [None])[0] try: settable_quotas = QUOTAS.get_settable_quotas(context, project_id, user_id=user_id) except exception.Forbidden: raise webob.exc.HTTPForbidden() if not self.is_valid_body(body, 'quota_set'): msg = _("quota_set not specified") raise webob.exc.HTTPBadRequest(explanation=msg) quota_set = body['quota_set'] for key, value in quota_set.items(): if (key not in QUOTAS and key not in NON_QUOTA_KEYS): bad_keys.append(key) continue if key == 'force' and extended_loaded: # only check the force optional when the extended has # been loaded force_update = strutils.bool_from_string(value) elif key not in NON_QUOTA_KEYS and value: try: value = utils.validate_integer(value, key) except exception.InvalidInput as e: raise webob.exc.HTTPBadRequest( explanation=e.format_message()) LOG.debug("force update quotas: %s", force_update) if len(bad_keys) > 0: msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys) raise webob.exc.HTTPBadRequest(explanation=msg) try: quotas = self._get_quotas(context, id, user_id=user_id, usages=True) except exception.Forbidden: raise webob.exc.HTTPForbidden() for key, value in quota_set.items(): if key in NON_QUOTA_KEYS or (not value and value != 0): continue # validate whether already used and reserved exceeds the new # quota, this check will be ignored if admin want to force # update value = int(value) if force_update is not True and value >= 0: quota_value = quotas.get(key) if quota_value and quota_value['limit'] >= 0: quota_used = (quota_value['in_use'] + quota_value['reserved']) LOG.debug( "Quota %(key)s used: %(quota_used)s, " "value: %(value)s.", { 'key': key, 'quota_used': quota_used, 'value': value }) if quota_used > value: msg = (_("Quota value %(value)s for %(key)s are " "less than already used and reserved " "%(quota_used)s") % { 'value': value, 'key': key, 'quota_used': quota_used }) raise webob.exc.HTTPBadRequest(explanation=msg) minimum = settable_quotas[key]['minimum'] maximum = settable_quotas[key]['maximum'] self._validate_quota_limit(value, minimum, maximum) try: db.quota_create(context, project_id, key, value, user_id=user_id) except exception.QuotaExists: db.quota_update(context, project_id, key, value, user_id=user_id) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id, user_id=user_id)}
def test_unlimited_db_allowed_injected_files(self): self.flags(quota_max_injected_files=5) db.quota_create(self.context, self.project_id, 'injected_files', None) self.assertEqual(quota.allowed_injected_files(self.context, 100), 100)
def test_unlimited_db_allowed_injected_file_content_bytes(self): self.flags(quota_max_injected_file_content_bytes=12345) db.quota_create(self.context, self.project_id, 'injected_file_content_bytes', None) limit = quota.allowed_injected_file_content_bytes(self.context, 23456) self.assertEqual(limit, 23456)
def create_limit(cls, context, project_id, resource, limit, user_id=None): # NOTE(danms,comstud): Quotas likely needs an overhaul and currently # doesn't map very well to objects. Since there is quite a bit of # logic in the db api layer for this, just pass this through for now. db.quota_create(context, project_id, resource, limit, user_id=user_id)
def quota(self, project_id, user_id=None, key=None, value=None): """Create, update or display quotas for project/user If no quota key is provided, the quota will be displayed. If a valid quota key is provided and it does not exist, it will be created. Otherwise, it will be updated. """ ctxt = context.get_admin_context() if user_id: quota = QUOTAS.get_user_quotas(ctxt, project_id, user_id) else: user_id = None quota = QUOTAS.get_project_quotas(ctxt, project_id) # if key is None, that means we need to show the quotas instead # of updating them if key: settable_quotas = QUOTAS.get_settable_quotas(ctxt, project_id, user_id=user_id) if key in quota: minimum = settable_quotas[key]['minimum'] maximum = settable_quotas[key]['maximum'] if value.lower() == 'unlimited': value = -1 if int(value) < -1: print(_('Quota limit must be -1 or greater.')) return (2) if ((int(value) < minimum) and (maximum != -1 or (maximum == -1 and int(value) != -1))): print(_('Quota limit must be greater than %s.') % minimum) return (2) if maximum != -1 and int(value) > maximum: print(_('Quota limit must be less than %s.') % maximum) return (2) try: db.quota_create(ctxt, project_id, key, value, user_id=user_id) except exception.QuotaExists: db.quota_update(ctxt, project_id, key, value, user_id=user_id) else: print( _('%(key)s is not a valid quota key. Valid options are: ' '%(options)s.') % { 'key': key, 'options': ', '.join(quota) }) return (2) print_format = "%-36s %-10s %-10s %-10s" print(print_format % (_('Quota'), _('Limit'), _('In Use'), _('Reserved'))) # Retrieve the quota after update if user_id: quota = QUOTAS.get_user_quotas(ctxt, project_id, user_id) else: quota = QUOTAS.get_project_quotas(ctxt, project_id) for key, value in quota.iteritems(): if value['limit'] < 0 or value['limit'] is None: value['limit'] = 'unlimited' print(print_format % (key, value['limit'], value['in_use'], value['reserved']))
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id bad_keys = [] # By default, we can force update the quota if the extended # is not loaded force_update = True extended_loaded = False if self.ext_mgr.is_loaded('os-extended-quotas'): # force optional has been enabled, the default value of # force_update need to be changed to False extended_loaded = True force_update = False for key, value in body['quota_set'].items(): if (key not in QUOTAS and key not in NON_QUOTA_KEYS): bad_keys.append(key) continue if key == 'force' and extended_loaded: # only check the force optional when the extended has # been loaded force_update = strutils.bool_from_string(value) elif key not in NON_QUOTA_KEYS and value: try: value = int(value) except (ValueError, TypeError): msg = _("Quota '%(value)s' for %(key)s should be " "integer.") % locals() LOG.warn(msg) raise webob.exc.HTTPBadRequest(explanation=msg) self._validate_quota_limit(value) LOG.debug(_("force update quotas: %s") % force_update) if len(bad_keys) > 0: msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys) raise webob.exc.HTTPBadRequest(explanation=msg) try: project_quota = self._get_quotas(context, id, True) except exception.NotAuthorized: raise webob.exc.HTTPForbidden() for key, value in body['quota_set'].items(): if key in NON_QUOTA_KEYS or not value: continue # validate whether already used and reserved exceeds the new # quota, this check will be ignored if admin want to force # update value = int(value) if force_update is not True and value >= 0: quota_value = project_quota.get(key) if quota_value and quota_value['limit'] >= 0: quota_used = (quota_value['in_use'] + quota_value['reserved']) LOG.debug( _("Quota %(key)s used: %(quota_used)s, " "value: %(value)s."), { 'key': key, 'quota_used': quota_used, 'value': value }) if quota_used > value: msg = (_("Quota value %(value)s for %(key)s are " "greater than already used and reserved " "%(quota_used)s") % { 'value': value, 'key': key, 'quota_used': quota_used }) raise webob.exc.HTTPBadRequest(explanation=msg) try: db.quota_update(context, project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id)}
def test_unlimited_db_allowed_injected_file_content_bytes(self): self.flags(quota_max_injected_file_content_bytes=12345) db.quota_create(self.context, self.project_id, "injected_file_content_bytes", None) limit = quota.allowed_injected_file_content_bytes(self.context, 23456) self.assertEqual(limit, 23456)
def test_overridden_allowed_injected_files(self): self.flags(quota_max_injected_files=5) db.quota_create(self.context, self.project_id, 'injected_files', 77) self.assertEqual(quota.allowed_injected_files(self.context, 100), 77)
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id params = urlparse.parse_qs(req.environ.get('QUERY_STRING', '')) user_id = params.get('user_id', [None])[0] quota_set = body['quota_set'] force_update = strutils.bool_from_string( quota_set.get('force', 'False')) try: settable_quotas = QUOTAS.get_settable_quotas(context, project_id, user_id=user_id) except exception.Forbidden: raise webob.exc.HTTPForbidden() try: quotas = self._get_quotas(context, id, user_id=user_id, usages=True) except exception.Forbidden: raise webob.exc.HTTPForbidden() LOG.debug("Force update quotas: %s", force_update) for key, value in body['quota_set'].iteritems(): if key == 'force' or (not value and value != 0): continue # validate whether already used and reserved exceeds the new # quota, this check will be ignored if admin want to force # update value = int(value) if force_update is not True and value >= 0: quota_value = quotas.get(key) if quota_value and quota_value['limit'] >= 0: quota_used = (quota_value['in_use'] + quota_value['reserved']) LOG.debug( "Quota %(key)s used: %(quota_used)s, " "value: %(value)s.", { 'key': key, 'quota_used': quota_used, 'value': value }) if quota_used > value: msg = (_("Quota value %(value)s for %(key)s are " "less than already used and reserved " "%(quota_used)s") % { 'value': value, 'key': key, 'quota_used': quota_used }) raise webob.exc.HTTPBadRequest(explanation=msg) minimum = settable_quotas[key]['minimum'] maximum = settable_quotas[key]['maximum'] self._validate_quota_limit(value, minimum, maximum) try: db.quota_create(context, project_id, key, value, user_id=user_id) except exception.QuotaExists: db.quota_update(context, project_id, key, value, user_id=user_id) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return self._format_quota_set( id, self._get_quotas(context, id, user_id=user_id))
def update(self, req, id, body): context = req.environ['nova.context'] authorize_update(context) project_id = id params = urlparse.parse_qs(req.environ.get('QUERY_STRING', '')) user_id = params.get('user_id', [None])[0] bad_keys = [] force_update = False if not self.is_valid_body(body, 'quota_set'): msg = _("quota_set not specified") raise webob.exc.HTTPBadRequest(explanation=msg) quota_set = body['quota_set'] for key, value in quota_set.items(): if key not in QUOTAS and key != 'force': bad_keys.append(key) continue if key == 'force': force_update = strutils.bool_from_string(value) elif key != 'force' and value: try: value = int(value) except (ValueError, TypeError): msg = _("Quota value for key '%(key)s' should be an " "integer. It is actually type '%(vtype)s'.") msg = msg % {'key': key, 'vtype': type(value)} LOG.warn(msg) raise webob.exc.HTTPBadRequest(explanation=msg) if len(bad_keys) > 0: msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys) raise webob.exc.HTTPBadRequest(explanation=msg) try: settable_quotas = QUOTAS.get_settable_quotas(context, project_id, user_id=user_id) except exception.NotAuthorized: raise webob.exc.HTTPForbidden() try: quotas = self._get_quotas(context, id, user_id=user_id, usages=True) except exception.NotAuthorized: raise webob.exc.HTTPForbidden() LOG.debug(_("Force update quotas: %s"), force_update) for key, value in body['quota_set'].iteritems(): if key == 'force' or (not value and value != 0): continue # validate whether already used and reserved exceeds the new # quota, this check will be ignored if admin want to force # update value = int(value) if force_update is not True and value >= 0: quota_value = quotas.get(key) if quota_value and quota_value['limit'] >= 0: quota_used = (quota_value['in_use'] + quota_value['reserved']) LOG.debug( _("Quota %(key)s used: %(quota_used)s, " "value: %(value)s."), { 'key': key, 'quota_used': quota_used, 'value': value }) if quota_used > value: msg = (_("Quota value %(value)s for %(key)s are " "less than already used and reserved " "%(quota_used)s") % { 'value': value, 'key': key, 'quota_used': quota_used }) raise webob.exc.HTTPBadRequest(explanation=msg) minimum = settable_quotas[key]['minimum'] maximum = settable_quotas[key]['maximum'] self._validate_quota_limit(value, minimum, maximum) try: db.quota_create(context, project_id, key, value, user_id=user_id) except exception.QuotaExists: db.quota_update(context, project_id, key, value, user_id=user_id) except exception.AdminRequired: raise webob.exc.HTTPForbidden() return self._format_quota_set( id, self._get_quotas(context, id, user_id=user_id))