Merge "[quota] Enable ``DbQuotaDriverNull`` as a production driver"

This commit is contained in:
Zuul 2022-04-12 14:55:22 +00:00 committed by Gerrit Code Review
commit a5bcc34bf4
14 changed files with 167 additions and 76 deletions

View File

@ -19,8 +19,13 @@ from oslo_config import cfg
from neutron._i18n import _
QUOTA_DB_MODULE = 'neutron.db.quota.driver_nolock'
QUOTA_DB_DRIVER = QUOTA_DB_MODULE + '.DbQuotaNoLockDriver'
QUOTA_DB_DIRECTORY = 'neutron.db.quota.'
QUOTA_DB_DRIVER_LEGACY = QUOTA_DB_DIRECTORY + 'driver.DbQuotaDriver'
QUOTA_DB_DRIVER_NO_LOCK = (QUOTA_DB_DIRECTORY +
'driver_nolock.DbQuotaNoLockDriver')
QUOTA_DB_DRIVER_NULL = QUOTA_DB_DIRECTORY + 'driver_null.DbQuotaDriverNull'
QUOTA_DB_DRIVER = QUOTA_DB_DRIVER_NO_LOCK
QUOTAS_CFG_GROUP = 'QUOTAS'
DEFAULT_QUOTA = -1

View File

@ -16,7 +16,6 @@ import collections
import datetime
from neutron_lib.db import api as db_api
from neutron_lib.db import quota_api as nlib_quota_api
from oslo_db import exception as db_exc
from neutron.common import utils
@ -250,58 +249,3 @@ def remove_expired_reservations(context, project_id=None, timeout=None):
expiring_time -= datetime.timedelta(seconds=timeout)
return quota_obj.Reservation.delete_expired(context, expiring_time,
project_id)
class NullQuotaDriver(nlib_quota_api.QuotaDriverAPI):
@staticmethod
def get_default_quotas(context, resources, project_id):
pass
@staticmethod
def get_project_quotas(context, resources, project_id):
pass
@staticmethod
def get_detailed_project_quotas(context, resources, project_id):
pass
@staticmethod
def delete_project_quota(context, project_id):
pass
@staticmethod
def get_all_quotas(context, resources):
pass
@staticmethod
def update_quota_limit(context, project_id, resource, limit):
pass
@staticmethod
def make_reservation(context, project_id, resources, deltas, plugin):
pass
@staticmethod
def commit_reservation(context, reservation_id):
pass
@staticmethod
def cancel_reservation(context, reservation_id):
pass
@staticmethod
def limit_check(context, project_id, resources, values):
pass
@staticmethod
def get_resource_usage(context, project_id, resources, resource_name):
pass
@staticmethod
def quota_limit_check(context, project_id, resources, deltas):
pass
@staticmethod
def get_workers():
return []

View File

@ -0,0 +1,71 @@
# Copyright (c) 2022 Red Hat, Inc.
# 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_lib.db import quota_api as nlib_quota_api
class DbQuotaDriverNull(nlib_quota_api.QuotaDriverAPI):
@staticmethod
def get_default_quotas(context, resources, project_id):
return {}
@staticmethod
def get_project_quotas(context, resources, project_id):
return {}
@staticmethod
def get_detailed_project_quotas(context, resources, project_id):
return {}
@staticmethod
def delete_project_quota(context, project_id):
pass
@staticmethod
def get_all_quotas(context, resources):
return []
@staticmethod
def update_quota_limit(context, project_id, resource, limit):
pass
@staticmethod
def make_reservation(context, project_id, resources, deltas, plugin):
pass
@staticmethod
def commit_reservation(context, reservation_id):
pass
@staticmethod
def cancel_reservation(context, reservation_id):
pass
@staticmethod
def limit_check(context, project_id, resources, values):
pass
@staticmethod
def get_resource_usage(context, project_id, resources, resource_name):
return 0
@staticmethod
def quota_limit_check(context, project_id, resources, deltas):
pass
@staticmethod
def get_workers():
return []

View File

@ -21,8 +21,6 @@ from neutron.conf import quota
from neutron.quota import resource_registry
LOG = logging.getLogger(__name__)
QUOTA_DB_MODULE = quota.QUOTA_DB_MODULE
QUOTA_DB_DRIVER = quota.QUOTA_DB_DRIVER
# Register the configuration options

View File

@ -94,6 +94,9 @@ class NeutronConfigFixture(ConfigFixture):
'report_interval': str(env_desc.agent_down_time // 2),
'log_agent_heartbeats': 'True',
},
'quotas': {
'quota_driver': env_desc.quota_driver
},
})
if use_local_apipaste:

View File

