Remove deprecated quota code.

This completes blueprint quota-refactor by removing the now-unused
classic quotas code.

This change is fairly substantial.  To make it easier to review, it has been
broken up into 3 parts.  This is the third part.

Change-Id: I8856f84655ef2e6d61b3d1f52190b83a96c87fdb
This commit is contained in:
Kevin L. Mitchell 2012-05-11 17:19:48 -05:00
parent 9c9c4d7853
commit d37e49fda0
2 changed files with 2 additions and 639 deletions

View File

@ -89,189 +89,6 @@ FLAGS = flags.FLAGS
FLAGS.register_opts(quota_opts)
quota_resources = ['metadata_items', 'injected_file_content_bytes',
'volumes', 'gigabytes', 'ram', 'floating_ips', 'instances',
'injected_files', 'cores', 'security_groups', 'security_group_rules',
'key_pairs']
def _get_default_quotas():
defaults = {
'instances': FLAGS.quota_instances,
'cores': FLAGS.quota_cores,
'ram': FLAGS.quota_ram,
'volumes': FLAGS.quota_volumes,
'gigabytes': FLAGS.quota_gigabytes,
'floating_ips': FLAGS.quota_floating_ips,
'metadata_items': FLAGS.quota_metadata_items,
'injected_files': FLAGS.quota_injected_files,
'injected_file_content_bytes':
FLAGS.quota_injected_file_content_bytes,
'security_groups': FLAGS.quota_security_groups,
'security_group_rules': FLAGS.quota_security_group_rules,
'key_pairs': FLAGS.quota_key_pairs,
}
# -1 in the quota flags means unlimited
return defaults
def get_class_quotas(context, quota_class, defaults=None):
"""Update defaults with the quota class values."""
if not defaults:
defaults = _get_default_quotas()
quota = db.quota_class_get_all_by_name(context, quota_class)
for key in defaults.keys():
if key in quota:
defaults[key] = quota[key]
return defaults
def get_project_quotas(context, project_id):
defaults = _get_default_quotas()
if context.quota_class:
get_class_quotas(context, context.quota_class, defaults)
quota = db.quota_get_all_by_project(context, project_id)
for key in defaults.keys():
if key in quota:
defaults[key] = quota[key]
return defaults
def _get_request_allotment(requested, used, quota):
if quota == -1:
return requested
return quota - used
def allowed_instances(context, requested_instances, instance_type):
"""Check quota and return min(requested_instances, allowed_instances)."""
project_id = context.project_id
context = context.elevated()
requested_cores = requested_instances * instance_type['vcpus']
requested_ram = requested_instances * instance_type['memory_mb']
usage = db.instance_data_get_for_project(context, project_id)
used_instances, used_cores, used_ram = usage
quota = get_project_quotas(context, project_id)
allowed_instances = _get_request_allotment(requested_instances,
used_instances,
quota['instances'])
allowed_cores = _get_request_allotment(requested_cores, used_cores,
quota['cores'])
allowed_ram = _get_request_allotment(requested_ram, used_ram, quota['ram'])
if instance_type['vcpus']:
allowed_instances = min(allowed_instances,
allowed_cores // instance_type['vcpus'])
if instance_type['memory_mb']:
allowed_instances = min(allowed_instances,
allowed_ram // instance_type['memory_mb'])
return min(requested_instances, allowed_instances)
def allowed_volumes(context, requested_volumes, size):
"""Check quota and return min(requested_volumes, allowed_volumes)."""
project_id = context.project_id
context = context.elevated()
size = int(size)
requested_gigabytes = requested_volumes * size
used_volumes, used_gigabytes = db.volume_data_get_for_project(context,
project_id)
quota = get_project_quotas(context, project_id)
allowed_volumes = _get_request_allotment(requested_volumes, used_volumes,
quota['volumes'])
allowed_gigabytes = _get_request_allotment(requested_gigabytes,
used_gigabytes,
quota['gigabytes'])
if size != 0:
allowed_volumes = min(allowed_volumes,
int(allowed_gigabytes // size))
return min(requested_volumes, allowed_volumes)
def allowed_floating_ips(context, requested_floating_ips):
"""Check quota and return min(requested, allowed) floating ips."""
project_id = context.project_id
context = context.elevated()
used_floating_ips = db.floating_ip_count_by_project(context, project_id)
quota = get_project_quotas(context, project_id)
allowed_floating_ips = _get_request_allotment(requested_floating_ips,
used_floating_ips,
quota['floating_ips'])
return min(requested_floating_ips, allowed_floating_ips)
def allowed_security_groups(context, requested_security_groups):
"""Check quota and return min(requested, allowed) security groups."""
project_id = context.project_id
context = context.elevated()
used_sec_groups = db.security_group_count_by_project(context, project_id)
quota = get_project_quotas(context, project_id)
allowed_sec_groups = _get_request_allotment(requested_security_groups,
used_sec_groups,
quota['security_groups'])
return min(requested_security_groups, allowed_sec_groups)
def allowed_security_group_rules(context, security_group_id,
requested_rules):
"""Check quota and return min(requested, allowed) sec group rules."""
project_id = context.project_id
context = context.elevated()
used_rules = db.security_group_rule_count_by_group(context,
security_group_id)
quota = get_project_quotas(context, project_id)
allowed_rules = _get_request_allotment(requested_rules,
used_rules,
quota['security_group_rules'])
return min(requested_rules, allowed_rules)
def allowed_key_pairs(context, requested_key_pairs):
"""Check quota and return min(requested, allowed) key pairs."""
user_id = context.user_id
project_id = context.project_id
context = context.elevated()
used_key_pairs = db.key_pair_count_by_user(context, user_id)
quota = get_project_quotas(context, project_id)
allowed_key_pairs = _get_request_allotment(requested_key_pairs,
used_key_pairs,
quota['key_pairs'])
return min(requested_key_pairs, allowed_key_pairs)
def _calculate_simple_quota(context, resource, requested):
"""Check quota for resource; return min(requested, allowed)."""
quota = get_project_quotas(context, context.project_id)
allowed = _get_request_allotment(requested, 0, quota[resource])
return min(requested, allowed)
def allowed_metadata_items(context, requested_metadata_items):
"""Return the number of metadata items allowed."""
return _calculate_simple_quota(context, 'metadata_items',
requested_metadata_items)
def allowed_injected_files(context, requested_injected_files):
"""Return the number of injected files allowed."""
return _calculate_simple_quota(context, 'injected_files',
requested_injected_files)
def allowed_injected_file_content_bytes(context, requested_bytes):
"""Return the number of bytes allowed per injected file content."""
resource = 'injected_file_content_bytes'
return _calculate_simple_quota(context, resource, requested_bytes)
def allowed_injected_file_path_bytes(context):
"""Return the number of bytes allowed in an injected file path."""
return FLAGS.quota_injected_file_path_bytes
class DbQuotaDriver(object):
"""
Driver to perform necessary checks to enforce quotas and obtain

View File

@ -37,233 +37,7 @@ from nova import volume
FLAGS = flags.FLAGS
class GetQuotaTestCase(test.TestCase):
def setUp(self):
super(GetQuotaTestCase, self).setUp()
self.flags(quota_instances=10,
quota_cores=20,
quota_ram=50 * 1024,
quota_volumes=10,
quota_gigabytes=1000,
quota_floating_ips=10,
quota_security_groups=10,
quota_security_group_rules=20,
quota_key_pairs=10,
quota_metadata_items=128,
quota_injected_files=5,
quota_injected_file_content_bytes=10 * 1024)
self.context = context.RequestContext('admin', 'admin', is_admin=True)
def _stub_class(self):
def fake_quota_class_get_all_by_name(context, quota_class):
result = dict(class_name=quota_class)
if quota_class == 'test_class':
result.update(
instances=5,
cores=10,
ram=25 * 1024,
volumes=5,
gigabytes=500,
floating_ips=5,
quota_security_groups=10,
quota_security_group_rules=20,
quota_key_pairs=10,
metadata_items=64,
injected_files=2,
injected_file_content_bytes=5 * 1024,
invalid_quota=100,
)
return result
self.stubs.Set(db, 'quota_class_get_all_by_name',
fake_quota_class_get_all_by_name)
def _stub_project(self, override=False):
def fake_quota_get_all_by_project(context, project_id):
result = dict(project_id=project_id)
if override:
result.update(
instances=2,
cores=5,
ram=12 * 1024,
volumes=2,
gigabytes=250,
floating_ips=2,
security_groups=5,
security_group_rules=10,
key_pairs=5,
metadata_items=32,
injected_files=1,
injected_file_content_bytes=2 * 1024,
invalid_quota=50,
)
return result
self.stubs.Set(db, 'quota_get_all_by_project',
fake_quota_get_all_by_project)
def test_default_quotas(self):
result = quota._get_default_quotas()
self.assertEqual(result, dict(
instances=10,
cores=20,
ram=50 * 1024,
volumes=10,
gigabytes=1000,
floating_ips=10,
security_groups=10,
security_group_rules=20,
key_pairs=10,
metadata_items=128,
injected_files=5,
injected_file_content_bytes=10 * 1024,
))
def test_default_quotas_unlimited(self):
self.flags(quota_instances=-1,
quota_cores=-1,
quota_ram=-1,
quota_volumes=-1,
quota_gigabytes=-1,
quota_floating_ips=-1,
quota_security_groups=-1,
quota_security_group_rules=-1,
quota_key_pairs=-1,
quota_metadata_items=-1,
quota_injected_files=-1,
quota_injected_file_content_bytes=-1)
result = quota._get_default_quotas()
self.assertEqual(result, dict(
instances=-1,
cores=-1,
ram=-1,
volumes=-1,
gigabytes=-1,
floating_ips=-1,
security_groups=-1,
security_group_rules=-1,
key_pairs=-1,
metadata_items=-1,
injected_files=-1,
injected_file_content_bytes=-1,
))
def test_class_quotas_noclass(self):
self._stub_class()
result = quota.get_class_quotas(self.context, 'noclass')
self.assertEqual(result, dict(
instances=10,
cores=20,
ram=50 * 1024,
volumes=10,
gigabytes=1000,
floating_ips=10,
security_groups=10,
security_group_rules=20,
key_pairs=10,
metadata_items=128,
injected_files=5,
injected_file_content_bytes=10 * 1024,
))
def test_class_quotas(self):
self._stub_class()
result = quota.get_class_quotas(self.context, 'test_class')
self.assertEqual(result, dict(
instances=5,
cores=10,
ram=25 * 1024,
volumes=5,
gigabytes=500,
floating_ips=5,
security_groups=10,
security_group_rules=20,
key_pairs=10,
metadata_items=64,
injected_files=2,
injected_file_content_bytes=5 * 1024,
))
def test_project_quotas_defaults_noclass(self):
self._stub_class()
self._stub_project()
result = quota.get_project_quotas(self.context, 'admin')
self.assertEqual(result, dict(
instances=10,
cores=20,
ram=50 * 1024,
volumes=10,
gigabytes=1000,
floating_ips=10,
security_groups=10,
security_group_rules=20,
key_pairs=10,
metadata_items=128,
injected_files=5,
injected_file_content_bytes=10 * 1024,
))
def test_project_quotas_overrides_noclass(self):
self._stub_class()
self._stub_project(True)
result = quota.get_project_quotas(self.context, 'admin')
self.assertEqual(result, dict(
instances=2,
cores=5,
ram=12 * 1024,
volumes=2,
gigabytes=250,
floating_ips=2,
security_groups=5,
security_group_rules=10,
key_pairs=5,
metadata_items=32,
injected_files=1,
injected_file_content_bytes=2 * 1024,
))
def test_project_quotas_defaults_withclass(self):
self._stub_class()
self._stub_project()
self.context.quota_class = 'test_class'
result = quota.get_project_quotas(self.context, 'admin')
self.assertEqual(result, dict(
instances=5,
cores=10,
ram=25 * 1024,
volumes=5,
gigabytes=500,
floating_ips=5,
security_groups=10,
security_group_rules=20,
key_pairs=10,
metadata_items=64,
injected_files=2,
injected_file_content_bytes=5 * 1024,
))
def test_project_quotas_overrides_withclass(self):
self._stub_class()
self._stub_project(True)
self.context.quota_class = 'test_class'
result = quota.get_project_quotas(self.context, 'admin')
self.assertEqual(result, dict(
instances=2,
cores=5,
ram=12 * 1024,
volumes=2,
gigabytes=250,
floating_ips=2,
security_groups=5,
security_group_rules=10,
key_pairs=5,
metadata_items=32,
injected_files=1,
injected_file_content_bytes=2 * 1024,
))
class OldQuotaTestCase(test.TestCase):
class QuotaIntegrationTestCase(test.TestCase):
class StubImageService(object):
@ -271,7 +45,7 @@ class OldQuotaTestCase(test.TestCase):
return {"properties": {}}
def setUp(self):
super(OldQuotaTestCase, self).setUp()
super(QuotaIntegrationTestCase, self).setUp()
self.flags(connection_type='fake',
quota_instances=2,
quota_cores=4,
@ -324,178 +98,6 @@ class OldQuotaTestCase(test.TestCase):
vol['size'] = size
return db.volume_create(self.context, vol)['id']
def _get_instance_type(self, name):
instance_types = {
'm1.tiny': dict(memory_mb=512, vcpus=1, root_gb=0, flavorid=1),
'm1.small': dict(memory_mb=2048, vcpus=1, root_gb=20, flavorid=2),
'm1.medium':
dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3),
'm1.large': dict(memory_mb=8192, vcpus=4, root_gb=80, flavorid=4),
'm1.xlarge':
dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5),
'm1.nocpu': dict(memory_mb=512, vcpus=0, root_gb=0, flavorid=6),
'm1.nomem': dict(memory_mb=0, vcpus=1, root_gb=0, flavorid=7)}
return instance_types[name]
def test_quota_no_mem_no_cpu(self):
num_instances = quota.allowed_instances(self.context, 100,
self._get_instance_type('m1.nocpu'))
self.assertEqual(num_instances, 2)
num_instances = quota.allowed_instances(self.context, 100,
self._get_instance_type('m1.nomem'))
self.assertEqual(num_instances, 2)
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_unlimited_instances(self):
self.flags(quota_instances=2, quota_ram=-1, 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, 'instances', -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_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', -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_volumes(self):
self.flags(quota_volumes=10, quota_gigabytes=-1)
volumes = quota.allowed_volumes(self.context, 100, 1)
self.assertEqual(volumes, 10)
db.quota_create(self.context, self.project_id, 'volumes', -1)
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_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', -1)
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', -1)
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_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', -1)
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_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_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',
-1)
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 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', -1)
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_too_many_instances(self):
instance_ids = []
for i in range(FLAGS.quota_instances):
@ -573,48 +175,6 @@ class OldQuotaTestCase(test.TestCase):
image_href=image_uuid,
metadata=metadata)
def test_default_allowed_injected_files(self):
self.flags(quota_injected_files=55)
self.assertEqual(quota.allowed_injected_files(self.context, 100), 55)
def test_overridden_allowed_injected_files(self):
self.flags(quota_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_unlimited_default_allowed_injected_files(self):
self.flags(quota_injected_files=-1)
self.assertEqual(quota.allowed_injected_files(self.context, 100), 100)
def test_unlimited_db_allowed_injected_files(self):
self.flags(quota_injected_files=5)
db.quota_create(self.context, self.project_id, 'injected_files', -1)
self.assertEqual(quota.allowed_injected_files(self.context, 100), 100)
def test_default_allowed_injected_file_content_bytes(self):
self.flags(quota_injected_file_content_bytes=12345)
limit = quota.allowed_injected_file_content_bytes(self.context, 23456)
self.assertEqual(limit, 12345)
def test_overridden_allowed_injected_file_content_bytes(self):
self.flags(quota_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 test_unlimited_default_allowed_injected_file_content_bytes(self):
self.flags(quota_injected_file_content_bytes=-1)
limit = quota.allowed_injected_file_content_bytes(self.context, 23456)
self.assertEqual(limit, 23456)
def test_unlimited_db_allowed_injected_file_content_bytes(self):
self.flags(quota_injected_file_content_bytes=12345)
db.quota_create(self.context, self.project_id,
'injected_file_content_bytes', -1)
limit = quota.allowed_injected_file_content_bytes(self.context, 23456)
self.assertEqual(limit, 23456)
def _create_with_injected_files(self, files):
self.flags(image_service='nova.image.fake.FakeImageService')
api = compute.API(image_service=self.StubImageService())
@ -659,11 +219,6 @@ class OldQuotaTestCase(test.TestCase):
self.assertRaises(exception.QuotaError,
self._create_with_injected_files, files)
def test_allowed_injected_file_path_bytes(self):
self.assertEqual(
quota.allowed_injected_file_path_bytes(self.context),
FLAGS.quota_injected_file_path_bytes)
def test_max_injected_file_path_bytes(self):
max = FLAGS.quota_injected_file_path_bytes
path = ''.join(['a' for i in xrange(max)])
@ -677,15 +232,6 @@ class OldQuotaTestCase(test.TestCase):
self.assertRaises(exception.QuotaError,
self._create_with_injected_files, files)
def test_quota_class_unlimited(self):
self.flags(quota_floating_ips=10)
items = quota.allowed_floating_ips(self.context, 10)
self.assertEqual(items, 10)
self.context.quota_class = 'foo'
db.quota_class_create(self.context, 'foo', 'floating_ips', -1)
items = quota.allowed_floating_ips(self.context, 100)
self.assertEqual(items, 100)
class FakeContext(object):
def __init__(self, project_id, quota_class):