-
Notifications
You must be signed in to change notification settings - Fork 784
/
datacenters.go
75 lines (61 loc) · 2.11 KB
/
datacenters.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package dependency
import (
"fmt"
"log"
"sort"
"time"
"github.com/hashicorp/consul/api"
)
var sleepTime = 15 * time.Second
// Datacenters is the dependency to query all datacenters
type Datacenters struct {
rawKey string
}
// Fetch queries the Consul API defined by the given client and returns a slice
// of strings representing the datacenters
func (d *Datacenters) Fetch(client *api.Client, options *api.QueryOptions) (interface{}, *api.QueryMeta, error) {
log.Printf("[DEBUG] (%s) querying Consul with %+v", d.Display(), options)
// This is pretty ghetto, but the datacenters endpoint does not support
// blocking queries, so we are going to "fake it until we make it". When we
// first query, the LastIndex will be "0", meaning we should immediately
// return data, but future calls will include a LastIndex. If we have a
// LastIndex in the query metadata, sleep for 15 seconds before asking Consul
// again.
//
// This is probably okay given the frequency in which datacenters actually
// change, but is technically not edge-triggering.
if options.WaitIndex != 0 {
log.Printf("[DEBUG] (%s) pretending to long-poll", d.Display())
time.Sleep(sleepTime)
}
catalog := client.Catalog()
result, err := catalog.Datacenters()
if err != nil {
return nil, nil, err
}
log.Printf("[DEBUG] (%s) Consul returned %d datacenters", d.Display(), len(result))
sort.Strings(result)
qm := &api.QueryMeta{LastIndex: uint64(time.Now().Unix())}
return result, qm, nil
}
// HashCode returns the hash code for this dependency.
func (d *Datacenters) HashCode() string {
return fmt.Sprintf("Datacenters|%s", d.rawKey)
}
// Display returns a string that should be displayed to the user in output (for
// example).
func (d *Datacenters) Display() string {
if d.rawKey == "" {
return fmt.Sprintf(`"datacenters"`)
}
return fmt.Sprintf(`"datacenters(%s)"`, d.rawKey)
}
// ParseDatacenters creates a new datacenter dependency.
func ParseDatacenters(s ...string) (*Datacenters, error) {
switch len(s) {
case 0:
return &Datacenters{rawKey: ""}, nil
default:
return nil, fmt.Errorf("expected 0 arguments, got %d", len(s))
}
}