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  }