示例#1
0
func TestParseResolverSpec(t *testing.T) {
	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:8080", true, "tcp", "127.0.0.1:8080"},
		{":8080", true, "tcp", util.EnsureHost(":8080")},
		{"127.0.0.1", true, "tcp", "127.0.0.1"},
		{"tcp=127.0.0.1", true, "tcp", "127.0.0.1"},
		{"lb=127.0.0.1", true, "lb", "127.0.0.1"},
		{"unix=/tmp/unix-socket12345", true, "unix", "/tmp/unix-socket12345"},
		{"http-lb=localhost:8080", true, "http-lb", "localhost:8080"},
		{"http-lb=:8080", true, "http-lb", util.EnsureHost(":8080")},
		{"", false, "", ""},
		{"foo=127.0.0.1", false, "", ""},
		{"lb=", false, "", ""},
	}

	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)
		}
	}
}
示例#2
0
// 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.EnsureHost(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())
	}
}
示例#3
0
// 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" {
		addr = util.EnsureHost(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
}
示例#4
0
	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.EnsureHost(context.Addr)
	},
}

func init() {
	cockroachCmd.AddCommand(
		initCmd,
		startCmd,
		certCmd,
		exterminateCmd,
		quitCmd,

		logCmd,

		sqlShellCmd,
		kvCmd,