b3ea68948b
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.
90 lines
2.1 KiB
Go
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
|
|
}
|