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  }