@ -19,6 +19,7 @@ from oslo_config import cfg
from neutron.agent.linux import ip_lib
from neutron.common import utils as common_utils
from neutron.conf import quota as quota_conf
from neutron.plugins.ml2.drivers.linuxbridge.agent import \
linuxbridge_neutron_agent as lb_agent
from neutron.tests.common.exclusive_resources import ip_address
@ -42,7 +43,8 @@ class EnvironmentDescription(object):
has_placement=False, placement_port=None,
dhcp_scheduler_class=None, ml2_extension_drivers=None,
api_workers=1,
enable_traditional_dhcp=True, local_ip_ext=False):
enable_traditional_dhcp=True, local_ip_ext=False,
quota_driver=quota_conf.QUOTA_DB_DRIVER):
self.network_type = network_type
self.l2_pop = l2_pop
self.qos = qos
@ -69,6 +71,7 @@ class EnvironmentDescription(object):
self.local_ip_ext = local_ip_ext
if self.local_ip_ext:
self.service_plugins += ',local_ip'
self.quota_driver = quota_driver
@property
def tunneling_enabled(self):

View File

@ -0,0 +1,51 @@
# Copyright (c) 2022 Red Hat, Inc.
# 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_utils import uuidutils
from neutron.conf import quota as quota_conf
from neutron.tests.fullstack import base
from neutron.tests.fullstack.resources import environment
from neutron.tests.unit import testlib_api
load_tests = testlib_api.module_load_tests
class TestQuota(base.BaseFullStackTestCase):
scenarios = [
('DbQuotaDriver',
{'quota_driver': quota_conf.QUOTA_DB_DRIVER_LEGACY}),
('DbQuotaNoLockDriver',
{'quota_driver': quota_conf.QUOTA_DB_DRIVER_NO_LOCK}),
('DbQuotaDriverNull',
{'quota_driver': quota_conf.QUOTA_DB_DRIVER_NULL}),
]
def setUp(self, *args):
host_descriptions = [environment.HostDescription()]
env = environment.Environment(environment.EnvironmentDescription(
quota_driver=self.quota_driver), host_descriptions)
super().setUp(env)
self.tenant_id = uuidutils.generate_uuid()
def test_create_network_and_port(self):
network = self.safe_client.create_network(self.tenant_id)
self.safe_client.create_subnet(self.tenant_id, network['id'],
'20.0.0.0/24')
port = self.safe_client.create_port(self.tenant_id, network['id'])
port_id = port['id']
port = self.safe_client.client.list_ports(id=port_id)['ports'][0]
self.assertEqual(port_id, port['id'])

View File

@ -1033,7 +1033,7 @@ class ExtensionExtendedAttributeTestCase(base.BaseTestCase):
quota.QUOTAS._driver = None
cfg.CONF.set_override('quota_driver',
'neutron.db.quota.api.NullQuotaDriver',
'neutron.db.quota.driver_null.DbQuotaDriverNull',
group='QUOTAS')
def _do_request(self, method, path, data=None, params=None, action=None):

View File

