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

Add TLS support for libkv #1254

Merged
merged 1 commit into from
Oct 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

132 changes: 132 additions & 0 deletions Godeps/_workspace/src/github.com/docker/docker/pkg/tlsconfig/config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var (
Name: "list",
ShortName: "l",
Usage: "List nodes in a cluster",
Flags: []cli.Flag{flTimeout},
Flags: []cli.Flag{flTimeout, flDiscoveryOpt},
Action: list,
},
{
Expand All @@ -28,14 +28,14 @@ var (
flTLS, flTLSCaCert, flTLSCert, flTLSKey, flTLSVerify,
flHeartBeat,
flEnableCors,
flCluster, flClusterOpt},
flCluster, flDiscoveryOpt, flClusterOpt},
Action: manage,
},
{
Name: "join",
ShortName: "j",
Usage: "join a docker cluster",
Flags: []cli.Flag{flJoinAdvertise, flHeartBeat, flTTL},
Flags: []cli.Flag{flJoinAdvertise, flHeartBeat, flTTL, flDiscoveryOpt},
Action: join,
},
}
Expand Down
2 changes: 1 addition & 1 deletion cli/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func create(c *cli.Context) {
log.Fatalf("the `create` command takes no arguments. See '%s create --help'.", c.App.Name)
}
discovery := &token.Discovery{}
discovery.Initialize("", 0, 0)
discovery.Initialize("", 0, 0, nil)
token, err := discovery.CreateCluster()
if err != nil {
log.Fatal(err)
Expand Down
5 changes: 5 additions & 0 deletions cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ var (
Usage: "cluster driver options",
Value: &cli.StringSlice{},
}
flDiscoveryOpt = cli.StringSliceFlag{
Name: "discovery-opt",
Usage: "discovery options",
Value: &cli.StringSlice{},
}

flLeaderElection = cli.BoolFlag{
Name: "replication",
Expand Down
3 changes: 2 additions & 1 deletion cli/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ func join(c *cli.Context) {
if ttl <= hb {
log.Fatal("--ttl must be strictly superior to the heartbeat value")
}
d, err := discovery.New(dflag, hb, ttl)

d, err := discovery.New(dflag, hb, ttl, getDiscoveryOpt(c))
if err != nil {
log.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func list(c *cli.Context) {
log.Fatalf("invalid --timeout: %v", err)
}

d, err := discovery.New(dflag, timeout, 0)
d, err := discovery.New(dflag, timeout, 0, getDiscoveryOpt(c))
if err != nil {
log.Fatal(err)
}
Expand Down
20 changes: 17 additions & 3 deletions cli/manage.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
"path"
"strings"
"time"

log "github.com/Sirupsen/logrus"
Expand Down Expand Up @@ -97,7 +98,7 @@ func loadTLSConfig(ca, cert, key string, verify bool) (*tls.Config, error) {
}

// Initialize the discovery service.
func createDiscovery(uri string, c *cli.Context) discovery.Discovery {
func createDiscovery(uri string, c *cli.Context, discoveryOpt []string) discovery.Discovery {
hb, err := time.ParseDuration(c.String("heartbeat"))
if err != nil {
log.Fatalf("invalid --heartbeat: %v", err)
Expand All @@ -107,14 +108,27 @@ func createDiscovery(uri string, c *cli.Context) discovery.Discovery {
}

// Set up discovery.
discovery, err := discovery.New(uri, hb, 0)
discovery, err := discovery.New(uri, hb, 0, getDiscoveryOpt(c))
if err != nil {
log.Fatal(err)
}

return discovery
}

func getDiscoveryOpt(c *cli.Context) map[string]string {
// Process the store options
options := map[string]string{}
for _, option := range c.StringSlice("discovery-opt") {
if !strings.Contains(option, "=") {
log.Fatal("--discovery-opt must contain key=value strings")
}
kvpair := strings.SplitN(option, "=", 2)
options[kvpair[0]] = kvpair[1]
}
return options
}

func setupReplication(c *cli.Context, cluster cluster.Cluster, server *api.Server, discovery discovery.Discovery, addr string, leaderTTL time.Duration, tlsConfig *tls.Config) {
kvDiscovery, ok := discovery.(*kvdiscovery.Discovery)
if !ok {
Expand Down Expand Up @@ -222,7 +236,7 @@ func manage(c *cli.Context) {
if uri == "" {
log.Fatalf("discovery required to manage a cluster. See '%s manage --help'.", c.App.Name)
}
discovery := createDiscovery(uri, c)
discovery := createDiscovery(uri, c, c.StringSlice("discovery-opt"))
s, err := strategy.New(c.String("strategy"))
if err != nil {
log.Fatal(err)
Expand Down
8 changes: 4 additions & 4 deletions discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ func (e Entries) Diff(cmp Entries) (Entries, Entries) {
// The Discovery interface is implemented by Discovery backends which
// manage swarm host entries.
type Discovery interface {
// Initialize the discovery with URIs, a heartbeat and a ttl.
Initialize(string, time.Duration, time.Duration) error
// Initialize the discovery with URIs, a heartbeat, a ttl and optional settings.
Initialize(string, time.Duration, time.Duration, map[string]string) error

// Watch the discovery for entry changes.
// Returns a channel that will receive changes or an error.
Expand Down Expand Up @@ -133,12 +133,12 @@ func parse(rawurl string) (string, string) {

// New returns a new Discovery given a URL, heartbeat and ttl settings.
// Returns an error if the URL scheme is not supported.
func New(rawurl string, heartbeat time.Duration, ttl time.Duration) (Discovery, error) {
func New(rawurl string, heartbeat time.Duration, ttl time.Duration, discoveryOpt map[string]string) (Discovery, error) {
scheme, uri := parse(rawurl)

if discovery, exists := discoveries[scheme]; exists {
log.WithFields(log.Fields{"name": scheme, "uri": uri}).Debug("Initializing discovery service")
err := discovery.Initialize(uri, heartbeat, ttl)
err := discovery.Initialize(uri, heartbeat, ttl, discoveryOpt)
return discovery, err
}

Expand Down
2 changes: 1 addition & 1 deletion discovery/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func Init() {
}

// Initialize is exported
func (s *Discovery) Initialize(path string, heartbeat time.Duration, ttl time.Duration) error {
func (s *Discovery) Initialize(path string, heartbeat time.Duration, ttl time.Duration, _ map[string]string) error {
s.path = path
s.heartbeat = heartbeat
return nil
Expand Down
8 changes: 4 additions & 4 deletions discovery/file/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import (

func TestInitialize(t *testing.T) {
d := &Discovery{}
d.Initialize("/path/to/file", 1000, 0)
d.Initialize("/path/to/file", 1000, 0, nil)
assert.Equal(t, d.path, "/path/to/file")
}

func TestNew(t *testing.T) {
d, err := discovery.New("file:///path/to/file", 0, 0)
d, err := discovery.New("file:///path/to/file", 0, 0, nil)
assert.NoError(t, err)
assert.Equal(t, d.(*Discovery).path, "/path/to/file")
}
Expand Down Expand Up @@ -73,15 +73,15 @@ func TestWatch(t *testing.T) {

// Set up file discovery.
d := &Discovery{}
d.Initialize(tmp.Name(), 1000, 0)
d.Initialize(tmp.Name(), 1000, 0, nil)
stopCh := make(chan struct{})
ch, errCh := d.Watch(stopCh)

// Make sure it fires errors since the file doesn't exist.
assert.Error(t, <-errCh)
// We have to drain the error channel otherwise Watch will get stuck.
go func() {
for _ = range errCh {
for range errCh {
}
}()

Expand Down
30 changes: 28 additions & 2 deletions discovery/kv/kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

log "github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/tlsconfig"
"github.com/docker/libkv"
"github.com/docker/libkv/store"
"github.com/docker/libkv/store/consul"
Expand Down Expand Up @@ -47,7 +48,7 @@ func Init() {
}

// Initialize is exported
func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration) error {
func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration, discoveryOpt map[string]string) error {
var (
parts = strings.SplitN(uris, "/", 2)
addrs = strings.Split(parts[0], ",")
Expand All @@ -63,9 +64,34 @@ func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Du
s.ttl = ttl
s.path = path.Join(s.prefix, discoveryPath)

var config *store.Config
if discoveryOpt["kv.cacertfile"] != "" && discoveryOpt["kv.certfile"] != "" && discoveryOpt["kv.keyfile"] != "" {
log.Debug("Initializing discovery with TLS")
tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
CAFile: discoveryOpt["kv.cacertfile"],
CertFile: discoveryOpt["kv.certfile"],
KeyFile: discoveryOpt["kv.keyfile"],
})
if err != nil {
return err
}
config = &store.Config{
// Set ClientTLS to trigger https (bug in libkv/etcd)
ClientTLS: &store.ClientTLSConfig{
CACertFile: discoveryOpt["kv.cacertfile"],
CertFile: discoveryOpt["kv.certfile"],
KeyFile: discoveryOpt["kv.keyfile"],
},
// The actual TLS config that will be used
TLS: tlsConfig,
}
} else {
log.Debug("Initializing discovery without TLS")
}

// Creates a new store, will ignore options given
// if not supported by the chosen store
s.store, err = libkv.NewStore(s.backend, addrs, &store.Config{})
s.store, err = libkv.NewStore(s.backend, addrs, config)
return err
}

Expand Down
Loading