github.com/didip/deis@v1.4.1/deisctl/config/etcd.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "net" 6 "net/http" 7 "strings" 8 "time" 9 10 "github.com/coreos/fleet/pkg" 11 "github.com/coreos/fleet/ssh" 12 "github.com/coreos/go-etcd/etcd" 13 "github.com/deis/deis/deisctl/backend/fleet" 14 ) 15 16 func getTunnelFlag() string { 17 tun := fleet.Flags.Tunnel 18 if tun != "" && !strings.Contains(tun, ":") { 19 tun += ":22" 20 } 21 return tun 22 } 23 24 func getChecker() *ssh.HostKeyChecker { 25 if !fleet.Flags.StrictHostKeyChecking { 26 return nil 27 } 28 keyFile := ssh.NewHostKeyFile(fleet.Flags.KnownHostsFile) 29 return ssh.NewHostKeyChecker(keyFile) 30 } 31 32 type etcdClient struct { 33 etcd *etcd.Client 34 } 35 36 func (c *etcdClient) Get(key string) (string, error) { 37 sort, recursive := true, false 38 resp, err := c.etcd.Get(key, sort, recursive) 39 if err != nil { 40 return "", err 41 } 42 return resp.Node.Value, nil 43 } 44 45 func (c *etcdClient) Set(key string, value string) (string, error) { 46 resp, err := c.etcd.Set(key, value, 0) // don't use TTLs 47 if err != nil { 48 return "", err 49 } 50 return resp.Node.Value, nil 51 } 52 53 func getEtcdClient() (*etcdClient, error) { 54 var dial func(string, string) (net.Conn, error) 55 sshTimeout := time.Duration(fleet.Flags.SSHTimeout*1000) * time.Millisecond 56 tun := getTunnelFlag() 57 if tun != "" { 58 sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false, sshTimeout) 59 if err != nil { 60 return nil, fmt.Errorf("failed initializing SSH client: %v", err) 61 } 62 63 dial = func(network, addr string) (net.Conn, error) { 64 tcpaddr, err := net.ResolveTCPAddr(network, addr) 65 if err != nil { 66 return nil, err 67 } 68 return sshClient.DialTCP(network, nil, tcpaddr) 69 } 70 } 71 72 tlsConfig, err := pkg.ReadTLSConfigFiles(fleet.Flags.EtcdCAFile, 73 fleet.Flags.EtcdCertFile, fleet.Flags.EtcdKeyFile) 74 if err != nil { 75 return nil, err 76 } 77 78 trans := http.Transport{ 79 Dial: dial, 80 TLSClientConfig: tlsConfig, 81 } 82 83 timeout := time.Duration(fleet.Flags.RequestTimeout*1000) * time.Millisecond 84 machines := []string{fleet.Flags.Endpoint} 85 86 c := etcd.NewClient(machines) 87 c.SetDialTimeout(timeout) 88 89 // use custom transport with SSH tunnel capability 90 c.SetTransport(&trans) 91 92 return &etcdClient{etcd: c}, nil 93 }