Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 578328 Details for
Bug 813768
CVE-2012-2101 openstack-nova: No quota enforced on security group rules
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
proposed fix
security_group_quotas.patch (text/plain), 27.49 KB, created by
Pádraig Brady
on 2012-04-18 11:49:53 UTC
(
hide
)
Description:
proposed fix
Filename:
MIME Type:
Creator:
Pádraig Brady
Created:
2012-04-18 11:49:53 UTC
Size:
27.49 KB
patch
obsolete
>diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py >index 9346d10..012afb9 100644 >--- a/nova/api/ec2/cloud.py >+++ b/nova/api/ec2/cloud.py >@@ -41,6 +41,7 @@ from nova import flags > from nova.image import s3 > from nova import log as logging > from nova import network >+from nova import quota > from nova import utils > from nova import volume > >@@ -725,6 +726,13 @@ class CloudController(object): > raise exception.EC2APIError(err % values_for_rule) > postvalues.append(values_for_rule) > >+ allowed = quota.allowed_security_group_rules(context, >+ security_group['id'], >+ 1) >+ if allowed < 1: >+ msg = _("Quota exceeded, too many security group rules.") >+ raise exception.EC2APIError(msg) >+ > rule_ids = [] > for values_for_rule in postvalues: > security_group_rule = db.security_group_rule_create( >@@ -782,6 +790,10 @@ class CloudController(object): > msg = _('group %s already exists') > raise exception.EC2APIError(msg % group_name) > >+ if quota.allowed_security_groups(context, 1) < 1: >+ msg = _("Quota exceeded, too many security groups.") >+ raise exception.EC2APIError(msg) >+ > group = {'user_id': context.user_id, > 'project_id': context.project_id, > 'name': group_name, >diff --git a/nova/api/openstack/compute/contrib/security_groups.py b/nova/api/openstack/compute/contrib/security_groups.py >index 0d85c7b..281cc8c 100644 >--- a/nova/api/openstack/compute/contrib/security_groups.py >+++ b/nova/api/openstack/compute/contrib/security_groups.py >@@ -31,6 +31,7 @@ from nova import db > from nova import exception > from nova import flags > from nova import log as logging >+from nova import quota > from nova import utils > > >@@ -289,6 +290,10 @@ class SecurityGroupController(SecurityGroupControllerBase): > group_name = group_name.strip() > group_description = group_description.strip() > >+ if quota.allowed_security_groups(context, 1) < 1: >+ msg = _("Quota exceeded, too many security groups.") >+ raise exc.HTTPBadRequest(explanation=msg) >+ > LOG.audit(_("Create Security Group %s"), group_name, context=context) > self.compute_api.ensure_default_security_group(context) > if db.security_group_exists(context, context.project_id, group_name): >@@ -376,6 +381,13 @@ class SecurityGroupRulesController(SecurityGroupControllerBase): > msg = _('This rule already exists in group %s') % parent_group_id > raise exc.HTTPBadRequest(explanation=msg) > >+ allowed = quota.allowed_security_group_rules(context, >+ parent_group_id, >+ 1) >+ if allowed < 1: >+ msg = _("Quota exceeded, too many security group rules.") >+ raise exc.HTTPBadRequest(explanation=msg) >+ > security_group_rule = db.security_group_rule_create(context, values) > self.sgh.trigger_security_group_rule_create_refresh( > context, [security_group_rule['id']]) >diff --git a/nova/db/api.py b/nova/db/api.py >index f217a9e..9f3cf5f 100644 >--- a/nova/db/api.py >+++ b/nova/db/api.py >@@ -1151,6 +1151,11 @@ def security_group_destroy(context, security_group_id): > return IMPL.security_group_destroy(context, security_group_id) > > >+def security_group_count_by_project(context, project_id): >+ """Count number of security groups in a project.""" >+ return IMPL.security_group_count_by_project(context, project_id) >+ >+ > #################### > > >@@ -1182,6 +1187,11 @@ def security_group_rule_get(context, security_group_rule_id): > return IMPL.security_group_rule_get(context, security_group_rule_id) > > >+def security_group_rule_count_by_group(context, security_group_id): >+ """Count rules in a given security group.""" >+ return IMPL.security_group_rule_count_by_group(context, security_group_id) >+ >+ > ################### > > >diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py >index ff1b5a3..2e0278b 100644 >--- a/nova/db/sqlalchemy/api.py >+++ b/nova/db/sqlalchemy/api.py >@@ -2903,6 +2903,13 @@ def security_group_destroy(context, security_group_id): > 'updated_at': literal_column('updated_at')}) > > >+@require_context >+def security_group_count_by_project(context, project_id): >+ authorize_project_context(context, project_id) >+ return model_query(context, models.SecurityGroup, read_deleted="no").\ >+ filter_by(project_id=project_id).\ >+ count() >+ > ################### > > >@@ -2961,6 +2968,14 @@ def security_group_rule_destroy(context, security_group_rule_id): > security_group_rule.delete(session=session) > > >+@require_context >+def security_group_rule_count_by_group(context, security_group_id): >+ return model_query(context, models.SecurityGroupIngressRule, >+ read_deleted="no").\ >+ filter_by(parent_group_id=security_group_id).\ >+ count() >+ >+# > ################### > > >diff --git a/nova/quota.py b/nova/quota.py >index a5ee5cd..9f43f72 100644 >--- a/nova/quota.py >+++ b/nova/quota.py >@@ -54,6 +54,12 @@ quota_opts = [ > cfg.IntOpt('quota_injected_file_path_bytes', > default=255, > help='number of bytes allowed per injected file path'), >+ cfg.IntOpt('quota_security_groups', >+ default=10, >+ help='number of security groups per project'), >+ cfg.IntOpt('quota_security_group_rules', >+ default=20, >+ help='number of security rules per security group'), > ] > > FLAGS = flags.FLAGS >@@ -62,7 +68,7 @@ FLAGS.register_opts(quota_opts) > > quota_resources = ['metadata_items', 'injected_file_content_bytes', > 'volumes', 'gigabytes', 'ram', 'floating_ips', 'instances', >- 'injected_files', 'cores'] >+ 'injected_files', 'cores', 'security_groups', 'security_group_rules'] > > > def _get_default_quotas(): >@@ -77,6 +83,8 @@ def _get_default_quotas(): > '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, > } > # -1 in the quota flags means unlimited > return defaults >@@ -170,6 +178,32 @@ def allowed_floating_ips(context, requested_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 _calculate_simple_quota(context, resource, requested): > """Check quota for resource; return min(requested, allowed).""" > quota = get_project_quotas(context, context.project_id) >diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py >index 6ac0ed0..78ca783 100644 >--- a/nova/tests/api/ec2/test_cloud.py >+++ b/nova/tests/api/ec2/test_cloud.py >@@ -271,6 +271,18 @@ class CloudTestCase(test.TestCase): > delete = self.cloud.delete_security_group > self.assertTrue(delete(self.context, 'testgrp')) > >+ def test_security_group_quota_limit(self): >+ self.flags(quota_security_groups=10) >+ for i in range(1, 10): >+ name = 'test name %i' % i >+ descript = 'test description %i' % i >+ create = self.cloud.create_security_group >+ result = create(self.context, name, descript) >+ >+ # 11'th group should fail >+ self.assertRaises(exception.EC2APIError, >+ create, self.context, 'foo', 'bar') >+ > def test_delete_security_group_by_id(self): > sec = db.security_group_create(self.context, > {'project_id': self.context.project_id, >@@ -436,6 +448,19 @@ class CloudTestCase(test.TestCase): > self.assertRaises(exception.EC2APIError, authz, self.context, > group_name=sec['name'], **kwargs) > >+ def test_security_group_ingress_quota_limit(self): >+ self.flags(quota_security_group_rules=20) >+ kwargs = {'project_id': self.context.project_id, 'name': 'test'} >+ sec_group = db.security_group_create(self.context, kwargs) >+ authz = self.cloud.authorize_security_group_ingress >+ for i in range(100, 120): >+ kwargs = {'to_port': i, 'from_port': i, 'ip_protocol': 'tcp'} >+ authz(self.context, group_id=sec_group['id'], **kwargs) >+ >+ kwargs = {'to_port': 121, 'from_port': 121, 'ip_protocol': 'tcp'} >+ self.assertRaises(exception.EC2APIError, authz, self.context, >+ group_id=sec_group['id'], **kwargs) >+ > def _test_authorize_security_group_no_ports_with_source_group(self, proto): > kwargs = {'project_id': self.context.project_id, 'name': 'test'} > sec = db.security_group_create(self.context, kwargs) >diff --git a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py >index e29d266..d922152 100644 >--- a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py >+++ b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py >@@ -26,7 +26,8 @@ def quota_set(class_name): > return {'quota_class_set': {'id': class_name, 'metadata_items': 128, > 'volumes': 10, 'gigabytes': 1000, 'ram': 51200, > 'floating_ips': 10, 'instances': 10, 'injected_files': 5, >- 'cores': 20, 'injected_file_content_bytes': 10240}} >+ 'cores': 20, 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, 'security_group_rules': 20}} > > > class QuotaClassSetsTest(test.TestCase): >@@ -45,7 +46,10 @@ class QuotaClassSetsTest(test.TestCase): > 'metadata_items': 128, > 'gigabytes': 1000, > 'injected_files': 5, >- 'injected_file_content_bytes': 10240} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20, >+ } > > quota_set = self.controller._format_quota_set('test_class', > raw_quota_set) >@@ -61,6 +65,8 @@ class QuotaClassSetsTest(test.TestCase): > self.assertEqual(qs['metadata_items'], 128) > self.assertEqual(qs['injected_files'], 5) > self.assertEqual(qs['injected_file_content_bytes'], 10240) >+ self.assertEqual(qs['security_groups'], 10) >+ self.assertEqual(qs['security_group_rules'], 20) > > def test_quotas_show_as_admin(self): > req = fakes.HTTPRequest.blank( >@@ -81,7 +87,10 @@ class QuotaClassSetsTest(test.TestCase): > 'ram': 51200, 'volumes': 10, > 'gigabytes': 1000, 'floating_ips': 10, > 'metadata_items': 128, 'injected_files': 5, >- 'injected_file_content_bytes': 10240}} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20, >+ }} > > req = fakes.HTTPRequest.blank( > '/v2/fake4/os-quota-class-sets/test_class', >@@ -95,7 +104,10 @@ class QuotaClassSetsTest(test.TestCase): > 'ram': 51200, 'volumes': 10, > 'gigabytes': 1000, 'floating_ips': 10, > 'metadata_items': 128, 'injected_files': 5, >- 'injected_file_content_bytes': 10240}} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20, >+ }} > > req = fakes.HTTPRequest.blank( > '/v2/fake4/os-quota-class-sets/test_class') >@@ -120,6 +132,8 @@ class QuotaTemplateXMLSerializerTest(test.TestCase): > floating_ips=60, > instances=70, > injected_files=80, >+ security_groups=10, >+ security_group_rules=20, > cores=90)) > text = self.serializer.serialize(exemplar) > >@@ -144,6 +158,8 @@ class QuotaTemplateXMLSerializerTest(test.TestCase): > floating_ips='60', > instances='70', > injected_files='80', >+ security_groups='10', >+ security_group_rules='20', > cores='90')) > intext = ("<?xml version='1.0' encoding='UTF-8'?>\n" > '<quota_class_set>' >@@ -157,6 +173,8 @@ class QuotaTemplateXMLSerializerTest(test.TestCase): > '<instances>70</instances>' > '<injected_files>80</injected_files>' > '<cores>90</cores>' >+ '<security_groups>10</security_groups>' >+ '<security_group_rules>20</security_group_rules>' > '</quota_class_set>') > > result = self.deserializer.deserialize(intext)['body'] >diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py >index ea34a4e..b603ae6 100644 >--- a/nova/tests/api/openstack/compute/contrib/test_quotas.py >+++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py >@@ -28,7 +28,8 @@ def quota_set(id): > return {'quota_set': {'id': id, 'metadata_items': 128, 'volumes': 10, > 'gigabytes': 1000, 'ram': 51200, 'floating_ips': 10, > 'instances': 10, 'injected_files': 5, 'cores': 20, >- 'injected_file_content_bytes': 10240}} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, 'security_group_rules': 20}} > > > class QuotaSetsTest(test.TestCase): >@@ -47,7 +48,10 @@ class QuotaSetsTest(test.TestCase): > 'metadata_items': 128, > 'gigabytes': 1000, > 'injected_files': 5, >- 'injected_file_content_bytes': 10240} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20, >+ } > > quota_set = self.controller._format_quota_set('1234', raw_quota_set) > qs = quota_set['quota_set'] >@@ -62,6 +66,8 @@ class QuotaSetsTest(test.TestCase): > self.assertEqual(qs['metadata_items'], 128) > self.assertEqual(qs['injected_files'], 5) > self.assertEqual(qs['injected_file_content_bytes'], 10240) >+ self.assertEqual(qs['security_groups'], 10) >+ self.assertEqual(qs['security_group_rules'], 20) > > def test_quotas_defaults(self): > uri = '/v2/fake_tenant/os-quota-sets/fake_tenant/defaults' >@@ -79,7 +85,10 @@ class QuotaSetsTest(test.TestCase): > 'floating_ips': 10, > 'metadata_items': 128, > 'injected_files': 5, >- 'injected_file_content_bytes': 10240}} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20, >+ }} > > self.assertEqual(res_dict, expected) > >@@ -100,7 +109,9 @@ class QuotaSetsTest(test.TestCase): > 'ram': 51200, 'volumes': 10, > 'gigabytes': 1000, 'floating_ips': 10, > 'metadata_items': 128, 'injected_files': 5, >- 'injected_file_content_bytes': 10240}} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20}} > > req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me', > use_admin_context=True) >@@ -113,7 +124,9 @@ class QuotaSetsTest(test.TestCase): > 'ram': 51200, 'volumes': 10, > 'gigabytes': 1000, 'floating_ips': 10, > 'metadata_items': 128, 'injected_files': 5, >- 'injected_file_content_bytes': 10240}} >+ 'injected_file_content_bytes': 10240, >+ 'security_groups': 10, >+ 'security_group_rules': 20}} > > req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me') > self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, >@@ -149,6 +162,8 @@ class QuotaXMLSerializerTest(test.TestCase): > floating_ips=60, > instances=70, > injected_files=80, >+ security_groups=10, >+ security_group_rules=20, > cores=90)) > text = self.serializer.serialize(exemplar) > >@@ -172,6 +187,8 @@ class QuotaXMLSerializerTest(test.TestCase): > floating_ips='60', > instances='70', > injected_files='80', >+ security_groups='10', >+ security_group_rules='20', > cores='90')) > intext = ("<?xml version='1.0' encoding='UTF-8'?>\n" > '<quota_set>' >@@ -184,6 +201,8 @@ class QuotaXMLSerializerTest(test.TestCase): > '<floating_ips>60</floating_ips>' > '<instances>70</instances>' > '<injected_files>80</injected_files>' >+ '<security_groups>10</security_groups>' >+ '<security_group_rules>20</security_group_rules>' > '<cores>90</cores>' > '</quota_set>') > >diff --git a/nova/tests/api/openstack/compute/contrib/test_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_security_groups.py >index 0cf66ec..8cc4cc6 100644 >--- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py >+++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py >@@ -25,12 +25,15 @@ from nova.api.openstack.compute.contrib import security_groups > from nova.api.openstack import wsgi > import nova.db > from nova import exception >+from nova import flags > from nova import test > from nova.tests.api.openstack import fakes > > > FAKE_UUID = 'a47ae74e-ab08-447f-8eee-ffd43fc46c16' > >+FLAGS = flags.FLAGS >+ > > class AttrDict(dict): > def __getattr__(self, k): >@@ -219,6 +222,18 @@ class TestSecurityGroups(test.TestCase): > self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, > req, {'security_group': sg}) > >+ def test_create_security_group_quota_limit(self): >+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups') >+ for num in range(1, FLAGS.quota_security_groups): >+ name = 'test%s' % num >+ sg = security_group_template(name=name) >+ res_dict = self.controller.create(req, {'security_group': sg}) >+ self.assertEqual(res_dict['security_group']['name'], name) >+ >+ sg = security_group_template() >+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, >+ req, {'security_group': sg}) >+ > def test_get_security_group_list(self): > groups = [] > for i, name in enumerate(['default', 'test']): >@@ -894,6 +909,22 @@ class TestSecurityGroupRules(test.TestCase): > self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, > req, '22222222222222') > >+ def test_create_rule_quota_limit(self): >+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-group-rules') >+ for num in range(100, 100 + FLAGS.quota_security_group_rules): >+ rule = { >+ 'ip_protocol': 'tcp', 'from_port': num, >+ 'to_port': num, 'parent_group_id': '2', 'group_id': '1' >+ } >+ self.controller.create(req, {'security_group_rule': rule}) >+ >+ rule = { >+ 'ip_protocol': 'tcp', 'from_port': '121', 'to_port': '121', >+ 'parent_group_id': '2', 'group_id': '1' >+ } >+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, >+ req, {'security_group_rule': rule}) >+ > > class TestSecurityGroupRulesXMLDeserializer(unittest.TestCase): > >diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py >index ae32323..06aaa26 100644 >--- a/nova/tests/test_quota.py >+++ b/nova/tests/test_quota.py >@@ -41,6 +41,8 @@ class GetQuotaTestCase(test.TestCase): > quota_volumes=10, > quota_gigabytes=1000, > quota_floating_ips=10, >+ quota_security_groups=10, >+ quota_security_group_rules=20, > quota_metadata_items=128, > quota_injected_files=5, > quota_injected_file_content_bytes=10 * 1024) >@@ -57,6 +59,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=5, > gigabytes=500, > floating_ips=5, >+ quota_security_groups=10, >+ quota_security_group_rules=20, > metadata_items=64, > injected_files=2, > injected_file_content_bytes=5 * 1024, >@@ -78,6 +82,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=2, > gigabytes=250, > floating_ips=2, >+ security_groups=5, >+ security_group_rules=10, > metadata_items=32, > injected_files=1, > injected_file_content_bytes=2 * 1024, >@@ -97,6 +103,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=10, > gigabytes=1000, > floating_ips=10, >+ security_groups=10, >+ security_group_rules=20, > metadata_items=128, > injected_files=5, > injected_file_content_bytes=10 * 1024, >@@ -109,6 +117,8 @@ class GetQuotaTestCase(test.TestCase): > quota_volumes=-1, > quota_gigabytes=-1, > quota_floating_ips=-1, >+ quota_security_groups=-1, >+ quota_security_group_rules=-1, > quota_metadata_items=-1, > quota_injected_files=-1, > quota_injected_file_content_bytes=-1) >@@ -120,6 +130,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=-1, > gigabytes=-1, > floating_ips=-1, >+ security_groups=-1, >+ security_group_rules=-1, > metadata_items=-1, > injected_files=-1, > injected_file_content_bytes=-1, >@@ -135,6 +147,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=10, > gigabytes=1000, > floating_ips=10, >+ security_groups=10, >+ security_group_rules=20, > metadata_items=128, > injected_files=5, > injected_file_content_bytes=10 * 1024, >@@ -150,6 +164,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=5, > gigabytes=500, > floating_ips=5, >+ security_groups=10, >+ security_group_rules=20, > metadata_items=64, > injected_files=2, > injected_file_content_bytes=5 * 1024, >@@ -166,6 +182,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=10, > gigabytes=1000, > floating_ips=10, >+ security_groups=10, >+ security_group_rules=20, > metadata_items=128, > injected_files=5, > injected_file_content_bytes=10 * 1024, >@@ -182,6 +200,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=2, > gigabytes=250, > floating_ips=2, >+ security_groups=5, >+ security_group_rules=10, > metadata_items=32, > injected_files=1, > injected_file_content_bytes=2 * 1024, >@@ -199,6 +219,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=5, > gigabytes=500, > floating_ips=5, >+ security_groups=10, >+ security_group_rules=20, > metadata_items=64, > injected_files=2, > injected_file_content_bytes=5 * 1024, >@@ -216,6 +238,8 @@ class GetQuotaTestCase(test.TestCase): > volumes=2, > gigabytes=250, > floating_ips=2, >+ security_groups=5, >+ security_group_rules=10, > metadata_items=32, > injected_files=1, > injected_file_content_bytes=2 * 1024, >@@ -404,6 +428,34 @@ class QuotaTestCase(test.TestCase): > 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_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)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 813768
: 578328