etcd: Allow disabling sync for load balanced etcd

Some etcd configurations (such as that provided by compose.io) place the
etcd cluster behind multiple load balancers or proxies.  In this
configuration, calling Sync (or AutoSync) on the etcd client will
replace the load balancer addresses with the underlying etcd server
address.

This will cause the etcd client to bypass the load balancers, and may
cause the connection to fail completely if the etcd servers are
protected by a firewall.

This patch provides a "sync" option for the etcd backend, which defaults
to the current behavior, but which can be used to turn off of sync.
This corresponds to etcdctl's --no-sync option.
This commit is contained in:
Eric Kidd 2016-01-11 13:56:58 -05:00
parent ebabcd857a
commit 69434fd13e
2 changed files with 27 additions and 5 deletions

View File

@ -6,6 +6,7 @@ import (
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
@ -43,6 +44,7 @@ const (
)
var (
EtcdSyncConfigError = errors.New("client setup failed: unable to parse etcd sync field in config")
EtcdSyncClusterError = errors.New("client setup failed: unable to sync etcd cluster")
EtcdAddressError = errors.New("client setup failed: address must be valid URL (ex. 'scheme://host:port')")
EtcdSemaphoreKeysEmptyError = errors.New("lock queue is empty")
@ -143,11 +145,25 @@ func newEtcdBackend(conf map[string]string) (Backend, error) {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
syncErr := c.Sync(ctx)
cancel()
if syncErr != nil {
return nil, EtcdSyncClusterError
// Should we sync the cluster state? There are three available options
// for our client library: don't sync (required for some proxies), sync
// once, or sync periodically with AutoSync. We currently support the
// first two.
sync := true
if v, ok := conf["sync"]; ok {
parsed, err := strconv.ParseBool(v)
if err != nil {
return nil, EtcdSyncConfigError
}
sync = parsed
}
if sync {
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
syncErr := c.Sync(ctx)
cancel()
if syncErr != nil {
return nil, EtcdSyncClusterError
}
}
kAPI := client.NewKeysAPI(c)

View File

@ -221,6 +221,12 @@ For etcd, the following options are supported:
Can be comma separated list (protocol://host:port) of many etcd instances.
Defaults to "http://localhost:2379" if not specified.
* `sync` (optional) - Should we synchronize the list of available etcd
servers on startup? This will parse as a boolean value, and can be set
to "0", "no", "false", "1", "yes", or "true". Defaults to true. Set
to false if your etcd cluster is behind a proxy server and syncing
causes Vault to fail.
* `username` (optional) - Username to use when authenticating with the etcd
server. May also be specified via the ETCD_USERNAME environment variable.