// MakeClient returns a client which is pointing at the node with the given // index. The given integer must be in the range [0,NumNodes()-1]. func (r *RemoteCluster) MakeClient(t util.Tester, i int) (*client.DB, *stop.Stopper) { stopper := stop.NewStopper() // TODO(tschottdorf,mberhault): TLS all the things! db, err := client.Open(stopper, "rpc://"+"root"+"@"+ util.EnsureHostPort(r.nodes[i].Addr)+ "?certs="+"certswhocares") if err != nil { t.Fatal(err) } return db, stopper }
func TestParseResolverSpec(t *testing.T) { def := util.EnsureHostPort(":") testCases := []struct { input string success bool resolverType string resolverAddress string }{ // Ports are not checked at parsing time. They are at GetAddress time though. {"127.0.0.1:26222", true, "tcp", "127.0.0.1:26222"}, {":26257", true, "tcp", def}, {"127.0.0.1", true, "tcp", "127.0.0.1:26257"}, {"tcp=127.0.0.1", true, "tcp", "127.0.0.1:26257"}, {"tcp=127.0.0.1:23456", true, "tcp", "127.0.0.1:23456"}, {"lb=127.0.0.1", true, "lb", "127.0.0.1:26257"}, {"unix=/tmp/unix-socket12345", true, "unix", "/tmp/unix-socket12345"}, {"http-lb=localhost:26257", true, "http-lb", "localhost:26257"}, {"http-lb=newhost:1234", true, "http-lb", "newhost:1234"}, {"http-lb=:26257", true, "http-lb", def}, {"http-lb=:", true, "http-lb", def}, {"", false, "", ""}, {"foo=127.0.0.1", false, "", ""}, {"lb=", false, "", ""}, {"", false, "tcp", ""}, {":", true, "tcp", def}, {"tcp=", false, "tcp", ""}, {"tcp=:", true, "tcp", def}, } for tcNum, tc := range testCases { resolver, err := NewResolver(nodeTestBaseContext, tc.input) if (err == nil) != tc.success { t.Errorf("#%d: expected success=%t, got err=%v", tcNum, tc.success, err) } if err != nil { continue } if resolver.Type() != tc.resolverType { t.Errorf("#%d: expected resolverType=%s, got %+v", tcNum, tc.resolverType, resolver) } if resolver.Addr() != tc.resolverAddress { t.Errorf("#%d: expected resolverAddress=%s, got %+v", tcNum, tc.resolverAddress, resolver) } } }
// NewResolver takes a resolver specification and returns a new resolver. // A specification is of the form: [<network type>=]<address> // Network type can be one of: // - tcp: plain hostname of ip address // - lb: load balancer host name or ip: points to an unknown number of backends // - unix: unix sockets // - http-lb: http load balancer: queries http(s)://<lb>/_status/details/local // for node addresses // If "network type" is not specified, "tcp" is assumed. func NewResolver(context *base.Context, spec string) (Resolver, error) { parts := strings.Split(spec, "=") var typ, addr string if len(parts) == 1 { // No type specified: assume "tcp". typ = "tcp" addr = strings.TrimSpace(parts[0]) } else if len(parts) == 2 { typ = strings.TrimSpace(parts[0]) addr = strings.TrimSpace(parts[1]) } else { return nil, util.Errorf("unable to parse gossip resolver spec: %q", spec) } // We should not have an empty address at this point. if len(addr) == 0 { return nil, util.Errorf("invalid address value in gossip resolver spec: %q", spec) } // Validate the type. if _, ok := validTypes[typ]; !ok { return nil, util.Errorf("unknown address type %q in gossip resolver spec: %q, "+ "valid types are %s", typ, spec, validTypes) } // For non-unix resolvers, make sure we fill in the host when not specified (eg: ":26257") if typ != "unix" { // Ensure addr has port and host set. addr = util.EnsureHostPort(addr) } // Create the actual resolver. if typ == "http-lb" { return &nodeLookupResolver{context: context, typ: typ, addr: addr}, nil } return &socketResolver{typ: typ, addr: addr}, nil }
// updatedAddr returns our "official" address based on the address we asked for // (oldAddr) and the address we successfully bound to (newAddr). It's kind of // hacky, but necessary to make TLS work. func updatedAddr(oldAddr, newAddr net.Addr) (net.Addr, error) { switch oldAddr.Network() { case "tcp", "tcp4", "tcp6": // After binding, it's possible that our host and/or port will be // different from what we requested. If the hostname is different, we // want to keep the original one since it's more likely to match our // TLS certificate. But if the port is different, it should be because // we asked for ":0" and got an arbitrary unused port; that needs to be // reflected in our addr. host, oldPort, err := net.SplitHostPort(util.EnsureHostPort(oldAddr.String())) if err != nil { return nil, fmt.Errorf("unable to parse original addr '%s': %v", oldAddr.String(), err) } _, newPort, err := net.SplitHostPort(newAddr.String()) if err != nil { return nil, fmt.Errorf("unable to parse new addr '%s': %v", newAddr.String(), err) } if newPort != oldPort && oldPort != "0" { log.Warningf("asked for port %s, got %s", oldPort, newPort) } return util.MakeUnresolvedAddr("tcp", net.JoinHostPort(host, newPort)), nil case "unix": if oldAddr.String() != newAddr.String() { return nil, fmt.Errorf("asked for unix addr %s, got %s", oldAddr, newAddr) } return newAddr, nil default: return nil, fmt.Errorf("unexpected network type: %s", oldAddr.Network()) } }
Run: func(cmd *cobra.Command, args []string) { info := util.GetBuildInfo() tw := tabwriter.NewWriter(os.Stdout, 2, 1, 2, ' ', 0) fmt.Fprintf(tw, "Build Vers: %s\n", info.Vers) fmt.Fprintf(tw, "Build Tag: %s\n", info.Tag) fmt.Fprintf(tw, "Build Time: %s\n", info.Time) fmt.Fprintf(tw, "Build Deps:\n\t%s\n", strings.Replace(strings.Replace(info.Deps, " ", "\n\t", -1), ":", "\t", -1)) _ = tw.Flush() }, } var cockroachCmd = &cobra.Command{ Use: "cockroach", PersistentPreRun: func(cmd *cobra.Command, args []string) { context.Addr = util.EnsureHostPort(context.Addr) }, } func init() { cockroachCmd.AddCommand( initCmd, startCmd, certCmd, exterminateCmd, quitCmd, logCmd, sqlShellCmd, kvCmd,
// URL returns the HTTP(s) endpoint. func (f *Farmer) URL(i int) string { return "http://" + util.EnsureHostPort(f.Nodes()[i]) }
// ConnString returns a connection string to pass to client.Open(). func (f *Farmer) ConnString(i int) string { // TODO(tschottdorf,mberhault): TLS all the things! return "rpc://" + "root" + "@" + util.EnsureHostPort(f.Nodes()[i]) + "?certs=" + "certswhocares" }
// Get queries the given node's HTTP endpoint for the given path, unmarshaling // into the supplied interface (or returning an error). func (r *RemoteCluster) Get(i int, path string, v interface{}) error { return getJSON(false /* !tls */, util.EnsureHostPort(r.nodes[i].Addr), path, v) }