Skip to content

Commit

Permalink
etcdctl: add serverName to secureCfg
Browse files Browse the repository at this point in the history
  • Loading branch information
jiaxuanzhou committed Aug 31, 2017
1 parent adbf107 commit bc91b6f
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 17 deletions.
112 changes: 96 additions & 16 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,10 +54,11 @@ type GlobalFlags struct {
}

type secureCfg struct {
cert string
key string
cacert string
serverName 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 @@ -194,15 +203,20 @@ func dialTimeoutFromCmd(cmd *cobra.Command) time.Duration {
}

func secureCfgFromCmd(cmd *cobra.Command) *secureCfg {
cert, key, cacert, serverName := keyAndCertFromCmd(cmd)
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,
serverName: serverName,
serverName: discoveryCfg.domain,

insecureTransport: insecureTr,
insecureSkipVerify: skipVerify,
Expand All @@ -225,7 +239,7 @@ func insecureSkipVerifyFromCmd(cmd *cobra.Command) bool {
return skipVerify
}

func keyAndCertFromCmd(cmd *cobra.Command) (cert, key, cacert, serverName string) {
func keyAndCertFromCmd(cmd *cobra.Command) (cert, key, cacert string) {
var err error
if cert, err = cmd.Flags().GetString("cert"); err != nil {
ExitWithError(ExitBadArgs, err)
Expand All @@ -245,14 +259,7 @@ func keyAndCertFromCmd(cmd *cobra.Command) (cert, key, cacert, serverName string
ExitWithError(ExitBadArgs, errors.New("empty string is passed to --cacert option"))
}

// TODO: reconstruct the duplicated code
if serverName, err = cmd.Flags().GetString("discovery-srv"); err != nil {
ExitWithError(ExitBadArgs, err)
} else if serverName == "" && cmd.Flags().Changed("discovery-srv") {
ExitWithError(ExitBadArgs, errors.New("empty string is passed to --discovery-srv option"))
}

return cert, key, cacert, serverName
return cert, key, cacert
}

func authCfgFromCmd(cmd *cobra.Command) *authCfg {
Expand Down Expand Up @@ -281,3 +288,76 @@ 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 discoveryCfgFromCmd(cmd *cobra.Command) *discoveryCfg {
var err error
var domainStr string
if domainStr, err = cmd.Flags().GetString("discovery-srv"); err != nil {
ExitWithError(ExitBadArgs, err)
} else if domainStr == "" && cmd.Flags().Changed("discovery-srv") {
ExitWithError(ExitBadArgs, errors.New("empty string is passed to --discovery-srv option"))
}

cfg := discoveryCfg{
domain: domainStr,
insecure: insecureDiscoveryFromCmd(cmd),
}
return &cfg
}

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 discoverer(domain string) ([]string, error) {
srvs, err := srv.GetClient("etcd-client", domain)
if err != nil {
return nil, err
}
return srvs.Endpoints, nil
}

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
}

eps, err := discoverer(discoveryCfg.domain)
if err != nil {
return nil, err
}
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
}
3 changes: 2 additions & 1 deletion etcdctl/ctlv3/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +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().StringVar(&globalFlags.TLS.ServerName, "discovery-srv", "", "domain name to query for SRV records describing cluster endpoints")
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

0 comments on commit bc91b6f

Please sign in to comment.