Revert "Remove quota-class logic from context and make unit tests pass"
This reverts commit e25316ecb9
.
The quota_classes API was used to set default quota values
so it shouldn't have been removed, so reverting a series
of changes that removed the API and it's internal code.
Related mailing list thread on the topic:
http://lists.openstack.org/pipermail/openstack-dev/2014-May/035383.html
Partial-Bug: #1299517
Change-Id: If903863d28fbab74cfe571709a01cd2cdd46d174
This commit is contained in:
parent
c07626012e
commit
d9cee6b2ee
|
@ -47,7 +47,7 @@ class RequestContext(object):
|
|||
def __init__(self, user_id, project_id, is_admin=None, read_deleted="no",
|
||||
roles=None, remote_address=None, timestamp=None,
|
||||
request_id=None, auth_token=None, overwrite=True,
|
||||
user_name=None, project_name=None,
|
||||
quota_class=None, user_name=None, project_name=None,
|
||||
service_catalog=None, instance_lock_checked=False, **kwargs):
|
||||
""":param read_deleted: 'no' indicates deleted records are hidden,
|
||||
'yes' indicates deleted records are visible,
|
||||
|
@ -89,6 +89,10 @@ class RequestContext(object):
|
|||
|
||||
self.instance_lock_checked = instance_lock_checked
|
||||
|
||||
# NOTE(markmc): this attribute is currently only used by the
|
||||
# rs_limits turnstile pre-processor.
|
||||
# See https://lists.launchpad.net/openstack/msg12200.html
|
||||
self.quota_class = quota_class
|
||||
self.user_name = user_name
|
||||
self.project_name = project_name
|
||||
self.is_admin = is_admin
|
||||
|
@ -125,6 +129,7 @@ class RequestContext(object):
|
|||
'timestamp': timeutils.strtime(self.timestamp),
|
||||
'request_id': self.request_id,
|
||||
'auth_token': self.auth_token,
|
||||
'quota_class': self.quota_class,
|
||||
'user_name': self.user_name,
|
||||
'service_catalog': self.service_catalog,
|
||||
'project_name': self.project_name,
|
||||
|
@ -214,3 +219,12 @@ def authorize_user_context(context, user_id):
|
|||
raise exception.Forbidden()
|
||||
elif context.user_id != user_id:
|
||||
raise exception.Forbidden()
|
||||
|
||||
|
||||
def authorize_quota_class_context(context, class_name):
|
||||
"""Ensures a request has permission to access the given quota class."""
|
||||
if is_user_context(context):
|
||||
if not context.quota_class:
|
||||
raise exception.Forbidden()
|
||||
elif context.quota_class != class_name:
|
||||
raise exception.Forbidden()
|
||||
|
|
|
@ -2894,6 +2894,8 @@ def quota_class_get_default(context):
|
|||
|
||||
@require_context
|
||||
def quota_class_get_all_by_name(context, class_name):
|
||||
nova.context.authorize_quota_class_context(context, class_name)
|
||||
|
||||
rows = model_query(context, models.QuotaClass, read_deleted="no").\
|
||||
filter_by(class_name=class_name).\
|
||||
all()
|
||||
|
|
|
@ -156,6 +156,16 @@ class DbQuotaDriver(object):
|
|||
quota_class=None, defaults=True, usages=None,
|
||||
remains=False):
|
||||
modified_quotas = {}
|
||||
# Get the quotas for the appropriate class. If the project ID
|
||||
# matches the one in the context, we use the quota_class from
|
||||
# the context, otherwise, we use the provided quota_class (if
|
||||
# any)
|
||||
if project_id == context.project_id:
|
||||
quota_class = context.quota_class
|
||||
if quota_class:
|
||||
class_quotas = db.quota_class_get_all_by_name(context, quota_class)
|
||||
else:
|
||||
class_quotas = {}
|
||||
|
||||
default_quotas = self.get_defaults(context, resources)
|
||||
|
||||
|
@ -164,7 +174,8 @@ class DbQuotaDriver(object):
|
|||
if not defaults and resource.name not in quotas:
|
||||
continue
|
||||
|
||||
limit = quotas.get(resource.name, default_quotas[resource.name])
|
||||
limit = quotas.get(resource.name, class_quotas.get(
|
||||
resource.name, default_quotas[resource.name]))
|
||||
modified_quotas[resource.name] = dict(limit=limit)
|
||||
|
||||
# Include usages if desired. This is optional because one
|
||||
|
@ -370,13 +381,13 @@ class DbQuotaDriver(object):
|
|||
# Grab and return the quotas (without usages)
|
||||
quotas = self.get_user_quotas(context, sub_resources,
|
||||
project_id, user_id,
|
||||
None, usages=False,
|
||||
context.quota_class, usages=False,
|
||||
project_quotas=project_quotas)
|
||||
else:
|
||||
# Grab and return the quotas (without usages)
|
||||
quotas = self.get_project_quotas(context, sub_resources,
|
||||
project_id,
|
||||
None,
|
||||
context.quota_class,
|
||||
usages=False,
|
||||
project_quotas=project_quotas)
|
||||
|
||||
|
@ -955,7 +966,7 @@ class BaseResource(object):
|
|||
project_id = kwargs.get('project_id', context.project_id)
|
||||
|
||||
# Ditto for the quota class
|
||||
quota_class = kwargs.get('quota_class', None)
|
||||
quota_class = kwargs.get('quota_class', context.quota_class)
|
||||
|
||||
# Look up the quota for the project
|
||||
if project_id:
|
||||
|
|
|
@ -357,7 +357,7 @@ class BaseResourceTestCase(test.TestCase):
|
|||
self.assertEqual(resource.flag, 'quota_instances')
|
||||
self.assertEqual(resource.default, -1)
|
||||
|
||||
def test_quota_no_project(self):
|
||||
def test_quota_no_project_no_class(self):
|
||||
self.flags(quota_instances=10)
|
||||
resource = quota.BaseResource('test_resource', 'quota_instances')
|
||||
driver = FakeDriver()
|
||||
|
@ -366,7 +366,7 @@ class BaseResourceTestCase(test.TestCase):
|
|||
|
||||
self.assertEqual(quota_value, 10)
|
||||
|
||||
def test_quota_with_project(self):
|
||||
def test_quota_with_project_no_class(self):
|
||||
self.flags(quota_instances=10)
|
||||
resource = quota.BaseResource('test_resource', 'quota_instances')
|
||||
driver = FakeDriver(by_project=dict(
|
||||
|
@ -377,6 +377,57 @@ class BaseResourceTestCase(test.TestCase):
|
|||
|
||||
self.assertEqual(quota_value, 15)
|
||||
|
||||
def test_quota_no_project_with_class(self):
|
||||
self.flags(quota_instances=10)
|
||||
resource = quota.BaseResource('test_resource', 'quota_instances')
|
||||
driver = FakeDriver(by_class=dict(
|
||||
test_class=dict(test_resource=20),
|
||||
))
|
||||
context = FakeContext(None, 'test_class')
|
||||
quota_value = resource.quota(driver, context)
|
||||
|
||||
self.assertEqual(quota_value, 20)
|
||||
|
||||
def test_quota_with_project_with_class(self):
|
||||
self.flags(quota_instances=10)
|
||||
resource = quota.BaseResource('test_resource', 'quota_instances')
|
||||
driver = FakeDriver(by_project=dict(
|
||||
test_project=dict(test_resource=15),
|
||||
),
|
||||
by_class=dict(
|
||||
test_class=dict(test_resource=20),
|
||||
))
|
||||
context = FakeContext('test_project', 'test_class')
|
||||
quota_value = resource.quota(driver, context)
|
||||
|
||||
self.assertEqual(quota_value, 15)
|
||||
|
||||
def test_quota_override_project_with_class(self):
|
||||
self.flags(quota_instances=10)
|
||||
resource = quota.BaseResource('test_resource', 'quota_instances')
|
||||
driver = FakeDriver(by_project=dict(
|
||||
test_project=dict(test_resource=15),
|
||||
override_project=dict(test_resource=20),
|
||||
))
|
||||
context = FakeContext('test_project', 'test_class')
|
||||
quota_value = resource.quota(driver, context,
|
||||
project_id='override_project')
|
||||
|
||||
self.assertEqual(quota_value, 20)
|
||||
|
||||
def test_quota_with_project_override_class(self):
|
||||
self.flags(quota_instances=10)
|
||||
resource = quota.BaseResource('test_resource', 'quota_instances')
|
||||
driver = FakeDriver(by_class=dict(
|
||||
test_class=dict(test_resource=15),
|
||||
override_class=dict(test_resource=20),
|
||||
))
|
||||
context = FakeContext('test_project', 'test_class')
|
||||
quota_value = resource.quota(driver, context,
|
||||
quota_class='override_class')
|
||||
|
||||
self.assertEqual(quota_value, 20)
|
||||
|
||||
|
||||
class QuotaEngineTestCase(test.TestCase):
|
||||
def test_init(self):
|
||||
|
@ -861,10 +912,11 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
'quota_get_all_by_project_and_user',
|
||||
'quota_get_all_by_project',
|
||||
'quota_usage_get_all_by_project_and_user',
|
||||
'quota_class_get_all_by_name',
|
||||
])
|
||||
self.assertEqual(result, dict(
|
||||
instances=dict(
|
||||
limit=10,
|
||||
limit=5,
|
||||
in_use=2,
|
||||
reserved=2,
|
||||
),
|
||||
|
@ -874,7 +926,7 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
reserved=4,
|
||||
),
|
||||
ram=dict(
|
||||
limit=50 * 1024,
|
||||
limit=25 * 1024,
|
||||
in_use=10 * 1024,
|
||||
reserved=0,
|
||||
),
|
||||
|
@ -889,7 +941,7 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
reserved=0,
|
||||
),
|
||||
metadata_items=dict(
|
||||
limit=128,
|
||||
limit=64,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
|
@ -899,7 +951,7 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
reserved=0,
|
||||
),
|
||||
injected_file_content_bytes=dict(
|
||||
limit=10 * 1024,
|
||||
limit=5 * 1024,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
|
@ -987,6 +1039,7 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
self.assertEqual(self.calls, [
|
||||
'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(
|
||||
|
@ -1202,6 +1255,159 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
),
|
||||
))
|
||||
|
||||
def test_get_user_quotas_alt_context_with_class(self):
|
||||
self.maxDiff = None
|
||||
self._stub_get_by_project_and_user()
|
||||
result = self.driver.get_user_quotas(
|
||||
FakeContext('test_project', 'test_class'),
|
||||
quota.QUOTAS._resources, 'test_project', 'fake_user',
|
||||
quota_class='test_class')
|
||||
|
||||
self.assertEqual(self.calls, [
|
||||
'quota_get_all_by_project_and_user',
|
||||
'quota_get_all_by_project',
|
||||
'quota_usage_get_all_by_project_and_user',
|
||||
'quota_class_get_all_by_name',
|
||||
])
|
||||
self.assertEqual(result, dict(
|
||||
instances=dict(
|
||||
limit=5,
|
||||
in_use=2,
|
||||
reserved=2,
|
||||
),
|
||||
cores=dict(
|
||||
limit=10,
|
||||
in_use=4,
|
||||
reserved=4,
|
||||
),
|
||||
ram=dict(
|
||||
limit=25 * 1024,
|
||||
in_use=10 * 1024,
|
||||
reserved=0,
|
||||
),
|
||||
floating_ips=dict(
|
||||
limit=10,
|
||||
in_use=2,
|
||||
reserved=0,
|
||||
),
|
||||
fixed_ips=dict(
|
||||
limit=10,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
metadata_items=dict(
|
||||
limit=64,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
injected_files=dict(
|
||||
limit=2,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
injected_file_content_bytes=dict(
|
||||
limit=5 * 1024,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
injected_file_path_bytes=dict(
|
||||
limit=127,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
security_groups=dict(
|
||||
limit=10,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
security_group_rules=dict(
|
||||
limit=20,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
key_pairs=dict(
|
||||
limit=100,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
))
|
||||
|
||||
def test_get_project_quotas_alt_context_with_class(self):
|
||||
self.maxDiff = None
|
||||
self._stub_get_by_project()
|
||||
result = self.driver.get_project_quotas(
|
||||
FakeContext('other_project', 'other_class'),
|
||||
quota.QUOTAS._resources, 'test_project', quota_class='test_class')
|
||||
|
||||
self.assertEqual(self.calls, [
|
||||
'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(
|
||||
limit=5,
|
||||
in_use=2,
|
||||
reserved=2,
|
||||
),
|
||||
cores=dict(
|
||||
limit=10,
|
||||
in_use=4,
|
||||
reserved=4,
|
||||
),
|
||||
ram=dict(
|
||||
limit=25 * 1024,
|
||||
in_use=10 * 1024,
|
||||
reserved=0,
|
||||
),
|
||||
floating_ips=dict(
|
||||
limit=10,
|
||||
in_use=2,
|
||||
reserved=0,
|
||||
),
|
||||
fixed_ips=dict(
|
||||
limit=10,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
metadata_items=dict(
|
||||
limit=64,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
injected_files=dict(
|
||||
limit=2,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
injected_file_content_bytes=dict(
|
||||
limit=5 * 1024,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
injected_file_path_bytes=dict(
|
||||
limit=127,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
security_groups=dict(
|
||||
limit=10,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
security_group_rules=dict(
|
||||
limit=20,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
key_pairs=dict(
|
||||
limit=100,
|
||||
in_use=0,
|
||||
reserved=0,
|
||||
),
|
||||
))
|
||||
|
||||
def test_get_user_quotas_no_defaults(self):
|
||||
self._stub_get_by_project_and_user()
|
||||
result = self.driver.get_user_quotas(
|
||||
|
@ -1213,6 +1419,7 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
'quota_get_all_by_project_and_user',
|
||||
'quota_get_all_by_project',
|
||||
'quota_usage_get_all_by_project_and_user',
|
||||
'quota_class_get_all_by_name',
|
||||
])
|
||||
self.assertEqual(result, dict(
|
||||
cores=dict(
|
||||
|
@ -1241,6 +1448,7 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
self.assertEqual(self.calls, [
|
||||
'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(
|
||||
|
@ -1270,16 +1478,17 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
self.assertEqual(self.calls, [
|
||||
'quota_get_all_by_project_and_user',
|
||||
'quota_get_all_by_project',
|
||||
'quota_class_get_all_by_name',
|
||||
])
|
||||
self.assertEqual(result, dict(
|
||||
instances=dict(
|
||||
limit=10,
|
||||
limit=5,
|
||||
),
|
||||
cores=dict(
|
||||
limit=10,
|
||||
),
|
||||
ram=dict(
|
||||
limit=50 * 1024,
|
||||
limit=25 * 1024,
|
||||
),
|
||||
floating_ips=dict(
|
||||
limit=10,
|
||||
|
@ -1288,13 +1497,13 @@ class DbQuotaDriverTestCase(test.TestCase):
|
|||
limit=10,
|
||||
),
|
||||
metadata_items=dict(
|
||||
limit=128,
|
||||
limit=64,
|
||||
),
|
||||
injected_files=dict(
|
||||
limit=2,
|
||||
),
|
||||
injected_file_content_bytes=dict(
|
||||
limit=10 * 1024,
|
||||
limit=5 * 1024,
|
||||
),
|
||||
injected_file_path_bytes=dict(
|
||||
limit=127,
|
||||
|
@ -1318,6 +1527,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(
|
||||
|
|
Loading…
Reference in New Issue