diff --git a/neutron/db/_model_query.py b/neutron/db/_model_query.py new file mode 100644 index 00000000000..be43258c47e --- /dev/null +++ b/neutron/db/_model_query.py @@ -0,0 +1,125 @@ +# 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. + + +""" +NOTE: This module shall not be used by external projects. It will be moved + to neutron-lib in due course, and then it can be used from there. +""" + +from neutron.common import utils + +# Classes implementing extensions will register hooks into this dictionary +# for "augmenting" the "core way" of building a query for retrieving objects +# from a model class. Hooks are registered by invoking register_hook(). +_model_query_hooks = { + # model1 : { + # hook1: { + # 'query': query_hook, + # 'filter': filter_hook, + # 'result_filters': result_filters + # }, + # hook2: { + # 'query': query_hook, + # 'filter': filter_hook, + # 'result_filters': result_filters + # }, + # ... + # }, + # model2 : { + # hook1: { + # 'query': query_hook, + # 'filter': filter_hook, + # 'result_filters': result_filters + # }, + # hook2: { + # 'query': query_hook, + # 'filter': filter_hook, + # 'result_filters': result_filters + # }, + # ... + # }, + # ... +} + + +def register_hook(model, name, query_hook, filter_hook, + result_filters=None): + """Register a hook to be invoked when a query is executed. + + :param model: The DB Model that the hook applies to. + :type model: sqlalchemy orm model + + :param name: A name for the hook. + :type name: str + + :param query_hook: The method to be called to augment the query. + :type query_hook: callable or None + + :param filter_hook: A method to be called to augment the query filter. + :type filter_hook: callable or None + + :param result_filters: A Method to be called to filter the query result. + :type result_filters: callable or None + + Adds the hook components to the _model_query_hooks dict. Models are the + keys of this dict, whereas the value is another dict mapping hook names + to callables performing the hook. + + Each hook has three components: + "query", used to build the query expression + "filter", used to build the filter expression + "result_filters", used for final filtering on the query result + + Query hooks take as input the query being built and return a + transformed query expression. + def mymodel_query_hook(context, original_model, query): + augmented_query = ... + return augmented_query + + Filter hooks take as input the filter expression being built and return + a transformed filter expression + def mymodel_filter_hook(context, original_model, filters): + refined_filters = ... + return refined_filters + + Result filter hooks take as input the query expression and the filter + expression, and return a final transformed query expression. + def mymodel_result_filter_hook(query, filters): + final_filters = ... + return query.filter(final_filters) + + """ + if callable(query_hook): + query_hook = utils.make_weak_ref(query_hook) + if callable(filter_hook): + filter_hook = utils.make_weak_ref(filter_hook) + if callable(result_filters): + result_filters = utils.make_weak_ref(result_filters) + _model_query_hooks.setdefault(model, {})[name] = { + 'query': query_hook, + 'filter': filter_hook, + 'result_filters': result_filters + } + + +def get_hooks(model): + """Retrieve the model query hooks for a model. + + :param model: The DB Model to look up for query hooks. + :type model: sqlalchemy orm model + + :return: list of hooks + :rtype: list of dict of callable + + """ + return _model_query_hooks.get(model, {}).values() diff --git a/neutron/db/_resource_extend.py b/neutron/db/_resource_extend.py new file mode 100644 index 00000000000..a5456d19129 --- /dev/null +++ b/neutron/db/_resource_extend.py @@ -0,0 +1,61 @@ +# 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. + +""" +NOTE: This module shall not be used by external projects. It will be moved + to neutron-lib in due course, and then it can be used from there. +""" + +from neutron.common import utils + +# This dictionary will store methods for extending API resources. +# Extensions can add their own methods by invoking register_funcs(). +_resource_extend_functions = { + # : [, , ...], + # : [, , ...], + # ... +} + + +def register_funcs(resource, funcs): + """Add functions to extend a resource. + + :param resource: A resource collection name. + :type resource: str + + :param funcs: A list of functions. + :type funcs: list of callable + + These functions take a resource dict and a resource object and + update the resource dict with extension data (possibly retrieved + from the resource db object). + def _extend_foo_with_bar(foo_res, foo_db): + foo_res['bar'] = foo_db.bar_info # example + return foo_res + + """ + funcs = [utils.make_weak_ref(f) if callable(f) else f + for f in funcs] + _resource_extend_functions.setdefault(resource, []).extend(funcs) + + +def get_funcs(resource): + """Retrieve a list of functions extending a resource. + + :param resource: A resource collection name. + :type resource: str + + :return: A list (possibly empty) of functions extending resource. + :rtype: list of callable + + """ + return _resource_extend_functions.get(resource, []) diff --git a/neutron/db/address_scope_db.py b/neutron/db/address_scope_db.py index d41bfc18abc..3ff6461a21e 100644 --- a/neutron/db/address_scope_db.py +++ b/neutron/db/address_scope_db.py @@ -17,9 +17,9 @@ from oslo_utils import uuidutils from neutron._i18n import _ from neutron.api.v2 import attributes as attr +from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils from neutron.db import api as db_api -from neutron.db import db_base_plugin_v2 from neutron.extensions import address_scope as ext_address_scope from neutron.objects import address_scope as obj_addr_scope from neutron.objects import base as base_obj @@ -133,5 +133,5 @@ class AddressScopeDbMixin(ext_address_scope.AddressScopePluginBase): network_res[ext_address_scope.IPV6_ADDRESS_SCOPE] = as_id return network_res - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attr.NETWORKS, ['_extend_network_dict_address_scope']) diff --git a/neutron/db/allowedaddresspairs_db.py b/neutron/db/allowedaddresspairs_db.py index 665a2a88a83..972fc00f8a6 100644 --- a/neutron/db/allowedaddresspairs_db.py +++ b/neutron/db/allowedaddresspairs_db.py @@ -16,8 +16,8 @@ from neutron_lib.api import validators from neutron.api.v2 import attributes as attr +from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils -from neutron.db import db_base_plugin_v2 from neutron.common import utils from neutron.extensions import allowedaddresspairs as addr_pair @@ -73,8 +73,7 @@ class AllowedAddressPairsMixin(object): port_res[addr_pair.ADDRESS_PAIRS] = allowed_address_pairs return port_res - # Register dict extend functions for ports - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attr.PORTS, ['_extend_port_dict_allowed_address_pairs']) def _delete_allowed_address_pairs(self, context, id): diff --git a/neutron/db/availability_zone/network.py b/neutron/db/availability_zone/network.py index 5b4b98412a5..422ed2ca7b3 100644 --- a/neutron/db/availability_zone/network.py +++ b/neutron/db/availability_zone/network.py @@ -12,7 +12,7 @@ # under the License. from neutron.api.v2 import attributes -from neutron.db import common_db_mixin +from neutron.db import _resource_extend as resource_extend from neutron.extensions import availability_zone as az_ext from neutron.extensions import network_availability_zone as net_az @@ -26,5 +26,5 @@ class NetworkAvailabilityZoneMixin(net_az.NetworkAvailabilityZonePluginBase): net_res[az_ext.AVAILABILITY_ZONES] = ( self.get_network_availability_zones(net_db)) - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.NETWORKS, ['_extend_availability_zone']) diff --git a/neutron/db/common_db_mixin.py b/neutron/db/common_db_mixin.py index 5402df2a742..439a79dba9a 100644 --- a/neutron/db/common_db_mixin.py +++ b/neutron/db/common_db_mixin.py @@ -24,7 +24,8 @@ from sqlalchemy import or_ from sqlalchemy import sql from neutron.api.v2 import attributes -from neutron.common import utils +from neutron.db import _model_query +from neutron.db import _resource_extend from neutron.db import _utils as ndb_utils @@ -37,52 +38,20 @@ resource_fields = ndb_utils.resource_fields class CommonDbMixin(object): """Common methods used in core and service plugins.""" - # Plugins, mixin classes implementing extension will register - # hooks into the dict below for "augmenting" the "core way" of - # building a query for retrieving objects from a model class. - # To this aim, the register_model_query_hook and unregister_query_hook - # from this class should be invoked - _model_query_hooks = {} - # This dictionary will store methods for extending attributes of - # api resources. Mixins can use this dict for adding their own methods - # TODO(salvatore-orlando): Avoid using class-level variables - _dict_extend_functions = {} - - @classmethod - def register_model_query_hook(cls, model, name, query_hook, filter_hook, + @staticmethod + def register_model_query_hook(model, name, query_hook, filter_hook, result_filters=None): - """Register a hook to be invoked when a query is executed. + _model_query.register_hook( + model, name, query_hook, filter_hook, + result_filters=result_filters) - Add the hooks to the _model_query_hooks dict. Models are the keys - of this dict, whereas the value is another dict mapping hook names to - callables performing the hook. - Each hook has a "query" component, used to build the query expression - and a "filter" component, which is used to build the filter expression. - - Query hooks take as input the query being built and return a - transformed query expression. - - Filter hooks take as input the filter expression being built and return - a transformed filter expression - """ - if callable(query_hook): - query_hook = utils.make_weak_ref(query_hook) - if callable(filter_hook): - filter_hook = utils.make_weak_ref(filter_hook) - if callable(result_filters): - result_filters = utils.make_weak_ref(result_filters) - cls._model_query_hooks.setdefault(model, {})[name] = { - 'query': query_hook, 'filter': filter_hook, - 'result_filters': result_filters} - - @classmethod - def register_dict_extend_funcs(cls, resource, funcs): - funcs = [utils.make_weak_ref(f) if callable(f) else f - for f in funcs] - cls._dict_extend_functions.setdefault(resource, []).extend(funcs) + @staticmethod + def register_dict_extend_funcs(resource, funcs): + _resource_extend.register_funcs(resource, funcs) @property + # TODO(HenryG): Remove; used only by vmware-nsx. def safe_reference(self): """Return a weakref to the instance. @@ -115,13 +84,12 @@ class CommonDbMixin(object): else: query_filter = (model.tenant_id == context.tenant_id) # Execute query hooks registered from mixins and plugins - for _name, hooks in six.iteritems(self._model_query_hooks.get(model, - {})): - query_hook = self._resolve_ref(hooks.get('query')) + for hook in _model_query.get_hooks(model): + query_hook = self._resolve_ref(hook.get('query')) if query_hook: query = query_hook(context, model, query) - filter_hook = self._resolve_ref(hooks.get('filter')) + filter_hook = self._resolve_ref(hook.get('filter')) if filter_hook: query_filter = filter_hook(context, model, query_filter) @@ -195,10 +163,10 @@ class CommonDbMixin(object): # scoped query query = query.outerjoin(model.rbac_entries) query = query.filter(is_shared) - for _nam, hooks in six.iteritems(self._model_query_hooks.get(model, - {})): + for hook in _model_query.get_hooks(model): result_filter = self._resolve_ref( - hooks.get('result_filters', None)) + hook.get('result_filters', None)) + if result_filter: query = result_filter(query, filters) return query @@ -213,8 +181,7 @@ class CommonDbMixin(object): def _apply_dict_extend_functions(self, resource_type, response, db_object): - for func in self._dict_extend_functions.get( - resource_type, []): + for func in _resource_extend.get_funcs(resource_type): args = (response, db_object) if not isinstance(func, six.string_types): # must call unbound method - use self as 1st argument diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index 2d1120b39b9..8d2e16a3084 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -41,6 +41,7 @@ from neutron.common import constants as n_const from neutron.common import exceptions as n_exc from neutron.common import ipv6_utils from neutron.common import utils +from neutron.db import _model_query as model_query from neutron.db import _utils as ndb_utils from neutron.db import api as db_api from neutron.db import db_base_plugin_common @@ -1388,7 +1389,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, if tenant_id != router['tenant_id']: raise n_exc.DeviceIDNotOwnedByTenant(device_id=device_id) - db_base_plugin_common.DbBasePluginCommon.register_model_query_hook( + model_query.register_hook( models_v2.Port, "port", None, diff --git a/neutron/db/dns_db.py b/neutron/db/dns_db.py index c3e5902d4e2..f71d2a4a74c 100644 --- a/neutron/db/dns_db.py +++ b/neutron/db/dns_db.py @@ -20,7 +20,7 @@ from oslo_log import log as logging from neutron._i18n import _, _LE from neutron.common import utils -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.extensions import dns from neutron.extensions import l3 from neutron.objects import floatingip as fip_obj @@ -71,8 +71,7 @@ class DNSDbMixin(object): floatingip_res['dns_name'] = floatingip_db.dns['dns_name'] return floatingip_res - # Register dict extend functions for floating ips - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( l3.FLOATINGIPS, ['_extend_floatingip_dict_dns']) def _process_dns_floatingip_create_precommit(self, context, diff --git a/neutron/db/external_net_db.py b/neutron/db/external_net_db.py index 985a0a99750..3d1c7a4c0d3 100644 --- a/neutron/db/external_net_db.py +++ b/neutron/db/external_net_db.py @@ -25,8 +25,9 @@ from neutron.callbacks import events from neutron.callbacks import exceptions as c_exc from neutron.callbacks import registry from neutron.callbacks import resources +from neutron.db import _model_query as model_query +from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils -from neutron.db import db_base_plugin_v2 from neutron.db.models import l3 as l3_models from neutron.db import models_v2 from neutron.db import rbac_db_models as rbac_db @@ -67,10 +68,7 @@ class External_net_db_mixin(object): return query.filter(models_v2.Network.external.has()) return query.filter(~models_v2.Network.external.has()) - # TODO(salvatore-orlando): Perform this operation without explicitly - # referring to db_base_plugin_v2, as plugins that do not extend from it - # might exist in the future - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( + model_query.register_hook( models_v2.Network, "external_net", None, @@ -86,8 +84,7 @@ class External_net_db_mixin(object): network_res[external_net.EXTERNAL] = network_db.external is not None return network_res - # Register dict extend functions for networks - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.NETWORKS, ['_extend_network_dict_l3']) def _process_l3_create(self, context, net_data, req_data): diff --git a/neutron/db/extradhcpopt_db.py b/neutron/db/extradhcpopt_db.py index 7a78c11c2a6..1184bf30a9a 100644 --- a/neutron/db/extradhcpopt_db.py +++ b/neutron/db/extradhcpopt_db.py @@ -14,7 +14,7 @@ # under the License. from neutron.api.v2 import attributes -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.extensions import extra_dhcp_opt as edo_ext from neutron.objects.port.extensions import extra_dhcp_opt as obj_extra_dhcp @@ -120,5 +120,5 @@ class ExtraDhcpOptMixin(object): for dho in port.dhcp_opts] return res - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, ['_extend_port_dict_extra_dhcp_opt']) diff --git a/neutron/db/extraroute_db.py b/neutron/db/extraroute_db.py index 3a3bc621483..02ba7e01166 100644 --- a/neutron/db/extraroute_db.py +++ b/neutron/db/extraroute_db.py @@ -20,7 +20,7 @@ from oslo_log import log as logging from neutron._i18n import _ from neutron.common import utils -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.db import l3_db from neutron.db import models_v2 from neutron.extensions import extraroute @@ -48,7 +48,7 @@ class ExtraRoute_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin): router_db['route_list'] )) - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( l3.ROUTERS, ['_extend_router_dict_extraroute']) def update_router(self, context, id, router): diff --git a/neutron/db/l3_attrs_db.py b/neutron/db/l3_attrs_db.py index bd868b659d3..5d8b0efa92a 100644 --- a/neutron/db/l3_attrs_db.py +++ b/neutron/db/l3_attrs_db.py @@ -15,7 +15,7 @@ from oslo_config import cfg from neutron._i18n import _ -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.db.models import l3_attrs from neutron.extensions import availability_zone as az from neutron.extensions import l3 @@ -62,5 +62,5 @@ class ExtraAttributesMixin(object): raise RuntimeError(_("Tried to set a key '%s' that doesn't exist " "in the extra attributes table.") % key) - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( l3.ROUTERS, ['_extend_extra_router_dict']) diff --git a/neutron/db/l3_gwmode_db.py b/neutron/db/l3_gwmode_db.py index ec7c7b4b48c..ff44c29e424 100644 --- a/neutron/db/l3_gwmode_db.py +++ b/neutron/db/l3_gwmode_db.py @@ -18,7 +18,7 @@ import sqlalchemy as sa from sqlalchemy import sql from neutron._i18n import _ -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.db import l3_db from neutron.db.models import l3 as l3_models from neutron.extensions import l3 @@ -41,8 +41,7 @@ setattr(l3_models.Router, 'enable_snat', class L3_NAT_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin): """Mixin class to add configurable gateway modes.""" - # Register dict extend functions for ports and networks - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( l3.ROUTERS, ['_extend_router_dict_gw_mode']) def _extend_router_dict_gw_mode(self, router_res, router_db): diff --git a/neutron/db/netmtu_db.py b/neutron/db/netmtu_db.py index 101477a4966..1f983b8941c 100644 --- a/neutron/db/netmtu_db.py +++ b/neutron/db/netmtu_db.py @@ -16,7 +16,7 @@ from oslo_config import cfg from neutron.api.v2 import attributes -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.extensions import netmtu from neutron.plugins.common import utils @@ -36,5 +36,5 @@ class Netmtu_db_mixin(object): network_res[netmtu.MTU] = utils.get_deployment_physnet_mtu() return network_res - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.NETWORKS, ['_extend_network_dict_mtu']) diff --git a/neutron/db/portbindings_base.py b/neutron/db/portbindings_base.py index 8114d2c529f..c9b51a7fc96 100644 --- a/neutron/db/portbindings_base.py +++ b/neutron/db/portbindings_base.py @@ -14,7 +14,7 @@ # under the License. from neutron.api.v2 import attributes -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend class PortBindingBaseMixin(object): @@ -36,5 +36,5 @@ def _extend_port_dict_binding(plugin, port_res, port_db): def register_port_dict_function(): - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, [_extend_port_dict_binding]) diff --git a/neutron/db/portbindings_db.py b/neutron/db/portbindings_db.py index 9cd8b076e9b..fe79d4b297e 100644 --- a/neutron/db/portbindings_db.py +++ b/neutron/db/portbindings_db.py @@ -16,7 +16,8 @@ from neutron_lib.api import validators from neutron.api.v2 import attributes -from neutron.db import db_base_plugin_v2 +from neutron.db import _model_query as model_query +from neutron.db import _resource_extend as resource_extend from neutron.db.models import portbinding as pmodels from neutron.db import models_v2 from neutron.db import portbindings_base @@ -39,7 +40,7 @@ class PortBindingMixin(portbindings_base.PortBindingBaseMixin): query = query.filter(pmodels.PortBindingPort.host.in_(values)) return query - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( + model_query.register_hook( models_v2.Port, "portbindings_port", '_port_model_hook', @@ -102,6 +103,4 @@ def _extend_port_dict_binding(plugin, port_res, port_db): plugin.extend_port_dict_binding(port_res, port_db) -# Register dict extend functions for ports -db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( - attributes.PORTS, [_extend_port_dict_binding]) +resource_extend.register_funcs(attributes.PORTS, [_extend_port_dict_binding]) diff --git a/neutron/db/portsecurity_db.py b/neutron/db/portsecurity_db.py index 70d177c4ff3..bd551270bbf 100644 --- a/neutron/db/portsecurity_db.py +++ b/neutron/db/portsecurity_db.py @@ -16,16 +16,15 @@ from neutron_lib.api import validators from neutron.api.v2 import attributes as attrs from neutron.common import utils -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.db import portsecurity_db_common from neutron.extensions import portsecurity as psec class PortSecurityDbMixin(portsecurity_db_common.PortSecurityDbCommon): - # Register dict extend functions for ports and networks - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attrs.NETWORKS, ['_extend_port_security_dict']) - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attrs.PORTS, ['_extend_port_security_dict']) def _extend_port_security_dict(self, response_data, db_data): diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index 6f71dfa4ee7..96379b2ff14 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -28,9 +28,9 @@ from neutron.callbacks import registry from neutron.callbacks import resources from neutron.common import constants as n_const from neutron.common import utils +from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils from neutron.db import api as db_api -from neutron.db import db_base_plugin_v2 from neutron.db.models import securitygroup as sg_models from neutron.extensions import securitygroup as ext_sg @@ -662,8 +662,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): port_res[ext_sg.SECURITYGROUPS] = security_group_ids return port_res - # Register dict extend functions for ports - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, ['_extend_port_dict_security_group']) def _process_port_create_security_group(self, context, port, diff --git a/neutron/db/standardattrdescription_db.py b/neutron/db/standardattrdescription_db.py index ec566bd37b5..98548ece5b4 100644 --- a/neutron/db/standardattrdescription_db.py +++ b/neutron/db/standardattrdescription_db.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron.db import common_db_mixin +from neutron.db import _resource_extend as resource_extend from neutron.db import standard_attr @@ -26,7 +26,7 @@ class StandardAttrDescriptionMixin(object): def __new__(cls, *args, **kwargs): for resource in standard_attr.get_standard_attr_resource_model_map(): - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( resource, ['_extend_standard_attr_description']) return super(StandardAttrDescriptionMixin, cls).__new__(cls, *args, **kwargs) diff --git a/neutron/db/subnet_service_type_db_models.py b/neutron/db/subnet_service_type_db_models.py index 115ac4ac34b..60f2be95a69 100644 --- a/neutron/db/subnet_service_type_db_models.py +++ b/neutron/db/subnet_service_type_db_models.py @@ -17,7 +17,7 @@ # any models at all from neutron.api.v2 import attributes -from neutron.db import common_db_mixin +from neutron.db import _resource_extend as resource_extend class SubnetServiceTypeMixin(object): @@ -28,5 +28,5 @@ class SubnetServiceTypeMixin(object): service_type in subnet_db.service_types] - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.SUBNETS, [_extend_subnet_service_types]) diff --git a/neutron/db/vlantransparent_db.py b/neutron/db/vlantransparent_db.py index ba024fe6b17..1af6ad4bbf1 100644 --- a/neutron/db/vlantransparent_db.py +++ b/neutron/db/vlantransparent_db.py @@ -13,7 +13,7 @@ # under the License. from neutron.api.v2 import attributes -from neutron.db import db_base_plugin_v2 +from neutron.db import _resource_extend as resource_extend from neutron.extensions import vlantransparent @@ -25,5 +25,5 @@ class Vlantransparent_db_mixin(object): network_db.vlan_transparent) return network_res - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.NETWORKS, ['_extend_network_dict_vlan_transparent']) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 9173725ac9a..f59bcdc4ade 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -46,6 +46,8 @@ from neutron.common import constants as n_const from neutron.common import rpc as n_rpc from neutron.common import topics from neutron.common import utils +from neutron.db import _model_query as model_query +from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils from neutron.db import address_scope_db from neutron.db import agents_db @@ -579,17 +581,16 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, if port_db.port_binding: self._update_port_dict_binding(port_res, port_db.port_binding) - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, ['_ml2_extend_port_dict_binding']) - # Register extend dict methods for network and port resources. - # Each mechanism driver that supports extend attribute for the resources - # can add those attribute to the result. - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + # ML2's resource extend functions allow extension drivers that extend + # attributes for the resources to add those attributes to the result. + resource_extend.register_funcs( attributes.NETWORKS, ['_ml2_md_extend_network_dict']) - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, ['_ml2_md_extend_port_dict']) - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.SUBNETS, ['_ml2_md_extend_subnet_dict']) def _ml2_md_extend_network_dict(self, result, netdb): @@ -616,7 +617,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, bind_criteria = models.PortBinding.host.in_(values) return query.filter(models_v2.Port.port_binding.has(bind_criteria)) - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( + model_query.register_hook( models_v2.Port, "ml2_port_bindings", None, diff --git a/neutron/services/auto_allocate/db.py b/neutron/services/auto_allocate/db.py index e450ffab0b9..2ff29a9b501 100644 --- a/neutron/services/auto_allocate/db.py +++ b/neutron/services/auto_allocate/db.py @@ -25,10 +25,10 @@ from neutron.callbacks import events from neutron.callbacks import registry from neutron.callbacks import resources from neutron.common import exceptions as c_exc +from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils from neutron.db import api as db_api from neutron.db import common_db_mixin -from neutron.db import db_base_plugin_v2 from neutron.extensions import l3 from neutron.objects import auto_allocate as auto_allocate_obj from neutron.objects import base as base_obj @@ -75,7 +75,7 @@ def _ensure_external_network_default_value_callback( class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin): - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.NETWORKS, [_extend_external_network_default]) def __new__(cls, *args, **kwargs): diff --git a/neutron/services/l3_router/l3_router_plugin.py b/neutron/services/l3_router/l3_router_plugin.py index 9ed3ee9ec81..6e521816a20 100644 --- a/neutron/services/l3_router/l3_router_plugin.py +++ b/neutron/services/l3_router/l3_router_plugin.py @@ -22,6 +22,7 @@ from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api from neutron.api.rpc.handlers import l3_rpc from neutron.common import rpc as n_rpc from neutron.common import topics +from neutron.db import _resource_extend as resource_extend from neutron.db import common_db_mixin from neutron.db import dns_db from neutron.db import extraroute_db @@ -125,5 +126,5 @@ def add_flavor_id(plugin, router_res, router_db): router_res['flavor_id'] = router_db['flavor_id'] -common_db_mixin.CommonDbMixin.register_dict_extend_funcs( +resource_extend.register_funcs( l3.ROUTERS, [add_flavor_id]) diff --git a/neutron/services/revisions/revision_plugin.py b/neutron/services/revisions/revision_plugin.py index ab32b131c0a..853704e4242 100644 --- a/neutron/services/revisions/revision_plugin.py +++ b/neutron/services/revisions/revision_plugin.py @@ -17,8 +17,8 @@ from sqlalchemy.orm import exc from sqlalchemy.orm import session as se from neutron._i18n import _, _LW +from neutron.db import _resource_extend as resource_extend from neutron.db import api as db_api -from neutron.db import db_base_plugin_v2 from neutron.db import standard_attr from neutron.services import service_base @@ -33,7 +33,7 @@ class RevisionPlugin(service_base.ServicePluginBase): def __init__(self): super(RevisionPlugin, self).__init__() for resource in standard_attr.get_standard_attr_resource_model_map(): - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( resource, [self.extend_resource_dict_revision]) db_api.sqla_listen(se.Session, 'before_flush', self.bump_revisions) diff --git a/neutron/services/segments/plugin.py b/neutron/services/segments/plugin.py index 1cde18056a7..602124f7f70 100644 --- a/neutron/services/segments/plugin.py +++ b/neutron/services/segments/plugin.py @@ -29,7 +29,7 @@ from neutron.callbacks import events from neutron.callbacks import registry from neutron.callbacks import resources from neutron.common import exceptions as n_exc -from neutron.db import common_db_mixin +from neutron.db import _resource_extend as resource_extend from neutron.db.models import segment as segment_model from neutron.db import models_v2 from neutron.extensions import ip_allocation @@ -79,11 +79,11 @@ class Plugin(db.SegmentDbMixin, segment.SegmentPluginBase): supported_extension_aliases = ["segment", "ip_allocation", "l2_adjacency"] def __init__(self): - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.NETWORKS, [_extend_network_dict_binding]) - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.SUBNETS, [_extend_subnet_dict_binding]) - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, [_extend_port_dict_binding]) self.nova_updater = NovaSegmentNotifier() diff --git a/neutron/services/tag/tag_plugin.py b/neutron/services/tag/tag_plugin.py index 5dbc76dc17f..3285c617187 100644 --- a/neutron/services/tag/tag_plugin.py +++ b/neutron/services/tag/tag_plugin.py @@ -21,6 +21,8 @@ from oslo_log import helpers as log_helpers from sqlalchemy.orm import exc from neutron.api.v2 import attributes +from neutron.db import _model_query as model_query +from neutron.db import _resource_extend as resource_extend from neutron.db import api as db_api from neutron.db import common_db_mixin from neutron.db.models import l3 as l3_model @@ -31,6 +33,7 @@ from neutron.extensions import l3 as l3_ext from neutron.extensions import tag as tag_ext +# Taggable resources resource_model_map = { # When we'll add other resources, we must add new extension for them # if we don't have better discovery mechanism instead of it. @@ -131,13 +134,11 @@ class TagPlugin(common_db_mixin.CommonDbMixin, tag_ext.TagPluginBase): def __new__(cls, *args, **kwargs): inst = super(TagPlugin, cls).__new__(cls, *args, **kwargs) inst._filter_methods = [] # prevent GC of our partial functions - # support only _apply_dict_extend_functions supported resources - # at the moment. for resource, model in resource_model_map.items(): - common_db_mixin.CommonDbMixin.register_dict_extend_funcs( + resource_extend.register_funcs( resource, [_extend_tags_dict]) method = functools.partial(tag_methods.apply_tag_filters, model) inst._filter_methods.append(method) - common_db_mixin.CommonDbMixin.register_model_query_hook( + model_query.register_hook( model, "tag", None, None, method) return inst diff --git a/neutron/services/timestamp/timestamp_plugin.py b/neutron/services/timestamp/timestamp_plugin.py index eee6aadeeb4..a1926ac0e82 100644 --- a/neutron/services/timestamp/timestamp_plugin.py +++ b/neutron/services/timestamp/timestamp_plugin.py @@ -12,7 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron.db import db_base_plugin_v2 +from neutron.db import _model_query as model_query +from neutron.db import _resource_extend as resource_extend from neutron.db import models_v2 from neutron.db import standard_attr from neutron.objects import base as base_obj @@ -31,9 +32,9 @@ class TimeStampPlugin(service_base.ServicePluginBase, self.register_db_events() rs_model_maps = standard_attr.get_standard_attr_resource_model_map() for rsmap, model in rs_model_maps.items(): - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( rsmap, [self.extend_resource_dict_timestamp]) - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( + model_query.register_hook( model, "change_since_query", None, None, self._change_since_result_filter_hook) # TODO(jlibosva): Move this to register_model_query_hook diff --git a/neutron/services/trunk/plugin.py b/neutron/services/trunk/plugin.py index 924785cf1e6..0315e801ce3 100644 --- a/neutron/services/trunk/plugin.py +++ b/neutron/services/trunk/plugin.py @@ -22,10 +22,10 @@ from neutron.api.v2 import attributes from neutron.callbacks import events from neutron.callbacks import registry from neutron.callbacks import resources +from neutron.db import _resource_extend as resource_extend from neutron.db import api as db_api from neutron.db import common_db_mixin from neutron.db import db_base_plugin_common -from neutron.db import db_base_plugin_v2 from neutron.extensions import portbindings from neutron.objects import base as objects_base from neutron.objects import trunk as trunk_objects @@ -69,7 +69,7 @@ class TrunkPlugin(service_base.ServicePluginBase, __native_sorting_support = True def __init__(self): - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( attributes.PORTS, [_extend_port_trunk_details]) self._rpc_backend = None self._drivers = [] diff --git a/neutron/tests/tools.py b/neutron/tests/tools.py index 952a792213a..a778707f7c0 100644 --- a/neutron/tests/tools.py +++ b/neutron/tests/tools.py @@ -35,7 +35,7 @@ import unittest2 from neutron.api.v2 import attributes from neutron.common import constants as n_const -from neutron.db import common_db_mixin +from neutron.db import _model_query as model_query from neutron.plugins.common import constants as p_const @@ -125,13 +125,13 @@ class SafeCleanupFixture(fixtures.Fixture): class CommonDbMixinHooksFixture(fixtures.Fixture): def _setUp(self): - self.original_hooks = common_db_mixin.CommonDbMixin._model_query_hooks + self.original_hooks = model_query._model_query_hooks self.addCleanup(self.restore_hooks) - common_db_mixin.CommonDbMixin._model_query_hooks = copy.copy( - common_db_mixin.CommonDbMixin._model_query_hooks) + model_query._model_query_hooks = copy.copy( + model_query._model_query_hooks) def restore_hooks(self): - common_db_mixin.CommonDbMixin._model_query_hooks = self.original_hooks + model_query._model_query_hooks = self.original_hooks def setup_mock_calls(mocked_call, expected_calls_and_values): diff --git a/neutron/tests/unit/extensions/test_l3.py b/neutron/tests/unit/extensions/test_l3.py index 373eeebc7d8..c0f4973af11 100644 --- a/neutron/tests/unit/extensions/test_l3.py +++ b/neutron/tests/unit/extensions/test_l3.py @@ -37,6 +37,7 @@ from neutron.callbacks import events from neutron.callbacks import exceptions from neutron.callbacks import registry from neutron.callbacks import resources +from neutron.db import _resource_extend as resource_extend from neutron.db import common_db_mixin from neutron.db import db_base_plugin_v2 from neutron.db import dns_db @@ -616,7 +617,7 @@ class L3NatTestCaseBase(L3NatTestCaseMixin): def _extend_router_dict_test_attr(*args, **kwargs): self.extension_called = True - db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs( + resource_extend.register_funcs( l3.ROUTERS, [_extend_router_dict_test_attr]) self.assertFalse(self.extension_called) with self.router(): diff --git a/neutron/tests/unit/objects/test_base.py b/neutron/tests/unit/objects/test_base.py index f7820c7442e..e00949d27e0 100644 --- a/neutron/tests/unit/objects/test_base.py +++ b/neutron/tests/unit/objects/test_base.py @@ -31,7 +31,7 @@ import testtools from neutron.common import constants from neutron.common import utils -from neutron.db import db_base_plugin_v2 +from neutron.db import _model_query as model_query from neutron.db.models import l3 as l3_model from neutron.db import standard_attr from neutron import objects @@ -1507,7 +1507,7 @@ class BaseDbObjectTestCase(_BaseObjectTestCase, return query self.obj_registry.register(self._test_class) - db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook( + model_query.register_hook( self._test_class.db_model, 'foo_filter', None,