clusterlint/checks/registry.go

131 lines
2.9 KiB
Go

/*
Copyright 2019 DigitalOcean
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package checks
import (
"errors"
"fmt"
"sync"
)
type checkRegistry struct {
mu sync.RWMutex
checks map[string]Check
groups map[string][]Check
}
var (
registry *checkRegistry
initOnce sync.Once
)
// Register registers a check. This should be called from each check
// implementation's init().
func Register(check Check) error {
initOnce.Do(func() {
registry = &checkRegistry{
checks: make(map[string]Check),
groups: make(map[string][]Check),
}
})
registry.mu.Lock()
defer registry.mu.Unlock()
name := check.Name()
if name == "" {
return errors.New("checks must have non-empty names")
}
if _, ok := registry.checks[name]; ok {
return fmt.Errorf("check named %q already exists", name)
}
registry.checks[name] = check
for _, group := range check.Groups() {
registry.groups[group] = append(registry.groups[group], check)
}
return nil
}
// List returns all the registered checks.
func List() []Check {
registry.mu.RLock()
defer registry.mu.RUnlock()
ret := make([]Check, 0, len(registry.checks))
for _, check := range registry.checks {
ret = append(ret, check)
}
return ret
}
// ListGroups returns the names of all registered check groups.
func ListGroups() []string {
registry.mu.RLock()
defer registry.mu.RUnlock()
ret := make([]string, 0, len(registry.groups))
for group := range registry.groups {
ret = append(ret, group)
}
return ret
}
// GetGroup returns the checks in a particular group.
func GetGroup(name string) []Check {
registry.mu.RLock()
defer registry.mu.RUnlock()
ret := make([]Check, 0, len(registry.groups[name]))
for _, check := range registry.groups[name] {
ret = append(ret, check)
}
return ret
}
// GetGroups returns checks that belong to any of the specified group.
func GetGroups(groups []string) ([]Check, error) {
registry.mu.RLock()
defer registry.mu.RUnlock()
var ret []Check
for _, group := range groups {
if checks, ok := registry.groups[group]; ok {
ret = append(ret, checks...)
} else {
return nil, fmt.Errorf("Group %s not found", group)
}
}
return ret, nil
}
// Get retrieves the specified check from the registry,
// throws an error if not found
func Get(name string) (Check, error) {
registry.mu.RLock()
defer registry.mu.RUnlock()
if registry.checks[name] != nil {
return registry.checks[name], nil
}
return nil, fmt.Errorf("Check not found: %s", name)
}