github.com/wasbazi/deis@v1.7.1-0.20150609203025-5765871615de/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) Delete(key string) error { 46 _, err := c.etcd.Delete(key, false) 47 return err 48 } 49 50 func (c *etcdClient) Set(key string, value string) (string, error) { 51 resp, err := c.etcd.Set(key, value, 0) // don't use TTLs 52 if err != nil { 53 return "", err 54 } 55 return resp.Node.Value, nil 56 } 57 58 func getEtcdClient() (*etcdClient, error) { 59 var dial func(string, string) (net.Conn, error) 60 sshTimeout := time.Duration(fleet.Flags.SSHTimeout*1000) * time.Millisecond 61 tun := getTunnelFlag() 62 if tun != "" { 63 sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false, sshTimeout) 64 if err != nil { 65 return nil, fmt.Errorf("failed initializing SSH client: %v", err) 66 } 67 68 dial = func(network, addr string) (net.Conn, error) { 69 tcpaddr, err := net.ResolveTCPAddr(network, addr) 70 if err != nil { 71 return nil, err 72 } 73 return sshClient.DialTCP(network, nil, tcpaddr) 74 } 75 } 76 77 tlsConfig, err := pkg.ReadTLSConfigFiles(fleet.Flags.EtcdCAFile, 78 fleet.Flags.EtcdCertFile, fleet.Flags.EtcdKeyFile) 79 if err != nil { 80 return nil, err 81 } 82 83 trans := http.Transport{ 84 Dial: dial, 85 TLSClientConfig: tlsConfig, 86 } 87 88 timeout := time.Duration(fleet.Flags.RequestTimeout*1000) * time.Millisecond 89 machines := []string{fleet.Flags.Endpoint} 90 91 c := etcd.NewClient(machines) 92 c.SetDialTimeout(timeout) 93 94 // use custom transport with SSH tunnel capability 95 c.SetTransport(&trans) 96 97 return &etcdClient{etcd: c}, nil 98 }