Use db model hook to filter external network

Fixes bug 1132849

Change-Id: I47e01a11afaf6e6bcf06da7bd713fd39b05600ff
This commit is contained in:
He Jie Xu 2013-02-25 21:50:54 +08:00
parent bec2549657
commit 0156ec175c
10 changed files with 34 additions and 19 deletions

View File

@ -118,7 +118,8 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
return query
@classmethod
def register_model_query_hook(cls, model, name, query_hook, filter_hook):
def register_model_query_hook(cls, model, name, query_hook, filter_hook,
result_filters=None):
""" register an hook to be invoked when a query is executed.
Add the hooks to the _model_query_hooks dict. Models are the keys
@ -138,7 +139,8 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
# add key to dict
model_hooks = {}
cls._model_query_hooks[model] = model_hooks
model_hooks[name] = {'query': query_hook, 'filter': filter_hook}
model_hooks[name] = {'query': query_hook, 'filter': filter_hook,
'result_filters': result_filters}
def _get_by_id(self, context, model, id):
query = self._model_query(context, model)
@ -208,6 +210,11 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
column = getattr(model, key, None)
if column:
query = query.filter(column.in_(value))
for _name, hooks in self._model_query_hooks.get(model,
{}).iteritems():
result_filter = hooks.get('result_filters', None)
if result_filter:
query = result_filter(self, query, filters)
return query
def _get_collection_query(self, context, model, filters=None,

View File

@ -92,6 +92,14 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
*conditions)
return conditions
def _network_result_filter_hook(self, query, filters):
vals = filters and filters.get('router:external', [])
if not vals:
return query
if vals[0]:
return query.filter((ExternalNetwork.network_id != expr.null()))
return query.filter((ExternalNetwork.network_id == expr.null()))
# 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
@ -99,7 +107,8 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
models_v2.Network,
"external_net",
_network_model_hook,
_network_filter_hook)
_network_filter_hook,
_network_result_filter_hook)
def _get_router(self, context, id):
try:

View File

@ -347,8 +347,6 @@ class HyperVQuantumPlugin(db_base_plugin_v2.QuantumDbPluginV2,
self._extend_network_dict_provider(context, net)
self._extend_network_dict_l3(context, net)
# TODO(rkukura): Filter on extended provider attributes.
nets = self._filter_nets_l3(context, nets, filters)
return [self._fields(net, fields) for net in nets]
def _extend_port_dict_binding(self, context, port):

View File

@ -449,9 +449,6 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
self._extend_network_dict_provider(context, net)
self._extend_network_dict_l3(context, net)
# TODO(rkukura): Filter on extended provider attributes.
nets = self._filter_nets_l3(context, nets, filters)
return [self._fields(net, fields) for net in nets]
def _extend_port_dict_binding(self, context, port):

View File

@ -374,7 +374,6 @@ class MidonetPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
id=n['id'])
self._extend_network_dict_l3(context, n)
qnets = self._filter_nets_l3(context, qnets, filters)
return [self._fields(net, fields) for net in qnets]
def delete_network(self, context, id):

View File

@ -342,7 +342,6 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
nets = super(NECPluginV2, self).get_networks(context, filters, None)
for net in nets:
self._extend_network_dict_l3(context, net)
nets = self._filter_nets_l3(context, nets, filters)
return [self._fields(net, fields) for net in nets]
def _extend_port_dict_binding(self, context, port):

View File

@ -1041,9 +1041,6 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
self._extend_network_dict_l3(context, net)
self._extend_network_qos_queue(context, net)
quantum_lswitches = self._filter_nets_l3(context,
quantum_lswitches,
filters)
tenant_ids = filters and filters.get('tenant_id') or None
filter_fmt = "&tag=%s&tag_scope=os_tid"
if context.is_admin and not tenant_ids:

View File

@ -538,9 +538,6 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
self._extend_network_dict_provider(context, net)
self._extend_network_dict_l3(context, net)
# TODO(rkukura): Filter on extended provider attributes.
nets = self._filter_nets_l3(context, nets, filters)
return [self._fields(net, fields) for net in nets]
def _extend_port_dict_binding(self, context, port):

View File

@ -187,7 +187,6 @@ class RyuQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
None)
for net in nets:
self._extend_network_dict_l3(context, net)
nets = self._filter_nets_l3(context, nets, filters)
return [self._fields(net, fields) for net in nets]

View File

@ -293,8 +293,6 @@ class TestL3NatPlugin(db_base_plugin_v2.QuantumDbPluginV2,
marker=marker, page_reverse=page_reverse)
for net in nets:
self._extend_network_dict_l3(context, net)
nets = self._filter_nets_l3(context, nets, filters)
return [self._fields(net, fields) for net in nets]
def delete_port(self, context, id, l3_port_check=True):
@ -1400,6 +1398,21 @@ class L3NatDBTestCase(L3NatTestCaseBase):
query_params="%s=False" % l3.EXTERNAL)
self.assertEqual(len(body['networks']), 1)
def test_list_nets_external_pagination(self):
if self._skip_native_pagination:
self.skipTest("Skip test for not implemented pagination feature")
with contextlib.nested(self.network(name='net1'),
self.network(name='net3')) as (n1, n3):
self._set_net_external(n1['network']['id'])
self._set_net_external(n3['network']['id'])
with self.network(name='net2') as n2:
self._test_list_with_pagination(
'network', (n1, n3), ('name', 'asc'), 1, 3,
query_params='router:external=True')
self._test_list_with_pagination(
'network', (n2, ), ('name', 'asc'), 1, 2,
query_params='router:external=False')
def test_get_network_succeeds_without_filter(self):
plugin = QuantumManager.get_plugin()
ctx = context.Context(None, None, is_admin=True)