Browse Source

etcdctl: added domain discovery flag

provided a domain, will look up SRV records for etcd endpoints

Fixes #2636
Mohammad Samman 10 years ago
parent
commit
43437e21f9
3 changed files with 48 additions and 2 deletions
  1. 13 1
      etcdctl/README.md
  2. 34 1
      etcdctl/command/util.go
  3. 1 0
      etcdctl/main.go

+ 13 - 1
etcdctl/README.md

@@ -235,7 +235,8 @@ The following exit codes can be returned from etcdctl:
 
 If your etcd cluster isn't available on `http://127.0.0.1:2379` you can specify
 a `--peers` flag or `ETCDCTL_PEERS` environment variable. You can list one peer,
-or a comma-separated list of peers.
+or a comma-separated list of peers. This option is ignored if the `--discovery-srv`
+option is provided.
 
 ```
 ETCDCTL_PEERS="http://10.0.28.1:4002" etcdctl set my-key to-a-value
@@ -244,6 +245,17 @@ etcdctl --peers http://10.0.28.1:4002 my-key to-a-value
 etcdctl --peers http://10.0.28.1:4002,http://10.0.28.2:4002,http://10.0.28.3:4002 etcdctl set my-key to-a-value
 ```
 
+## DNS Discovery
+
+If you want to discover your etcd cluster through domain SRV records you can specify
+a `--discovery-srv` flag or `ETCDCTL_DISCOVERY_SRV` environment variable. This option takes
+precedence over the `--peers` flag.
+
+```
+ETCDCTL_DISCOVERY_SRV="some-domain" etcdctl set my-key to-a-value
+etcdctl --discovery-srv some-domain set my-key to-a-value
+```
+
 ## Project Details
 
 ### Versioning

+ 34 - 1
etcdctl/command/util.go

@@ -75,8 +75,40 @@ func getPeersFlagValue(c *cli.Context) []string {
 	return strings.Split(peerstr, ",")
 }
 
+func getDomainDiscoveryFlagValue(c *cli.Context) ([]string, error) {
+	domainstr := c.GlobalString("discovery-srv")
+
+	// Use an environment variable if nothing was supplied on the
+	// command line
+	if domainstr == "" {
+		domainstr = os.Getenv("ETCDCTL_DISCOVERY_SRV")
+	}
+
+	// If we still don't have domain discovery, return nothing
+	if domainstr == "" {
+		return []string{}, nil
+	}
+
+	discoverer := client.NewSRVDiscover()
+	eps, err := discoverer.Discover(domainstr)
+	if err != nil {
+		return nil, err
+	}
+
+	return eps, err
+}
+
 func getEndpoints(c *cli.Context) ([]string, error) {
-	eps := getPeersFlagValue(c)
+	eps, err := getDomainDiscoveryFlagValue(c)
+	if err != nil {
+		return nil, err
+	}
+
+	// If domain discovery returns no endpoints, check peer flag
+	if len(eps) == 0 {
+		eps = getPeersFlagValue(c)
+	}
+
 	for i, ep := range eps {
 		u, err := url.Parse(ep)
 		if err != nil {
@@ -89,6 +121,7 @@ func getEndpoints(c *cli.Context) ([]string, error) {
 
 		eps[i] = u.String()
 	}
+
 	return eps, nil
 }
 

+ 1 - 0
etcdctl/main.go

@@ -31,6 +31,7 @@ func main() {
 		cli.BoolFlag{Name: "debug", Usage: "output cURL commands which can be used to reproduce the request"},
 		cli.BoolFlag{Name: "no-sync", Usage: "don't synchronize cluster information before sending request"},
 		cli.StringFlag{Name: "output, o", Value: "simple", Usage: "output response in the given format (`simple`, `extended` or `json`)"},
+		cli.StringFlag{Name: "discovery-srv, D", Usage: "domain name to query for SRV records describing cluster endpoints"},
 		cli.StringFlag{Name: "peers, C", Value: "", Usage: "a comma-delimited list of machine addresses in the cluster (default: \"127.0.0.1:4001,127.0.0.1:2379\")"},
 		cli.StringFlag{Name: "cert-file", Value: "", Usage: "identify HTTPS client using this SSL certificate file"},
 		cli.StringFlag{Name: "key-file", Value: "", Usage: "identify HTTPS client using this SSL key file"},