LOG = logging.getLogger(__name__)
+# Hooks used to select records which belong a target plugin.
+def _meta_network_model_hook(context, original_model, query):
+ return query.outerjoin(NetworkFlavor,
+ NetworkFlavor.network_id == models_v2.Network.id)
+
+
+def _meta_flavor_filter_hook(query, filters):
+ if FLAVOR_NETWORK in filters:
+ return query.filter(NetworkFlavor.flavor ==
+ filters[FLAVOR_NETWORK][0])
+ return query
+
+
# Metaplugin Exceptions
class FlavorNotFound(exc.NotFound):
message = _("Flavor %(flavor)s could not be found")
for method_name, flavor in extension_list:
self.extension_map[method_name] = flavor
+ # Register hooks.
+ # The hooks are applied for each target plugin instance when
+ # calling the base class to get networks so that only records
+ # which belong to the plugin are selected.
+ #NOTE: Doing registration here (within __init__()) is to avoid
+ # registration when merely importing this file. This is only
+ # for running whole unit tests.
+ db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
+ models_v2.Network,
+ 'metaplugin_net',
+ _meta_network_model_hook,
+ None,
+ _meta_flavor_filter_hook)
+
def _load_plugin(self, plugin_provider):
LOG.debug(_("Plugin location: %s"), plugin_provider)
plugin_klass = importutils.import_class(plugin_provider)
del net['id']
return net
- def get_networks_with_flavor(self, context, filters=None,
- fields=None):
- collection = self._model_query(context, models_v2.Network)
- model = NetworkFlavor
- collection = collection.join(model,
- models_v2.Network.id == model.network_id)
- if filters:
- for key, value in filters.iteritems():
- if key == FLAVOR_NETWORK:
- column = NetworkFlavor.flavor
- else:
- column = getattr(models_v2.Network, key, None)
- if column:
- collection = collection.filter(column.in_(value))
- return [self._make_network_dict(c, fields) for c in collection]
-
def get_networks(self, context, filters=None, fields=None):
- nets = self.get_networks_with_flavor(context, filters, None)
- if filters:
- nets = self._filter_nets_l3(context, nets, filters)
- nets = [self.get_network(context, net['id'], fields)
- for net in nets]
+ nets = []
+ for flavor, plugin in self.plugins.items():
+ if (filters and FLAVOR_NETWORK in filters and
+ not flavor in filters[FLAVOR_NETWORK]):
+ continue
+ if filters:
+ #NOTE: copy each time since a target plugin may modify
+ # plugin_filters.
+ plugin_filters = filters.copy()
+ else:
+ plugin_filters = {}
+ plugin_filters[FLAVOR_NETWORK] = [flavor]
+ plugin_nets = plugin.get_networks(context, plugin_filters, fields)
+ for net in plugin_nets:
+ if not fields or FLAVOR_NETWORK in fields:
+ net[FLAVOR_NETWORK] = flavor
+ nets.append(net)
return nets
def _get_flavor_by_network_id(self, context, network_id):
from neutron import context
from neutron.db import api as db
+from neutron.db import db_base_plugin_v2
+from neutron.db import models_v2
from neutron.extensions.flavor import (FLAVOR_NETWORK, FLAVOR_ROUTER)
from neutron.openstack.common import uuidutils
from neutron.plugins.metaplugin.meta_neutron_plugin import FlavorNotFound
'neutron.openstack.common.rpc.impl_fake')
+# Hooks registered by metaplugin must not exist for other plugins UT.
+# So hooks must be unregistered (overwrite to None in fact).
+def unregister_meta_hooks():
+ db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
+ models_v2.Network, 'metaplugin_net', None, None, None)
+
+
class MetaNeutronPluginV2Test(base.BaseTestCase):
"""Class conisting of MetaNeutronPluginV2 unit tests."""
db.configure_db()
self.addCleanup(db.clear_db)
+ self.addCleanup(unregister_meta_hooks)
setup_metaplugin_conf(self.has_l3)