diff --git a/kit/feature/flag.go b/kit/feature/flag.go index 045e8a53a4..7c21d8d5bb 100644 --- a/kit/feature/flag.go +++ b/kit/feature/flag.go @@ -21,6 +21,9 @@ type Flag interface { // MakeFlag constructs a Flag. The concrete implementation is inferred from the provided default. func MakeFlag(name, key, owner string, defaultValue interface{}, lifetime Lifetime, expose bool) Flag { + if v, ok := defaultValue.(int); ok { + defaultValue = int32(v) + } b := MakeBase(name, key, owner, defaultValue, lifetime, expose) switch v := defaultValue.(type) { case bool: @@ -29,8 +32,6 @@ func MakeFlag(name, key, owner string, defaultValue interface{}, lifetime Lifeti return FloatFlag{b, v} case int32: return IntFlag{b, v} - case int: - return IntFlag{b, int32(v)} case string: return StringFlag{b, v} default: diff --git a/kit/feature/flux.go b/kit/feature/flux.go new file mode 100644 index 0000000000..90498296e5 --- /dev/null +++ b/kit/feature/flux.go @@ -0,0 +1,45 @@ +package feature + +import ( + "fmt" + + fluxfeature "github.com/influxdata/flux/dependencies/feature" +) + +type fluxFlag struct { + flag fluxfeature.Flag +} + +func (f fluxFlag) Key() string { + return f.flag.Key() +} + +func (f fluxFlag) Default() interface{} { + // Flux uses int for int flags and influxdb uses int32. + // Convert to int32 here so influxdb understands our flag. + switch v := f.flag.Default().(type) { + case int: + return int32(v) + default: + return v + } +} + +func (f fluxFlag) Expose() bool { + return false +} + +func (f fluxFlag) AuthenticationOptional() bool { + return true +} + +func init() { + for _, flag := range fluxfeature.Flags() { + if _, ok := byKey[flag.Key()]; ok { + panic(fmt.Errorf("duplicate feature flag defined in flux and idpe: %s", flag.Key())) + } + wrappedFlag := fluxFlag{flag: flag} + all = append(all, wrappedFlag) + byKey[flag.Key()] = wrappedFlag + } +} diff --git a/kit/feature/override/override.go b/kit/feature/override/override.go index 48ec197fc6..abc782743a 100644 --- a/kit/feature/override/override.go +++ b/kit/feature/override/override.go @@ -65,12 +65,12 @@ func (f Flagger) coerce(s string, flag feature.Flag) (iface interface{}, err err flag, _ = f.byKey(base.Key()) } - switch flag.(type) { - case feature.BoolFlag: + switch flag.Default().(type) { + case bool: iface, err = strconv.ParseBool(s) - case feature.IntFlag: + case int32: iface, err = strconv.Atoi(s) - case feature.FloatFlag: + case float64: iface, err = strconv.ParseFloat(s, 64) default: iface = s diff --git a/query/stdlib/influxdata/influxdb/dependencies.go b/query/stdlib/influxdata/influxdb/dependencies.go index df31b2e587..b4c5a3ddf4 100644 --- a/query/stdlib/influxdata/influxdb/dependencies.go +++ b/query/stdlib/influxdata/influxdb/dependencies.go @@ -4,8 +4,10 @@ import ( "context" "github.com/influxdata/flux" + fluxfeature "github.com/influxdata/flux/dependencies/feature" influxdeps "github.com/influxdata/flux/dependencies/influxdb" "github.com/influxdata/influxdb/v2" + "github.com/influxdata/influxdb/v2/kit/feature" "github.com/influxdata/influxdb/v2/kit/prom" "github.com/influxdata/influxdb/v2/query" "github.com/influxdata/influxdb/v2/storage" @@ -62,7 +64,8 @@ type Dependencies struct { func (d Dependencies) Inject(ctx context.Context) context.Context { ctx = d.FluxDeps.Inject(ctx) - return d.StorageDeps.Inject(ctx) + ctx = d.StorageDeps.Inject(ctx) + return InjectFlagsFromContext(ctx) } // PrometheusCollectors satisfies the prom.PrometheusCollector interface. @@ -108,3 +111,26 @@ func NewDependencies( } return deps, nil } + +type flags map[string]interface{} + +// InjectFlagsFromContext will take the idpe feature flags from +// the context and wrap them in a flux feature flagger for the +// flux engine. +func InjectFlagsFromContext(ctx context.Context) context.Context { + flagger := flags(feature.FlagsFromContext(ctx)) + return fluxfeature.Inject(ctx, flagger) +} + +func (f flags) FlagValue(ctx context.Context, flag fluxfeature.Flag) interface{} { + v, ok := f[flag.Key()] + if !ok { + v = flag.Default() + } + + // Flux uses int for intflag and influxdb uses int32 so convert here. + if i, ok := v.(int32); ok { + return int(i) + } + return v +}