mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
FeatureFlags: Avoid using cfg.IsFeatureToggleEnabled (#81407)
This commit is contained in:
parent
1a1531ca5e
commit
1fab107e79
@ -35,7 +35,7 @@ var (
|
|||||||
// that HTTPServer needs
|
// that HTTPServer needs
|
||||||
func (hs *HTTPServer) declareFixedRoles() error {
|
func (hs *HTTPServer) declareFixedRoles() error {
|
||||||
// Declare plugins roles
|
// Declare plugins roles
|
||||||
if err := pluginaccesscontrol.DeclareRBACRoles(hs.accesscontrolService, hs.Cfg); err != nil {
|
if err := pluginaccesscontrol.DeclareRBACRoles(hs.accesscontrolService, hs.Cfg, hs.Features); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initConflictCfg(cmd *utils.ContextCommandLine) (*setting.Cfg, error) {
|
func initConflictCfg(cmd *utils.ContextCommandLine) (*setting.Cfg, *featuremgmt.FeatureManager, error) {
|
||||||
configOptions := strings.Split(cmd.String("configOverrides"), " ")
|
configOptions := strings.Split(cmd.String("configOverrides"), " ")
|
||||||
configOptions = append(configOptions, cmd.Args().Slice()...)
|
configOptions = append(configOptions, cmd.Args().Slice()...)
|
||||||
cfg, err := setting.NewCfgFromArgs(setting.CommandLineArgs{
|
cfg, err := setting.NewCfgFromArgs(setting.CommandLineArgs{
|
||||||
@ -43,17 +43,19 @@ func initConflictCfg(cmd *utils.ContextCommandLine) (*setting.Cfg, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return cfg, nil
|
|
||||||
|
features, err := featuremgmt.ProvideManagerService(cfg)
|
||||||
|
return cfg, features, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializeConflictResolver(cmd *utils.ContextCommandLine, f Formatter, ctx *cli.Context) (*ConflictResolver, error) {
|
func initializeConflictResolver(cmd *utils.ContextCommandLine, f Formatter, ctx *cli.Context) (*ConflictResolver, error) {
|
||||||
cfg, err := initConflictCfg(cmd)
|
cfg, features, err := initConflictCfg(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%v: %w", "failed to load configuration", err)
|
return nil, fmt.Errorf("%v: %w", "failed to load configuration", err)
|
||||||
}
|
}
|
||||||
s, err := getSqlStore(cfg)
|
s, err := getSqlStore(cfg, features)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%v: %w", "failed to get to sql", err)
|
return nil, fmt.Errorf("%v: %w", "failed to get to sql", err)
|
||||||
}
|
}
|
||||||
@ -67,11 +69,7 @@ func initializeConflictResolver(cmd *utils.ContextCommandLine, f Formatter, ctx
|
|||||||
return nil, fmt.Errorf("%v: %w", "failed to get user service", err)
|
return nil, fmt.Errorf("%v: %w", "failed to get user service", err)
|
||||||
}
|
}
|
||||||
routing := routing.ProvideRegister()
|
routing := routing.ProvideRegister()
|
||||||
featMgmt, err := featuremgmt.ProvideManagerService(cfg, nil)
|
acService, err := acimpl.ProvideService(cfg, s, routing, nil, nil, nil, features)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%v: %w", "failed to get feature management service", err)
|
|
||||||
}
|
|
||||||
acService, err := acimpl.ProvideService(cfg, s, routing, nil, nil, nil, featMgmt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%v: %w", "failed to get access control", err)
|
return nil, fmt.Errorf("%v: %w", "failed to get access control", err)
|
||||||
}
|
}
|
||||||
@ -80,13 +78,13 @@ func initializeConflictResolver(cmd *utils.ContextCommandLine, f Formatter, ctx
|
|||||||
return &resolver, nil
|
return &resolver, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSqlStore(cfg *setting.Cfg) (*sqlstore.SQLStore, error) {
|
func getSqlStore(cfg *setting.Cfg, features featuremgmt.FeatureToggles) (*sqlstore.SQLStore, error) {
|
||||||
tracer, err := tracing.ProvideService(cfg)
|
tracer, err := tracing.ProvideService(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%v: %w", "failed to initialize tracer service", err)
|
return nil, fmt.Errorf("%v: %w", "failed to initialize tracer service", err)
|
||||||
}
|
}
|
||||||
bus := bus.ProvideBus(tracer)
|
bus := bus.ProvideBus(tracer)
|
||||||
return sqlstore.ProvideService(cfg, &migrations.OSSMigrations{}, bus, tracer)
|
return sqlstore.ProvideService(cfg, features, &migrations.OSSMigrations{}, bus, tracer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runListConflictUsers() func(context *cli.Context) error {
|
func runListConflictUsers() func(context *cli.Context) error {
|
||||||
|
@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
grafanaAPIServer "github.com/grafana/grafana/pkg/services/grafana-apiserver"
|
grafanaAPIServer "github.com/grafana/grafana/pkg/services/grafana-apiserver"
|
||||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
|
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,10 +51,7 @@ func (o *APIServerOptions) loadAPIGroupBuilders(args []string) error {
|
|||||||
case "example.grafana.app":
|
case "example.grafana.app":
|
||||||
o.builders = append(o.builders, example.NewTestingAPIBuilder())
|
o.builders = append(o.builders, example.NewTestingAPIBuilder())
|
||||||
case "featuretoggle.grafana.app":
|
case "featuretoggle.grafana.app":
|
||||||
features, err := featuremgmt.ProvideManagerService(&setting.Cfg{}, &licensing.OSSLicensingService{})
|
features := featuremgmt.WithFeatureManager(setting.FeatureMgmtSettings{}, nil) // none... for now
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
o.builders = append(o.builders, featuretoggle.NewFeatureFlagAPIBuilder(features))
|
o.builders = append(o.builders, featuretoggle.NewFeatureFlagAPIBuilder(features))
|
||||||
case "testdata.datasource.grafana.app":
|
case "testdata.datasource.grafana.app":
|
||||||
ds, err := server.InitializeDataSourceAPIServer(g)
|
ds, err := server.InitializeDataSourceAPIServer(g)
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
|
testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
|
||||||
@ -19,6 +20,7 @@ import (
|
|||||||
// This currently builds its dependencies manually and only works for testdata.
|
// This currently builds its dependencies manually and only works for testdata.
|
||||||
func NewTestDataAPIServer(group string) (*DataSourceAPIBuilder, error) {
|
func NewTestDataAPIServer(group string) (*DataSourceAPIBuilder, error) {
|
||||||
pluginID := "grafana-testdata-datasource"
|
pluginID := "grafana-testdata-datasource"
|
||||||
|
features := featuremgmt.WithFeatures() // None for now!
|
||||||
|
|
||||||
if group != "testdata.datasource.grafana.app" {
|
if group != "testdata.datasource.grafana.app" {
|
||||||
return nil, fmt.Errorf("only %s is currently supported", pluginID)
|
return nil, fmt.Errorf("only %s is currently supported", pluginID)
|
||||||
@ -47,7 +49,7 @@ func NewTestDataAPIServer(group string) (*DataSourceAPIBuilder, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
accessControl, pluginStore, dsService, dsCache, err := apiBuilderServices(cfg, pluginID)
|
accessControl, pluginStore, dsService, dsCache, err := apiBuilderServices(cfg, features, pluginID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/encryption/provider"
|
"github.com/grafana/grafana/pkg/services/encryption/provider"
|
||||||
encryptionService "github.com/grafana/grafana/pkg/services/encryption/service"
|
encryptionService "github.com/grafana/grafana/pkg/services/encryption/service"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/hooks"
|
|
||||||
"github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders"
|
"github.com/grafana/grafana/pkg/services/kmsproviders/osskmsproviders"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/config"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/config"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
@ -46,7 +44,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func apiBuilderServices(cfg *setting.Cfg, pluginID string) (
|
func apiBuilderServices(cfg *setting.Cfg, features featuremgmt.FeatureToggles, pluginID string) (
|
||||||
*acimpl.AccessControl,
|
*acimpl.AccessControl,
|
||||||
*pluginstore.Service,
|
*pluginstore.Service,
|
||||||
*datasourceService.Service,
|
*datasourceService.Service,
|
||||||
@ -60,16 +58,14 @@ func apiBuilderServices(cfg *setting.Cfg, pluginID string) (
|
|||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
routeRegisterImpl := routing.ProvideRegister()
|
routeRegisterImpl := routing.ProvideRegister()
|
||||||
hooksService := hooks.ProvideService()
|
featureManager, err := featuremgmt.ProvideManagerService(cfg)
|
||||||
ossLicensingService := licensing.ProvideService(cfg, hooksService)
|
|
||||||
featureManager, err := featuremgmt.ProvideManagerService(cfg, ossLicensingService)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
inProcBus := bus.ProvideBus(tracingService)
|
inProcBus := bus.ProvideBus(tracingService)
|
||||||
ossMigrations := migrations.ProvideOSSMigrations()
|
ossMigrations := migrations.ProvideOSSMigrations(features)
|
||||||
sqlStore, err := sqlstore.ProvideService(cfg, ossMigrations, inProcBus, tracingService)
|
sqlStore, err := sqlstore.ProvideService(cfg, features, ossMigrations, inProcBus, tracingService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,7 +19,6 @@ type FeatureManager struct {
|
|||||||
|
|
||||||
Settings setting.FeatureMgmtSettings
|
Settings setting.FeatureMgmtSettings
|
||||||
|
|
||||||
licensing licensing.Licensing
|
|
||||||
flags map[string]*FeatureFlag
|
flags map[string]*FeatureFlag
|
||||||
enabled map[string]bool // only the "on" values
|
enabled map[string]bool // only the "on" values
|
||||||
startup map[string]bool // the explicit values registered at startup
|
startup map[string]bool // the explicit values registered at startup
|
||||||
@ -62,10 +60,6 @@ func (fm *FeatureManager) registerFlags(flags ...FeatureFlag) {
|
|||||||
flag.RequiresDevMode = true
|
flag.RequiresDevMode = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if add.RequiresLicense {
|
|
||||||
flag.RequiresLicense = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if add.RequiresRestart {
|
if add.RequiresRestart {
|
||||||
flag.RequiresRestart = true
|
flag.RequiresRestart = true
|
||||||
}
|
}
|
||||||
@ -81,10 +75,6 @@ func (fm *FeatureManager) meetsRequirements(ff *FeatureFlag) (bool, string) {
|
|||||||
return false, "requires dev mode"
|
return false, "requires dev mode"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ff.RequiresLicense && (fm.licensing == nil || !fm.licensing.FeatureEnabled(ff.Name)) {
|
|
||||||
return false, "license requirement"
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, ""
|
return true, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,37 +24,6 @@ func TestFeatureManager(t *testing.T) {
|
|||||||
require.Equal(t, map[string]bool{"a": true}, ft.GetEnabled(context.Background()))
|
require.Equal(t, map[string]bool{"a": true}, ft.GetEnabled(context.Background()))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("check license validation", func(t *testing.T) {
|
|
||||||
ft := FeatureManager{
|
|
||||||
flags: map[string]*FeatureFlag{},
|
|
||||||
warnings: map[string]string{},
|
|
||||||
}
|
|
||||||
ft.registerFlags(FeatureFlag{
|
|
||||||
Name: "a",
|
|
||||||
RequiresLicense: true,
|
|
||||||
RequiresDevMode: true,
|
|
||||||
Expression: "true",
|
|
||||||
}, FeatureFlag{
|
|
||||||
Name: "b",
|
|
||||||
Expression: "true",
|
|
||||||
})
|
|
||||||
require.False(t, ft.IsEnabledGlobally("a"))
|
|
||||||
require.True(t, ft.IsEnabledGlobally("b"))
|
|
||||||
require.False(t, ft.IsEnabledGlobally("c")) // uknown flag
|
|
||||||
|
|
||||||
// Try changing "requires license"
|
|
||||||
ft.registerFlags(FeatureFlag{
|
|
||||||
Name: "a",
|
|
||||||
RequiresLicense: false, // shuld still require license!
|
|
||||||
}, FeatureFlag{
|
|
||||||
Name: "b",
|
|
||||||
RequiresLicense: true, // expression is still "true"
|
|
||||||
})
|
|
||||||
require.False(t, ft.IsEnabledGlobally("a"))
|
|
||||||
require.False(t, ft.IsEnabledGlobally("b"))
|
|
||||||
require.False(t, ft.IsEnabledGlobally("c"))
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("check description and docs configs", func(t *testing.T) {
|
t.Run("check description and docs configs", func(t *testing.T) {
|
||||||
ft := FeatureManager{
|
ft := FeatureManager{
|
||||||
flags: map[string]*FeatureFlag{},
|
flags: map[string]*FeatureFlag{},
|
||||||
|
@ -127,7 +127,6 @@ type FeatureFlag struct {
|
|||||||
|
|
||||||
// Special behavior properties
|
// Special behavior properties
|
||||||
RequiresDevMode bool `json:"requiresDevMode,omitempty"` // can not be enabled in production
|
RequiresDevMode bool `json:"requiresDevMode,omitempty"` // can not be enabled in production
|
||||||
RequiresLicense bool `json:"requiresLicense,omitempty"` // Must be enabled in the license
|
|
||||||
FrontendOnly bool `json:"frontend,omitempty"` // change is only seen in the frontend
|
FrontendOnly bool `json:"frontend,omitempty"` // change is only seen in the frontend
|
||||||
HideFromDocs bool `json:"hideFromDocs,omitempty"` // don't add the values to docs
|
HideFromDocs bool `json:"hideFromDocs,omitempty"` // don't add the values to docs
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@ var (
|
|||||||
Name: "publicDashboardsEmailSharing",
|
Name: "publicDashboardsEmailSharing",
|
||||||
Description: "Enables public dashboard sharing to be restricted to only allowed emails",
|
Description: "Enables public dashboard sharing to be restricted to only allowed emails",
|
||||||
Stage: FeatureStagePublicPreview,
|
Stage: FeatureStagePublicPreview,
|
||||||
RequiresLicense: true,
|
|
||||||
Owner: grafanaSharingSquad,
|
Owner: grafanaSharingSquad,
|
||||||
HideFromDocs: true,
|
HideFromDocs: true,
|
||||||
HideFromAdminPage: true,
|
HideFromAdminPage: true,
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,10 +17,9 @@ var (
|
|||||||
}, []string{"name"})
|
}, []string{"name"})
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideManagerService(cfg *setting.Cfg, licensing licensing.Licensing) (*FeatureManager, error) {
|
func ProvideManagerService(cfg *setting.Cfg) (*FeatureManager, error) {
|
||||||
mgmt := &FeatureManager{
|
mgmt := &FeatureManager{
|
||||||
isDevMod: cfg.Env != setting.Prod,
|
isDevMod: cfg.Env != setting.Prod,
|
||||||
licensing: licensing,
|
|
||||||
flags: make(map[string]*FeatureFlag, 30),
|
flags: make(map[string]*FeatureFlag, 30),
|
||||||
enabled: make(map[string]bool),
|
enabled: make(map[string]bool),
|
||||||
startup: make(map[string]bool),
|
startup: make(map[string]bool),
|
||||||
|
@ -5,40 +5,12 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFeatureService(t *testing.T) {
|
func TestFeatureService(t *testing.T) {
|
||||||
license := stubLicenseServier{
|
|
||||||
flags: []FeatureFlag{
|
|
||||||
{
|
|
||||||
Name: "a.yes.default",
|
|
||||||
RequiresLicense: true,
|
|
||||||
Expression: "true",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "a.yes",
|
|
||||||
RequiresLicense: true,
|
|
||||||
Expression: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "b.no",
|
|
||||||
RequiresLicense: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
enabled: map[string]bool{
|
|
||||||
"a.yes.default": true,
|
|
||||||
"a.yes": true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
require.False(t, license.FeatureEnabled("unknown"))
|
|
||||||
require.False(t, license.FeatureEnabled("b.no"))
|
|
||||||
require.True(t, license.FeatureEnabled("a.yes"))
|
|
||||||
require.True(t, license.FeatureEnabled("a.yes.default"))
|
|
||||||
|
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
mgmt, err := ProvideManagerService(cfg, license)
|
mgmt, err := ProvideManagerService(cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, mgmt)
|
require.NotNil(t, mgmt)
|
||||||
|
|
||||||
@ -46,40 +18,3 @@ func TestFeatureService(t *testing.T) {
|
|||||||
require.False(t, mgmt.IsEnabledGlobally("a.yes.default"))
|
require.False(t, mgmt.IsEnabledGlobally("a.yes.default"))
|
||||||
require.False(t, mgmt.IsEnabledGlobally("a.yes")) // licensed, but not enabled
|
require.False(t, mgmt.IsEnabledGlobally("a.yes")) // licensed, but not enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
_ licensing.Licensing = (*stubLicenseServier)(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
type stubLicenseServier struct {
|
|
||||||
flags []FeatureFlag
|
|
||||||
enabled map[string]bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) Expiry() int64 {
|
|
||||||
return 100
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) Edition() string {
|
|
||||||
return "test"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) ContentDeliveryPrefix() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) LicenseURL(showAdminLicensingPage bool) string {
|
|
||||||
return "http://??"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) StateInfo() string {
|
|
||||||
return "ok"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) EnabledFeatures() map[string]bool {
|
|
||||||
return map[string]bool{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stubLicenseServier) FeatureEnabled(feature string) bool {
|
|
||||||
return s.enabled[feature]
|
|
||||||
}
|
|
||||||
|
@ -1,158 +1,158 @@
|
|||||||
Name,Stage,Owner,Created,requiresDevMode,RequiresLicense,RequiresRestart,FrontendOnly
|
Name,Stage,Owner,Created,requiresDevMode,RequiresRestart,FrontendOnly
|
||||||
disableEnvelopeEncryption,GA,@grafana/grafana-as-code,2022-05-24,false,false,false,false
|
disableEnvelopeEncryption,GA,@grafana/grafana-as-code,2022-05-24,false,false,false
|
||||||
live-service-web-worker,experimental,@grafana/grafana-app-platform-squad,2021-11-09,false,false,false,true
|
live-service-web-worker,experimental,@grafana/grafana-app-platform-squad,2021-11-09,false,false,true
|
||||||
queryOverLive,experimental,@grafana/grafana-app-platform-squad,2022-01-05,false,false,false,true
|
queryOverLive,experimental,@grafana/grafana-app-platform-squad,2022-01-05,false,false,true
|
||||||
panelTitleSearch,preview,@grafana/grafana-app-platform-squad,2022-02-15,false,false,false,false
|
panelTitleSearch,preview,@grafana/grafana-app-platform-squad,2022-02-15,false,false,false
|
||||||
publicDashboards,GA,@grafana/sharing-squad,2022-04-07,false,false,false,false
|
publicDashboards,GA,@grafana/sharing-squad,2022-04-07,false,false,false
|
||||||
publicDashboardsEmailSharing,preview,@grafana/sharing-squad,2022-12-21,false,true,false,false
|
publicDashboardsEmailSharing,preview,@grafana/sharing-squad,2022-12-21,false,false,false
|
||||||
lokiExperimentalStreaming,experimental,@grafana/observability-logs,2023-06-19,false,false,false,false
|
lokiExperimentalStreaming,experimental,@grafana/observability-logs,2023-06-19,false,false,false
|
||||||
featureHighlights,GA,@grafana/grafana-as-code,2022-02-03,false,false,false,false
|
featureHighlights,GA,@grafana/grafana-as-code,2022-02-03,false,false,false
|
||||||
migrationLocking,preview,@grafana/backend-platform,2022-02-15,false,false,false,false
|
migrationLocking,preview,@grafana/backend-platform,2022-02-15,false,false,false
|
||||||
storage,experimental,@grafana/grafana-app-platform-squad,2022-03-17,false,false,false,false
|
storage,experimental,@grafana/grafana-app-platform-squad,2022-03-17,false,false,false
|
||||||
correlations,GA,@grafana/explore-squad,2022-09-16,false,false,false,false
|
correlations,GA,@grafana/explore-squad,2022-09-16,false,false,false
|
||||||
exploreContentOutline,GA,@grafana/explore-squad,2023-11-03,false,false,false,true
|
exploreContentOutline,GA,@grafana/explore-squad,2023-11-03,false,false,true
|
||||||
datasourceQueryMultiStatus,experimental,@grafana/plugins-platform-backend,2022-05-03,false,false,false,false
|
datasourceQueryMultiStatus,experimental,@grafana/plugins-platform-backend,2022-05-03,false,false,false
|
||||||
traceToMetrics,experimental,@grafana/observability-traces-and-profiling,2022-03-07,false,false,false,true
|
traceToMetrics,experimental,@grafana/observability-traces-and-profiling,2022-03-07,false,false,true
|
||||||
autoMigrateOldPanels,preview,@grafana/dataviz-squad,2022-06-11,false,false,false,true
|
autoMigrateOldPanels,preview,@grafana/dataviz-squad,2022-06-11,false,false,true
|
||||||
disableAngular,preview,@grafana/dataviz-squad,2023-03-23,false,false,false,true
|
disableAngular,preview,@grafana/dataviz-squad,2023-03-23,false,false,true
|
||||||
canvasPanelNesting,experimental,@grafana/dataviz-squad,2022-05-31,false,false,false,true
|
canvasPanelNesting,experimental,@grafana/dataviz-squad,2022-05-31,false,false,true
|
||||||
newVizTooltips,preview,@grafana/dataviz-squad,2023-11-03,false,false,false,true
|
newVizTooltips,preview,@grafana/dataviz-squad,2023-11-03,false,false,true
|
||||||
scenes,experimental,@grafana/dashboards-squad,2022-07-07,false,false,false,true
|
scenes,experimental,@grafana/dashboards-squad,2022-07-07,false,false,true
|
||||||
disableSecretsCompatibility,experimental,@grafana/hosted-grafana-team,2022-07-13,false,false,true,false
|
disableSecretsCompatibility,experimental,@grafana/hosted-grafana-team,2022-07-13,false,true,false
|
||||||
logRequestsInstrumentedAsUnknown,experimental,@grafana/hosted-grafana-team,2022-06-10,false,false,false,false
|
logRequestsInstrumentedAsUnknown,experimental,@grafana/hosted-grafana-team,2022-06-10,false,false,false
|
||||||
dataConnectionsConsole,GA,@grafana/plugins-platform-backend,2022-06-01,false,false,false,false
|
dataConnectionsConsole,GA,@grafana/plugins-platform-backend,2022-06-01,false,false,false
|
||||||
topnav,deprecated,@grafana/grafana-frontend-platform,2022-06-20,false,false,false,false
|
topnav,deprecated,@grafana/grafana-frontend-platform,2022-06-20,false,false,false
|
||||||
dockedMegaMenu,experimental,@grafana/grafana-frontend-platform,2023-09-18,false,false,false,true
|
dockedMegaMenu,experimental,@grafana/grafana-frontend-platform,2023-09-18,false,false,true
|
||||||
returnToPrevious,experimental,@grafana/grafana-frontend-platform,2024-01-09,false,false,false,true
|
returnToPrevious,experimental,@grafana/grafana-frontend-platform,2024-01-09,false,false,true
|
||||||
grpcServer,preview,@grafana/grafana-app-platform-squad,2022-09-27,false,false,false,false
|
grpcServer,preview,@grafana/grafana-app-platform-squad,2022-09-27,false,false,false
|
||||||
unifiedStorage,experimental,@grafana/grafana-app-platform-squad,2022-12-01,true,false,true,false
|
unifiedStorage,experimental,@grafana/grafana-app-platform-squad,2022-12-01,true,true,false
|
||||||
cloudWatchCrossAccountQuerying,GA,@grafana/aws-datasources,2022-11-28,false,false,false,false
|
cloudWatchCrossAccountQuerying,GA,@grafana/aws-datasources,2022-11-28,false,false,false
|
||||||
redshiftAsyncQueryDataSupport,GA,@grafana/aws-datasources,2022-08-27,false,false,false,false
|
redshiftAsyncQueryDataSupport,GA,@grafana/aws-datasources,2022-08-27,false,false,false
|
||||||
athenaAsyncQueryDataSupport,GA,@grafana/aws-datasources,2022-08-27,false,false,false,true
|
athenaAsyncQueryDataSupport,GA,@grafana/aws-datasources,2022-08-27,false,false,true
|
||||||
cloudwatchNewRegionsHandler,GA,@grafana/aws-datasources,2023-09-25,false,false,false,false
|
cloudwatchNewRegionsHandler,GA,@grafana/aws-datasources,2023-09-25,false,false,false
|
||||||
showDashboardValidationWarnings,experimental,@grafana/dashboards-squad,2022-10-14,false,false,false,false
|
showDashboardValidationWarnings,experimental,@grafana/dashboards-squad,2022-10-14,false,false,false
|
||||||
mysqlAnsiQuotes,experimental,@grafana/backend-platform,2022-10-12,false,false,false,false
|
mysqlAnsiQuotes,experimental,@grafana/backend-platform,2022-10-12,false,false,false
|
||||||
accessControlOnCall,preview,@grafana/identity-access-team,2022-10-19,false,false,false,false
|
accessControlOnCall,preview,@grafana/identity-access-team,2022-10-19,false,false,false
|
||||||
nestedFolders,preview,@grafana/backend-platform,2022-10-22,false,false,false,false
|
nestedFolders,preview,@grafana/backend-platform,2022-10-22,false,false,false
|
||||||
nestedFolderPicker,GA,@grafana/grafana-frontend-platform,2023-07-24,false,false,false,true
|
nestedFolderPicker,GA,@grafana/grafana-frontend-platform,2023-07-24,false,false,true
|
||||||
disablePrometheusExemplarSampling,GA,@grafana/observability-metrics,2022-12-19,false,false,false,false
|
disablePrometheusExemplarSampling,GA,@grafana/observability-metrics,2022-12-19,false,false,false
|
||||||
alertingBacktesting,experimental,@grafana/alerting-squad,2022-10-20,false,false,false,false
|
alertingBacktesting,experimental,@grafana/alerting-squad,2022-10-20,false,false,false
|
||||||
editPanelCSVDragAndDrop,experimental,@grafana/grafana-bi-squad,2022-12-20,false,false,false,true
|
editPanelCSVDragAndDrop,experimental,@grafana/grafana-bi-squad,2022-12-20,false,false,true
|
||||||
alertingNoNormalState,preview,@grafana/alerting-squad,2023-01-14,false,false,false,false
|
alertingNoNormalState,preview,@grafana/alerting-squad,2023-01-14,false,false,false
|
||||||
logsContextDatasourceUi,GA,@grafana/observability-logs,2023-01-27,false,false,false,true
|
logsContextDatasourceUi,GA,@grafana/observability-logs,2023-01-27,false,false,true
|
||||||
lokiQuerySplitting,GA,@grafana/observability-logs,2023-02-09,false,false,false,true
|
lokiQuerySplitting,GA,@grafana/observability-logs,2023-02-09,false,false,true
|
||||||
lokiQuerySplittingConfig,experimental,@grafana/observability-logs,2023-03-20,false,false,false,true
|
lokiQuerySplittingConfig,experimental,@grafana/observability-logs,2023-03-20,false,false,true
|
||||||
individualCookiePreferences,experimental,@grafana/backend-platform,2023-02-23,false,false,false,false
|
individualCookiePreferences,experimental,@grafana/backend-platform,2023-02-23,false,false,false
|
||||||
prometheusMetricEncyclopedia,GA,@grafana/observability-metrics,2023-03-07,false,false,false,true
|
prometheusMetricEncyclopedia,GA,@grafana/observability-metrics,2023-03-07,false,false,true
|
||||||
influxdbBackendMigration,GA,@grafana/observability-metrics,2023-03-15,false,false,false,true
|
influxdbBackendMigration,GA,@grafana/observability-metrics,2023-03-15,false,false,true
|
||||||
influxqlStreamingParser,experimental,@grafana/observability-metrics,2023-11-29,false,false,false,false
|
influxqlStreamingParser,experimental,@grafana/observability-metrics,2023-11-29,false,false,false
|
||||||
clientTokenRotation,GA,@grafana/identity-access-team,2023-03-23,false,false,false,false
|
clientTokenRotation,GA,@grafana/identity-access-team,2023-03-23,false,false,false
|
||||||
prometheusDataplane,GA,@grafana/observability-metrics,2023-03-29,false,false,false,false
|
prometheusDataplane,GA,@grafana/observability-metrics,2023-03-29,false,false,false
|
||||||
lokiMetricDataplane,GA,@grafana/observability-logs,2023-04-13,false,false,false,false
|
lokiMetricDataplane,GA,@grafana/observability-logs,2023-04-13,false,false,false
|
||||||
lokiLogsDataplane,experimental,@grafana/observability-logs,2023-07-13,false,false,false,false
|
lokiLogsDataplane,experimental,@grafana/observability-logs,2023-07-13,false,false,false
|
||||||
dataplaneFrontendFallback,GA,@grafana/observability-metrics,2023-04-24,false,false,false,true
|
dataplaneFrontendFallback,GA,@grafana/observability-metrics,2023-04-24,false,false,true
|
||||||
disableSSEDataplane,experimental,@grafana/observability-metrics,2023-04-24,false,false,false,false
|
disableSSEDataplane,experimental,@grafana/observability-metrics,2023-04-24,false,false,false
|
||||||
alertStateHistoryLokiSecondary,experimental,@grafana/alerting-squad,2023-03-30,false,false,false,false
|
alertStateHistoryLokiSecondary,experimental,@grafana/alerting-squad,2023-03-30,false,false,false
|
||||||
alertStateHistoryLokiPrimary,experimental,@grafana/alerting-squad,2023-03-30,false,false,false,false
|
alertStateHistoryLokiPrimary,experimental,@grafana/alerting-squad,2023-03-30,false,false,false
|
||||||
alertStateHistoryLokiOnly,experimental,@grafana/alerting-squad,2023-03-30,false,false,false,false
|
alertStateHistoryLokiOnly,experimental,@grafana/alerting-squad,2023-03-30,false,false,false
|
||||||
unifiedRequestLog,experimental,@grafana/backend-platform,2023-03-31,false,false,false,false
|
unifiedRequestLog,experimental,@grafana/backend-platform,2023-03-31,false,false,false
|
||||||
renderAuthJWT,preview,@grafana/grafana-as-code,2023-04-03,false,false,false,false
|
renderAuthJWT,preview,@grafana/grafana-as-code,2023-04-03,false,false,false
|
||||||
externalServiceAuth,experimental,@grafana/identity-access-team,2023-04-11,true,false,false,false
|
externalServiceAuth,experimental,@grafana/identity-access-team,2023-04-11,true,false,false
|
||||||
refactorVariablesTimeRange,preview,@grafana/dashboards-squad,2023-06-06,false,false,false,false
|
refactorVariablesTimeRange,preview,@grafana/dashboards-squad,2023-06-06,false,false,false
|
||||||
enableElasticsearchBackendQuerying,GA,@grafana/observability-logs,2023-04-14,false,false,false,false
|
enableElasticsearchBackendQuerying,GA,@grafana/observability-logs,2023-04-14,false,false,false
|
||||||
advancedDataSourcePicker,GA,@grafana/dashboards-squad,2023-04-14,false,false,false,true
|
advancedDataSourcePicker,GA,@grafana/dashboards-squad,2023-04-14,false,false,true
|
||||||
faroDatasourceSelector,preview,@grafana/app-o11y,2023-05-04,false,false,false,true
|
faroDatasourceSelector,preview,@grafana/app-o11y,2023-05-04,false,false,true
|
||||||
enableDatagridEditing,preview,@grafana/grafana-bi-squad,2023-04-24,false,false,false,true
|
enableDatagridEditing,preview,@grafana/grafana-bi-squad,2023-04-24,false,false,true
|
||||||
extraThemes,experimental,@grafana/grafana-frontend-platform,2023-05-10,false,false,false,true
|
extraThemes,experimental,@grafana/grafana-frontend-platform,2023-05-10,false,false,true
|
||||||
lokiPredefinedOperations,experimental,@grafana/observability-logs,2023-06-02,false,false,false,true
|
lokiPredefinedOperations,experimental,@grafana/observability-logs,2023-06-02,false,false,true
|
||||||
pluginsFrontendSandbox,experimental,@grafana/plugins-platform-backend,2023-06-05,false,false,false,true
|
pluginsFrontendSandbox,experimental,@grafana/plugins-platform-backend,2023-06-05,false,false,true
|
||||||
dashboardEmbed,experimental,@grafana/grafana-as-code,2023-07-06,false,false,false,true
|
dashboardEmbed,experimental,@grafana/grafana-as-code,2023-07-06,false,false,true
|
||||||
frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,2023-07-05,false,false,false,true
|
frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,2023-07-05,false,false,true
|
||||||
sqlDatasourceDatabaseSelection,preview,@grafana/grafana-bi-squad,2023-06-06,false,false,false,true
|
sqlDatasourceDatabaseSelection,preview,@grafana/grafana-bi-squad,2023-06-06,false,false,true
|
||||||
lokiFormatQuery,experimental,@grafana/observability-logs,2023-06-21,false,false,false,true
|
lokiFormatQuery,experimental,@grafana/observability-logs,2023-06-21,false,false,true
|
||||||
cloudWatchLogsMonacoEditor,GA,@grafana/aws-datasources,2023-06-12,false,false,false,true
|
cloudWatchLogsMonacoEditor,GA,@grafana/aws-datasources,2023-06-12,false,false,true
|
||||||
exploreScrollableLogsContainer,experimental,@grafana/observability-logs,2023-06-15,false,false,false,true
|
exploreScrollableLogsContainer,experimental,@grafana/observability-logs,2023-06-15,false,false,true
|
||||||
recordedQueriesMulti,GA,@grafana/observability-metrics,2023-06-14,false,false,false,false
|
recordedQueriesMulti,GA,@grafana/observability-metrics,2023-06-14,false,false,false
|
||||||
pluginsDynamicAngularDetectionPatterns,experimental,@grafana/plugins-platform-backend,2023-06-26,false,false,false,false
|
pluginsDynamicAngularDetectionPatterns,experimental,@grafana/plugins-platform-backend,2023-06-26,false,false,false
|
||||||
vizAndWidgetSplit,experimental,@grafana/dashboards-squad,2023-06-27,false,false,false,true
|
vizAndWidgetSplit,experimental,@grafana/dashboards-squad,2023-06-27,false,false,true
|
||||||
prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,2023-07-05,false,false,false,true
|
prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,2023-07-05,false,false,true
|
||||||
logsExploreTableVisualisation,experimental,@grafana/observability-logs,2023-07-12,false,false,false,true
|
logsExploreTableVisualisation,experimental,@grafana/observability-logs,2023-07-12,false,false,true
|
||||||
awsDatasourcesTempCredentials,experimental,@grafana/aws-datasources,2023-07-06,false,false,false,false
|
awsDatasourcesTempCredentials,experimental,@grafana/aws-datasources,2023-07-06,false,false,false
|
||||||
transformationsRedesign,GA,@grafana/observability-metrics,2023-07-12,false,false,false,true
|
transformationsRedesign,GA,@grafana/observability-metrics,2023-07-12,false,false,true
|
||||||
mlExpressions,experimental,@grafana/alerting-squad,2023-07-13,false,false,false,false
|
mlExpressions,experimental,@grafana/alerting-squad,2023-07-13,false,false,false
|
||||||
traceQLStreaming,experimental,@grafana/observability-traces-and-profiling,2023-07-26,false,false,false,true
|
traceQLStreaming,experimental,@grafana/observability-traces-and-profiling,2023-07-26,false,false,true
|
||||||
metricsSummary,experimental,@grafana/observability-traces-and-profiling,2023-08-28,false,false,false,true
|
metricsSummary,experimental,@grafana/observability-traces-and-profiling,2023-08-28,false,false,true
|
||||||
grafanaAPIServerWithExperimentalAPIs,experimental,@grafana/grafana-app-platform-squad,2023-10-06,true,false,true,false
|
grafanaAPIServerWithExperimentalAPIs,experimental,@grafana/grafana-app-platform-squad,2023-10-06,true,true,false
|
||||||
grafanaAPIServerEnsureKubectlAccess,experimental,@grafana/grafana-app-platform-squad,2023-12-06,true,false,true,false
|
grafanaAPIServerEnsureKubectlAccess,experimental,@grafana/grafana-app-platform-squad,2023-12-06,true,true,false
|
||||||
featureToggleAdminPage,experimental,@grafana/grafana-operator-experience-squad,2023-07-18,false,false,true,false
|
featureToggleAdminPage,experimental,@grafana/grafana-operator-experience-squad,2023-07-18,false,true,false
|
||||||
awsAsyncQueryCaching,GA,@grafana/aws-datasources,2023-07-21,false,false,false,false
|
awsAsyncQueryCaching,GA,@grafana/aws-datasources,2023-07-21,false,false,false
|
||||||
splitScopes,GA,@grafana/identity-access-team,2023-07-21,false,false,true,false
|
splitScopes,GA,@grafana/identity-access-team,2023-07-21,false,true,false
|
||||||
permissionsFilterRemoveSubquery,experimental,@grafana/backend-platform,2023-08-02,false,false,false,false
|
permissionsFilterRemoveSubquery,experimental,@grafana/backend-platform,2023-08-02,false,false,false
|
||||||
prometheusConfigOverhaulAuth,GA,@grafana/observability-metrics,2023-07-21,false,false,false,false
|
prometheusConfigOverhaulAuth,GA,@grafana/observability-metrics,2023-07-21,false,false,false
|
||||||
configurableSchedulerTick,experimental,@grafana/alerting-squad,2023-07-26,false,false,true,false
|
configurableSchedulerTick,experimental,@grafana/alerting-squad,2023-07-26,false,true,false
|
||||||
influxdbSqlSupport,GA,@grafana/observability-metrics,2023-08-02,false,false,true,false
|
influxdbSqlSupport,GA,@grafana/observability-metrics,2023-08-02,false,true,false
|
||||||
alertingNoDataErrorExecution,GA,@grafana/alerting-squad,2023-08-15,false,false,true,false
|
alertingNoDataErrorExecution,GA,@grafana/alerting-squad,2023-08-15,false,true,false
|
||||||
angularDeprecationUI,experimental,@grafana/plugins-platform-backend,2023-08-29,false,false,false,true
|
angularDeprecationUI,experimental,@grafana/plugins-platform-backend,2023-08-29,false,false,true
|
||||||
dashgpt,preview,@grafana/dashboards-squad,2023-11-17,false,false,false,true
|
dashgpt,preview,@grafana/dashboards-squad,2023-11-17,false,false,true
|
||||||
reportingRetries,preview,@grafana/sharing-squad,2023-08-31,false,false,true,false
|
reportingRetries,preview,@grafana/sharing-squad,2023-08-31,false,true,false
|
||||||
sseGroupByDatasource,experimental,@grafana/observability-metrics,2023-09-07,false,false,false,false
|
sseGroupByDatasource,experimental,@grafana/observability-metrics,2023-09-07,false,false,false
|
||||||
requestInstrumentationStatusSource,experimental,@grafana/plugins-platform-backend,2023-09-11,false,false,false,false
|
requestInstrumentationStatusSource,experimental,@grafana/plugins-platform-backend,2023-09-11,false,false,false
|
||||||
libraryPanelRBAC,experimental,@grafana/dashboards-squad,2023-10-11,false,false,true,false
|
libraryPanelRBAC,experimental,@grafana/dashboards-squad,2023-10-11,false,true,false
|
||||||
lokiRunQueriesInParallel,privatePreview,@grafana/observability-logs,2023-09-19,false,false,false,false
|
lokiRunQueriesInParallel,privatePreview,@grafana/observability-logs,2023-09-19,false,false,false
|
||||||
wargamesTesting,experimental,@grafana/hosted-grafana-team,2023-09-13,false,false,false,false
|
wargamesTesting,experimental,@grafana/hosted-grafana-team,2023-09-13,false,false,false
|
||||||
alertingInsights,GA,@grafana/alerting-squad,2023-09-14,false,false,false,true
|
alertingInsights,GA,@grafana/alerting-squad,2023-09-14,false,false,true
|
||||||
externalCorePlugins,experimental,@grafana/plugins-platform-backend,2023-09-22,false,false,false,false
|
externalCorePlugins,experimental,@grafana/plugins-platform-backend,2023-09-22,false,false,false
|
||||||
pluginsAPIMetrics,experimental,@grafana/plugins-platform-backend,2023-09-21,false,false,false,true
|
pluginsAPIMetrics,experimental,@grafana/plugins-platform-backend,2023-09-21,false,false,true
|
||||||
httpSLOLevels,experimental,@grafana/hosted-grafana-team,2023-09-22,false,false,true,false
|
httpSLOLevels,experimental,@grafana/hosted-grafana-team,2023-09-22,false,true,false
|
||||||
idForwarding,experimental,@grafana/identity-access-team,2023-09-25,false,false,false,false
|
idForwarding,experimental,@grafana/identity-access-team,2023-09-25,false,false,false
|
||||||
cloudWatchWildCardDimensionValues,GA,@grafana/aws-datasources,2023-09-27,false,false,false,false
|
cloudWatchWildCardDimensionValues,GA,@grafana/aws-datasources,2023-09-27,false,false,false
|
||||||
externalServiceAccounts,privatePreview,@grafana/identity-access-team,2023-09-28,false,false,false,false
|
externalServiceAccounts,privatePreview,@grafana/identity-access-team,2023-09-28,false,false,false
|
||||||
panelMonitoring,experimental,@grafana/dataviz-squad,2023-10-08,false,false,false,true
|
panelMonitoring,experimental,@grafana/dataviz-squad,2023-10-08,false,false,true
|
||||||
enableNativeHTTPHistogram,experimental,@grafana/hosted-grafana-team,2023-10-03,false,false,false,false
|
enableNativeHTTPHistogram,experimental,@grafana/hosted-grafana-team,2023-10-03,false,false,false
|
||||||
formatString,preview,@grafana/grafana-bi-squad,2023-10-13,false,false,false,true
|
formatString,preview,@grafana/grafana-bi-squad,2023-10-13,false,false,true
|
||||||
transformationsVariableSupport,preview,@grafana/grafana-bi-squad,2023-10-04,false,false,false,true
|
transformationsVariableSupport,preview,@grafana/grafana-bi-squad,2023-10-04,false,false,true
|
||||||
kubernetesPlaylists,experimental,@grafana/grafana-app-platform-squad,2023-11-08,false,false,true,false
|
kubernetesPlaylists,experimental,@grafana/grafana-app-platform-squad,2023-11-08,false,true,false
|
||||||
kubernetesSnapshots,experimental,@grafana/grafana-app-platform-squad,2023-12-04,false,false,true,false
|
kubernetesSnapshots,experimental,@grafana/grafana-app-platform-squad,2023-12-04,false,true,false
|
||||||
cloudWatchBatchQueries,preview,@grafana/aws-datasources,2023-10-20,false,false,false,false
|
cloudWatchBatchQueries,preview,@grafana/aws-datasources,2023-10-20,false,false,false
|
||||||
recoveryThreshold,GA,@grafana/alerting-squad,2023-10-10,false,false,true,false
|
recoveryThreshold,GA,@grafana/alerting-squad,2023-10-10,false,true,false
|
||||||
lokiStructuredMetadata,experimental,@grafana/observability-logs,2023-11-16,false,false,false,false
|
lokiStructuredMetadata,experimental,@grafana/observability-logs,2023-11-16,false,false,false
|
||||||
teamHttpHeaders,experimental,@grafana/identity-access-team,2023-10-17,false,false,false,false
|
teamHttpHeaders,experimental,@grafana/identity-access-team,2023-10-17,false,false,false
|
||||||
awsDatasourcesNewFormStyling,experimental,@grafana/aws-datasources,2023-10-12,false,false,false,true
|
awsDatasourcesNewFormStyling,experimental,@grafana/aws-datasources,2023-10-12,false,false,true
|
||||||
cachingOptimizeSerializationMemoryUsage,experimental,@grafana/grafana-operator-experience-squad,2023-10-12,false,false,false,false
|
cachingOptimizeSerializationMemoryUsage,experimental,@grafana/grafana-operator-experience-squad,2023-10-12,false,false,false
|
||||||
panelTitleSearchInV1,experimental,@grafana/backend-platform,2023-10-13,true,false,false,false
|
panelTitleSearchInV1,experimental,@grafana/backend-platform,2023-10-13,true,false,false
|
||||||
pluginsInstrumentationStatusSource,experimental,@grafana/plugins-platform-backend,2023-10-17,false,false,false,false
|
pluginsInstrumentationStatusSource,experimental,@grafana/plugins-platform-backend,2023-10-17,false,false,false
|
||||||
managedPluginsInstall,preview,@grafana/plugins-platform-backend,2023-10-18,false,false,false,false
|
managedPluginsInstall,preview,@grafana/plugins-platform-backend,2023-10-18,false,false,false
|
||||||
prometheusPromQAIL,experimental,@grafana/observability-metrics,2023-10-19,false,false,false,true
|
prometheusPromQAIL,experimental,@grafana/observability-metrics,2023-10-19,false,false,true
|
||||||
addFieldFromCalculationStatFunctions,preview,@grafana/grafana-bi-squad,2023-11-03,false,false,false,true
|
addFieldFromCalculationStatFunctions,preview,@grafana/grafana-bi-squad,2023-11-03,false,false,true
|
||||||
alertmanagerRemoteSecondary,experimental,@grafana/alerting-squad,2023-10-30,false,false,false,false
|
alertmanagerRemoteSecondary,experimental,@grafana/alerting-squad,2023-10-30,false,false,false
|
||||||
alertmanagerRemotePrimary,experimental,@grafana/alerting-squad,2023-10-30,false,false,false,false
|
alertmanagerRemotePrimary,experimental,@grafana/alerting-squad,2023-10-30,false,false,false
|
||||||
alertmanagerRemoteOnly,experimental,@grafana/alerting-squad,2023-10-30,false,false,false,false
|
alertmanagerRemoteOnly,experimental,@grafana/alerting-squad,2023-10-30,false,false,false
|
||||||
annotationPermissionUpdate,experimental,@grafana/identity-access-team,2023-10-31,false,false,false,false
|
annotationPermissionUpdate,experimental,@grafana/identity-access-team,2023-10-31,false,false,false
|
||||||
extractFieldsNameDeduplication,experimental,@grafana/grafana-bi-squad,2023-11-02,false,false,false,true
|
extractFieldsNameDeduplication,experimental,@grafana/grafana-bi-squad,2023-11-02,false,false,true
|
||||||
dashboardSceneForViewers,experimental,@grafana/dashboards-squad,2023-11-02,false,false,false,true
|
dashboardSceneForViewers,experimental,@grafana/dashboards-squad,2023-11-02,false,false,true
|
||||||
dashboardScene,experimental,@grafana/dashboards-squad,2023-11-13,false,false,false,true
|
dashboardScene,experimental,@grafana/dashboards-squad,2023-11-13,false,false,true
|
||||||
panelFilterVariable,experimental,@grafana/dashboards-squad,2023-11-03,false,false,false,true
|
panelFilterVariable,experimental,@grafana/dashboards-squad,2023-11-03,false,false,true
|
||||||
pdfTables,preview,@grafana/sharing-squad,2023-11-06,false,false,false,false
|
pdfTables,preview,@grafana/sharing-squad,2023-11-06,false,false,false
|
||||||
ssoSettingsApi,experimental,@grafana/identity-access-team,2023-11-08,false,false,false,false
|
ssoSettingsApi,experimental,@grafana/identity-access-team,2023-11-08,false,false,false
|
||||||
canvasPanelPanZoom,preview,@grafana/dataviz-squad,2023-12-27,false,false,false,true
|
canvasPanelPanZoom,preview,@grafana/dataviz-squad,2023-12-27,false,false,true
|
||||||
logsInfiniteScrolling,experimental,@grafana/observability-logs,2023-11-09,false,false,false,true
|
logsInfiniteScrolling,experimental,@grafana/observability-logs,2023-11-09,false,false,true
|
||||||
flameGraphItemCollapsing,experimental,@grafana/observability-traces-and-profiling,2023-11-09,false,false,false,true
|
flameGraphItemCollapsing,experimental,@grafana/observability-traces-and-profiling,2023-11-09,false,false,true
|
||||||
alertingDetailsViewV2,experimental,@grafana/alerting-squad,2023-11-09,false,false,false,true
|
alertingDetailsViewV2,experimental,@grafana/alerting-squad,2023-11-09,false,false,true
|
||||||
datatrails,experimental,@grafana/dashboards-squad,2023-11-15,false,false,false,true
|
datatrails,experimental,@grafana/dashboards-squad,2023-11-15,false,false,true
|
||||||
alertingSimplifiedRouting,experimental,@grafana/alerting-squad,2023-11-10,false,false,false,false
|
alertingSimplifiedRouting,experimental,@grafana/alerting-squad,2023-11-10,false,false,false
|
||||||
logRowsPopoverMenu,GA,@grafana/observability-logs,2023-11-16,false,false,false,true
|
logRowsPopoverMenu,GA,@grafana/observability-logs,2023-11-16,false,false,true
|
||||||
pluginsSkipHostEnvVars,experimental,@grafana/plugins-platform-backend,2023-11-15,false,false,false,false
|
pluginsSkipHostEnvVars,experimental,@grafana/plugins-platform-backend,2023-11-15,false,false,false
|
||||||
tableSharedCrosshair,experimental,@grafana/grafana-bi-squad,2023-12-12,false,false,false,true
|
tableSharedCrosshair,experimental,@grafana/grafana-bi-squad,2023-12-12,false,false,true
|
||||||
regressionTransformation,preview,@grafana/grafana-bi-squad,2023-11-24,false,false,false,true
|
regressionTransformation,preview,@grafana/grafana-bi-squad,2023-11-24,false,false,true
|
||||||
displayAnonymousStats,GA,@grafana/identity-access-team,2023-11-29,false,false,false,true
|
displayAnonymousStats,GA,@grafana/identity-access-team,2023-11-29,false,false,true
|
||||||
lokiQueryHints,GA,@grafana/observability-logs,2023-12-18,false,false,false,true
|
lokiQueryHints,GA,@grafana/observability-logs,2023-12-18,false,false,true
|
||||||
kubernetesFeatureToggles,experimental,@grafana/grafana-operator-experience-squad,2023-12-22,false,false,false,true
|
kubernetesFeatureToggles,experimental,@grafana/grafana-operator-experience-squad,2023-12-22,false,false,true
|
||||||
alertingPreviewUpgrade,preview,@grafana/alerting-squad,2024-01-03,false,false,true,false
|
alertingPreviewUpgrade,preview,@grafana/alerting-squad,2024-01-03,false,true,false
|
||||||
enablePluginsTracingByDefault,experimental,@grafana/plugins-platform-backend,2024-01-09,false,false,true,false
|
enablePluginsTracingByDefault,experimental,@grafana/plugins-platform-backend,2024-01-09,false,true,false
|
||||||
cloudRBACRoles,experimental,@grafana/identity-access-team,2024-01-10,false,false,true,false
|
cloudRBACRoles,experimental,@grafana/identity-access-team,2024-01-10,false,true,false
|
||||||
alertingQueryOptimization,GA,@grafana/alerting-squad,2024-01-10,false,false,false,false
|
alertingQueryOptimization,GA,@grafana/alerting-squad,2024-01-10,false,false,false
|
||||||
newFolderPicker,experimental,@grafana/grafana-frontend-platform,2024-01-12,false,false,false,true
|
newFolderPicker,experimental,@grafana/grafana-frontend-platform,2024-01-12,false,false,true
|
||||||
jitterAlertRules,GA,@grafana/alerting-squad,2024-01-17,false,false,true,false
|
jitterAlertRules,GA,@grafana/alerting-squad,2024-01-17,false,true,false
|
||||||
jitterAlertRulesWithinGroups,preview,@grafana/alerting-squad,2024-01-17,false,false,true,false
|
jitterAlertRulesWithinGroups,preview,@grafana/alerting-squad,2024-01-17,false,true,false
|
||||||
onPremToCloudMigrations,experimental,@grafana/grafana-operator-experience-squad,2024-01-22,false,false,false,false
|
onPremToCloudMigrations,experimental,@grafana/grafana-operator-experience-squad,2024-01-22,false,false,false
|
||||||
alertingSaveStatePeriodic,privatePreview,@grafana/alerting-squad,2024-01-22,false,false,false,false
|
alertingSaveStatePeriodic,privatePreview,@grafana/alerting-squad,2024-01-22,false,false,false
|
||||||
|
|
@ -218,7 +218,6 @@ func generateCSV() string {
|
|||||||
"Owner", //string(flag.Owner),
|
"Owner", //string(flag.Owner),
|
||||||
"Created",
|
"Created",
|
||||||
"requiresDevMode", //strconv.FormatBool(flag.RequiresDevMode),
|
"requiresDevMode", //strconv.FormatBool(flag.RequiresDevMode),
|
||||||
"RequiresLicense", //strconv.FormatBool(flag.RequiresLicense),
|
|
||||||
"RequiresRestart", //strconv.FormatBool(flag.RequiresRestart),
|
"RequiresRestart", //strconv.FormatBool(flag.RequiresRestart),
|
||||||
"FrontendOnly", //strconv.FormatBool(flag.FrontendOnly),
|
"FrontendOnly", //strconv.FormatBool(flag.FrontendOnly),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -239,7 +238,6 @@ func generateCSV() string {
|
|||||||
string(flag.Owner),
|
string(flag.Owner),
|
||||||
dateFormatter(flag.Created),
|
dateFormatter(flag.Created),
|
||||||
strconv.FormatBool(flag.RequiresDevMode),
|
strconv.FormatBool(flag.RequiresDevMode),
|
||||||
strconv.FormatBool(flag.RequiresLicense),
|
|
||||||
strconv.FormatBool(flag.RequiresRestart),
|
strconv.FormatBool(flag.RequiresRestart),
|
||||||
strconv.FormatBool(flag.FrontendOnly),
|
strconv.FormatBool(flag.FrontendOnly),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -30,7 +30,7 @@ func ReqCanAdminPlugins(cfg *setting.Cfg) func(rc *contextmodel.ReqContext) bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeclareRBACRoles(service ac.Service, cfg *setting.Cfg) error {
|
func DeclareRBACRoles(service ac.Service, cfg *setting.Cfg, features featuremgmt.FeatureToggles) error {
|
||||||
AppPluginsReader := ac.RoleRegistration{
|
AppPluginsReader := ac.RoleRegistration{
|
||||||
Role: ac.RoleDTO{
|
Role: ac.RoleDTO{
|
||||||
Name: ac.FixedRolePrefix + "plugins.app:reader",
|
Name: ac.FixedRolePrefix + "plugins.app:reader",
|
||||||
@ -69,7 +69,7 @@ func DeclareRBACRoles(service ac.Service, cfg *setting.Cfg) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !cfg.PluginAdminEnabled ||
|
if !cfg.PluginAdminEnabled ||
|
||||||
(cfg.PluginAdminExternalManageEnabled && !cfg.IsFeatureToggleEnabled(featuremgmt.FlagManagedPluginsInstall)) {
|
(cfg.PluginAdminExternalManageEnabled && !features.IsEnabledGlobally(featuremgmt.FlagManagedPluginsInstall)) {
|
||||||
PluginsMaintainer.Grants = []string{}
|
PluginsMaintainer.Grants = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@ -45,7 +46,7 @@ type DatabaseConfig struct {
|
|||||||
TransactionRetries int
|
TransactionRetries int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatabaseConfig(cfg *setting.Cfg) (*DatabaseConfig, error) {
|
func NewDatabaseConfig(cfg *setting.Cfg, features featuremgmt.FeatureToggles) (*DatabaseConfig, error) {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
return nil, errors.New("cfg cannot be nil")
|
return nil, errors.New("cfg cannot be nil")
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ func NewDatabaseConfig(cfg *setting.Cfg) (*DatabaseConfig, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dbCfg.buildConnectionString(cfg); err != nil {
|
if err := dbCfg.buildConnectionString(cfg, features); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ func (dbCfg *DatabaseConfig) readConfig(cfg *setting.Cfg) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbCfg *DatabaseConfig) buildConnectionString(cfg *setting.Cfg) error {
|
func (dbCfg *DatabaseConfig) buildConnectionString(cfg *setting.Cfg, features featuremgmt.FeatureToggles) error {
|
||||||
if dbCfg.ConnectionString != "" {
|
if dbCfg.ConnectionString != "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -154,8 +155,7 @@ func (dbCfg *DatabaseConfig) buildConnectionString(cfg *setting.Cfg) error {
|
|||||||
cnnstr += fmt.Sprintf("&transaction_isolation=%s", val)
|
cnnstr += fmt.Sprintf("&transaction_isolation=%s", val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:staticcheck
|
if features != nil && features.IsEnabledGlobally(featuremgmt.FlagMysqlAnsiQuotes) {
|
||||||
if cfg.IsFeatureToggleEnabled(featuremgmt.FlagMysqlAnsiQuotes) {
|
|
||||||
cnnstr += "&sql_mode='ANSI_QUOTES'"
|
cnnstr += "&sql_mode='ANSI_QUOTES'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,11 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
type databaseConfigTest struct {
|
type databaseConfigTest struct {
|
||||||
@ -109,7 +110,7 @@ func TestIntegrationSQLConnectionString(t *testing.T) {
|
|||||||
for _, testCase := range databaseConfigTestCases {
|
for _, testCase := range databaseConfigTestCases {
|
||||||
t.Run(testCase.name, func(t *testing.T) {
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
cfg := makeDatabaseTestConfig(t, testCase)
|
cfg := makeDatabaseTestConfig(t, testCase)
|
||||||
dbCfg, err := NewDatabaseConfig(cfg)
|
dbCfg, err := NewDatabaseConfig(cfg, testCase.features)
|
||||||
require.Equal(t, testCase.err, err)
|
require.Equal(t, testCase.err, err)
|
||||||
if testCase.expConnStr != "" {
|
if testCase.expConnStr != "" {
|
||||||
assert.Equal(t, testCase.expConnStr, dbCfg.ConnectionString)
|
assert.Equal(t, testCase.expConnStr, dbCfg.ConnectionString)
|
||||||
|
@ -154,8 +154,6 @@ func TestMigrations(t *testing.T) {
|
|||||||
desc: "with editors can admin",
|
desc: "with editors can admin",
|
||||||
config: &setting.Cfg{
|
config: &setting.Cfg{
|
||||||
EditorsCanAdmin: true,
|
EditorsCanAdmin: true,
|
||||||
// nolint:staticcheck
|
|
||||||
IsFeatureToggleEnabled: func(key string) bool { return key == "accesscontrol" },
|
|
||||||
Raw: ini.Empty(),
|
Raw: ini.Empty(),
|
||||||
},
|
},
|
||||||
expectedRolePerms: map[string][]rawPermission{
|
expectedRolePerms: map[string][]rawPermission{
|
||||||
@ -262,9 +260,6 @@ func setupTestDB(t *testing.T) *xorm.Engine {
|
|||||||
mg := migrator.NewMigrator(x, &setting.Cfg{
|
mg := migrator.NewMigrator(x, &setting.Cfg{
|
||||||
Logger: log.New("acmigration.test"),
|
Logger: log.New("acmigration.test"),
|
||||||
Raw: ini.Empty(),
|
Raw: ini.Empty(),
|
||||||
IsFeatureToggleEnabled: func(key string) bool {
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
migrations := &migrations.OSSMigrations{}
|
migrations := &migrations.OSSMigrations{}
|
||||||
migrations.AddMigration(mg)
|
migrations.AddMigration(mg)
|
||||||
|
@ -21,13 +21,14 @@ import (
|
|||||||
// specifically added
|
// specifically added
|
||||||
|
|
||||||
type OSSMigrations struct {
|
type OSSMigrations struct {
|
||||||
|
features featuremgmt.FeatureToggles
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideOSSMigrations() *OSSMigrations {
|
func ProvideOSSMigrations(features featuremgmt.FeatureToggles) *OSSMigrations {
|
||||||
return &OSSMigrations{}
|
return &OSSMigrations{features}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*OSSMigrations) AddMigration(mg *Migrator) {
|
func (oss *OSSMigrations) AddMigration(mg *Migrator) {
|
||||||
mg.AddCreateMigration()
|
mg.AddCreateMigration()
|
||||||
addUserMigrations(mg)
|
addUserMigrations(mg)
|
||||||
addTempUserMigrations(mg)
|
addTempUserMigrations(mg)
|
||||||
@ -94,13 +95,9 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
|
|||||||
AddExternalAlertmanagerToDatasourceMigration(mg)
|
AddExternalAlertmanagerToDatasourceMigration(mg)
|
||||||
|
|
||||||
addFolderMigrations(mg)
|
addFolderMigrations(mg)
|
||||||
// nolint:staticcheck
|
if oss.features != nil && oss.features.IsEnabledGlobally(featuremgmt.FlagExternalServiceAuth) {
|
||||||
if mg.Cfg != nil && mg.Cfg.IsFeatureToggleEnabled != nil {
|
|
||||||
// nolint:staticcheck
|
|
||||||
if mg.Cfg.IsFeatureToggleEnabled(featuremgmt.FlagExternalServiceAuth) {
|
|
||||||
oauthserver.AddMigration(mg)
|
oauthserver.AddMigration(mg)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
anonservice.AddMigration(mg)
|
anonservice.AddMigration(mg)
|
||||||
signingkeys.AddMigration(mg)
|
signingkeys.AddMigration(mg)
|
||||||
@ -115,13 +112,9 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
|
|||||||
ualert.CreateOrgMigratedKVStoreEntries(mg)
|
ualert.CreateOrgMigratedKVStoreEntries(mg)
|
||||||
|
|
||||||
// https://github.com/grafana/identity-access-team/issues/546: tracks removal of the feature toggle from the annotation permission migration
|
// https://github.com/grafana/identity-access-team/issues/546: tracks removal of the feature toggle from the annotation permission migration
|
||||||
// nolint:staticcheck
|
if oss.features != nil && oss.features.IsEnabledGlobally(featuremgmt.FlagAnnotationPermissionUpdate) {
|
||||||
if mg.Cfg != nil && mg.Cfg.IsFeatureToggleEnabled != nil {
|
|
||||||
// nolint:staticcheck
|
|
||||||
if mg.Cfg.IsFeatureToggleEnabled(featuremgmt.FlagAnnotationPermissionUpdate) {
|
|
||||||
accesscontrol.AddManagedDashboardAnnotationActionsMigration(mg)
|
accesscontrol.AddManagedDashboardAnnotationActionsMigration(mg)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
addKVStoreMySQLValueTypeLongTextMigration(mg)
|
addKVStoreMySQLValueTypeLongTextMigration(mg)
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ type ContextSessionKey struct{}
|
|||||||
|
|
||||||
type SQLStore struct {
|
type SQLStore struct {
|
||||||
Cfg *setting.Cfg
|
Cfg *setting.Cfg
|
||||||
|
features featuremgmt.FeatureToggles
|
||||||
sqlxsession *session.SessionDB
|
sqlxsession *session.SessionDB
|
||||||
|
|
||||||
bus bus.Bus
|
bus bus.Bus
|
||||||
@ -52,7 +53,10 @@ type SQLStore struct {
|
|||||||
recursiveQueriesMu sync.Mutex
|
recursiveQueriesMu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideService(cfg *setting.Cfg, migrations registry.DatabaseMigrator, bus bus.Bus, tracer tracing.Tracer) (*SQLStore, error) {
|
func ProvideService(cfg *setting.Cfg,
|
||||||
|
features featuremgmt.FeatureToggles,
|
||||||
|
migrations registry.DatabaseMigrator,
|
||||||
|
bus bus.Bus, tracer tracing.Tracer) (*SQLStore, error) {
|
||||||
// This change will make xorm use an empty default schema for postgres and
|
// This change will make xorm use an empty default schema for postgres and
|
||||||
// by that mimic the functionality of how it was functioning before
|
// by that mimic the functionality of how it was functioning before
|
||||||
// xorm's changes above.
|
// xorm's changes above.
|
||||||
@ -61,9 +65,9 @@ func ProvideService(cfg *setting.Cfg, migrations registry.DatabaseMigrator, bus
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
s.features = features
|
||||||
|
|
||||||
// nolint:staticcheck
|
if err := s.Migrate(features.IsEnabledGlobally(featuremgmt.FlagMigrationLocking)); err != nil {
|
||||||
if err := s.Migrate(cfg.IsFeatureToggleEnabled(featuremgmt.FlagMigrationLocking)); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +91,8 @@ func ProvideService(cfg *setting.Cfg, migrations registry.DatabaseMigrator, bus
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideServiceForTests(cfg *setting.Cfg, migrations registry.DatabaseMigrator) (*SQLStore, error) {
|
func ProvideServiceForTests(cfg *setting.Cfg, features featuremgmt.FeatureToggles, migrations registry.DatabaseMigrator) (*SQLStore, error) {
|
||||||
return initTestDB(cfg, migrations, InitTestDBOpt{EnsureDefaultOrgAndUser: true})
|
return initTestDB(cfg, features, migrations, InitTestDBOpt{EnsureDefaultOrgAndUser: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSQLStore(cfg *setting.Cfg, engine *xorm.Engine,
|
func newSQLStore(cfg *setting.Cfg, engine *xorm.Engine,
|
||||||
@ -239,7 +243,7 @@ func (ss *SQLStore) initEngine(engine *xorm.Engine) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
dbCfg, err := NewDatabaseConfig(ss.Cfg)
|
dbCfg, err := NewDatabaseConfig(ss.Cfg, ss.features)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -402,15 +406,11 @@ type InitTestDBOpt struct {
|
|||||||
FeatureFlags []string
|
FeatureFlags []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var featuresEnabledDuringTests = []string{
|
|
||||||
featuremgmt.FlagPanelTitleSearch,
|
|
||||||
featuremgmt.FlagUnifiedStorage,
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitTestDBWithMigration initializes the test DB given custom migrations.
|
// InitTestDBWithMigration initializes the test DB given custom migrations.
|
||||||
func InitTestDBWithMigration(t ITestDB, migration registry.DatabaseMigrator, opts ...InitTestDBOpt) *SQLStore {
|
func InitTestDBWithMigration(t ITestDB, migration registry.DatabaseMigrator, opts ...InitTestDBOpt) *SQLStore {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
store, err := initTestDB(setting.NewCfg(), migration, opts...)
|
features := getFeaturesForTesting(opts...)
|
||||||
|
store, err := initTestDB(setting.NewCfg(), features, migration, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to initialize sql store: %s", err)
|
t.Fatalf("failed to initialize sql store: %s", err)
|
||||||
}
|
}
|
||||||
@ -420,7 +420,9 @@ func InitTestDBWithMigration(t ITestDB, migration registry.DatabaseMigrator, opt
|
|||||||
// InitTestDB initializes the test DB.
|
// InitTestDB initializes the test DB.
|
||||||
func InitTestDB(t ITestDB, opts ...InitTestDBOpt) *SQLStore {
|
func InitTestDB(t ITestDB, opts ...InitTestDBOpt) *SQLStore {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
store, err := initTestDB(setting.NewCfg(), &migrations.OSSMigrations{}, opts...)
|
features := getFeaturesForTesting(opts...)
|
||||||
|
|
||||||
|
store, err := initTestDB(setting.NewCfg(), features, migrations.ProvideOSSMigrations(features), opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to initialize sql store: %s", err)
|
t.Fatalf("failed to initialize sql store: %s", err)
|
||||||
}
|
}
|
||||||
@ -432,8 +434,26 @@ func InitTestDBWithCfg(t ITestDB, opts ...InitTestDBOpt) (*SQLStore, *setting.Cf
|
|||||||
return store, store.Cfg
|
return store, store.Cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getFeaturesForTesting(opts ...InitTestDBOpt) featuremgmt.FeatureToggles {
|
||||||
|
featureKeys := []any{
|
||||||
|
featuremgmt.FlagPanelTitleSearch,
|
||||||
|
featuremgmt.FlagUnifiedStorage,
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
if len(opt.FeatureFlags) > 0 {
|
||||||
|
for _, f := range opt.FeatureFlags {
|
||||||
|
featureKeys = append(featureKeys, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return featuremgmt.WithFeatures(featureKeys...)
|
||||||
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
//nolint:gocyclo
|
||||||
func initTestDB(testCfg *setting.Cfg, migration registry.DatabaseMigrator, opts ...InitTestDBOpt) (*SQLStore, error) {
|
func initTestDB(testCfg *setting.Cfg,
|
||||||
|
features featuremgmt.FeatureToggles,
|
||||||
|
migration registry.DatabaseMigrator,
|
||||||
|
opts ...InitTestDBOpt) (*SQLStore, error) {
|
||||||
testSQLStoreMutex.Lock()
|
testSQLStoreMutex.Lock()
|
||||||
defer testSQLStoreMutex.Unlock()
|
defer testSQLStoreMutex.Unlock()
|
||||||
|
|
||||||
@ -441,14 +461,6 @@ func initTestDB(testCfg *setting.Cfg, migration registry.DatabaseMigrator, opts
|
|||||||
opts = []InitTestDBOpt{{EnsureDefaultOrgAndUser: false, FeatureFlags: []string{}}}
|
opts = []InitTestDBOpt{{EnsureDefaultOrgAndUser: false, FeatureFlags: []string{}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
features := make([]string, len(featuresEnabledDuringTests))
|
|
||||||
copy(features, featuresEnabledDuringTests)
|
|
||||||
for _, opt := range opts {
|
|
||||||
if len(opt.FeatureFlags) > 0 {
|
|
||||||
features = append(features, opt.FeatureFlags...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if testSQLStore == nil {
|
if testSQLStore == nil {
|
||||||
dbType := migrator.SQLite
|
dbType := migrator.SQLite
|
||||||
|
|
||||||
@ -460,14 +472,7 @@ func initTestDB(testCfg *setting.Cfg, migration registry.DatabaseMigrator, opts
|
|||||||
// set test db config
|
// set test db config
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
cfg.IsFeatureToggleEnabled = func(key string) bool {
|
cfg.IsFeatureToggleEnabled = features.IsEnabledGlobally
|
||||||
for _, enabledFeature := range features {
|
|
||||||
if enabledFeature == key {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
sec, err := cfg.Raw.NewSection("database")
|
sec, err := cfg.Raw.NewSection("database")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -555,14 +560,7 @@ func initTestDB(testCfg *setting.Cfg, migration registry.DatabaseMigrator, opts
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
testSQLStore.Cfg.IsFeatureToggleEnabled = func(key string) bool {
|
testSQLStore.Cfg.IsFeatureToggleEnabled = features.IsEnabledGlobally
|
||||||
for _, enabledFeature := range features {
|
|
||||||
if enabledFeature == key {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := testSQLStore.Dialect.TruncateDBTables(testSQLStore.GetEngine()); err != nil {
|
if err := testSQLStore.Dialect.TruncateDBTables(testSQLStore.GetEngine()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -41,7 +41,7 @@ func newConfig(cfg *setting.Cfg) *config {
|
|||||||
host := fmt.Sprintf("%s:%d", ip, port)
|
host := fmt.Sprintf("%s:%d", ip, port)
|
||||||
|
|
||||||
return &config{
|
return &config{
|
||||||
enabled: true, // cfg.IsFeatureToggleEnabled(featuremgmt.FlagGrafanaStorageServer),
|
enabled: true,
|
||||||
devMode: cfg.Env == setting.Dev,
|
devMode: cfg.Env == setting.Dev,
|
||||||
ip: ip,
|
ip: ip,
|
||||||
port: port,
|
port: port,
|
||||||
|
@ -144,12 +144,6 @@ func (o *OSSImpl) Section(section string) Section {
|
|||||||
|
|
||||||
func (*OSSImpl) RegisterReloadHandler(string, ReloadHandler) {}
|
func (*OSSImpl) RegisterReloadHandler(string, ReloadHandler) {}
|
||||||
|
|
||||||
// Deprecated: use feature toggles
|
|
||||||
func (o *OSSImpl) IsFeatureToggleEnabled(name string) bool {
|
|
||||||
// nolint:staticcheck
|
|
||||||
return o.Cfg.IsFeatureToggleEnabled(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
type keyValImpl struct {
|
type keyValImpl struct {
|
||||||
key *ini.Key
|
key *ini.Key
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user