Merge "Extending quota support for neutron LBaaS entities"
This commit is contained in:
commit
5d199086a4
@ -283,6 +283,9 @@ notification_driver = neutron.openstack.common.notifier.rpc_notifier
|
||||
# ======== end of WSGI parameters related to the API server ==========
|
||||
|
||||
[quotas]
|
||||
# Default driver to use for quota checks
|
||||
# quota_driver = neutron.db.quota_db.DbQuotaDriver
|
||||
|
||||
# Resource name(s) that are supported in quota features
|
||||
# quota_items = network,subnet,port
|
||||
|
||||
@ -307,15 +310,31 @@ notification_driver = neutron.openstack.common.notifier.rpc_notifier
|
||||
# unlimited.
|
||||
# quota_security_group_rule = 100
|
||||
|
||||
# Number of vips allowed per tenant. A negative value means unlimited.
|
||||
# quota_vip = 10
|
||||
|
||||
# Number of pools allowed per tenant. A negative value means unlimited.
|
||||
# quota_pool = 10
|
||||
|
||||
# Number of pool members allowed per tenant. A negative value means unlimited.
|
||||
# The default is unlimited because a member is not a real resource consumer
|
||||
# on Openstack. However, on back-end, a member is a resource consumer
|
||||
# and that is the reason why quota is possible.
|
||||
# quota_member = -1
|
||||
|
||||
# Number of health monitors allowed per tenant. A negative value means
|
||||
# unlimited.
|
||||
# The default is unlimited because a health monitor is not a real resource
|
||||
# consumer on Openstack. However, on back-end, a member is a resource consumer
|
||||
# and that is the reason why quota is possible.
|
||||
# quota_health_monitors = -1
|
||||
|
||||
# Number of routers allowed per tenant. A negative value means unlimited.
|
||||
# quota_router = 10
|
||||
|
||||
# Number of floating IPs allowed per tenant. A negative value means unlimited.
|
||||
# quota_floatingip = 50
|
||||
|
||||
# Default driver to use for quota checks
|
||||
# quota_driver = neutron.db.quota_db.DbQuotaDriver
|
||||
|
||||
[agent]
|
||||
# Use "sudo neutron-rootwrap /etc/neutron/rootwrap.conf" to use the real
|
||||
# root filter facility.
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import abc
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
from neutron.api import extensions
|
||||
@ -290,6 +291,26 @@ SUB_RESOURCE_ATTRIBUTE_MAP = {
|
||||
}
|
||||
}
|
||||
|
||||
lbaas_quota_opts = [
|
||||
cfg.IntOpt('quota_vip',
|
||||
default=10,
|
||||
help=_('Number of vips allowed per tenant. '
|
||||
'A negative value means unlimited.')),
|
||||
cfg.IntOpt('quota_pool',
|
||||
default=10,
|
||||
help=_('Number of pools allowed per tenant. '
|
||||
'A negative value means unlimited.')),
|
||||
cfg.IntOpt('quota_member',
|
||||
default=-1,
|
||||
help=_('Number of pool members allowed per tenant. '
|
||||
'A negative value means unlimited.')),
|
||||
cfg.IntOpt('quota_health_monitor',
|
||||
default=-1,
|
||||
help=_('Number of health monitors allowed per tenant. '
|
||||
'A negative value means unlimited.'))
|
||||
]
|
||||
cfg.CONF.register_opts(lbaas_quota_opts, 'QUOTAS')
|
||||
|
||||
|
||||
class Loadbalancer(extensions.ExtensionDescriptor):
|
||||
|
||||
|
@ -28,6 +28,7 @@ from neutron.common import config
|
||||
from neutron.extensions import loadbalancer
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.common import constants
|
||||
from neutron import quota
|
||||
from neutron.tests.unit import test_api_v2
|
||||
from neutron.tests.unit import test_extensions
|
||||
from neutron.tests.unit import testlib_api
|
||||
@ -81,6 +82,11 @@ class LoadBalancerExtensionTestCase(testlib_api.WebTestCase):
|
||||
ext_mgr = LoadBalancerTestExtensionManager()
|
||||
self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr)
|
||||
self.api = webtest.TestApp(self.ext_mdw)
|
||||
|
||||
quota.QUOTAS._driver = None
|
||||
cfg.CONF.set_override('quota_driver', quota.QUOTA_CONF_DRIVER,
|
||||
group='QUOTAS')
|
||||
|
||||
super(LoadBalancerExtensionTestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
|
@ -0,0 +1,168 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2014 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from neutron import context
|
||||
from neutron import quota
|
||||
from neutron.tests.unit import test_api_v2
|
||||
from neutron.tests.unit import test_quota_ext
|
||||
|
||||
_get_path = test_api_v2._get_path
|
||||
|
||||
|
||||
class LBaaSQuotaExtensionTestCase(
|
||||
test_quota_ext.QuotaExtensionTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(LBaaSQuotaExtensionTestCase, self).setUp()
|
||||
cfg.CONF.set_override(
|
||||
'quota_items',
|
||||
['vip', 'pool', 'member', 'health_monitor', 'extra1'],
|
||||
group='QUOTAS')
|
||||
quota.register_resources_from_config()
|
||||
|
||||
|
||||
class LBaaSQuotaExtensionDbTestCase(LBaaSQuotaExtensionTestCase):
|
||||
fmt = 'json'
|
||||
|
||||
def setUp(self):
|
||||
cfg.CONF.set_override(
|
||||
'quota_driver',
|
||||
'neutron.db.quota_db.DbQuotaDriver',
|
||||
group='QUOTAS')
|
||||
super(LBaaSQuotaExtensionDbTestCase, self).setUp()
|
||||
|
||||
def test_quotas_loaded_right(self):
|
||||
res = self.api.get(_get_path('quotas', fmt=self.fmt))
|
||||
quota = self.deserialize(res)
|
||||
self.assertEqual([], quota['quotas'])
|
||||
self.assertEqual(200, res.status_int)
|
||||
|
||||
def test_quotas_default_values(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id)}
|
||||
res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
extra_environ=env)
|
||||
quota = self.deserialize(res)
|
||||
self.assertEqual(10, quota['quota']['vip'])
|
||||
self.assertEqual(10, quota['quota']['pool'])
|
||||
self.assertEqual(-1, quota['quota']['member'])
|
||||
self.assertEqual(-1, quota['quota']['health_monitor'])
|
||||
self.assertEqual(-1, quota['quota']['extra1'])
|
||||
|
||||
def test_show_quotas_with_admin(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id + '2',
|
||||
is_admin=True)}
|
||||
res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
extra_environ=env)
|
||||
self.assertEqual(200, res.status_int)
|
||||
quota = self.deserialize(res)
|
||||
self.assertEqual(10, quota['quota']['vip'])
|
||||
self.assertEqual(10, quota['quota']['pool'])
|
||||
self.assertEqual(-1, quota['quota']['member'])
|
||||
self.assertEqual(-1, quota['quota']['health_monitor'])
|
||||
|
||||
def test_show_quotas_with_owner_tenant(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id,
|
||||
is_admin=False)}
|
||||
res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
extra_environ=env)
|
||||
self.assertEqual(200, res.status_int)
|
||||
quota = self.deserialize(res)
|
||||
self.assertEqual(10, quota['quota']['vip'])
|
||||
self.assertEqual(10, quota['quota']['pool'])
|
||||
self.assertEqual(-1, quota['quota']['member'])
|
||||
self.assertEqual(-1, quota['quota']['health_monitor'])
|
||||
|
||||
def test_update_quotas_to_unlimited(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id,
|
||||
is_admin=True)}
|
||||
quotas = {'quota': {'pool': -1}}
|
||||
res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
self.serialize(quotas), extra_environ=env,
|
||||
expect_errors=False)
|
||||
self.assertEqual(200, res.status_int)
|
||||
|
||||
def test_update_quotas_exceeding_current_limit(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id,
|
||||
is_admin=True)}
|
||||
quotas = {'quota': {'pool': 120}}
|
||||
res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
self.serialize(quotas), extra_environ=env,
|
||||
expect_errors=False)
|
||||
self.assertEqual(200, res.status_int)
|
||||
|
||||
def test_update_quotas_with_admin(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id + '2',
|
||||
is_admin=True)}
|
||||
quotas = {'quota': {'pool': 100}}
|
||||
res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
self.serialize(quotas), extra_environ=env)
|
||||
self.assertEqual(200, res.status_int)
|
||||
env2 = {'neutron.context': context.Context('', tenant_id)}
|
||||
res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
extra_environ=env2)
|
||||
quota = self.deserialize(res)
|
||||
self.assertEqual(10, quota['quota']['vip'])
|
||||
self.assertEqual(100, quota['quota']['pool'])
|
||||
self.assertEqual(-1, quota['quota']['member'])
|
||||
self.assertEqual(-1, quota['quota']['health_monitor'])
|
||||
|
||||
|
||||
class LBaaSQuotaExtensionDbTestCaseXML(LBaaSQuotaExtensionDbTestCase):
|
||||
fmt = 'xml'
|
||||
|
||||
|
||||
class LBaaSQuotaExtensionCfgTestCase(
|
||||
LBaaSQuotaExtensionTestCase):
|
||||
|
||||
def setUp(self):
|
||||
cfg.CONF.set_override(
|
||||
'quota_driver',
|
||||
'neutron.quota.ConfDriver',
|
||||
group='QUOTAS')
|
||||
super(LBaaSQuotaExtensionCfgTestCase, self).setUp()
|
||||
|
||||
def test_quotas_default_values(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
env = {'neutron.context': context.Context('', tenant_id)}
|
||||
res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
extra_environ=env)
|
||||
quota = self.deserialize(res)
|
||||
self.assertEqual(10, quota['quota']['vip'])
|
||||
self.assertEqual(10, quota['quota']['pool'])
|
||||
self.assertEqual(-1, quota['quota']['member'])
|
||||
self.assertEqual(-1, quota['quota']['health_monitor'])
|
||||
self.assertEqual(-1, quota['quota']['extra1'])
|
||||
|
||||
def test_update_quotas_forbidden(self):
|
||||
tenant_id = 'tenant_id1'
|
||||
quotas = {'quota': {'pool': 100}}
|
||||
res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt),
|
||||
self.serialize(quotas),
|
||||
expect_errors=True)
|
||||
self.assertEqual(403, res.status_int)
|
||||
|
||||
|
||||
class LBaaSQuotaExtensionCfgTestCaseXML(LBaaSQuotaExtensionCfgTestCase):
|
||||
fmt = 'xml'
|
Loading…
Reference in New Issue
Block a user