Skip to content

Commit

Permalink
move the newClientCfg into clientv3 package so as to be reused by bot…
Browse files Browse the repository at this point in the history
…h etcdctl and v3discovery
  • Loading branch information
ahrtr committed Mar 18, 2022
1 parent c633e39 commit 54dd8cd
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 111 deletions.
54 changes: 54 additions & 0 deletions client/v3/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package clientv3
import (
"context"
"crypto/tls"
"go.etcd.io/etcd/client/pkg/v3/transport"
"time"

"go.uber.org/zap"
Expand Down Expand Up @@ -118,3 +119,56 @@ type AuthConfig struct {
Username string `json:"username"`
Password string `json:"password"`
}

// NewClientConfig creates a Config based on the provided ConfigSpec.
func NewClientConfig(confSpec *ConfigSpec, lg *zap.Logger) (*Config, error) {
var cfgtls *transport.TLSInfo

if confSpec.Secure != nil {
scfg := confSpec.Secure
if scfg.Cert != "" || scfg.Key != "" || scfg.Cacert != "" || scfg.ServerName != "" {
cfgtls = &transport.TLSInfo{
CertFile: scfg.Cert,
KeyFile: scfg.Key,
TrustedCAFile: scfg.Cacert,
ServerName: scfg.ServerName,
Logger: lg,
}
}
}

cfg := &Config{
Endpoints: confSpec.Endpoints,
DialTimeout: confSpec.DialTimeout,
DialKeepAliveTime: confSpec.KeepAliveTime,
DialKeepAliveTimeout: confSpec.KeepAliveTimeout,
}

if cfgtls != nil {
if clientTLS, err := cfgtls.ClientConfig(); err == nil {
cfg.TLS = clientTLS
} else {
return nil, err
}
}

// If key/cert is not given but user wants secure connection, we
// should still setup an empty tls configuration for gRPC to setup
// secure connection.
if cfg.TLS == nil && !confSpec.Secure.InsecureTransport {
cfg.TLS = &tls.Config{}
}

// If the user wants to skip TLS verification then we should set
// the InsecureSkipVerify flag in tls configuration.
if cfg.TLS != nil && confSpec.Secure.InsecureSkipVerify {
cfg.TLS.InsecureSkipVerify = true
}

if confSpec.Auth != nil {
cfg.Username = confSpec.Auth.Username
cfg.Password = confSpec.Auth.Password
}

return cfg, nil
}
75 changes: 14 additions & 61 deletions etcdctl/ctlv3/command/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package command

import (
"crypto/tls"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -138,7 +137,8 @@ func clientConfigFromCmd(cmd *cobra.Command) *clientv3.ConfigSpec {

func mustClientCfgFromCmd(cmd *cobra.Command) *clientv3.Config {
cc := clientConfigFromCmd(cmd)
cfg, err := newClientCfg(cc.Endpoints, cc.DialTimeout, cc.KeepAliveTime, cc.KeepAliveTimeout, cc.Secure, cc.Auth)
lg, _ := zap.NewProduction()
cfg, err := clientv3.NewClientConfig(cc, lg)
if err != nil {
cobrautl.ExitWithError(cobrautl.ExitBadArgs, err)
}
Expand All @@ -151,7 +151,8 @@ func mustClientFromCmd(cmd *cobra.Command) *clientv3.Client {
}

func mustClient(cc *clientv3.ConfigSpec) *clientv3.Client {
cfg, err := newClientCfg(cc.Endpoints, cc.DialTimeout, cc.KeepAliveTime, cc.KeepAliveTimeout, cc.Secure, cc.Auth)
lg, _ := zap.NewProduction()
cfg, err := clientv3.NewClientConfig(cc, lg)
if err != nil {
cobrautl.ExitWithError(cobrautl.ExitBadArgs, err)
}
Expand All @@ -165,64 +166,16 @@ func mustClient(cc *clientv3.ConfigSpec) *clientv3.Client {
}

func newClientCfg(endpoints []string, dialTimeout, keepAliveTime, keepAliveTimeout time.Duration, scfg *clientv3.SecureConfig, acfg *clientv3.AuthConfig) (*clientv3.Config, error) {
// set tls if any one tls option set
var cfgtls *transport.TLSInfo
tlsinfo := transport.TLSInfo{}
tlsinfo.Logger, _ = zap.NewProduction()
if scfg.Cert != "" {
tlsinfo.CertFile = scfg.Cert
cfgtls = &tlsinfo
}

if scfg.Key != "" {
tlsinfo.KeyFile = scfg.Key
cfgtls = &tlsinfo
}

if scfg.Cacert != "" {
tlsinfo.TrustedCAFile = scfg.Cacert
cfgtls = &tlsinfo
}

if scfg.ServerName != "" {
tlsinfo.ServerName = scfg.ServerName
cfgtls = &tlsinfo
}

cfg := &clientv3.Config{
Endpoints: endpoints,
DialTimeout: dialTimeout,
DialKeepAliveTime: keepAliveTime,
DialKeepAliveTimeout: keepAliveTimeout,
}

if cfgtls != nil {
clientTLS, err := cfgtls.ClientConfig()
if err != nil {
return nil, err
}
cfg.TLS = clientTLS
}

// if key/cert is not given but user wants secure connection, we
// should still setup an empty tls configuration for gRPC to setup
// secure connection.
if cfg.TLS == nil && !scfg.InsecureTransport {
cfg.TLS = &tls.Config{}
}

// If the user wants to skip TLS verification then we should set
// the InsecureSkipVerify flag in tls configuration.
if scfg.InsecureSkipVerify && cfg.TLS != nil {
cfg.TLS.InsecureSkipVerify = true
}

if acfg != nil {
cfg.Username = acfg.Username
cfg.Password = acfg.Password
}

return cfg, nil
lg, _ := zap.NewProduction()
confSpec := &clientv3.ConfigSpec{
Endpoints: endpoints,
DialTimeout: dialTimeout,
KeepAliveTime: keepAliveTime,
KeepAliveTimeout: keepAliveTimeout,
Secure: scfg,
Auth: acfg,
}
return clientv3.NewClientConfig(confSpec, lg)
}

func argOrStdin(args []string, stdin io.Reader, i int) (string, error) {
Expand Down
51 changes: 1 addition & 50 deletions server/etcdserver/api/v3discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package v3discovery

import (
"context"
"crypto/tls"
"errors"

"math"
Expand All @@ -28,7 +27,6 @@ import (
"strings"
"time"

"go.etcd.io/etcd/client/pkg/v3/transport"
"go.etcd.io/etcd/client/pkg/v3/types"
"go.etcd.io/etcd/client/v3"

Expand Down Expand Up @@ -173,7 +171,7 @@ func newDiscovery(lg *zap.Logger, dcfg *DiscoveryConfig, id types.ID) (*discover
}

lg = lg.With(zap.String("discovery-token", dcfg.Token), zap.String("discovery-endpoints", strings.Join(dcfg.Endpoints, ",")))
cfg, err := newClientCfg(dcfg, lg)
cfg, err := clientv3.NewClientConfig(&dcfg.ConfigSpec, lg)
if err != nil {
return nil, err
}
Expand All @@ -192,53 +190,6 @@ func newDiscovery(lg *zap.Logger, dcfg *DiscoveryConfig, id types.ID) (*discover
}, nil
}

// The following function follows the same logic as etcdctl, refer to
// https://github.com/etcd-io/etcd/blob/f9a8c49c695b098d66a07948666664ea10d01a82/etcdctl/ctlv3/command/global.go#L191-L250
func newClientCfg(dcfg *DiscoveryConfig, lg *zap.Logger) (*clientv3.Config, error) {
var cfgtls *transport.TLSInfo

if dcfg.Secure.Cert != "" || dcfg.Secure.Key != "" || dcfg.Secure.Cacert != "" {
cfgtls = &transport.TLSInfo{
CertFile: dcfg.Secure.Cert,
KeyFile: dcfg.Secure.Key,
TrustedCAFile: dcfg.Secure.Cacert,
Logger: lg,
}
}

cfg := &clientv3.Config{
Endpoints: dcfg.Endpoints,
DialTimeout: dcfg.DialTimeout,
DialKeepAliveTime: dcfg.KeepAliveTime,
DialKeepAliveTimeout: dcfg.KeepAliveTimeout,
Username: dcfg.Auth.Username,
Password: dcfg.Auth.Password,
}

if cfgtls != nil {
if clientTLS, err := cfgtls.ClientConfig(); err == nil {
cfg.TLS = clientTLS
} else {
return nil, err
}
}

// If key/cert is not given but user wants secure connection, we
// should still setup an empty tls configuration for gRPC to setup
// secure connection.
if cfg.TLS == nil && !dcfg.Secure.InsecureTransport {
cfg.TLS = &tls.Config{}
}

// If the user wants to skip TLS verification then we should set
// the InsecureSkipVerify flag in tls configuration.
if cfg.TLS != nil && dcfg.Secure.InsecureSkipVerify {
cfg.TLS.InsecureSkipVerify = true
}

return cfg, nil
}

func (d *discovery) getCluster() (string, error) {
cls, clusterSize, rev, err := d.checkCluster()
if err != nil {
Expand Down

0 comments on commit 54dd8cd

Please sign in to comment.