@ -40,6 +40,7 @@ from neutron.api import api_common
from neutron.api import extensions
from neutron.api.v2 import base as v2_base
from neutron.api.v2 import router
from neutron.conf import quota as quota_conf
from neutron import policy
from neutron import quota
from neutron.tests import base
@ -49,7 +50,7 @@ from neutron.tests.unit import testlib_api
EXTDIR = os.path.join(base.ROOTDIR, 'unit/extensions')
NULL_QUOTA_DRIVER = 'neutron.db.quota.api.NullQuotaDriver'
NULL_QUOTA_DRIVER = 'neutron.db.quota.driver_null.DbQuotaDriverNull'
_uuid = uuidutils.generate_uuid
@ -98,7 +99,7 @@ class APIv2TestBase(base.BaseTestCase):
self.api = webtest.TestApp(api)
quota.QUOTAS._driver = None
cfg.CONF.set_override('quota_driver', quota.QUOTA_DB_DRIVER,
cfg.CONF.set_override('quota_driver', quota_conf.QUOTA_DB_DRIVER,
group='QUOTAS')
# APIRouter initialization resets policy module, re-initializing it

View File

@ -25,6 +25,7 @@ from webob import exc
import webtest
from neutron.api import extensions
from neutron.conf import quota as quota_conf
from neutron import manager
from neutron import quota
from neutron.tests.unit.api import test_extensions
@ -83,7 +84,7 @@ class ExtensionTestCase(testlib_api.WebTestCase):
setattr(instance, native_sorting_attr_name, True)
if use_quota:
quota.QUOTAS._driver = None
cfg.CONF.set_override('quota_driver', quota.QUOTA_DB_DRIVER,
cfg.CONF.set_override('quota_driver', quota_conf.QUOTA_DB_DRIVER,
group='QUOTAS')
setattr(instance, 'path_prefix', resource_prefix)

View File

@ -27,6 +27,7 @@ import webtest
from neutron.api import extensions
from neutron.api.v2 import router
from neutron.conf import quota as quota_conf
from neutron.extensions import providernet as pnet
from neutron import quota
from neutron.tests import tools
@ -80,7 +81,7 @@ class ProvidernetExtensionTestCase(testlib_api.WebTestCase):
self.api = webtest.TestApp(router.APIRouter())
quota.QUOTAS._driver = None
cfg.CONF.set_override('quota_driver', quota.QUOTA_DB_DRIVER,
cfg.CONF.set_override('quota_driver', quota_conf.QUOTA_DB_DRIVER,
group='QUOTAS')
def _prepare_net_data(self):

View File

@ -31,6 +31,7 @@ from neutron.common import config
from neutron.conf import quota as qconf
from neutron.db.quota import driver
from neutron.db.quota import driver_nolock
from neutron.db.quota import driver_null
from neutron import quota
from neutron.quota import resource_registry
from neutron.tests import base
@ -88,7 +89,7 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase):
def setUp(self):
cfg.CONF.set_override(
'quota_driver', quota.QUOTA_DB_DRIVER, group='QUOTAS')
'quota_driver', qconf.QUOTA_DB_DRIVER, group='QUOTAS')
super(QuotaExtensionDbTestCase, self).setUp()
def test_quotas_loaded_right(self):
@ -443,7 +444,7 @@ class QuotaExtensionCfgTestCase(QuotaExtensionTestCase):
def setUp(self):
cfg.CONF.set_override(
'quota_driver', quota.QUOTA_DB_DRIVER, group='QUOTAS')
'quota_driver', qconf.QUOTA_DB_DRIVER, group='QUOTAS')
super(QuotaExtensionCfgTestCase, self).setUp()
def test_quotas_default_values(self):
@ -524,20 +525,24 @@ class TestDbQuotaDriver(base.BaseTestCase):
class TestQuotaDriverLoad(base.BaseTestCase):
def _test_quota_driver(self, cfg_driver, loaded_driver,
with_quota_db_module=True):
MODULE_CLASS = [
(qconf.QUOTA_DB_DRIVER_LEGACY, driver.DbQuotaDriver),
(qconf.QUOTA_DB_DRIVER_NO_LOCK, driver_nolock.DbQuotaNoLockDriver),
(qconf.QUOTA_DB_DRIVER_NULL, driver_null.DbQuotaDriverNull),
]
def _test_quota_driver(self, module, cfg_driver, loaded_driver):
quota.QUOTAS._driver = None
cfg.CONF.set_override('quota_driver', cfg_driver, group='QUOTAS')
with mock.patch.dict(sys.modules, {}):
if (not with_quota_db_module and
quota.QUOTA_DB_MODULE in sys.modules):
if module in sys.modules:
del sys.modules[quota.QUOTA_DB_MODULE]
driver = quota.QUOTAS.get_driver()
self.assertEqual(loaded_driver, driver.__class__.__name__)
def test_quota_driver_load(self):
for klass in (driver.DbQuotaDriver,
driver_nolock.DbQuotaNoLockDriver):
for module, klass in self.MODULE_CLASS:
self._test_quota_driver(
module,
'.'.join([klass.__module__, klass.__name__]),
klass.__name__, True)
klass.__name__)

View File

@ -17,6 +17,7 @@ from neutron_lib.db import api as db_api
from oslo_config import cfg
from webob import exc as web_exc
from neutron.conf import quota as quota_conf
from neutron.db import db_base_plugin_v2
from neutron.db import vlantransparent_db as vlt_db
from neutron.extensions import vlantransparent as vlt
@ -72,7 +73,7 @@ class VlanTransparentExtensionTestCase(test_db_base_plugin_v2.TestNetworksV2):
ext_mgr=ext_mgr)
quota.QUOTAS._driver = None
cfg.CONF.set_override('quota_driver', quota.QUOTA_DB_DRIVER,
cfg.CONF.set_override('quota_driver', quota_conf.QUOTA_DB_DRIVER,
group='QUOTAS')
def test_network_create_with_vlan_transparent_attr(self):

View File

@ -0,0 +1,7 @@
---
features:
- |
Enabled ``DbQuotaDriverNull`` as production ready database quota driver.
This driver does not have access to the database and will return empty
values to the request queries. This driver can be used to override the
Neutron quota engine.