Allow subclasses to modify dict_extend hooks

Partial-Bug 1219991

This change modifies the hook processing for dict_extend routines
to call the method on the instance if a hook is registered as a string.
Otherwise, the callable hook is directly invoked as an unbound method.

This patch fixes hook registration for all extensions except port_binding.
This is because some plugins are currently working around this limitation
by invoking both the global hook and another dict_extend function,
which might either be registered as another hook, or invoked explicitly
before returning the response.
Fixing this would go beyong the scope of this patch.

Change-Id: Ibe78433e6554aa7fdf5156fc75b8339254876e78
This commit is contained in:
Salvatore Orlando 2013-09-02 17:37:22 -07:00
parent b63c6f9f83
commit a07bbac1c4
8 changed files with 30 additions and 16 deletions

View File

@ -154,6 +154,19 @@ class CommonDbMixin(object):
query = result_filter(query, filters)
return query
def _apply_dict_extend_functions(self, resource_type,
response, db_object):
for func in self._dict_extend_functions.get(
resource_type, []):
args = (response, db_object)
if isinstance(func, basestring):
func = getattr(self, func, None)
else:
# must call unbound method - use self as 1st argument
args = (self,) + args
if func:
func(*args)
def _get_collection_query(self, context, model, filters=None,
sorts=None, limit=None, marker_obj=None,
page_reverse=False):
@ -865,9 +878,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
for subnet in network['subnets']]}
# Call auxiliary extend functions, if any
if process_extensions:
for func in self._dict_extend_functions.get(attributes.NETWORKS,
[]):
func(self, res, network)
self._apply_dict_extend_functions(
attributes.NETWORKS, res, network)
return self._fields(res, fields)
def _make_subnet_dict(self, subnet, fields=None):
@ -907,9 +919,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
"device_owner": port["device_owner"]}
# Call auxiliary extend functions, if any
if process_extensions:
for func in self._dict_extend_functions.get(attributes.PORTS,
[]):
func(self, res, port)
self._apply_dict_extend_functions(
attributes.PORTS, res, port)
return self._fields(res, fields)
def _create_bulk(self, resource, context, request_items):

View File

@ -128,4 +128,4 @@ class ExtraDhcpOptMixin(object):
return res
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, [_extend_port_dict_extra_dhcp_opt])
attributes.PORTS, ['_extend_port_dict_extra_dhcp_opt'])

View File

@ -63,7 +63,7 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
))
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
l3.ROUTERS, [_extend_router_dict_extraroute])
l3.ROUTERS, ['_extend_router_dict_extraroute'])
def update_router(self, context, id, router):
r = router['router']

View File

@ -143,9 +143,12 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
if router['gw_port_id']:
nw_id = router.gw_port['network_id']
res[EXTERNAL_GW_INFO] = {'network_id': nw_id}
# NOTE(salv-orlando): The following assumes this mixin is used in a
# class inheriting from CommonDbMixin, which is true for all existing
# plugins.
if process_extensions:
for func in self._dict_extend_functions.get(l3.ROUTERS, []):
func(self, res, router)
self._apply_dict_extend_functions(
l3.ROUTERS, res, router)
return self._fields(res, fields)
def create_router(self, context, router):
@ -792,7 +795,7 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
# Register dict extend functions for networks
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.NETWORKS, [_extend_network_dict_l3])
attributes.NETWORKS, ['_extend_network_dict_l3'])
def _process_l3_create(self, context, net_data, req_data):
external = req_data.get(l3.EXTERNAL)

View File

@ -177,6 +177,6 @@ class PortSecurityDbMixin(object):
# Register dict extend functions for ports and networks
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attrs.NETWORKS, [_extend_port_security_dict])
attrs.NETWORKS, ['_extend_port_security_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attrs.PORTS, [_extend_port_security_dict])
attrs.PORTS, ['_extend_port_security_dict'])

View File

@ -444,7 +444,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.PORTS, [_extend_port_dict_security_group])
attr.PORTS, ['_extend_port_dict_security_group'])
def _process_port_create_security_group(self, context, port,
security_group_ids):

View File

@ -66,4 +66,4 @@ class DistributedRouter_mixin(object):
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
l3.ROUTERS, [_extend_router_dict_distributed])
l3.ROUTERS, ['_extend_router_dict_distributed'])

View File

@ -59,7 +59,7 @@ class MacLearningDbMixin(object):
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, [_extend_port_mac_learning_state])
attributes.PORTS, ['_extend_port_mac_learning_state'])
def _update_mac_learning_state(self, context, port_id, enabled):
try: