diff --git a/neutron/plugins/ml2/db.py b/neutron/plugins/ml2/db.py index de1e9838764..1ee3bd539ff 100644 --- a/neutron/plugins/ml2/db.py +++ b/neutron/plugins/ml2/db.py @@ -292,6 +292,46 @@ def get_distributed_port_bindings(context, port_id): return bindings +@db_api.context_manager.reader +def partial_port_ids_to_full_ids(context, partial_ids): + """Takes a list of the start of port IDs and returns full IDs. + + Returns dictionary of partial IDs to full IDs if a single match + is found. + """ + result = {} + to_full_query = (context.session.query(models_v2.Port.id). + filter(or_(*[models_v2.Port.id.startswith(p) + for p in partial_ids]))) + candidates = [match[0] for match in to_full_query] + for partial_id in partial_ids: + matching = [c for c in candidates if c.startswith(partial_id)] + if len(matching) == 1: + result[partial_id] = matching[0] + continue + if len(matching) < 1: + LOG.info("No ports have port_id starting with %s", partial_id) + elif len(matching) > 1: + LOG.error(_LE("Multiple ports have port_id starting with %s"), + partial_id) + return result + + +@db_api.context_manager.reader +def get_port_db_objects(context, port_ids): + """Takes a list of port_ids and returns matching port db objects. + + return format is a dictionary keyed by passed in IDs with db objects + for values or None if the port was not present. + """ + port_qry = (context.session.query(models_v2.Port). + filter(models_v2.Port.id.in_(port_ids))) + result = {p: None for p in port_ids} + for port in port_qry: + result[port.id] = port + return result + + @db_api.context_manager.reader def is_dhcp_active_on_any_subnet(context, subnet_ids): if not subnet_ids: diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 7ddee09f513..8c156dc053b 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -884,6 +884,23 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, return [db_utils.resource_fields(net, fields) for net in nets] + def get_network_contexts(self, context, network_ids): + """Return a map of network_id to NetworkContext for network_ids.""" + net_filters = {'id': list(set(network_ids))} + nets_by_netid = { + n['id']: n for n in self.get_networks(context, + filters=net_filters) + } + segments_by_netid = segments_db.get_networks_segments( + context, nets_by_netid.keys()) + netctxs_by_netid = { + net_id: driver_context.NetworkContext( + self, context, nets_by_netid[net_id], + segments=segments_by_netid[net_id]) + for net_id in nets_by_netid.keys() + } + return netctxs_by_netid + @utils.transaction_guard def delete_network(self, context, id): # the only purpose of this override is to protect this from being