open-nomad/command/agent/consul/namespaces_client.go
Seth Hoenig b3ea68948b build: run gofmt on all go source files
Go 1.19 will forecefully format all your doc strings. To get this
out of the way, here is one big commit with all the changes gofmt
wants to make.
2022-08-16 11:14:11 -05:00

90 lines
2.1 KiB
Go

package consul
import (
"sort"
"sync"
"time"
)
const (
// namespaceEnabledCacheTTL is how long to cache the response from Consul
// /v1/agent/self API, which is used to determine whether namespaces are
// available.
namespaceEnabledCacheTTL = 1 * time.Minute
)
// NamespacesClient is a wrapper for the Consul NamespacesAPI, that is used to
// deal with Consul OSS vs Consul Enterprise behavior in listing namespaces.
type NamespacesClient struct {
namespacesAPI NamespaceAPI
agentAPI AgentAPI
lock sync.Mutex
enabled bool // namespaces requires Ent + Namespaces feature
updated time.Time // memoize response for a while
}
// NewNamespacesClient returns a NamespacesClient backed by a NamespaceAPI.
func NewNamespacesClient(namespacesAPI NamespaceAPI, agentAPI AgentAPI) *NamespacesClient {
return &NamespacesClient{
namespacesAPI: namespacesAPI,
agentAPI: agentAPI,
}
}
func stale(updated, now time.Time) bool {
return now.After(updated.Add(namespaceEnabledCacheTTL))
}
func (ns *NamespacesClient) allowable(now time.Time) bool {
ns.lock.Lock()
defer ns.lock.Unlock()
if !stale(ns.updated, now) {
return ns.enabled
}
self, err := ns.agentAPI.Self()
if err != nil {
return ns.enabled
}
sku, ok := SKU(self)
if !ok {
return ns.enabled
}
if sku != "ent" {
ns.enabled = false
ns.updated = now
return ns.enabled
}
ns.enabled = Namespaces(self)
ns.updated = now
return ns.enabled
}
// List returns a list of Consul Namespaces.
//
// TODO(shoenig): return empty string instead of "default" when namespaces are not enabled. (Coming in followup PR).
func (ns *NamespacesClient) List() ([]string, error) {
if !ns.allowable(time.Now()) {
// TODO(shoenig): lets return the empty string instead, that way we do not
// need to normalize at call sites later on
return []string{"default"}, nil
}
namespaces, _, err := ns.namespacesAPI.List(nil)
if err != nil {
return nil, err
}
result := make([]string, 0, len(namespaces))
for _, namespace := range namespaces {
result = append(result, namespace.Name)
}
sort.Strings(result)
return result, nil
}