def del_host(self, host_name): if not self.hosts.has_key(host_name): return defer.fail(DirectoryException( 'Cannot delete host - does not exist.', DirectoryException.NONEXISTING_NAME)) if host_name in self.restricted_names: return defer.fail(DirectoryException( 'Cannot delete host %s.' % host_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.hosts[host_name] del self.hosts[host_name] for info in ret.netinfos: if info.dpid != None: del self.host_loc_bindings[info.dpid.as_host() + (info.port << 48)] elif info.dladdr != None: dl = info.dladdr.hb_long() del self.host_dl_bindings[dl] del self.routers[dl] del self.gateways[dl] elif info.nwaddr != None: del self.host_nw_bindings[info.nwaddr] for alias in ret.aliases: self._del_member_from_groups(ret, Directory.HOST_PRINCIPAL, mangle_name(self.name, alias)) return self._del_member_from_groups(ret, Directory.HOST_PRINCIPAL, mangle_name(self.name, host_name))
def get_group_membership(self, group_type, member_name=None, local_groups=None): group_dict = self.groups.get(group_type) if group_dict is None: return defer.fail( DirectoryException("Invalid or unsupported group type '%s'" % group_type)) if member_name is None \ or (isinstance(member_name, basestring) and member_name == ""): return defer.succeed(group_dict.keys()) groups = set() if is_mangled_name(member_name): mangled_name = member_name else: mangled_name = mangle_name(self.name, member_name) if isinstance(member_name, netinet.cidr_ipaddr): groups.update(self.cidr_cache.get_groups(member_name)) else: for group, gi in group_dict.iteritems(): if mangled_name in gi.member_names: groups.add(group) parentgroups = set() for group in groups: parentgroups.update( set( self._get_group_parents_s(group_type, mangle_name(self.name, group)))) for lgroup in (local_groups or []): parentgroups.update( set(self._get_group_parents_s(group_type, lgroup))) return defer.succeed(tuple(groups | parentgroups))
def del_switch(self, switch_name): if not self.switches.has_key(switch_name): return defer.fail(DirectoryException( 'Cannot delete switch - does not exist.', DirectoryException.NONEXISTING_NAME)) if switch_name in self.restricted_names: return defer.fail(DirectoryException('Cannot delete switch %s.' % switch_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.switches[switch_name] del self.switches[switch_name] del self.switch_bindings[ret.dpid.as_host()] #delete the associated locations locations = self.locations.values() filter_list(locations, lambda location : location.dpid != ret.dpid) ret.locations = locations for loc in locations: key = loc.dpid.as_host() + (loc.port << 48) del self.locations[loc.name] del self.location_bindings[key] #delete location from groups - ignore deferred result as the #call is actually synchronous self._del_member_from_groups(ret, Directory.LOCATION_PRINCIPAL, mangle_name(self.name, loc)) return self._del_member_from_groups(ret, Directory.SWITCH_PRINCIPAL, mangle_name(self.name, switch_name))
def member_op_start(self, request, arg, otype_str): try: groupname = arg["<group name>"] groupdir = arg["<group dir>"] mangled_group = mangle_name(groupdir, groupname) membername = arg["<member name>"] memberdir = arg.get("<member dir>") ptype_str = get_principal_type_from_args(arg) ctype_str = find_value_in_args(arg, ["principal", "address", "subgroup"]) if memberdir == self.dm.discovered_dir.name: return webservice.badRequest( request, "Discovered principals " "may not be added to groups; try moving principal to " "a persistent directory first.", ) ptype = groupname_to_type[ptype_str] is_address = ctype_str == "address" if is_address and ptype == Directory_Factory.DLADDR_GROUP: mangled_member = create_eaddr(membername.encode("utf-8")) elif is_address and ptype == Directory_Factory.NWADDR_GROUP: mangled_member = create_cidr_ipaddr(membername.encode("utf-8")) else: mangled_member = mangle_name(memberdir, membername) if mangled_member is None: return webservice.badRequest(request, "Invalid group member parameter: '%s'" % membername) d = self.dm.get_group(ptype, mangled_group) f = lambda x: self.member_op(request, x, mangled_member, ptype_str, otype_str, ctype_str) d.addCallback(f) d.addErrback(self.err, request, "member_op_start", "Could not retrieve group.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "member_op_start", "Could not retrieve group.")
def get_group_membership(self, group_type, member_name=None, local_groups=None): group_dict = self.groups.get(group_type) if group_dict is None: return defer.fail(DirectoryException( "Invalid or unsupported group type '%s'" %group_type)) if member_name is None \ or (isinstance(member_name, basestring) and member_name == ""): return defer.succeed(group_dict.keys()) groups = set() if is_mangled_name(member_name): mangled_name = member_name else: mangled_name = mangle_name(self.name, member_name) if isinstance(member_name, netinet.cidr_ipaddr): groups.update(self.cidr_cache.get_groups(member_name)) else: for group, gi in group_dict.iteritems(): if mangled_name in gi.member_names: groups.add(group) parentgroups = set() for group in groups: parentgroups.update(set(self._get_group_parents_s(group_type, mangle_name(self.name, group)))) for lgroup in (local_groups or []): parentgroups.update(set(self._get_group_parents_s(group_type, lgroup))) return defer.succeed(tuple(groups | parentgroups))
def del_host(self, host_name): if not self.hosts.has_key(host_name): return defer.fail( DirectoryException('Cannot delete host - does not exist.', DirectoryException.NONEXISTING_NAME)) if host_name in self.restricted_names: return defer.fail( DirectoryException('Cannot delete host %s.' % host_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.hosts[host_name] del self.hosts[host_name] for info in ret.netinfos: if info.dpid != None: del self.host_loc_bindings[info.dpid.as_host() + (info.port << 48)] elif info.dladdr != None: dl = info.dladdr.hb_long() del self.host_dl_bindings[dl] del self.routers[dl] del self.gateways[dl] elif info.nwaddr != None: del self.host_nw_bindings[info.nwaddr] for alias in ret.aliases: self._del_member_from_groups(ret, Directory.HOST_PRINCIPAL, mangle_name(self.name, alias)) return self._del_member_from_groups(ret, Directory.HOST_PRINCIPAL, mangle_name(self.name, host_name))
def del_switch(self, switch_name): if not self.switches.has_key(switch_name): return defer.fail( DirectoryException('Cannot delete switch - does not exist.', DirectoryException.NONEXISTING_NAME)) if switch_name in self.restricted_names: return defer.fail( DirectoryException('Cannot delete switch %s.' % switch_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.switches[switch_name] del self.switches[switch_name] del self.switch_bindings[ret.dpid.as_host()] #delete the associated locations locations = self.locations.values() filter_list(locations, lambda location: location.dpid != ret.dpid) ret.locations = locations for loc in locations: key = loc.dpid.as_host() + (loc.port << 48) del self.locations[loc.name] del self.location_bindings[key] #delete location from groups - ignore deferred result as the #call is actually synchronous self._del_member_from_groups(ret, Directory.LOCATION_PRINCIPAL, mangle_name(self.name, loc)) return self._del_member_from_groups( ret, Directory.SWITCH_PRINCIPAL, mangle_name(self.name, switch_name))
def handle_name_for_name(self, request, arg, input_type_str, output_type_str): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err(res, request, "handle_name_for_name", "Could not find associated " + output_type_str + "s.") try: def cb(res): if len(errCalled) > 0: return try: request.write(simplejson.dumps(res)) request.finish() except Exception, e: return err_specific(Failure()) input_type = get_nametype_from_string(input_type_str) output_type = get_nametype_from_string(output_type_str) name = arg['<principal name>'] dirname = arg['<dir name>'] mangled_name = mangle_name(dirname,name) self.bindings_dir.get_name_for_name(mangled_name, input_type,output_type,cb) return NOT_DONE_YET
def del_group(self, group_type, group_name): group_dict = self.groups.get(group_type) if group_dict is None: return defer.fail( DirectoryException("Invalid or unsupported group type %s" % group_type)) if not group_dict.has_key(group_name): return defer.fail( DirectoryException('Cannot delete group - does not exist.', DirectoryException.NONEXISTING_NAME)) parent_group_dict = self.parent_groups.get(group_type) mangled_gname = mangle_name(self.name, group_name) #remove index to our parent groups if parent_group_dict.has_key(mangled_gname): for pg in parent_group_dict[mangled_gname]: group_dict[pg].subgroup_names.remove(mangled_gname) del parent_group_dict[mangled_gname] ret = group_dict[group_name] #remove subgroups parent group reference to us for sg in ret.subgroup_names: if sg in parent_group_dict: parent_group_dict[sg].discard(group_name) #remove the group from the cidr lookup cache if group_type == Directory.NWADDR_GROUP: for member in ret.member_names: self.cidr_cache.del_cidr(group_info.name, member) #remove the group del group_dict[group_name] return defer.succeed(ret)
def handle_name_for_name(self, request, arg, input_type_str, output_type_str): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err( res, request, "handle_name_for_name", "Could not find associated " + output_type_str + "s.") try: def cb(res): if len(errCalled) > 0: return try: request.write(simplejson.dumps(res)) request.finish() except Exception, e: return err_specific(Failure()) input_type = get_nametype_from_string(input_type_str) output_type = get_nametype_from_string(output_type_str) name = arg['<principal name>'] dirname = arg['<dir name>'] mangled_name = mangle_name(dirname, name) self.bindings_dir.get_name_for_name(mangled_name, input_type, output_type, cb) return NOT_DONE_YET
def del_group(self, group_type, group_name): group_dict = self.groups.get(group_type) if group_dict is None: return defer.fail(DirectoryException( "Invalid or unsupported group type %s" %group_type)) if not group_dict.has_key(group_name): return defer.fail( DirectoryException('Cannot delete group - does not exist.', DirectoryException.NONEXISTING_NAME)) parent_group_dict = self.parent_groups.get(group_type) mangled_gname = mangle_name(self.name, group_name) #remove index to our parent groups if parent_group_dict.has_key(mangled_gname): for pg in parent_group_dict[mangled_gname]: group_dict[pg].subgroup_names.remove(mangled_gname) del parent_group_dict[mangled_gname] ret = group_dict[group_name] #remove subgroups parent group reference to us for sg in ret.subgroup_names: if sg in parent_group_dict: parent_group_dict[sg].discard(group_name) #remove the group from the cidr lookup cache if group_type == Directory.NWADDR_GROUP: for member in ret.member_names: self.cidr_cache.del_cidr(group_info.name, member) #remove the group del group_dict[group_name] return defer.succeed(ret)
def handle_is_active(self, request, arg, principal_type_str): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err(res, request, "handle_is_active", "Could not retrieve active status.") try: name = arg['<principal name>'] dirname = arg['<dir name>'] mangled_name = mangle_name(dirname,name) def cb(res): if len(errCalled) > 0: return try: is_non_empty = len(res) > 0 ret = simplejson.dumps(is_non_empty) if not is_non_empty: self.write_result_or_404(request, arg, ret,principal_type_str) else: request.write(ret) request.finish() except Exception, e: return err_specific(Failure()) principal_type = get_nametype_from_string(principal_type_str) bstore = self.bindings_dir.get_bstore() if principal_type == Name.USER or principal_type == Name.HOST: bstore.get_entities_by_name(mangled_name,principal_type, cb) else : bstore.get_location_by_name(mangled_name,principal_type, cb) return NOT_DONE_YET
def ok(res): if res is None: webservice.notFound(request, "%s '%s' does not exist." % (type_str.capitalize(), mangle_name(dirname,name))) else: request.write(ret) request.finish()
def ok(res): if res is None: webservice.notFound( request, "%s '%s' does not exist." % (type_str.capitalize(), mangle_name(dirname, name))) else: request.write(ret) request.finish()
def get_host_flows(self, request, arg): try: hostname = arg["<principal name>"] dirname = arg["<dir name>"] mangled_name = mangle_name(dirname, hostname).encode('utf-8') flows = self._fc.get_host_flows(mangled_name) return self.flow_infos_to_json(flows) except Exception, e: msg = str(e) or "Unknown Error" return internalError(request, "Failed to retrieve flows: %s" % msg)
def get_host_flows(self, request, arg): try: hostname = arg["<principal name>"] dirname = arg["<dir name>"] mangled_name = mangle_name(dirname, hostname).encode('utf-8') flows = self._fc.get_host_flows(mangled_name) return self.flow_infos_to_json(flows) except Exception, e: msg = str(e) or "Unknown Error" return internalError(request, "Failed to retrieve flows: %s"%msg)
def del_user(self, user_name): if not self.users.has_key(user_name): return defer.fail(DirectoryException('Cannot delete user - does ' 'not exist.', DirectoryException.NONEXISTING_NAME)) if user_name in self.restricted_names: return defer.fail(DirectoryException('Cannot delete user %s.' % user_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.users[user_name] del self.users[user_name] return self._del_member_from_groups(ret, Directory.USER_PRINCIPAL, mangle_name(self.name, user_name))
def member_op_start(self, request, arg, otype_str): try: groupname = arg['<group name>'] groupdir = arg['<group dir>'] mangled_group = mangle_name(groupdir, groupname) membername = arg['<member name>'] memberdir = arg.get('<member dir>') ptype_str = get_principal_type_from_args(arg) ctype_str = find_value_in_args( arg, ["principal", "address", "subgroup"]) if memberdir == self.dm.discovered_dir.name: return webservice.badRequest( request, "Discovered principals " "may not be added to groups; try moving principal to " "a persistent directory first.") ptype = groupname_to_type[ptype_str] is_address = ctype_str == "address" if is_address and ptype == Directory_Factory.DLADDR_GROUP: mangled_member = create_eaddr(membername.encode('utf-8')) elif is_address and ptype == Directory_Factory.NWADDR_GROUP: mangled_member = create_cidr_ipaddr(membername.encode('utf-8')) else: mangled_member = mangle_name(memberdir, membername) if mangled_member is None: return webservice.badRequest( request, "Invalid group member parameter: '%s'" % membername) d = self.dm.get_group(ptype, mangled_group) f = lambda x: self.member_op(request, x, mangled_member, ptype_str, otype_str, ctype_str) d.addCallback(f) d.addErrback(self.err, request, "member_op_start", "Could not retrieve group.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "member_op_start", "Could not retrieve group.")
def group_op_start(self, request, arg, otype_str): try: groupname = arg["<group name>"] dirname = arg.get("<group dir>") mangled_group = mangle_name(dirname, groupname) ptype_str = get_principal_type_from_args(arg) ptype = groupname_to_type[ptype_str] d = self.dm.get_group(ptype, mangled_group) f = lambda x: self.group_op(request, x, mangled_group, ptype_str, otype_str) d.addCallback(f) d.addErrback(self.err, request, "group_op_start", "Could not retrieve group.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "group_op_start", "Could not retrieve group.")
def del_user(self, user_name): if not self.users.has_key(user_name): return defer.fail( DirectoryException('Cannot delete user - does ' 'not exist.', DirectoryException.NONEXISTING_NAME)) if user_name in self.restricted_names: return defer.fail( DirectoryException('Cannot delete user %s.' % user_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.users[user_name] del self.users[user_name] return self._del_member_from_groups(ret, Directory.USER_PRINCIPAL, mangle_name(self.name, user_name))
def del_location(self, location_name): if not self.locations.has_key(location_name): return defer.fail(DirectoryException( 'Cannot delete location - does not exist.', DirectoryException.NONEXISTING_NAME)) if location_name in self.restricted_names: return defer.fail(DirectoryException( 'Cannot delete location %s.' % location_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.locations[location_name] key = ret.dpid.as_host() + (ret.port << 48) del self.locations[location_name] del self.location_bindings[key] return self._del_member_from_groups(ret, Directory.LOCATION_PRINCIPAL, mangle_name(self.name, location_name))
def handle_interface_request(self, request, arg): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err(res, request, "handle_interface_request", "Could not retrieve interface information.") try: mangled_name = mangle_name(arg['<dir name>'], arg['<principal name>']) def single_interface_cb(res, name): if len(errCalled) > 0: return for i in res: n = self._get_name_for_iface(i) if name == n: request.write(simplejson.dumps(i)) request.finish() return msg = "Host '%s' has no interface '%s'." % (mangled_name, name) lg.error(msg) webservice.notFound(request, msg) def all_interfaces_cb(res): if len(errCalled) > 0: return name_list = [self._get_name_for_iface(i) for i in res] ret = simplejson.dumps(name_list) if len(name_list) == 0: self.write_result_or_404(request, arg, ret, "host") else: request.write(simplejson.dumps(name_list)) request.finish() d = self.bindings_dir.get_interfaces_for_host(mangled_name) if '<interface name>' in arg: d.addCallback(single_interface_cb, arg['<interface name>']) else: d.addCallback(all_interfaces_cb) d.addErrback(err_specific) return NOT_DONE_YET except Exception, e: return err_specific(Failure())
def get_port_principals(self, request, arg, switch_info): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err(res, request, "get_port_principals", "Could not retrieve port principals.") try: switchname = mangle_name(arg['<dir name>'], arg['<principal name>']) portname = arg['<port name>'] # what type of names are we looking for ? name_type = Name.USER if 'host' in arg: name_type = Name.HOST def done(arr): # list may contain duplicates, remove them l = list(sets.Set(arr)) request.write(simplejson.dumps(l)) request.finish() def cb1(loc_list): if len(errCalled) > 0: return try: if len(loc_list) == 0: done([]) return dpid_obj = datapathid.from_host(int(loc_list[0][0])) port_num = int(loc_list[0][1]) def cb2(name_list): if len(errCalled) > 0: return try: ret = [] for n in name_list: if n[1] == name_type: ret.append(n[0]) done(ret) except Exception, e: return err_specific(Failure()) self.bstore.get_names_by_ap(dpid_obj,port_num,cb2) except Exception, e: return err_specific(Failure())
def handle_interface_request(self, request, arg): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err(res, request, "handle_interface_request", "Could not retrieve interface information.") try: mangled_name = mangle_name(arg['<dir name>'], arg['<principal name>']) def single_interface_cb(res, name): if len(errCalled) > 0: return for i in res: n = self._get_name_for_iface(i) if name == n: request.write(simplejson.dumps(i)) request.finish() return msg = "Host '%s' has no interface '%s'." % (mangled_name, name) lg.error(msg) webservice.notFound(request, msg) def all_interfaces_cb(res): if len(errCalled) > 0: return name_list = [ self._get_name_for_iface(i) for i in res] ret = simplejson.dumps(name_list) if len(name_list) == 0: self.write_result_or_404(request, arg, ret,"host") else: request.write(simplejson.dumps(name_list)) request.finish() d = self.bindings_dir.get_interfaces_for_host(mangled_name) if '<interface name>' in arg: d.addCallback(single_interface_cb, arg['<interface name>']) else: d.addCallback(all_interfaces_cb) d.addErrback(err_specific) return NOT_DONE_YET except Exception, e: return err_specific(Failure())
def group_op_start(self, request, arg, otype_str): try: groupname = arg['<group name>'] dirname = arg.get('<group dir>') mangled_group = mangle_name(dirname, groupname) ptype_str = get_principal_type_from_args(arg) ptype = groupname_to_type[ptype_str] d = self.dm.get_group(ptype, mangled_group) f = lambda x: self.group_op(request, x, mangled_group, ptype_str, otype_str) d.addCallback(f) d.addErrback(self.err, request, "group_op_start", "Could not retrieve group.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "group_op_start", "Could not retrieve group.")
def del_location(self, location_name): if not self.locations.has_key(location_name): return defer.fail( DirectoryException('Cannot delete location - does not exist.', DirectoryException.NONEXISTING_NAME)) if location_name in self.restricted_names: return defer.fail( DirectoryException( 'Cannot delete location %s.' % location_name, DirectoryException.OPERATION_NOT_PERMITTED)) ret = self.locations[location_name] key = ret.dpid.as_host() + (ret.port << 48) del self.locations[location_name] del self.location_bindings[key] return self._del_member_from_groups( ret, Directory.LOCATION_PRINCIPAL, mangle_name(self.name, location_name))
def get_config_ws(self, request, arg): try: location_name = arg["<principal name>"] dir_name = arg["<dir name>"] mangled_name = mangle_name(dir_name, location_name) def write_to_ws(res): request.write(simplejson.dumps(res)) request.finish() d = self.start(mangled_name) d.addCallback(write_to_ws) d.addErrback(self.err, request, "start", "Could not retrieve location information.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "start", "Could not retrieve location information.")
def get_group_parents(self, request, arg): try: def cb(res): request.write(simplejson.dumps(res)) request.finish() groupname = arg["<group name>"] dirname = arg["<group dir>"] mangled_group = mangle_name(dirname, groupname) ptype_str = get_principal_type_from_args(arg) ptype = groupname_to_type[ptype_str] d = self.dm.get_group_parents(ptype, mangled_group) d.addCallback(cb) d.addErrback(self.err, request, "get_group_parents", "Could not retrieve group parents.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "get_group_parents", "Could not retrieve group parents.")
def __init_port_config__(self, arg, portname, dentry, sentry): if sentry is None: d = {} d['name'] = portname d['hw_addr'] = None d['curr'] = None d['supported'] = None d['enabled'] = None d['flood'] = None d['state'] = None d['link'] = None d['advertised'] = None d['peer'] = None d['config'] = None d['stat_speed'] = None d['stat_port_no'] = None else: d = copy.copy(sentry) d['stat_speed'] = d['speed'] d['stat_port_no'] = d['port_no'] del d['speed'] del d['port_no'] if dentry is None: d['location'] = None d['config_port_no'] = None d['config_speed'] = None d['config_duplex'] = None d['config_auto_neg'] = None d['config_neg_down'] = None d['config_admin_state'] = None else: if dentry.name is not None: d['location'] = mangle_name(arg['<dir name>'], dentry.name) d['config_port_no'] = dentry.port d['config_speed'] = dentry.speed d['config_duplex'] = dentry.duplex d['config_auto_neg'] = dentry.auto_neg d['config_neg_down'] = dentry.neg_down d['config_admin_state'] = dentry.admin_state return d
def get_group_parents(self, request, arg): try: def cb(res): request.write(simplejson.dumps(res)) request.finish() groupname = arg['<group name>'] dirname = arg['<group dir>'] mangled_group = mangle_name(dirname, groupname) ptype_str = get_principal_type_from_args(arg) ptype = groupname_to_type[ptype_str] d = self.dm.get_group_parents(ptype, mangled_group) d.addCallback(cb) d.addErrback(self.err, request, "get_group_parents", "Could not retrieve group parents.") return NOT_DONE_YET except Exception, e: return self.err(Failure(), request, "get_group_parents", "Could not retrieve group parents.")
def handle_is_active(self, request, arg, principal_type_str): errCalled = [] def err_specific(res): if len(errCalled) > 0: return errCalled.append("y") return self.err(res, request, "handle_is_active", "Could not retrieve active status.") try: name = arg['<principal name>'] dirname = arg['<dir name>'] mangled_name = mangle_name(dirname, name) def cb(res): if len(errCalled) > 0: return try: is_non_empty = len(res) > 0 ret = simplejson.dumps(is_non_empty) if not is_non_empty: self.write_result_or_404(request, arg, ret, principal_type_str) else: request.write(ret) request.finish() except Exception, e: return err_specific(Failure()) principal_type = get_nametype_from_string(principal_type_str) bstore = self.bindings_dir.get_bstore() if principal_type == Name.USER or principal_type == Name.HOST: bstore.get_entities_by_name(mangled_name, principal_type, cb) else: bstore.get_location_by_name(mangled_name, principal_type, cb) return NOT_DONE_YET