Move quota options to a config group.

As suggested in John Garbutt in I7e1986c5f11356060cc9db12605b1322c39e79c0,
move the quota config options into a config group of their own.

Change-Id: Ie06a370868f01fb9a1cc246a77d7823fac83e70e
This commit is contained in:
Michael Still 2016-07-26 00:45:38 +10:00 committed by Maciej Szankin
parent 1bcf3b553a
commit de0eff47f2
13 changed files with 191 additions and 117 deletions

View File

@ -17,10 +17,19 @@
from oslo_config import cfg from oslo_config import cfg
quota_group = cfg.OptGroup(
name='quota',
title='Quota Options',
help="""
Quota options allow to manage quotas in openstack deployment.
""")
quota_opts = [ quota_opts = [
cfg.IntOpt('quota_instances', cfg.IntOpt('instances',
min=-1, min=-1,
default=10, default=10,
deprecated_group='DEFAULT',
deprecated_name='quota_instances',
help=""" help="""
The number of instances allowed per project. The number of instances allowed per project.
@ -29,9 +38,11 @@ Possible Values
* 10 (default) or any positive integer. * 10 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_cores', cfg.IntOpt('cores',
min=-1, min=-1,
default=20, default=20,
deprecated_group='DEFAULT',
deprecated_name='quota_cores',
help=""" help="""
The number of instance cores or VCPUs allowed per project. The number of instance cores or VCPUs allowed per project.
@ -40,9 +51,11 @@ Possible values:
* 20 (default) or any positive integer. * 20 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_ram', cfg.IntOpt('ram',
min=-1, min=-1,
default=50 * 1024, default=50 * 1024,
deprecated_group='DEFAULT',
deprecated_name='quota_ram',
help=""" help="""
The number of megabytes of instance RAM allowed per project. The number of megabytes of instance RAM allowed per project.
@ -51,9 +64,11 @@ Possible values:
* 51200 (default) or any positive integer. * 51200 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_floating_ips', cfg.IntOpt('floating_ips',
min=-1, min=-1,
default=10, default=10,
deprecated_group='DEFAULT',
deprecated_name='quota_floating_ips',
help=""" help="""
The number of floating IPs allowed per project. Floating IPs are not allocated The number of floating IPs allowed per project. Floating IPs are not allocated
to instances by default. Users need to select them from the pool configured by to instances by default. Users need to select them from the pool configured by
@ -64,9 +79,11 @@ Possible values:
* 10 (default) or any positive integer. * 10 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_fixed_ips', cfg.IntOpt('fixed_ips',
min=-1, min=-1,
default=-1, default=-1,
deprecated_group='DEFAULT',
deprecated_name='quota_fixed_ips',
help=""" help="""
The number of fixed IPs allowed per project (this should be at least the number The number of fixed IPs allowed per project (this should be at least the number
of instances allowed). Unlike floating IPs, fixed IPs are allocated dynamically of instances allowed). Unlike floating IPs, fixed IPs are allocated dynamically
@ -77,9 +94,11 @@ Possible values:
* -1 (default) : treated as unlimited. * -1 (default) : treated as unlimited.
* Any positive integer. * Any positive integer.
"""), """),
cfg.IntOpt('quota_metadata_items', cfg.IntOpt('metadata_items',
min=-1, min=-1,
default=128, default=128,
deprecated_group='DEFAULT',
deprecated_name='quota_metadata_items',
help=""" help="""
The number of metadata items allowed per instance. User can associate metadata The number of metadata items allowed per instance. User can associate metadata
while instance creation in the form of key-value pairs. while instance creation in the form of key-value pairs.
@ -89,9 +108,11 @@ Possible values:
* 128 (default) or any positive integer. * 128 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_injected_files', cfg.IntOpt('injected_files',
min=-1, min=-1,
default=5, default=5,
deprecated_group='DEFAULT',
deprecated_name='quota_injected_files',
help=""" help="""
The number of injected files allowed. It allow users to customize the The number of injected files allowed. It allow users to customize the
personality of an instance by injecting data into it upon boot. Only text personality of an instance by injecting data into it upon boot. Only text
@ -104,9 +125,11 @@ Possible values:
* 5 (default) or any positive integer. * 5 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_injected_file_content_bytes', cfg.IntOpt('injected_file_content_bytes',
min=-1, min=-1,
default=10 * 1024, default=10 * 1024,
deprecated_group='DEFAULT',
deprecated_name='quota_injected_file_content_bytes',
help=""" help="""
The number of bytes allowed per injected file. The number of bytes allowed per injected file.
@ -115,9 +138,11 @@ Possible values:
* 10240 (default) or any positive integer representing number of bytes. * 10240 (default) or any positive integer representing number of bytes.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_injected_file_path_length', cfg.IntOpt('injected_file_path_length',
min=-1, min=-1,
default=255, default=255,
deprecated_group='DEFAULT',
deprecated_name='quota_injected_file_path_length',
help=""" help="""
The maximum allowed injected file path length. The maximum allowed injected file path length.
@ -126,9 +151,11 @@ Possible values:
* 255 (default) or any positive integer. * 255 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_security_groups', cfg.IntOpt('security_groups',
min=-1, min=-1,
default=10, default=10,
deprecated_group='DEFAULT',
deprecated_name='quota_security_groups',
help=""" help="""
The number of security groups per project. The number of security groups per project.
@ -137,9 +164,11 @@ Possible values:
* 10 (default) or any positive integer. * 10 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_security_group_rules', cfg.IntOpt('security_group_rules',
min=-1, min=-1,
default=20, default=20,
deprecated_group='DEFAULT',
deprecated_name='quota_security_group_rules',
help=""" help="""
The number of security rules per security group. The associated rules in each The number of security rules per security group. The associated rules in each
security group control the traffic to instances in the group. security group control the traffic to instances in the group.
@ -149,9 +178,11 @@ Possible values:
* 20 (default) or any positive integer. * 20 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_key_pairs', cfg.IntOpt('key_pairs',
min=-1, min=-1,
default=100, default=100,
deprecated_group='DEFAULT',
deprecated_name='quota_key_pairs',
help=""" help="""
The maximum number of key pairs allowed per user. Users can create at least one The maximum number of key pairs allowed per user. Users can create at least one
key pair for each project and use the key pair for multiple instances that key pair for each project and use the key pair for multiple instances that
@ -162,9 +193,11 @@ Possible values:
* 100 (default) or any positive integer. * 100 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_server_groups', cfg.IntOpt('server_groups',
min=-1, min=-1,
default=10, default=10,
deprecated_group='DEFAULT',
deprecated_name='quota_server_groups',
help=""" help="""
Add quota values to constrain the number of server groups per project. Server Add quota values to constrain the number of server groups per project. Server
group used to control the affinity and anti-affinity scheduling policy for a group used to control the affinity and anti-affinity scheduling policy for a
@ -177,9 +210,11 @@ Possible values:
* 10 (default) or any positive integer. * 10 (default) or any positive integer.
* -1 : treated as unlimited. * -1 : treated as unlimited.
"""), """),
cfg.IntOpt('quota_server_group_members', cfg.IntOpt('server_group_members',
min=-1, min=-1,
default=10, default=10,
deprecated_group='DEFAULT',
deprecated_name='quota_server_group_members',
help=""" help="""
Add quota values to constrain the number of servers per server group. Add quota values to constrain the number of servers per server group.
@ -190,6 +225,7 @@ Possible values:
"""), """),
cfg.IntOpt('reservation_expire', cfg.IntOpt('reservation_expire',
default=86400, default=86400,
deprecated_group='DEFAULT',
help=""" help="""
The number of seconds until a reservation expires. It represents the time The number of seconds until a reservation expires. It represents the time
period for invalidating quota reservations. period for invalidating quota reservations.
@ -201,6 +237,7 @@ Possible values:
cfg.IntOpt('until_refresh', cfg.IntOpt('until_refresh',
min=0, min=0,
default=0, default=0,
deprecated_group='DEFAULT',
help=""" help="""
The count of reservations until usage is refreshed. This defaults to 0 (off) to The count of reservations until usage is refreshed. This defaults to 0 (off) to
avoid additional load but it is useful to turn on to help keep quota usage avoid additional load but it is useful to turn on to help keep quota usage
@ -213,6 +250,7 @@ Possible values:
cfg.IntOpt('max_age', cfg.IntOpt('max_age',
min=0, min=0,
default=0, default=0,
deprecated_group='DEFAULT',
help=""" help="""
The number of seconds between subsequent usage refreshes. This defaults to 0 The number of seconds between subsequent usage refreshes. This defaults to 0
(off) to avoid additional load but it is useful to turn on to help keep quota (off) to avoid additional load but it is useful to turn on to help keep quota
@ -227,10 +265,12 @@ Possible values:
# TODO(pumaranikar): Add a new config to select between the db_driver and # TODO(pumaranikar): Add a new config to select between the db_driver and
# the no_op driver using stevedore. # the no_op driver using stevedore.
cfg.StrOpt('quota_driver', cfg.StrOpt('driver',
default='nova.quota.DbQuotaDriver', default='nova.quota.DbQuotaDriver',
deprecated_for_removal=True, deprecated_for_removal=True,
deprecated_since='14.0.0', deprecated_since='14.0.0',
deprecated_group='DEFAULT',
deprecated_name='quota_driver',
help=""" help="""
Provides abstraction for quota checks. Users can configure a specific Provides abstraction for quota checks. Users can configure a specific
driver to use for quota checks. driver to use for quota checks.
@ -244,10 +284,9 @@ Possible values:
def register_opts(conf): def register_opts(conf):
conf.register_opts(quota_opts) conf.register_group(quota_group)
conf.register_opts(quota_opts, group=quota_group)
# TODO(pumaranikar): We can consider moving these options to quota group
# and renaming them all to drop the quota bit.
def list_opts(): def list_opts():
return {'DEFAULT': quota_opts} return {quota_group: quota_opts}

View File

@ -4510,7 +4510,7 @@ def _security_group_ensure_default(context):
context.user_id, context.user_id,
'security_groups', 'security_groups',
1, 0, 1, 0,
CONF.until_refresh, CONF.quota.until_refresh,
context.session) context.session)
else: else:
usage.update({'in_use': int(usage.first().in_use) + 1}) usage.update({'in_use': int(usage.first().in_use) + 1})

View File

@ -485,7 +485,7 @@ class DbQuotaDriver(object):
# Set up the reservation expiration # Set up the reservation expiration
if expire is None: if expire is None:
expire = CONF.reservation_expire expire = CONF.quota.reservation_expire
if isinstance(expire, six.integer_types): if isinstance(expire, six.integer_types):
expire = datetime.timedelta(seconds=expire) expire = datetime.timedelta(seconds=expire)
if isinstance(expire, datetime.timedelta): if isinstance(expire, datetime.timedelta):
@ -539,7 +539,7 @@ class DbQuotaDriver(object):
# have to do the work there. # have to do the work there.
return db.quota_reserve(context, resources, quotas, user_quotas, return db.quota_reserve(context, resources, quotas, user_quotas,
deltas, expire, deltas, expire,
CONF.until_refresh, CONF.max_age, CONF.quota.until_refresh, CONF.quota.max_age,
project_id=project_id, user_id=user_id) project_id=project_id, user_id=user_id)
def commit(self, context, reservations, project_id=None, user_id=None): def commit(self, context, reservations, project_id=None, user_id=None):
@ -660,7 +660,8 @@ class DbQuotaDriver(object):
resource_names = syncable_resources resource_names = syncable_resources
return db.quota_usage_refresh(context, resources, resource_names, return db.quota_usage_refresh(context, resources, resource_names,
CONF.until_refresh, CONF.max_age, CONF.quota.until_refresh,
CONF.quota.max_age,
project_id=project_id, user_id=user_id) project_id=project_id, user_id=user_id)
def destroy_all_by_project_and_user(self, context, project_id, user_id): def destroy_all_by_project_and_user(self, context, project_id, user_id):
@ -1060,7 +1061,12 @@ class BaseResource(object):
def default(self): def default(self):
"""Return the default value of the quota.""" """Return the default value of the quota."""
return CONF[self.flag] if self.flag else -1 # NOTE(mikal): special case for quota_networks, which is an API
# flag and not a quota flag
if self.flag == 'quota_networks':
return CONF[self.flag]
return CONF.quota[self.flag] if self.flag else -1
class ReservableResource(BaseResource): class ReservableResource(BaseResource):
@ -1158,7 +1164,7 @@ class QuotaEngine(object):
if self.__driver: if self.__driver:
return self.__driver return self.__driver
if not self._driver_cls: if not self._driver_cls:
self._driver_cls = CONF.quota_driver self._driver_cls = CONF.quota.driver
if isinstance(self._driver_cls, six.string_types): if isinstance(self._driver_cls, six.string_types):
self._driver_cls = importutils.import_object(self._driver_cls) self._driver_cls = importutils.import_object(self._driver_cls)
self.__driver = self._driver_cls self.__driver = self._driver_cls
@ -1520,30 +1526,30 @@ QUOTAS = QuotaEngine()
resources = [ resources = [
ReservableResource('instances', '_sync_instances', 'quota_instances'), ReservableResource('instances', '_sync_instances', 'instances'),
ReservableResource('cores', '_sync_instances', 'quota_cores'), ReservableResource('cores', '_sync_instances', 'cores'),
ReservableResource('ram', '_sync_instances', 'quota_ram'), ReservableResource('ram', '_sync_instances', 'ram'),
ReservableResource('security_groups', '_sync_security_groups', ReservableResource('security_groups', '_sync_security_groups',
'quota_security_groups'), 'security_groups'),
ReservableResource('floating_ips', '_sync_floating_ips', ReservableResource('floating_ips', '_sync_floating_ips',
'quota_floating_ips'), 'floating_ips'),
ReservableResource('fixed_ips', '_sync_fixed_ips', 'quota_fixed_ips'), ReservableResource('fixed_ips', '_sync_fixed_ips', 'fixed_ips'),
AbsoluteResource('metadata_items', 'quota_metadata_items'), AbsoluteResource('metadata_items', 'metadata_items'),
AbsoluteResource('injected_files', 'quota_injected_files'), AbsoluteResource('injected_files', 'injected_files'),
AbsoluteResource('injected_file_content_bytes', AbsoluteResource('injected_file_content_bytes',
'quota_injected_file_content_bytes'), 'injected_file_content_bytes'),
AbsoluteResource('injected_file_path_bytes', AbsoluteResource('injected_file_path_bytes',
'quota_injected_file_path_length'), 'injected_file_path_length'),
CountableResource('security_group_rules', CountableResource('security_group_rules',
db.security_group_rule_count_by_group, db.security_group_rule_count_by_group,
'quota_security_group_rules'), 'security_group_rules'),
CountableResource('key_pairs', _keypair_get_count_by_user, CountableResource('key_pairs', _keypair_get_count_by_user,
'quota_key_pairs'), 'key_pairs'),
ReservableResource('server_groups', '_sync_server_groups', ReservableResource('server_groups', '_sync_server_groups',
'quota_server_groups'), 'server_groups'),
CountableResource('server_group_members', CountableResource('server_group_members',
_server_group_count_members_by_user, _server_group_count_members_by_user,
'quota_server_group_members'), 'server_group_members'),
] ]

View File

@ -228,7 +228,7 @@ class ServerGroupTestV21(ServerGroupTestBase):
def test_boot_servers_with_affinity_overquota(self): def test_boot_servers_with_affinity_overquota(self):
# Tests that we check server group member quotas and cleanup created # Tests that we check server group member quotas and cleanup created
# resources when we fail with OverQuota. # resources when we fail with OverQuota.
self.flags(quota_server_group_members=1) self.flags(server_group_members=1, group='quota')
# make sure we start with 0 servers # make sure we start with 0 servers
servers = self.api.get_servers(detail=False) servers = self.api.get_servers(detail=False)
self.assertEqual(0, len(servers)) self.assertEqual(0, len(servers))

View File

@ -310,7 +310,7 @@ class TestSecurityGroupsV21(test.TestCase):
self.req.environ['nova.context']) self.req.environ['nova.context'])
def test_create_security_group_quota_limit(self): def test_create_security_group_quota_limit(self):
for num in range(1, CONF.quota_security_groups): for num in range(1, CONF.quota.security_groups):
name = 'test%s' % num name = 'test%s' % num
sg = security_group_request_template(name=name) sg = security_group_request_template(name=name)
res_dict = self.controller.create(self.req, {'security_group': sg}) res_dict = self.controller.create(self.req, {'security_group': sg})
@ -1200,7 +1200,7 @@ class TestSecurityGroupRulesV21(test.TestCase):
self.req, self.invalid_id) self.req, self.invalid_id)
def test_create_rule_quota_limit(self): def test_create_rule_quota_limit(self):
for num in range(100, 100 + CONF.quota_security_group_rules): for num in range(100, 100 + CONF.quota.security_group_rules):
rule = { rule = {
'ip_protocol': 'tcp', 'from_port': num, 'ip_protocol': 'tcp', 'from_port': num,
'to_port': num, 'parent_group_id': self.sg2['id'], 'to_port': num, 'parent_group_id': self.sg2['id'],

View File

@ -1134,7 +1134,7 @@ class ServerActionsControllerTestV21(test.TestCase):
'metadata': {}, 'metadata': {},
}, },
} }
for num in range(CONF.quota_metadata_items + 1): for num in range(CONF.quota.metadata_items + 1):
body['createImage']['metadata']['foo%i' % num] = "bar" body['createImage']['metadata']['foo%i' % num] = "bar"
self.assertRaises(webob.exc.HTTPForbidden, self.assertRaises(webob.exc.HTTPForbidden,

View File

@ -104,7 +104,7 @@ class ServerGroupQuotasTestV21(test.TestCase):
policies = ['anti-affinity'] policies = ['anti-affinity']
sgroup['policies'] = policies sgroup['policies'] = policies
# Start by creating as many server groups as we're allowed to. # Start by creating as many server groups as we're allowed to.
for i in range(CONF.quota_server_groups): for i in range(CONF.quota.server_groups):
self.controller.create(self.req, body={'server_group': sgroup}) self.controller.create(self.req, body={'server_group': sgroup})
# Then, creating a server group should fail. # Then, creating a server group should fail.

View File

@ -75,7 +75,7 @@ def stub_server_metadata():
def stub_max_server_metadata(): def stub_max_server_metadata():
metadata = {"metadata": {}} metadata = {"metadata": {}}
for num in range(CONF.quota_metadata_items): for num in range(CONF.quota.metadata_items):
metadata['metadata']['key%i' % num] = "blah" metadata['metadata']['key%i' % num] = "blah"
return metadata return metadata
@ -582,7 +582,7 @@ class ServerMetaDataTestV21(test.TestCase):
self.stub_out('nova.db.instance_metadata_update', self.stub_out('nova.db.instance_metadata_update',
return_create_instance_metadata) return_create_instance_metadata)
data = {"metadata": {}} data = {"metadata": {}}
for num in range(CONF.quota_metadata_items + 1): for num in range(CONF.quota.metadata_items + 1):
data['metadata']['key%i' % num] = "blah" data['metadata']['key%i' % num] = "blah"
req = self._get_request() req = self._get_request()
req.method = 'POST' req.method = 'POST'
@ -621,7 +621,7 @@ class ServerMetaDataTestV21(test.TestCase):
self.stub_out('nova.db.instance_metadata_update', self.stub_out('nova.db.instance_metadata_update',
return_create_instance_metadata) return_create_instance_metadata)
data = {"metadata": {}} data = {"metadata": {}}
for num in range(CONF.quota_metadata_items + 1): for num in range(CONF.quota.metadata_items + 1):
data['metadata']['key%i' % num] = "blah" data['metadata']['key%i' % num] = "blah"
req = self._get_request() req = self._get_request()
req.method = 'PUT' req.method = 'PUT'
@ -637,7 +637,7 @@ class ServerMetaDataTestV21(test.TestCase):
self.stub_out('nova.db.instance_metadata_update', self.stub_out('nova.db.instance_metadata_update',
return_create_instance_metadata) return_create_instance_metadata)
data = {"metadata": {}} data = {"metadata": {}}
for num in range(CONF.quota_metadata_items + 1): for num in range(CONF.quota.metadata_items + 1):
data['metadata']['key%i' % num] = "blah" data['metadata']['key%i' % num] = "blah"
req = self._get_request() req = self._get_request()
req.method = 'PUT' req.method = 'PUT'

View File

@ -2891,14 +2891,14 @@ class ServersControllerCreateTest(test.TestCase):
self._test_create_instance_numa_topology_wrong(exc) self._test_create_instance_numa_topology_wrong(exc)
def test_create_instance_too_much_metadata(self): def test_create_instance_too_much_metadata(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata']['vote'] = 'fiddletown' self.body['server']['metadata']['vote'] = 'fiddletown'
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
self.assertRaises(webob.exc.HTTPForbidden, self.assertRaises(webob.exc.HTTPForbidden,
self.controller.create, self.req, body=self.body) self.controller.create, self.req, body=self.body)
def test_create_instance_metadata_key_too_long(self): def test_create_instance_metadata_key_too_long(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata'] = {('a' * 260): '12345'} self.body['server']['metadata'] = {('a' * 260): '12345'}
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
@ -2906,35 +2906,35 @@ class ServersControllerCreateTest(test.TestCase):
self.controller.create, self.req, body=self.body) self.controller.create, self.req, body=self.body)
def test_create_instance_metadata_value_too_long(self): def test_create_instance_metadata_value_too_long(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata'] = {'key1': ('a' * 260)} self.body['server']['metadata'] = {'key1': ('a' * 260)}
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
self.assertRaises(exception.ValidationError, self.assertRaises(exception.ValidationError,
self.controller.create, self.req, body=self.body) self.controller.create, self.req, body=self.body)
def test_create_instance_metadata_key_blank(self): def test_create_instance_metadata_key_blank(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata'] = {'': 'abcd'} self.body['server']['metadata'] = {'': 'abcd'}
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
self.assertRaises(exception.ValidationError, self.assertRaises(exception.ValidationError,
self.controller.create, self.req, body=self.body) self.controller.create, self.req, body=self.body)
def test_create_instance_metadata_not_dict(self): def test_create_instance_metadata_not_dict(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata'] = 'string' self.body['server']['metadata'] = 'string'
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
self.assertRaises(exception.ValidationError, self.assertRaises(exception.ValidationError,
self.controller.create, self.req, body=self.body) self.controller.create, self.req, body=self.body)
def test_create_instance_metadata_key_not_string(self): def test_create_instance_metadata_key_not_string(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata'] = {1: 'test'} self.body['server']['metadata'] = {1: 'test'}
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
self.assertRaises(exception.ValidationError, self.assertRaises(exception.ValidationError,
self.controller.create, self.req, body=self.body) self.controller.create, self.req, body=self.body)
def test_create_instance_metadata_value_not_string(self): def test_create_instance_metadata_value_not_string(self):
self.flags(quota_metadata_items=1) self.flags(metadata_items=1, group='quota')
self.body['server']['metadata'] = {'test': ['a', 'list']} self.body['server']['metadata'] = {'test': ['a', 'list']}
self.req.body = jsonutils.dump_as_bytes(self.body) self.req.body = jsonutils.dump_as_bytes(self.body)
self.assertRaises(exception.ValidationError, self.assertRaises(exception.ValidationError,

View File

@ -151,7 +151,7 @@ class CreateImportSharedTestMixIn(object):
def test_quota_limit(self): def test_quota_limit(self):
def fake_quotas_count(self, context, resource, *args, **kwargs): def fake_quotas_count(self, context, resource, *args, **kwargs):
return CONF.quota_key_pairs return CONF.quota.key_pairs
self.stubs.Set(QUOTAS, "count", fake_quotas_count) self.stubs.Set(QUOTAS, "count", fake_quotas_count)

View File

@ -157,7 +157,7 @@ def _quota_reserve(context, project_id, user_id):
sqlalchemy_api.QUOTA_SYNC_FUNCTIONS[sync_name] = getattr( sqlalchemy_api.QUOTA_SYNC_FUNCTIONS[sync_name] = getattr(
sqlalchemy_api, sync_name) sqlalchemy_api, sync_name)
return db.quota_reserve(context, resources, quotas, user_quotas, deltas, return db.quota_reserve(context, resources, quotas, user_quotas, deltas,
timeutils.utcnow(), CONF.until_refresh, timeutils.utcnow(), CONF.quota.until_refresh,
datetime.timedelta(days=1), project_id, user_id) datetime.timedelta(days=1), project_id, user_id)
@ -2237,7 +2237,7 @@ class SecurityGroupTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.assertEqual(1, usage.in_use) self.assertEqual(1, usage.in_use)
def test_security_group_ensure_default_until_refresh(self): def test_security_group_ensure_default_until_refresh(self):
self.flags(until_refresh=2) self.flags(until_refresh=2, group='quota')
self.ctxt.project_id = 'fake' self.ctxt.project_id = 'fake'
self.ctxt.user_id = 'fake' self.ctxt.user_id = 'fake'
db.security_group_ensure_default(self.ctxt) db.security_group_ensure_default(self.ctxt)

View File

@ -42,8 +42,9 @@ class QuotaIntegrationTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(QuotaIntegrationTestCase, self).setUp() super(QuotaIntegrationTestCase, self).setUp()
self.flags(quota_instances=2, self.flags(instances=2,
quota_cores=4) cores=4,
group='quota')
self.user_id = 'admin' self.user_id = 'admin'
self.project_id = 'admin' self.project_id = 'admin'
@ -80,7 +81,7 @@ class QuotaIntegrationTestCase(test.TestCase):
def test_too_many_instances(self): def test_too_many_instances(self):
instance_uuids = [] instance_uuids = []
for i in range(CONF.quota_instances): for i in range(CONF.quota.instances):
instance = self._create_instance() instance = self._create_instance()
instance_uuids.append(instance['uuid']) instance_uuids.append(instance['uuid'])
inst_type = flavors.get_flavor_by_name('m1.small') inst_type = flavors.get_flavor_by_name('m1.small')
@ -122,15 +123,15 @@ class QuotaIntegrationTestCase(test.TestCase):
def test_many_cores_with_unlimited_quota(self): def test_many_cores_with_unlimited_quota(self):
# Setting cores quota to unlimited: # Setting cores quota to unlimited:
self.flags(quota_cores=-1) self.flags(cores=-1, group='quota')
instance = self._create_instance(cores=4) instance = self._create_instance(cores=4)
db.instance_destroy(self.context, instance['uuid']) db.instance_destroy(self.context, instance['uuid'])
def test_too_many_addresses(self): def test_too_many_addresses(self):
# This test is specifically relying on nova-network. # This test is specifically relying on nova-network.
self.flags(use_neutron=False, self.flags(use_neutron=False,
quota_floating_ips=1,
network_manager='nova.network.manager.FlatDHCPManager') network_manager='nova.network.manager.FlatDHCPManager')
self.flags(floating_ips=1, group='quota')
# Apparently needed by the RPC tests... # Apparently needed by the RPC tests...
self.network = self.start_service('network', self.network = self.start_service('network',
manager=CONF.network_manager) manager=CONF.network_manager)
@ -148,8 +149,8 @@ class QuotaIntegrationTestCase(test.TestCase):
def test_auto_assigned(self): def test_auto_assigned(self):
# This test is specifically relying on nova-network. # This test is specifically relying on nova-network.
self.flags(use_neutron=False, self.flags(use_neutron=False,
quota_floating_ips=1,
network_manager='nova.network.manager.FlatDHCPManager') network_manager='nova.network.manager.FlatDHCPManager')
self.flags(floating_ips=1, group='quota')
# Apparently needed by the RPC tests... # Apparently needed by the RPC tests...
self.network = self.start_service('network', self.network = self.start_service('network',
manager=CONF.network_manager) manager=CONF.network_manager)
@ -168,7 +169,7 @@ class QuotaIntegrationTestCase(test.TestCase):
def test_too_many_metadata_items(self): def test_too_many_metadata_items(self):
metadata = {} metadata = {}
for i in range(CONF.quota_metadata_items + 1): for i in range(CONF.quota.metadata_items + 1):
metadata['key%s' % i] = 'value%s' % i metadata['key%s' % i] = 'value%s' % i
inst_type = flavors.get_flavor_by_name('m1.small') inst_type = flavors.get_flavor_by_name('m1.small')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
@ -198,38 +199,38 @@ class QuotaIntegrationTestCase(test.TestCase):
def test_max_injected_files(self): def test_max_injected_files(self):
files = [] files = []
for i in range(CONF.quota_injected_files): for i in range(CONF.quota.injected_files):
files.append(('/my/path%d' % i, 'config = test\n')) files.append(('/my/path%d' % i, 'config = test\n'))
self._create_with_injected_files(files) # no QuotaError self._create_with_injected_files(files) # no QuotaError
def test_too_many_injected_files(self): def test_too_many_injected_files(self):
files = [] files = []
for i in range(CONF.quota_injected_files + 1): for i in range(CONF.quota.injected_files + 1):
files.append(('/my/path%d' % i, 'my\ncontent%d\n' % i)) files.append(('/my/path%d' % i, 'my\ncontent%d\n' % i))
self.assertRaises(exception.QuotaError, self.assertRaises(exception.QuotaError,
self._create_with_injected_files, files) self._create_with_injected_files, files)
def test_max_injected_file_content_bytes(self): def test_max_injected_file_content_bytes(self):
max = CONF.quota_injected_file_content_bytes max = CONF.quota.injected_file_content_bytes
content = ''.join(['a' for i in range(max)]) content = ''.join(['a' for i in range(max)])
files = [('/test/path', content)] files = [('/test/path', content)]
self._create_with_injected_files(files) # no QuotaError self._create_with_injected_files(files) # no QuotaError
def test_too_many_injected_file_content_bytes(self): def test_too_many_injected_file_content_bytes(self):
max = CONF.quota_injected_file_content_bytes max = CONF.quota.injected_file_content_bytes
content = ''.join(['a' for i in range(max + 1)]) content = ''.join(['a' for i in range(max + 1)])
files = [('/test/path', content)] files = [('/test/path', content)]
self.assertRaises(exception.QuotaError, self.assertRaises(exception.QuotaError,
self._create_with_injected_files, files) self._create_with_injected_files, files)
def test_max_injected_file_path_bytes(self): def test_max_injected_file_path_bytes(self):
max = CONF.quota_injected_file_path_length max = CONF.quota.injected_file_path_length
path = ''.join(['a' for i in range(max)]) path = ''.join(['a' for i in range(max)])
files = [(path, 'config = quotatest')] files = [(path, 'config = quotatest')]
self._create_with_injected_files(files) # no QuotaError self._create_with_injected_files(files) # no QuotaError
def test_too_many_injected_file_path_bytes(self): def test_too_many_injected_file_path_bytes(self):
max = CONF.quota_injected_file_path_length max = CONF.quota.injected_file_path_length
path = ''.join(['a' for i in range(max + 1)]) path = ''.join(['a' for i in range(max + 1)])
files = [(path, 'config = quotatest')] files = [(path, 'config = quotatest')]
self.assertRaises(exception.QuotaError, self.assertRaises(exception.QuotaError,
@ -371,24 +372,24 @@ class BaseResourceTestCase(test.TestCase):
def test_with_flag(self): def test_with_flag(self):
# We know this flag exists, so use it... # We know this flag exists, so use it...
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
self.assertEqual(resource.name, 'test_resource') self.assertEqual(resource.name, 'test_resource')
self.assertEqual(resource.flag, 'quota_instances') self.assertEqual(resource.flag, 'instances')
self.assertEqual(resource.default, 10) self.assertEqual(resource.default, 10)
def test_with_flag_no_quota(self): def test_with_flag_no_quota(self):
self.flags(quota_instances=-1) self.flags(instances=-1, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
self.assertEqual(resource.name, 'test_resource') self.assertEqual(resource.name, 'test_resource')
self.assertEqual(resource.flag, 'quota_instances') self.assertEqual(resource.flag, 'instances')
self.assertEqual(resource.default, -1) self.assertEqual(resource.default, -1)
def test_quota_no_project_no_class(self): def test_quota_no_project_no_class(self):
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
driver = FakeDriver() driver = FakeDriver()
context = FakeContext(None, None) context = FakeContext(None, None)
quota_value = resource.quota(driver, context) quota_value = resource.quota(driver, context)
@ -396,8 +397,8 @@ class BaseResourceTestCase(test.TestCase):
self.assertEqual(quota_value, 10) self.assertEqual(quota_value, 10)
def test_quota_with_project_no_class(self): def test_quota_with_project_no_class(self):
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
driver = FakeDriver(by_project=dict( driver = FakeDriver(by_project=dict(
test_project=dict(test_resource=15), test_project=dict(test_resource=15),
)) ))
@ -407,8 +408,8 @@ class BaseResourceTestCase(test.TestCase):
self.assertEqual(quota_value, 15) self.assertEqual(quota_value, 15)
def test_quota_no_project_with_class(self): def test_quota_no_project_with_class(self):
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
driver = FakeDriver(by_class=dict( driver = FakeDriver(by_class=dict(
test_class=dict(test_resource=20), test_class=dict(test_resource=20),
)) ))
@ -418,8 +419,8 @@ class BaseResourceTestCase(test.TestCase):
self.assertEqual(quota_value, 20) self.assertEqual(quota_value, 20)
def test_quota_with_project_with_class(self): def test_quota_with_project_with_class(self):
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
driver = FakeDriver(by_project=dict( driver = FakeDriver(by_project=dict(
test_project=dict(test_resource=15), test_project=dict(test_resource=15),
), ),
@ -432,8 +433,8 @@ class BaseResourceTestCase(test.TestCase):
self.assertEqual(quota_value, 15) self.assertEqual(quota_value, 15)
def test_quota_override_project_with_class(self): def test_quota_override_project_with_class(self):
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
driver = FakeDriver(by_project=dict( driver = FakeDriver(by_project=dict(
test_project=dict(test_resource=15), test_project=dict(test_resource=15),
override_project=dict(test_resource=20), override_project=dict(test_resource=20),
@ -445,8 +446,8 @@ class BaseResourceTestCase(test.TestCase):
self.assertEqual(quota_value, 20) self.assertEqual(quota_value, 20)
def test_quota_with_project_override_class(self): def test_quota_with_project_override_class(self):
self.flags(quota_instances=10) self.flags(instances=10, group='quota')
resource = quota.BaseResource('test_resource', 'quota_instances') resource = quota.BaseResource('test_resource', 'instances')
driver = FakeDriver(by_class=dict( driver = FakeDriver(by_class=dict(
test_class=dict(test_resource=15), test_class=dict(test_resource=15),
override_class=dict(test_resource=20), override_class=dict(test_resource=20),
@ -828,22 +829,23 @@ class DbQuotaDriverTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(DbQuotaDriverTestCase, self).setUp() super(DbQuotaDriverTestCase, self).setUp()
self.flags(quota_instances=10, self.flags(instances=10,
quota_cores=20, cores=20,
quota_ram=50 * 1024, ram=50 * 1024,
quota_floating_ips=10, floating_ips=10,
quota_fixed_ips=10, fixed_ips=10,
quota_metadata_items=128, metadata_items=128,
quota_injected_files=5, injected_files=5,
quota_injected_file_content_bytes=10 * 1024, injected_file_content_bytes=10 * 1024,
quota_injected_file_path_length=255, injected_file_path_length=255,
quota_security_groups=10, security_groups=10,
quota_security_group_rules=20, security_group_rules=20,
quota_server_groups=10, server_groups=10,
quota_server_group_members=10, server_group_members=10,
reservation_expire=86400, reservation_expire=86400,
until_refresh=0, until_refresh=0,
max_age=0, max_age=0,
group='quota'
) )
self.driver = quota.DbQuotaDriver() self.driver = quota.DbQuotaDriver()
@ -2217,7 +2219,7 @@ class DbQuotaDriverTestCase(test.TestCase):
injected_file_path_bytes=256)) injected_file_path_bytes=256))
def test_limit_check_unlimited(self): def test_limit_check_unlimited(self):
self.flags(quota_metadata_items=-1) self.flags(metadata_items=-1, group='quota')
self._stub_get_project_quotas() self._stub_get_project_quotas()
self.driver.limit_check(FakeContext('test_project', 'test_class'), self.driver.limit_check(FakeContext('test_project', 'test_class'),
quota.QUOTAS._resources, quota.QUOTAS._resources,
@ -2308,7 +2310,7 @@ class DbQuotaDriverTestCase(test.TestCase):
def test_reserve_until_refresh(self): def test_reserve_until_refresh(self):
self._stub_get_project_quotas() self._stub_get_project_quotas()
self._stub_quota_reserve() self._stub_quota_reserve()
self.flags(until_refresh=500) self.flags(until_refresh=500, group='quota')
expire = timeutils.utcnow() + datetime.timedelta(seconds=120) expire = timeutils.utcnow() + datetime.timedelta(seconds=120)
result = self.driver.reserve(FakeContext('test_project', 'test_class'), result = self.driver.reserve(FakeContext('test_project', 'test_class'),
quota.QUOTAS._resources, quota.QUOTAS._resources,
@ -2323,7 +2325,7 @@ class DbQuotaDriverTestCase(test.TestCase):
def test_reserve_max_age(self): def test_reserve_max_age(self):
self._stub_get_project_quotas() self._stub_get_project_quotas()
self._stub_quota_reserve() self._stub_quota_reserve()
self.flags(max_age=86400) self.flags(max_age=86400, group='quota')
expire = timeutils.utcnow() + datetime.timedelta(seconds=120) expire = timeutils.utcnow() + datetime.timedelta(seconds=120)
result = self.driver.reserve(FakeContext('test_project', 'test_class'), result = self.driver.reserve(FakeContext('test_project', 'test_class'),
quota.QUOTAS._resources, quota.QUOTAS._resources,
@ -2750,7 +2752,7 @@ class QuotaReserveSqlAlchemyTestCase(QuotaSqlAlchemyBase):
def test_quota_reserve_cores_unlimited(self): def test_quota_reserve_cores_unlimited(self):
# Requesting 8 cores, quota_cores set to unlimited: # Requesting 8 cores, quota_cores set to unlimited:
self.flags(quota_cores=-1) self.flags(cores=-1, group='quota')
self._init_usages(1, 8, 1 * 1024, 1) self._init_usages(1, 8, 1 * 1024, 1)
self.assertEqual(self.sync_called, set([])) self.assertEqual(self.sync_called, set([]))
self.usages_list[0]["in_use"] = 1 self.usages_list[0]["in_use"] = 1
@ -2767,7 +2769,7 @@ class QuotaReserveSqlAlchemyTestCase(QuotaSqlAlchemyBase):
def test_quota_reserve_ram_unlimited(self): def test_quota_reserve_ram_unlimited(self):
# Requesting 10*1024 ram, quota_ram set to unlimited: # Requesting 10*1024 ram, quota_ram set to unlimited:
self.flags(quota_ram=-1) self.flags(ram=-1, group='quota')
self._init_usages(1, 1, 10 * 1024, 1) self._init_usages(1, 1, 10 * 1024, 1)
self.assertEqual(self.sync_called, set([])) self.assertEqual(self.sync_called, set([]))
self.usages_list[0]["in_use"] = 1 self.usages_list[0]["in_use"] = 1
@ -3078,19 +3080,20 @@ class NoopQuotaDriverTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(NoopQuotaDriverTestCase, self).setUp() super(NoopQuotaDriverTestCase, self).setUp()
self.flags(quota_instances=10, self.flags(instances=10,
quota_cores=20, cores=20,
quota_ram=50 * 1024, ram=50 * 1024,
quota_floating_ips=10, floating_ips=10,
quota_metadata_items=128, metadata_items=128,
quota_injected_files=5, injected_files=5,
quota_injected_file_content_bytes=10 * 1024, injected_file_content_bytes=10 * 1024,
quota_injected_file_path_length=255, injected_file_path_length=255,
quota_security_groups=10, security_groups=10,
quota_security_group_rules=20, security_group_rules=20,
reservation_expire=86400, reservation_expire=86400,
until_refresh=0, until_refresh=0,
max_age=0, max_age=0,
group='quota'
) )
self.expected_with_usages = {} self.expected_with_usages = {}

View File

@ -0,0 +1,26 @@
---
upgrade:
- |
Most quota options have been moved into their own
configuration group. The exception is quota_networks
as it is an API flag not a quota flag. These options are as
below:
- ``quota_instances`` (now ``instances``)
- ``quota_cores`` (now ``cores``)
- ``quota_ram`` (now ``ram``)
- ``quota_floating_ips`` (now ``floating_ips``)
- ``quota_fixed_ips`` (now ``fixed_ips``)
- ``quota_metadata_items`` (now ``metadata_items``)
- ``quota_injected_files`` (now ``injected_files``)
- ``quota_injected_file_content_bytes`` (now ``injected_file_content_bytes``)
- ``quota_injected_file_path_length`` (now ``injected_file_path_length``)
- ``quota_security_groups`` (now ``security_groups``)
- ``quota_security_group_rules`` (now ``security_group_rules``)
- ``quota_key_pairs`` (now ``key_pairs``)
- ``quota_server_groups`` (now ``server_groups``)
- ``quota_server_group_members`` (now ``server_group_members``)
- ``reservation_expire``
- ``until_refresh``
- ``max_age``
- ``quota_driver`` (now ``driver``)