Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

Commit

Permalink
feat(config): first pass at config subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Monroy committed Aug 28, 2014
1 parent c182966 commit 6d541aa
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 0 deletions.
8 changes: 8 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strconv"

"github.com/deis/deisctl/client"
"github.com/deis/deisctl/config"
"github.com/deis/deisctl/constant"
"github.com/deis/deisctl/update"
"github.com/deis/deisctl/utils"
Expand Down Expand Up @@ -227,6 +228,13 @@ func splitScaleTarget(target string) (c string, num int, err error) {
return
}

func Config() error {
if err := config.Config(); err != nil {
return err
}
return nil
}

func Update() error {
if err := utils.Execute(constant.HooksDir + "pre-update"); err != nil {
fmt.Println("pre-updatehook failed")
Expand Down
7 changes: 7 additions & 0 deletions config/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package config

// Client interface used for configuration
type Client interface {
Get(string) (string, error)
Set(string) (string, error)
}
92 changes: 92 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package config

import (
"fmt"
"strings"

docopt "github.com/docopt/docopt-go"
)

// Config runs the config subcommand
func Config() error {
usage := `Deis Cluster Configuration
Usage:
deisctl config <target> get [<key>...] [options]
deisctl config <target> set <key=val>... [options]
Options:
--verbose print out the request bodies [default: false]
`
// parse command-line arguments
args, err := docopt.Parse(usage, nil, true, "", true)
if err != nil {
return err
}
err = setConfigFlags(args)
if err != nil {
return err
}
return doConfig(args)
}

// Flags for config package
var Flags struct {
}

func setConfigFlags(args map[string]interface{}) error {
return nil
}

func doConfig(args map[string]interface{}) error {
client, err := getEtcdClient()
if err != nil {
return err
}

rootPath := "/deis/" + args["<target>"].(string) + "/"

var vals []string
if args["set"] == true {
vals, err = doConfigSet(client, rootPath, args["<key=val>"].([]string))
} else {
vals, err = doConfigGet(client, rootPath, args["<key>"].([]string))
}
if err != nil {
return err
}

// print results
for _, v := range vals {
fmt.Printf("%v\n", v)
}
return nil
}

func doConfigSet(client *etcdClient, root string, kvs []string) ([]string, error) {
var result []string
for _, kv := range kvs {
split := strings.Split(kv, "=")
if len(split) != 2 {
return result, fmt.Errorf("invalid argument: %v", kv)
}
val, err := client.Set(root+split[0], split[1])
if err != nil {
return result, err
}
result = append(result, val)
}
return result, nil
}

func doConfigGet(client *etcdClient, root string, keys []string) ([]string, error) {
var result []string
for _, k := range keys {
val, err := client.Get(root + k)
if err != nil {
return result, err
}
result = append(result, val)
}
return result, nil
}
92 changes: 92 additions & 0 deletions config/etcd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package config

import (
"fmt"
"net"
"net/http"
"strings"
"time"

fleetEtcd "github.com/coreos/fleet/etcd"
"github.com/coreos/fleet/ssh"
"github.com/coreos/go-etcd/etcd"
"github.com/deis/deisctl/client"
)

func getTunnelFlag() string {
tun := client.Flags.Tunnel
if tun != "" && !strings.Contains(tun, ":") {
tun += ":22"
}
return tun
}

func getChecker() *ssh.HostKeyChecker {
if !client.Flags.StrictHostKeyChecking {
return nil
}
keyFile := ssh.NewHostKeyFile(client.Flags.KnownHostsFile)
return ssh.NewHostKeyChecker(keyFile)
}

type etcdClient struct {
etcd *etcd.Client
}

func (c *etcdClient) Get(key string) (string, error) {
sort, recursive := true, false
resp, err := c.etcd.Get(key, sort, recursive)
if err != nil {
return "", err
}
return resp.Node.Value, nil
}

func (c *etcdClient) Set(key string, value string) (string, error) {
resp, err := c.etcd.Set(key, value, 0) // don't use TTLs
if err != nil {
return "", err
}
return resp.Node.Value, nil
}

func getEtcdClient() (*etcdClient, error) {
var dial func(string, string) (net.Conn, error)
tun := getTunnelFlag()
if tun != "" {
sshClient, err := ssh.NewSSHClient("core", tun, getChecker(), false)
if err != nil {
return nil, fmt.Errorf("failed initializing SSH client: %v", err)
}

dial = func(network, addr string) (net.Conn, error) {
tcpaddr, err := net.ResolveTCPAddr(network, addr)
if err != nil {
return nil, err
}
return sshClient.DialTCP(network, nil, tcpaddr)
}
}

tlsConfig, err := fleetEtcd.ReadTLSConfigFiles(client.Flags.EtcdCAFile,
client.Flags.EtcdCertFile, client.Flags.EtcdKeyFile)
if err != nil {
return nil, err
}

trans := http.Transport{
Dial: dial,
TLSClientConfig: tlsConfig,
}

timeout := time.Duration(client.Flags.RequestTimeout*1000) * time.Millisecond
machines := []string{client.Flags.Endpoint}

c := etcd.NewClient(machines)
c.SetDialTimeout(timeout)

// use custom transport with SSH tunnel capability
c.SetTransport(&trans)

return &etcdClient{etcd: c}, nil
}
2 changes: 2 additions & 0 deletions deisctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ Options:
err = cmd.Install(c, targets)
case "uninstall":
err = cmd.Uninstall(c, targets)
case "config":
err = cmd.Config()
case "update":
err = cmd.Update()
default:
Expand Down

0 comments on commit 6d541aa

Please sign in to comment.