influxdb/kit/feature/override/override.go

84 lines
1.9 KiB
Go

package override
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/influxdata/influxdb/v2/kit/feature"
)
// Flagger can override default flag values.
type Flagger struct {
overrides map[string]string
byKey feature.ByKeyFn
}
// Make a Flagger that returns defaults with any overrides parsed from the string.
func Make(overrides map[string]string, byKey feature.ByKeyFn) (Flagger, error) {
if byKey == nil {
byKey = feature.ByKey
}
// Check all provided override keys correspond to an existing Flag.
var missing []string
for k := range overrides {
if _, found := byKey(k); !found {
missing = append(missing, k)
}
}
if len(missing) > 0 {
return Flagger{}, fmt.Errorf("configured overrides for non-existent flags: %s", strings.Join(missing, ","))
}
return Flagger{
overrides: overrides,
byKey: byKey,
}, nil
}
// Flags returns a map of default values with overrides applied. It never returns an error.
func (f Flagger) Flags(_ context.Context, flags ...feature.Flag) (map[string]interface{}, error) {
if len(flags) == 0 {
flags = feature.Flags()
}
m := make(map[string]interface{}, len(flags))
for _, flag := range flags {
if s, overridden := f.overrides[flag.Key()]; overridden {
iface, err := f.coerce(s, flag)
if err != nil {
return nil, err
}
m[flag.Key()] = iface
} else {
m[flag.Key()] = flag.Default()
}
}
return m, nil
}
func (f Flagger) coerce(s string, flag feature.Flag) (iface interface{}, err error) {
if base, ok := flag.(feature.Base); ok {
flag, _ = f.byKey(base.Key())
}
switch flag.(type) {
case feature.BoolFlag:
iface, err = strconv.ParseBool(s)
case feature.IntFlag:
iface, err = strconv.Atoi(s)
case feature.FloatFlag:
iface, err = strconv.ParseFloat(s, 64)
default:
iface = s
}
if err != nil {
return nil, fmt.Errorf("coercing string %q based on flag type %T: %v", s, flag, err)
}
return
}