grafana/pkg/setting/provider.go
Arve Knudsen 78596a6756
Migrate to Wire for dependency injection (#32289)
Fixes #30144

Co-authored-by: dsotirakis <sotirakis.dim@gmail.com>
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Ida Furjesova <ida.furjesova@grafana.com>
Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com>
Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: spinillos <selenepinillos@gmail.com>
Co-authored-by: Karl Persson <kalle.persson@grafana.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
2021-08-25 15:11:22 +02:00

163 lines
4.1 KiB
Go

package setting
import (
"errors"
"strings"
"time"
"gopkg.in/ini.v1"
)
var (
ErrOperationNotPermitted = errors.New("operation not permitted")
)
type ValidationError struct {
Errors []error
}
func (v ValidationError) Error() string {
builder := strings.Builder{}
for i, e := range v.Errors {
builder.WriteString(e.Error())
if i != len(v.Errors)-1 {
builder.WriteString(", ")
}
}
return builder.String()
}
// Provider is a settings provider abstraction
// with thread-safety and runtime updates.
type Provider interface {
// Current returns a SettingsBag with a static copy of
// the current configured pairs of key/values for each
// configuration section.
Current() SettingsBag
// Update receives a SettingsBag with the pairs of key/values
// to be updated per section and a SettingsRemovals with the
// section keys to be removed.
Update(updates SettingsBag, removals SettingsRemovals) error
// KeyValue returns a key-value abstraction
// for the given pair of section and key.
KeyValue(section, key string) KeyValue
// Section returns a settings section
// abstraction for the given section name.
Section(section string) Section
// RegisterReloadHandler registers a handler for validation and reload
// of configuration updates tied to a specific section
RegisterReloadHandler(section string, handler ReloadHandler)
}
// Section is a settings section copy
// with all of its pairs of keys-values.
type Section interface {
// KeyValue returns a key-value
// abstraction for the given key.
KeyValue(key string) KeyValue
}
// KeyValue represents a settings key-value
// for a given pair of section and key.
type KeyValue interface {
// Key returns pair's key.
Key() string
// Value returns pair's value.
Value() string
// MustString returns the value's string representation
// If empty, then it returns the given default.
MustString(defaultVal string) string
// MustBool returns the value's boolean representation
// Otherwise returns the given default.
MustBool(defaultVal bool) bool
// MustDuration returns the value's time.Duration
// representation. Otherwise returns the given default.
MustDuration(defaultVal time.Duration) time.Duration
}
// ReloadHandler defines the expected behaviour from a
// service that have support for configuration reloads.
type ReloadHandler interface {
// Reload handles reloading of configuration changes.
Reload(section Section) error
// Validate validates the configuration, if the validation
// fails the configuration will not be updated neither reloaded.
Validate(section Section) error
}
type SettingsBag map[string]map[string]string
type SettingsRemovals map[string][]string
func ProvideProvider(cfg *Cfg) *OSSImpl {
return &OSSImpl{
Cfg: cfg,
}
}
type OSSImpl struct {
Cfg *Cfg
}
func (o OSSImpl) Current() SettingsBag {
settingsCopy := make(SettingsBag)
for _, section := range o.Cfg.Raw.Sections() {
settingsCopy[section.Name()] = make(map[string]string)
for _, key := range section.Keys() {
settingsCopy[section.Name()][key.Name()] = RedactedValue(key.Name(), key.Value())
}
}
return settingsCopy
}
func (OSSImpl) Update(SettingsBag, SettingsRemovals) error {
return errors.New("oss settings provider do not have support for settings updates")
}
func (o *OSSImpl) KeyValue(section, key string) KeyValue {
return o.Section(section).KeyValue(key)
}
func (o *OSSImpl) Section(section string) Section {
return &sectionImpl{section: o.Cfg.Raw.Section(section)}
}
func (OSSImpl) RegisterReloadHandler(string, ReloadHandler) {}
type keyValImpl struct {
key *ini.Key
}
func (k *keyValImpl) Key() string {
return k.key.Name()
}
func (k *keyValImpl) Value() string {
return k.key.Value()
}
func (k *keyValImpl) MustString(defaultVal string) string {
return k.key.MustString(defaultVal)
}
func (k *keyValImpl) MustBool(defaultVal bool) bool {
return k.key.MustBool(defaultVal)
}
func (k *keyValImpl) MustDuration(defaultVal time.Duration) time.Duration {
return k.key.MustDuration(defaultVal)
}
type sectionImpl struct {
section *ini.Section
}
func (s *sectionImpl) KeyValue(key string) KeyValue {
return &keyValImpl{s.section.Key(key)}
}