Bläddra i källkod

Merge pull request #8462 from jiaxuanzhou/serverName

etcdctl: add discovery-srv global flag for v3
Anthony Romano 8 år sedan
förälder
incheckning
9021b85692
2 ändrade filer med 92 tillägg och 7 borttagningar
  1. 90 7
      etcdctl/ctlv3/command/global.go
  2. 2 0
      etcdctl/ctlv3/ctl.go

+ 90 - 7
etcdctl/ctlv3/command/global.go

@@ -17,6 +17,7 @@ package command
 import (
 	"crypto/tls"
 	"errors"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"log"
@@ -27,6 +28,7 @@ import (
 	"github.com/bgentry/speakeasy"
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/pkg/flags"
+	"github.com/coreos/etcd/pkg/srv"
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/spf13/cobra"
 )
@@ -36,6 +38,7 @@ import (
 type GlobalFlags struct {
 	Insecure           bool
 	InsecureSkipVerify bool
+	InsecureDiscovery  bool
 	Endpoints          []string
 	DialTimeout        time.Duration
 	CommandTimeOut     time.Duration
@@ -51,9 +54,10 @@ type GlobalFlags struct {
 }
 
 type secureCfg struct {
-	cert   string
-	key    string
-	cacert string
+	cert       string
+	key        string
+	cacert     string
+	serverName string
 
 	insecureTransport  bool
 	insecureSkipVerify bool
@@ -64,6 +68,11 @@ type authCfg struct {
 	password string
 }
 
+type discoveryCfg struct {
+	domain   string
+	insecure bool
+}
+
 var display printer = &simplePrinter{}
 
 func initDisplayFromCmd(cmd *cobra.Command) {
@@ -91,7 +100,7 @@ func mustClientFromCmd(cmd *cobra.Command) *clientv3.Client {
 		clientv3.SetLogger(log.New(os.Stderr, "grpc: ", 0))
 	}
 
-	endpoints, err := cmd.Flags().GetStringSlice("endpoints")
+	endpoints, err := endpointsFromCmd(cmd)
 	if err != nil {
 		ExitWithError(ExitError, err)
 	}
@@ -137,6 +146,11 @@ func newClientCfg(endpoints []string, dialTimeout time.Duration, scfg *secureCfg
 		cfgtls = &tlsinfo
 	}
 
+	if scfg.serverName != "" {
+		tlsinfo.ServerName = scfg.serverName
+		cfgtls = &tlsinfo
+	}
+
 	cfg := &clientv3.Config{
 		Endpoints:   endpoints,
 		DialTimeout: dialTimeout,
@@ -192,11 +206,17 @@ func secureCfgFromCmd(cmd *cobra.Command) *secureCfg {
 	cert, key, cacert := keyAndCertFromCmd(cmd)
 	insecureTr := insecureTransportFromCmd(cmd)
 	skipVerify := insecureSkipVerifyFromCmd(cmd)
+	discoveryCfg := discoveryCfgFromCmd(cmd)
+
+	if discoveryCfg.insecure {
+		discoveryCfg.domain = ""
+	}
 
 	return &secureCfg{
-		cert:   cert,
-		key:    key,
-		cacert: cacert,
+		cert:       cert,
+		key:        key,
+		cacert:     cacert,
+		serverName: discoveryCfg.domain,
 
 		insecureTransport:  insecureTr,
 		insecureSkipVerify: skipVerify,
@@ -268,3 +288,66 @@ func authCfgFromCmd(cmd *cobra.Command) *authCfg {
 
 	return &cfg
 }
+
+func insecureDiscoveryFromCmd(cmd *cobra.Command) bool {
+	discovery, err := cmd.Flags().GetBool("insecure-discovery")
+	if err != nil {
+		ExitWithError(ExitError, err)
+	}
+	return discovery
+}
+
+func discoverySrvFromCmd(cmd *cobra.Command) string {
+	domainStr, err := cmd.Flags().GetString("discovery-srv")
+	if err != nil {
+		ExitWithError(ExitBadArgs, err)
+	}
+	return domainStr
+}
+
+func discoveryCfgFromCmd(cmd *cobra.Command) *discoveryCfg {
+	return &discoveryCfg{
+		domain:   discoverySrvFromCmd(cmd),
+		insecure: insecureDiscoveryFromCmd(cmd),
+	}
+}
+
+func endpointsFromCmd(cmd *cobra.Command) ([]string, error) {
+	eps, err := endpointsFromFlagValue(cmd)
+	if err != nil {
+		return nil, err
+	}
+	// If domain discovery returns no endpoints, check endpoints flag
+	if len(eps) == 0 {
+		eps, err = cmd.Flags().GetStringSlice("endpoints")
+	}
+	return eps, err
+}
+
+func endpointsFromFlagValue(cmd *cobra.Command) ([]string, error) {
+	discoveryCfg := discoveryCfgFromCmd(cmd)
+
+	// If we still don't have domain discovery, return nothing
+	if discoveryCfg.domain == "" {
+		return []string{}, nil
+	}
+
+	srvs, err := srv.GetClient("etcd-client", discoveryCfg.domain)
+	if err != nil {
+		return nil, err
+	}
+	eps := srvs.Endpoints
+	if discoveryCfg.insecure {
+		return eps, err
+	}
+	// strip insecure connections
+	ret := []string{}
+	for _, ep := range eps {
+		if strings.HasPrefix("http://", ep) {
+			fmt.Fprintf(os.Stderr, "ignoring discovered insecure endpoint %q\n", ep)
+			continue
+		}
+		ret = append(ret, ep)
+	}
+	return ret, err
+}

+ 2 - 0
etcdctl/ctlv3/ctl.go

@@ -54,11 +54,13 @@ func init() {
 
 	// TODO: secure by default when etcd enables secure gRPC by default.
 	rootCmd.PersistentFlags().BoolVar(&globalFlags.Insecure, "insecure-transport", true, "disable transport security for client connections")
+	rootCmd.PersistentFlags().BoolVar(&globalFlags.InsecureDiscovery, "insecure-discovery", true, "accept insecure SRV records describing cluster endpoints")
 	rootCmd.PersistentFlags().BoolVar(&globalFlags.InsecureSkipVerify, "insecure-skip-tls-verify", false, "skip server certificate verification")
 	rootCmd.PersistentFlags().StringVar(&globalFlags.TLS.CertFile, "cert", "", "identify secure client using this TLS certificate file")
 	rootCmd.PersistentFlags().StringVar(&globalFlags.TLS.KeyFile, "key", "", "identify secure client using this TLS key file")
 	rootCmd.PersistentFlags().StringVar(&globalFlags.TLS.CAFile, "cacert", "", "verify certificates of TLS-enabled secure servers using this CA bundle")
 	rootCmd.PersistentFlags().StringVar(&globalFlags.User, "user", "", "username[:password] for authentication (prompt if password is not supplied)")
+	rootCmd.PersistentFlags().StringVarP(&globalFlags.TLS.ServerName, "discovery-srv", "d", "", "domain name to query for SRV records describing cluster endpoints")
 
 	rootCmd.AddCommand(
 		command.NewGetCommand(),