[quotas]
# Default driver to use for quota checks
-# quota_driver = neutron.db.quota_db.DbQuotaDriver
+# quota_driver = neutron.db.quota.driver.DbQuotaDriver
# Resource name(s) that are supported in quota features
# This option is deprecated for removal in the M release, please refrain from using it
--- /dev/null
+# Copyright 2011 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 neutron.common import exceptions
+from neutron.db.quota import models as quota_models
+
+
+class DbQuotaDriver(object):
+ """Driver to perform necessary checks to enforce quotas and obtain quota
+ information.
+
+ The default driver utilizes the local database.
+ """
+
+ @staticmethod
+ def get_tenant_quotas(context, resources, tenant_id):
+ """Given a list of resources, retrieve the quotas for the given
+ tenant.
+
+ :param context: The request context, for access checks.
+ :param resources: A dictionary of the registered resource keys.
+ :param tenant_id: The ID of the tenant to return quotas for.
+ :return dict: from resource name to dict of name and limit
+ """
+
+ # init with defaults
+ tenant_quota = dict((key, resource.default)
+ for key, resource in resources.items())
+
+ # update with tenant specific limits
+ q_qry = context.session.query(quota_models.Quota).filter_by(
+ tenant_id=tenant_id)
+ tenant_quota.update((q['resource'], q['limit']) for q in q_qry)
+
+ return tenant_quota
+
+ @staticmethod
+ def delete_tenant_quota(context, tenant_id):
+ """Delete the quota entries for a given tenant_id.
+
+ Atfer deletion, this tenant will use default quota values in conf.
+ """
+ with context.session.begin():
+ tenant_quotas = context.session.query(quota_models.Quota)
+ tenant_quotas = tenant_quotas.filter_by(tenant_id=tenant_id)
+ tenant_quotas.delete()
+
+ @staticmethod
+ def get_all_quotas(context, resources):
+ """Given a list of resources, retrieve the quotas for the all tenants.
+
+ :param context: The request context, for access checks.
+ :param resources: A dictionary of the registered resource keys.
+ :return quotas: list of dict of tenant_id:, resourcekey1:
+ resourcekey2: ...
+ """
+ tenant_default = dict((key, resource.default)
+ for key, resource in resources.items())
+
+ all_tenant_quotas = {}
+
+ for quota in context.session.query(quota_models.Quota):
+ tenant_id = quota['tenant_id']
+
+ # avoid setdefault() because only want to copy when actually req'd
+ tenant_quota = all_tenant_quotas.get(tenant_id)
+ if tenant_quota is None:
+ tenant_quota = tenant_default.copy()
+ tenant_quota['tenant_id'] = tenant_id
+ all_tenant_quotas[tenant_id] = tenant_quota
+
+ tenant_quota[quota['resource']] = quota['limit']
+
+ return list(all_tenant_quotas.values())
+
+ @staticmethod
+ def update_quota_limit(context, tenant_id, resource, limit):
+ with context.session.begin():
+ tenant_quota = context.session.query(quota_models.Quota).filter_by(
+ tenant_id=tenant_id, resource=resource).first()
+
+ if tenant_quota:
+ tenant_quota.update({'limit': limit})
+ else:
+ tenant_quota = quota_models.Quota(tenant_id=tenant_id,
+ resource=resource,
+ limit=limit)
+ context.session.add(tenant_quota)
+
+ def _get_quotas(self, context, tenant_id, resources):
+ """Retrieves the quotas for specific resources.
+
+ A helper method which retrieves the quotas for the specific
+ resources identified by keys, and which apply to the current
+ context.
+
+ :param context: The request context, for access checks.
+ :param tenant_id: the tenant_id to check quota.
+ :param resources: A dictionary of the registered resources.
+ """
+ # Grab and return the quotas (without usages)
+ quotas = DbQuotaDriver.get_tenant_quotas(
+ context, resources, tenant_id)
+
+ return dict((k, v) for k, v in quotas.items())
+
+ def limit_check(self, context, tenant_id, resources, values):
+ """Check simple quota limits.
+
+ For limits--those quotas for which there is no usage
+ synchronization function--this method checks that a set of
+ proposed values are permitted by the limit restriction.
+
+ If any of the proposed values is over the defined quota, an
+ OverQuota exception will be raised with the sorted list of the
+ resources which are too high. Otherwise, the method returns
+ nothing.
+
+ :param context: The request context, for access checks.
+ :param tenant_id: The tenant_id to check the quota.
+ :param resources: A dictionary of the registered resources.
+ :param values: A dictionary of the values to check against the
+ quota.
+ """
+
+ # Ensure no value is less than zero
+ unders = [key for key, val in values.items() if val < 0]
+ if unders:
+ raise exceptions.InvalidQuotaValue(unders=sorted(unders))
+
+ # Get the applicable quotas
+ quotas = self._get_quotas(context, tenant_id, resources)
+
+ # Check the quotas and construct a list of the resources that
+ # would be put over limit by the desired values
+ overs = [key for key, val in values.items()
+ if quotas[key] >= 0 and quotas[key] < val]
+ if overs:
+ raise exceptions.OverQuota(overs=sorted(overs))
# License for the specific language governing permissions and limitations
# under the License.
-from neutron.common import exceptions
-from neutron.db.quota import models as quota_models
+import sys
+from neutron.db.quota import driver # noqa
-class DbQuotaDriver(object):
- """Driver to perform necessary checks to enforce quotas and obtain quota
- information.
-
- The default driver utilizes the local database.
- """
-
- @staticmethod
- def get_tenant_quotas(context, resources, tenant_id):
- """Given a list of resources, retrieve the quotas for the given
- tenant.
-
- :param context: The request context, for access checks.
- :param resources: A dictionary of the registered resource keys.
- :param tenant_id: The ID of the tenant to return quotas for.
- :return dict: from resource name to dict of name and limit
- """
-
- # init with defaults
- tenant_quota = dict((key, resource.default)
- for key, resource in resources.items())
-
- # update with tenant specific limits
- q_qry = context.session.query(quota_models.Quota).filter_by(
- tenant_id=tenant_id)
- tenant_quota.update((q['resource'], q['limit']) for q in q_qry)
-
- return tenant_quota
-
- @staticmethod
- def delete_tenant_quota(context, tenant_id):
- """Delete the quota entries for a given tenant_id.
-
- Atfer deletion, this tenant will use default quota values in conf.
- """
- with context.session.begin():
- tenant_quotas = context.session.query(quota_models.Quota)
- tenant_quotas = tenant_quotas.filter_by(tenant_id=tenant_id)
- tenant_quotas.delete()
-
- @staticmethod
- def get_all_quotas(context, resources):
- """Given a list of resources, retrieve the quotas for the all tenants.
-
- :param context: The request context, for access checks.
- :param resources: A dictionary of the registered resource keys.
- :return quotas: list of dict of tenant_id:, resourcekey1:
- resourcekey2: ...
- """
- tenant_default = dict((key, resource.default)
- for key, resource in resources.items())
-
- all_tenant_quotas = {}
-
- for quota in context.session.query(quota_models.Quota):
- tenant_id = quota['tenant_id']
-
- # avoid setdefault() because only want to copy when actually req'd
- tenant_quota = all_tenant_quotas.get(tenant_id)
- if tenant_quota is None:
- tenant_quota = tenant_default.copy()
- tenant_quota['tenant_id'] = tenant_id
- all_tenant_quotas[tenant_id] = tenant_quota
-
- tenant_quota[quota['resource']] = quota['limit']
-
- return list(all_tenant_quotas.values())
-
- @staticmethod
- def update_quota_limit(context, tenant_id, resource, limit):
- with context.session.begin():
- tenant_quota = context.session.query(quota_models.Quota).filter_by(
- tenant_id=tenant_id, resource=resource).first()
-
- if tenant_quota:
- tenant_quota.update({'limit': limit})
- else:
- tenant_quota = quota_models.Quota(tenant_id=tenant_id,
- resource=resource,
- limit=limit)
- context.session.add(tenant_quota)
-
- def _get_quotas(self, context, tenant_id, resources):
- """Retrieves the quotas for specific resources.
-
- A helper method which retrieves the quotas for the specific
- resources identified by keys, and which apply to the current
- context.
-
- :param context: The request context, for access checks.
- :param tenant_id: the tenant_id to check quota.
- :param resources: A dictionary of the registered resources.
- """
- # Grab and return the quotas (without usages)
- quotas = DbQuotaDriver.get_tenant_quotas(
- context, resources, tenant_id)
-
- return dict((k, v) for k, v in quotas.items())
-
- def limit_check(self, context, tenant_id, resources, values):
- """Check simple quota limits.
-
- For limits--those quotas for which there is no usage
- synchronization function--this method checks that a set of
- proposed values are permitted by the limit restriction.
-
- If any of the proposed values is over the defined quota, an
- OverQuota exception will be raised with the sorted list of the
- resources which are too high. Otherwise, the method returns
- nothing.
-
- :param context: The request context, for access checks.
- :param tenant_id: The tenant_id to check the quota.
- :param resources: A dictionary of the registered resources.
- :param values: A dictionary of the values to check against the
- quota.
- """
-
- # Ensure no value is less than zero
- unders = [key for key, val in values.items() if val < 0]
- if unders:
- raise exceptions.InvalidQuotaValue(unders=sorted(unders))
-
- # Get the applicable quotas
- quotas = self._get_quotas(context, tenant_id, resources)
-
- # Check the quotas and construct a list of the resources that
- # would be put over limit by the desired values
- overs = [key for key, val in values.items()
- if quotas[key] >= 0 and quotas[key] < val]
- if overs:
- raise exceptions.OverQuota(overs=sorted(overs))
+# This module has been preserved for backward compatibility, and will be
+# deprecated in the future
+sys.modules[__name__] = sys.modules['neutron.db.quota.driver']
RESOURCE_NAME = 'quota'
RESOURCE_COLLECTION = RESOURCE_NAME + "s"
QUOTAS = quota.QUOTAS
-DB_QUOTA_DRIVER = 'neutron.db.quota_db.DbQuotaDriver'
+DB_QUOTA_DRIVER = 'neutron.db.quota.driver.DbQuotaDriver'
EXTENDED_ATTRIBUTES_2_0 = {
RESOURCE_COLLECTION: {}
}
from neutron.db import db_base_plugin_v2
from neutron.db import external_net_db
from neutron.db import portbindings_db
-from neutron.db import quota_db
+from neutron.db.quota import driver
from neutron.extensions import portbindings
from neutron.extensions import providernet
from neutron.i18n import _LW
n1kv_db_v2.PolicyProfile_db_mixin,
network_db_v2.Credential_db_mixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
- quota_db.DbQuotaDriver):
+ driver.DbQuotaDriver):
"""
Implement the Neutron abstractions using Cisco Nexus1000V.
from neutron.db import external_net_db
from neutron.db import l3_gwmode_db
from neutron.db import portbindings_db
-from neutron.db import quota_db # noqa
from neutron.extensions import portbindings
from neutron.i18n import _LE, _LI, _LW
from neutron.plugins.ibm.common import config # noqa
from neutron.db import extradhcpopt_db
from neutron.db import models_v2
from neutron.db import netmtu_db
-from neutron.db import quota_db # noqa
+from neutron.db.quota import driver # noqa
from neutron.db import securitygroups_rpc_base as sg_db_rpc
from neutron.db import vlantransparent_db
from neutron.extensions import allowedaddresspairs as addr_pair
from neutron.db import l3_agentschedulers_db
from neutron.db import l3_gwmode_db
from neutron.db import portbindings_base
-from neutron.db import quota_db # noqa
from neutron.db import securitygroups_rpc_base as sg_db_rpc
from neutron.extensions import portbindings
from neutron.i18n import _LE
LOG = logging.getLogger(__name__)
-QUOTA_DB_MODULE = 'neutron.db.quota_db'
-QUOTA_DB_DRIVER = 'neutron.db.quota_db.DbQuotaDriver'
+QUOTA_DB_MODULE = 'neutron.db.quota.driver'
+QUOTA_DB_DRIVER = '%s.DbQuotaDriver' % QUOTA_DB_MODULE
QUOTA_CONF_DRIVER = 'neutron.quota.ConfDriver'
default_quota_items = ['network', 'subnet', 'port']
versionutils.report_deprecated_feature(
LOG, _LW("The quota driver neutron.quota.ConfDriver is "
"deprecated as of Liberty. "
- "neutron.db.quota_db.DbQuotaDriver should be "
- "used in its place"))
+ "neutron.db.quota.driver.DbQuotaDriver should "
+ "be used in its place"))
self._driver = _driver_class
LOG.info(_LI('Loaded quota_driver: %s.'), _driver_class)
return self._driver
It is also assumed that the per-tenant quota extension API is configured
in /etc/neutron/neutron.conf as follows:
- quota_driver = neutron.db.quota_db.DbQuotaDriver
+ quota_driver = neutron.db.driver.DbQuotaDriver
"""
@classmethod
from neutron.common import exceptions
from neutron import context
from neutron.db import db_base_plugin_v2 as base_plugin
-from neutron.db import quota_db
+from neutron.db.quota import driver
from neutron.tests.unit import testlib_api
-class FakePlugin(base_plugin.NeutronDbPluginV2, quota_db.DbQuotaDriver):
+class FakePlugin(base_plugin.NeutronDbPluginV2, driver.DbQuotaDriver):
"""A fake plugin class containing all DB methods."""
from neutron.common import constants
from neutron.common import exceptions
from neutron import context
-from neutron.db import quota_db
+from neutron.db.quota import driver
from neutron import quota
from neutron.tests import base
from neutron.tests import tools
def setUp(self):
cfg.CONF.set_override(
'quota_driver',
- 'neutron.db.quota_db.DbQuotaDriver',
+ 'neutron.db.quota.driver.DbQuotaDriver',
group='QUOTAS')
super(QuotaExtensionDbTestCase, self).setUp()
class TestDbQuotaDriver(base.BaseTestCase):
- """Test for neutron.db.quota_db.DbQuotaDriver."""
+ """Test for neutron.db.quota.driver.DbQuotaDriver."""
def test_get_tenant_quotas_arg(self):
- """Call neutron.db.quota_db.DbQuotaDriver._get_quotas."""
+ """Call neutron.db.quota.driver.DbQuotaDriver._get_quotas."""
- driver = quota_db.DbQuotaDriver()
+ quota_driver = driver.DbQuotaDriver()
ctx = context.Context('', 'bar')
foo_quotas = {'network': 5}
default_quotas = {'network': 10}
target_tenant = 'foo'
- with mock.patch.object(quota_db.DbQuotaDriver,
+ with mock.patch.object(driver.DbQuotaDriver,
'get_tenant_quotas',
return_value=foo_quotas) as get_tenant_quotas:
- quotas = driver._get_quotas(ctx,
- target_tenant,
- default_quotas)
+ quotas = quota_driver._get_quotas(ctx,
+ target_tenant,
+ default_quotas)
self.assertEqual(quotas, foo_quotas)
get_tenant_quotas.assert_called_once_with(ctx,
cfg.CONF.set_override('quota_driver', cfg_driver, group='QUOTAS')
with mock.patch.dict(sys.modules, {}):
if (not with_quota_db_module and
- 'neutron.db.quota_db' in sys.modules):
- del sys.modules['neutron.db.quota_db']
+ 'neutron.db.quota.driver' in sys.modules):
+ del sys.modules['neutron.db.quota.driver']
driver = quota.QUOTAS.get_driver()
self.assertEqual(loaded_driver, driver.__class__.__name__)
def test_quota_db_driver_with_quotas_table(self):
- self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver',
+ self._test_quota_driver('neutron.db.quota.driver.DbQuotaDriver',
'DbQuotaDriver', True)
def test_quota_db_driver_fallback_conf_driver(self):
- self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver',
+ self._test_quota_driver('neutron.db.quota.driver.DbQuotaDriver',
'ConfDriver', False)
def test_quota_conf_driver(self):
neutron.tests.unit.db.test_l3_hamode_db \
neutron.tests.unit.db.test_migration \
neutron.tests.unit.db.test_agents_db \
- neutron.tests.unit.db.test_quota_db \
+ neutron.tests.unit.db.quota.test_driver \
neutron.tests.unit.db.test_dvr_mac_db \
neutron.tests.unit.debug.test_commands \
neutron.tests.unit.tests.test_post_mortem_debug \