grafana/pkg/services/featuremgmt/service.go

70 lines
1.8 KiB
Go

package featuremgmt
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/setting"
)
var (
// The values are updated each time
featureToggleInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "feature_toggles_info",
Help: "info metric that exposes what feature toggles are enabled or not",
Namespace: "grafana",
}, []string{"name"})
)
func ProvideManagerService(cfg *setting.Cfg) (*FeatureManager, error) {
mgmt := &FeatureManager{
isDevMod: cfg.Env != setting.Prod,
flags: make(map[string]*FeatureFlag, 30),
enabled: make(map[string]bool),
startup: make(map[string]bool),
warnings: make(map[string]string),
Settings: cfg.FeatureManagement,
log: log.New("featuremgmt"),
}
// Register the standard flags
mgmt.registerFlags(standardFeatureFlags...)
// Load the flags from `custom.ini` files
flags, err := setting.ReadFeatureTogglesFromInitFile(cfg.Raw.Section("feature_toggles"))
if err != nil {
return mgmt, err
}
for key, val := range flags {
_, ok := mgmt.flags[key]
if !ok {
switch key {
// renamed the flag so it supports more panels
case "autoMigrateGraphPanels":
key = FlagAutoMigrateOldPanels
default:
mgmt.flags[key] = &FeatureFlag{
Name: key,
Stage: FeatureStageUnknown,
}
mgmt.warnings[key] = "unknown flag in config"
}
}
mgmt.startup[key] = val
}
// update the values
mgmt.update()
// Minimum approach to avoid circular dependency
// nolint:staticcheck
cfg.IsFeatureToggleEnabled = mgmt.IsEnabledGlobally
return mgmt, nil
}
// ProvideToggles allows read-only access to the feature state
func ProvideToggles(mgmt *FeatureManager) FeatureToggles {
return mgmt
}