Fallback to Quota Conf Driver if Quotas table is not defined
commit de15e0b9c5
enabled Quota DB driver default considering
production environments, but it breaks plugins without per-tenant
quota extension. In these plugin quotas tables is not loaded.
This commit fallbacks to ConfDriver if Quota model is not loaded by
checking neutron.db.quota_db which defines Quota model is imported.
Change-Id: Idaaaa9810598cfd3e5ce70020f498643b4819d16
Closes-Bug: #1236993
This commit is contained in:
parent
434b8b01bc
commit
46495f4995
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
"""Quotas for instances, volumes, and floating ips."""
|
"""Quotas for instances, volumes, and floating ips."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
import webob
|
import webob
|
||||||
|
|
||||||
@ -25,6 +27,10 @@ from neutron.openstack.common import importutils
|
|||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
QUOTA_DB_MODULE = 'neutron.db.quota_db'
|
||||||
|
QUOTA_DB_DRIVER = 'neutron.db.quota_db.DbQuotaDriver'
|
||||||
|
QUOTA_CONF_DRIVER = 'neutron.quota.ConfDriver'
|
||||||
|
|
||||||
quota_opts = [
|
quota_opts = [
|
||||||
cfg.ListOpt('quota_items',
|
cfg.ListOpt('quota_items',
|
||||||
default=['network', 'subnet', 'port'],
|
default=['network', 'subnet', 'port'],
|
||||||
@ -47,7 +53,7 @@ quota_opts = [
|
|||||||
help=_('Number of ports allowed per tenant, minus for '
|
help=_('Number of ports allowed per tenant, minus for '
|
||||||
'unlimited')),
|
'unlimited')),
|
||||||
cfg.StrOpt('quota_driver',
|
cfg.StrOpt('quota_driver',
|
||||||
default='neutron.db.quota_db.DbQuotaDriver',
|
default=QUOTA_DB_DRIVER,
|
||||||
help=_('Default driver to use for quota checks')),
|
help=_('Default driver to use for quota checks')),
|
||||||
]
|
]
|
||||||
# Register the configuration options
|
# Register the configuration options
|
||||||
@ -217,9 +223,16 @@ class QuotaEngine(object):
|
|||||||
if self._driver is None:
|
if self._driver is None:
|
||||||
_driver_class = (self._driver_class or
|
_driver_class = (self._driver_class or
|
||||||
cfg.CONF.QUOTAS.quota_driver)
|
cfg.CONF.QUOTAS.quota_driver)
|
||||||
|
if (_driver_class == QUOTA_DB_DRIVER and
|
||||||
|
QUOTA_DB_MODULE not in sys.modules):
|
||||||
|
# If quotas table is not loaded, force config quota driver.
|
||||||
|
_driver_class = QUOTA_CONF_DRIVER
|
||||||
|
LOG.info(_("ConfDriver is used as quota_driver because the "
|
||||||
|
"loaded plugin does not support 'quotas' table."))
|
||||||
if isinstance(_driver_class, basestring):
|
if isinstance(_driver_class, basestring):
|
||||||
_driver_class = importutils.import_object(_driver_class)
|
_driver_class = importutils.import_object(_driver_class)
|
||||||
self._driver = _driver_class
|
self._driver = _driver_class
|
||||||
|
LOG.info(_('Loaded quota_driver: %s.'), _driver_class)
|
||||||
return self._driver
|
return self._driver
|
||||||
|
|
||||||
def __contains__(self, resource):
|
def __contains__(self, resource):
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
import testtools
|
import testtools
|
||||||
@ -408,3 +410,32 @@ class TestDbQuotaDriver(base.BaseTestCase):
|
|||||||
get_tenant_quotas.assert_called_once_with(ctx,
|
get_tenant_quotas.assert_called_once_with(ctx,
|
||||||
default_quotas,
|
default_quotas,
|
||||||
target_tenant)
|
target_tenant)
|
||||||
|
|
||||||
|
|
||||||
|
class TestQuotaDriverLoad(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestQuotaDriverLoad, self).setUp()
|
||||||
|
# Make sure QuotaEngine is reinitialized in each test.
|
||||||
|
quota.QUOTAS._driver = None
|
||||||
|
|
||||||
|
def _test_quota_driver(self, cfg_driver, loaded_driver,
|
||||||
|
with_quota_db_module=True):
|
||||||
|
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']
|
||||||
|
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',
|
||||||
|
'DbQuotaDriver', True)
|
||||||
|
|
||||||
|
def test_quota_db_driver_fallback_conf_driver(self):
|
||||||
|
self._test_quota_driver('neutron.db.quota_db.DbQuotaDriver',
|
||||||
|
'ConfDriver', False)
|
||||||
|
|
||||||
|
def test_quota_conf_driver(self):
|
||||||
|
self._test_quota_driver('neutron.quota.ConfDriver',
|
||||||
|
'ConfDriver', True)
|
||||||
|
Loading…
Reference in New Issue
Block a user