// LookupName returns a list of SRV records. addrPath is the path to a // json file in zk. It can also reference a named port // (/zk/cell/zkns/path:_named_port) func LookupName(zconn zk.Conn, addrPath string) ([]*net.SRV, error) { zkPathParts := strings.Split(addrPath, ":") zkPath := zkPathParts[0] namedPort := "" if len(zkPathParts) == 2 { namedPort = zkPathParts[1] } addrs, err := ReadAddrs(zconn, zkPath) if err != nil { return nil, fmt.Errorf("LookupName failed: %v", err) } if namedPort == "" { if !addrs.IsValidA() && !addrs.IsValidCNAME() { return nil, fmt.Errorf("LookupName named port required: %v", addrPath) } } else if !addrs.IsValidSRV() { return nil, fmt.Errorf("LookupName invalid record: %v", addrPath) } isValidA := addrs.IsValidA() srvs := make([]*net.SRV, 0, len(addrs.Entries)) for _, addr := range addrs.Entries { // Set the weight to non-zero, otherwise the sort method is deactivated. srv := &net.SRV{Target: addr.Host, Weight: 1} if namedPort != "" { srv.Port = uint16(addr.NamedPortMap[namedPort]) if srv.Port == 0 { // If the port was requested and not defined it's probably // a bug, so fail hard. return nil, fmt.Errorf("LookupName found no such named port: %v", addrPath) } } else if isValidA { srv.Target = addr.IPv4 } srvs = append(srvs, srv) } netutil.SortRfc2782(srvs) return srvs, nil }
// SrvEntries converts EndPoints to net.SRV for a given port. // FIXME(msolomon) merge with zkns func SrvEntries(addrs *EndPoints, namedPort string) (srvs []*net.SRV, err error) { srvs = make([]*net.SRV, 0, len(addrs.Entries)) var srvErr error for _, entry := range addrs.Entries { host := entry.Host port := 0 if namedPort == "" { namedPort = DefaultPortName } port = entry.NamedPortMap[namedPort] if port == 0 { log.Warningf("vtns: bad port %v %v", namedPort, entry) continue } srvs = append(srvs, &net.SRV{Target: host, Port: uint16(port)}) } netutil.SortRfc2782(srvs) if srvErr != nil && len(srvs) == 0 { return nil, fmt.Errorf("SrvEntries failed: no valid endpoints found") } return }