Editable default quota support

Implement blueprint edit-default-quota

DocImpact

Using the class quotas named `default` as the default editable quotas.

We can use the following novaclient command to update default quota:

nova quota-class-update default <key> <value>

Change-Id: I5a5001fadcbd61d550ebd5bdc33613b0ffdf29b2
This commit is contained in:
liyingjun 2013-05-17 11:20:50 +08:00
parent 505af894f3
commit 682fb1de14
5 changed files with 75 additions and 10 deletions

View File

@ -911,6 +911,11 @@ def quota_class_get(context, class_name, resource):
return IMPL.quota_class_get(context, class_name, resource)
def quota_class_get_default(context):
"""Retrieve all default quotas."""
return IMPL.quota_class_get_default(context)
def quota_class_get_all_by_name(context, class_name):
"""Retrieve all quotas associated with a given quota class."""
return IMPL.quota_class_get_all_by_name(context, class_name)

View File

@ -81,6 +81,7 @@ get_session = db_session.get_session
_SHADOW_TABLE_PREFIX = 'shadow_'
_DEFAULT_QUOTA_NAME = 'default'
def get_backend():
@ -2576,6 +2577,18 @@ def quota_class_get(context, class_name, resource):
return result
def quota_class_get_default(context):
rows = model_query(context, models.QuotaClass, read_deleted="no").\
filter_by(class_name=_DEFAULT_QUOTA_NAME).\
all()
result = {'class_name': _DEFAULT_QUOTA_NAME}
for row in rows:
result[row.resource] = row.hard_limit
return result
@require_context
def quota_class_get_all_by_name(context, class_name):
nova.context.authorize_quota_class_context(context, class_name)

View File

@ -105,14 +105,18 @@ class DbQuotaDriver(object):
def get_defaults(self, context, resources):
"""Given a list of resources, retrieve the default quotas.
Use the class quotas named `_DEFAULT_QUOTA_NAME` as default quotas,
if it exists.
:param context: The request context, for access checks.
:param resources: A dictionary of the registered resources.
"""
quotas = {}
default_quotas = db.quota_class_get_default(context)
for resource in resources.values():
quotas[resource.name] = resource.default
quotas[resource.name] = default_quotas.get(resource.name,
resource.default)
return quotas
@ -180,6 +184,8 @@ class DbQuotaDriver(object):
else:
class_quotas = {}
default_quotas = self.get_defaults(context, resources)
for resource in resources.values():
# Omit default/quota class values
if not defaults and resource.name not in project_quotas:
@ -187,7 +193,7 @@ class DbQuotaDriver(object):
quotas[resource.name] = dict(
limit=project_quotas.get(resource.name, class_quotas.get(
resource.name, resource.default)),
resource.name, default_quotas[resource.name])),
)
# Include usages if desired. This is optional because one

View File

@ -3930,6 +3930,28 @@ class KeyPairTestCase(test.TestCase, ModelsObjectComparatorMixin):
param['user_id'], param['name'])
class QuotaClassTestCase(test.TestCase, ModelsObjectComparatorMixin):
def setUp(self):
super(QuotaClassTestCase, self).setUp()
self.ctxt = context.get_admin_context()
def test_quota_class_get_default(self):
params = {
'test_resource1': '10',
'test_resource2': '20',
'test_resource3': '30',
}
for res, limit in params.items():
db.quota_class_create(self.ctxt, 'default', res, limit)
defaults = db.quota_class_get_default(self.ctxt)
self.assertEqual(defaults, dict(class_name='default',
test_resource1=10,
test_resource2=20,
test_resource3=30))
class ArchiveTestCase(test.TestCase):
def setUp(self):

View File

@ -739,23 +739,36 @@ class DbQuotaDriverTestCase(test.TestCase):
def test_get_defaults(self):
# Use our pre-defined resources
self._stub_quota_class_get_default()
result = self.driver.get_defaults(None, quota.QUOTAS._resources)
self.assertEqual(result, dict(
instances=10,
instances=5,
cores=20,
ram=50 * 1024,
ram=25 * 1024,
floating_ips=10,
fixed_ips=10,
metadata_items=128,
metadata_items=64,
injected_files=5,
injected_file_content_bytes=10 * 1024,
injected_file_content_bytes=5 * 1024,
injected_file_path_bytes=255,
security_groups=10,
security_group_rules=20,
key_pairs=100,
))
def _stub_quota_class_get_default(self):
# Stub out quota_class_get_default
def fake_qcgd(context):
self.calls.append('quota_class_get_default')
return dict(
instances=5,
ram=25 * 1024,
metadata_items=64,
injected_file_content_bytes=5 * 1024,
)
self.stubs.Set(db, 'quota_class_get_default', fake_qcgd)
def _stub_quota_class_get_all_by_name(self):
# Stub out quota_class_get_all_by_name
def fake_qcgabn(context, quota_class):
@ -831,6 +844,7 @@ class DbQuotaDriverTestCase(test.TestCase):
self.stubs.Set(db, 'quota_usage_get_all_by_project', fake_qugabp)
self._stub_quota_class_get_all_by_name()
self._stub_quota_class_get_default()
def test_get_project_quotas(self):
self.maxDiff = None
@ -843,6 +857,7 @@ class DbQuotaDriverTestCase(test.TestCase):
'quota_get_all_by_project',
'quota_usage_get_all_by_project',
'quota_class_get_all_by_name',
'quota_class_get_default',
])
self.assertEqual(result, dict(
instances=dict(
@ -917,10 +932,11 @@ class DbQuotaDriverTestCase(test.TestCase):
self.assertEqual(self.calls, [
'quota_get_all_by_project',
'quota_usage_get_all_by_project',
'quota_class_get_default',
])
self.assertEqual(result, dict(
instances=dict(
limit=10,
limit=5,
in_use=2,
reserved=2,
),
@ -930,7 +946,7 @@ class DbQuotaDriverTestCase(test.TestCase):
reserved=4,
),
ram=dict(
limit=50 * 1024,
limit=25 * 1024,
in_use=10 * 1024,
reserved=0,
),
@ -945,7 +961,7 @@ class DbQuotaDriverTestCase(test.TestCase):
reserved=0,
),
metadata_items=dict(
limit=128,
limit=64,
in_use=0,
reserved=0,
),
@ -955,7 +971,7 @@ class DbQuotaDriverTestCase(test.TestCase):
reserved=0,
),
injected_file_content_bytes=dict(
limit=10 * 1024,
limit=5 * 1024,
in_use=0,
reserved=0,
),
@ -992,6 +1008,7 @@ class DbQuotaDriverTestCase(test.TestCase):
'quota_get_all_by_project',
'quota_usage_get_all_by_project',
'quota_class_get_all_by_name',
'quota_class_get_default',
])
self.assertEqual(result, dict(
instances=dict(
@ -1066,6 +1083,7 @@ class DbQuotaDriverTestCase(test.TestCase):
'quota_get_all_by_project',
'quota_usage_get_all_by_project',
'quota_class_get_all_by_name',
'quota_class_get_default',
])
self.assertEqual(result, dict(
cores=dict(
@ -1094,6 +1112,7 @@ class DbQuotaDriverTestCase(test.TestCase):
self.assertEqual(self.calls, [
'quota_get_all_by_project',
'quota_class_get_all_by_name',
'quota_class_get_default',
])
self.assertEqual(result, dict(
instances=dict(