Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

etcdctl: add discovery-srv global flag for v3 #8462

Merged
merged 1 commit into from
Sep 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 90 additions & 7 deletions etcdctl/ctlv3/command/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package command
import (
"crypto/tls"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
Expand All @@ -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"
)
Expand All @@ -36,6 +38,7 @@ import (
type GlobalFlags struct {
Insecure bool
InsecureSkipVerify bool
InsecureDiscovery bool
Endpoints []string
DialTimeout time.Duration
CommandTimeOut time.Duration
Expand All @@ -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
Expand All @@ -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) {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 changes: 2 additions & 0 deletions etcdctl/ctlv3/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down