Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Etcd DNS discovery #2521

Merged
merged 2 commits into from
Apr 4, 2017
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
48 changes: 48 additions & 0 deletions physical/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package physical
import (
"context"
"errors"
"fmt"
"net/url"
"os"
"strings"

"github.com/coreos/etcd/client"
"github.com/coreos/go-semver/semver"
Expand All @@ -13,6 +16,7 @@ import (
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")
EtcdMultipleBootstrapError = errors.New("client setup failed: multiple discovery or bootstrap flags specified, use either \"address\" or \"discovery_srv\"")
EtcdAddressError = errors.New("client setup failed: address must be valid URL (ex. 'scheme://host:port')")
EtcdSemaphoreKeysEmptyError = errors.New("lock queue is empty")
EtcdLockHeldError = errors.New("lock already held")
Expand Down Expand Up @@ -95,3 +99,47 @@ func getEtcdAPIVersion(c client.Client) (string, error) {

return "3", nil
}

// Retrieves the config option in order of priority:
// 1. The named environment variable if it exist
// 2. The key in the config map
func getEtcdOption(conf map[string]string, confKey, envVar string) (string, bool) {
confVal, inConf := conf[confKey]
envVal, inEnv := os.LookupEnv(envVar)
if inEnv {
return envVal, true
}
return confVal, inConf
}

func getEtcdEndpoints(conf map[string]string) ([]string, error) {
address, staticBootstrap := getEtcdOption(conf, "address", "ETCD_ADDR")
domain, useSrv := getEtcdOption(conf, "discovery_srv", "ETCD_DISCOVERY_SRV")
if useSrv && staticBootstrap {
return nil, EtcdMultipleBootstrapError
}

if staticBootstrap {
endpoints := strings.Split(address, Etcd2MachineDelimiter)
// Verify that the machines are valid URLs
for _, e := range endpoints {
u, urlErr := url.Parse(e)
if urlErr != nil || u.Scheme == "" {
return nil, EtcdAddressError
}
}
return endpoints, nil
}

if useSrv {
discoverer := client.NewSRVDiscover()
endpoints, err := discoverer.Discover(domain)
if err != nil {
return nil, fmt.Errorf("failed to discover etcd endpoints through SRV discovery: %v", err)
}
return endpoints, nil
}

// Set a default endpoints list if no option was set
return []string{"http://127.0.0.1:2379"}, nil
}
23 changes: 4 additions & 19 deletions physical/etcd2.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/base64"
"fmt"
"net/url"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -118,23 +117,9 @@ func newEtcd2Backend(conf map[string]string, logger log.Logger) (Backend, error)
}

func newEtcdV2Client(conf map[string]string) (client.Client, error) {
// Set a default machines list and check for an overriding address value.
machines := "http://127.0.0.1:2379"
if address, ok := conf["address"]; ok {
machines = address
}
machinesEnv := os.Getenv("ETCD_ADDR")
if machinesEnv != "" {
machines = machinesEnv
}
machinesParsed := strings.Split(machines, Etcd2MachineDelimiter)

// Verify that the machines are valid URLs
for _, machine := range machinesParsed {
u, urlErr := url.Parse(machine)
if urlErr != nil || u.Scheme == "" {
return nil, EtcdAddressError
}
endpoints, err := getEtcdEndpoints(conf)
if err != nil {
return nil, err
}

// Create a new client from the supplied address and attempt to sync with the
Expand All @@ -160,7 +145,7 @@ func newEtcdV2Client(conf map[string]string) (client.Client, error) {
}

cfg := client.Config{
Endpoints: machinesParsed,
Endpoints: endpoints,
Transport: cTransport,
}

Expand Down
7 changes: 3 additions & 4 deletions physical/etcd3.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ func newEtcd3Backend(conf map[string]string, logger log.Logger) (Backend, error)
path = "/" + path
}

// Set a default machines list and check for an overriding address value.
endpoints := []string{"http://127.0.0.1:2379"}
if address, ok := conf["address"]; ok {
endpoints = strings.Split(address, ",")
endpoints, err := getEtcdEndpoints(conf)
if err != nil {
return nil, err
}

cfg := clientv3.Config{
Expand Down
19 changes: 18 additions & 1 deletion website/source/docs/configuration/storage/etcd.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ storage "etcd" {
Etcd instances as a comma-separated list. This can also be provided via the
environment variable `ETCD_ADDR`.

- `discovery_srv` `(string: "example.com")` - Specifies the domain name to
query for SRV records describing cluster endpoints. This can also be provided
via the environment variable `ETCD_DISCOVERY_SRV`.

- `etcd_api` `(string: "<varies>")` – Specifies the version of the API to
communicate with. By default, this is derived automatically. If the cluster
version is 3.1+ and there has been no data written using the v2 API, the
Expand Down Expand Up @@ -89,6 +93,18 @@ discussed in more detail in the [HA concepts page](/docs/concepts/ha.html).

## `etcd` Examples

### DNS Discovery of cluster members

This example configures vault to discover the Etcd cluster members via SRV
records as outlined in the
[DNS Discovery protocol documentation][dns discovery].

```hcl
storage "etcd" {
discovery_srv = "example.com"
}
```

### Custom Authentication

This example shows connecting to the Etcd cluster using a username and password.
Expand All @@ -100,7 +116,7 @@ storage "etcd" {
}
```

### Custon Path
### Custom Path

This example shows storing data in a custom path.

Expand All @@ -122,3 +138,4 @@ storage "etcd" {
```

[etcd]: https://coreos.com/etcd "Etcd by CoreOS"
[dns discovery]: https://coreos.com/etcd/docs/latest/op-guide/clustering.html#dns-discovery "Etcd cluster DNS Discovery"