parent
9ec414016d
commit
a4ceaf0035
|
@ -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"
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
@ -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
|
||||
|
@ -160,7 +145,7 @@ func newEtcdV2Client(conf map[string]string) (client.Client, error) {
|
|||
}
|
||||
|
||||
cfg := client.Config{
|
||||
Endpoints: machinesParsed,
|
||||
Endpoints: endpoints,
|
||||
Transport: cTransport,
|
||||
}
|
||||
|
||||
|
|
|
@ -48,10 +48,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{
|
||||
|
|
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue