package etcd_tools import ( "crypto/tls" "crypto/x509" "errors" "log" "time" etcd "go.etcd.io/etcd/clientv3" ) type EasyConfig struct { Endpoints []string RootCACert string ClientCert string ClientKey string } func (c EasyConfig) prepare() (etcd.Config, error) { log.Println("enter prepare() for EasyConfig") log.Printf("clientCert is '%s'", c.ClientCert) cert, err := tls.X509KeyPair([]byte(c.ClientCert), []byte(c.ClientKey)) if err != nil { log.Println("error building keypair") return etcd.Config{}, err } pool := x509.NewCertPool() if !pool.AppendCertsFromPEM([]byte(c.RootCACert)) { return etcd.Config{}, errors.New("Could not append root CA.") } tc := &tls.Config{} tc.Certificates = make([]tls.Certificate, 1) tc.Certificates[0] = cert tc.RootCAs = pool tc.ClientCAs = pool tc.ClientAuth = tls.RequireAndVerifyClientCert if len(c.Endpoints) == 0 { return etcd.Config{}, errors.New("No endpoints specified.") } conn, err := tls.Dial("tcp", c.Endpoints[0], tc) if err != nil { log.Printf("can't connect to %s:%s", c.Endpoints[0], err) return etcd.Config{}, err } defer conn.Close() err = conn.Handshake() if err != nil { log.Printf("failed tls handshake with %s:%s", c.Endpoints[0], err) return etcd.Config{}, err } r := etcd.Config{} r.Endpoints = c.Endpoints r.DialTimeout = 5 * time.Second r.TLS = tc return r, nil }