summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/db/api.py5
-rw-r--r--nova/db/sqlalchemy/api.py13
-rw-r--r--nova/quota.py10
-rw-r--r--nova/tests/test_db_api.py22
-rw-r--r--nova/tests/test_quota.py35
5 files changed, 75 insertions, 10 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index 3130f7029..322247311 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -912,6 +912,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)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 9f7da2c39..e170cac55 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -81,6 +81,7 @@ get_session = db_session.get_session
_SHADOW_TABLE_PREFIX = 'shadow_'
+_DEFAULT_QUOTA_NAME = 'default'
def get_backend():
@@ -2618,6 +2619,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)
diff --git a/nova/quota.py b/nova/quota.py
index 8aaa3ed31..a1c877ecc 100644
--- a/nova/quota.py
+++ b/nova/quota.py
@@ -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
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index dc2cf0d24..11165e168 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -3947,6 +3947,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):
diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py
index b585aede5..30f823ace 100644
--- a/nova/tests/test_quota.py
+++ b/nova/tests/test_quota.py
@@ -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(