mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Use dw dynamic config (#91882)
* Remove kubernetesPlaylists feature_toggle * Remove unified_storage_mode * Remove double import * Read from config instead from feature_toggle * cover scenario for when unified storage is not defined * Be temporarily retro compatible with previous feature toggle * Properly read unified_storage section * [WIP] Read new format of config * Fix test * Fix other tests * Generate feature flags file * Use <group>.<resource> schema * Use <group>.resource format on the FE as well * Hide UniStore config from Frontend Signed-off-by: Maicon Costa <maiconscosta@gmail.com> * unwanted changes * Use feature toggles in the FE. Enforce FTs are present before enabling dual writing Co-authored-by: Ryan McKinley <ryantxu@users.noreply.github.com> * use kubernetes playlists feature toggle on the FE * Remove unwanted code * Remove configs from the FE * Remove commented code * Add more explicit example --------- Signed-off-by: Maicon Costa <maiconscosta@gmail.com> Co-authored-by: Maicon Costa <maiconscosta@gmail.com>
This commit is contained in:
@@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/api/response"
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
|
playlistalpha1 "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
internalplaylist "github.com/grafana/grafana/pkg/registry/apis/playlist"
|
internalplaylist "github.com/grafana/grafana/pkg/registry/apis/playlist"
|
||||||
grafanaapiserver "github.com/grafana/grafana/pkg/services/apiserver"
|
grafanaapiserver "github.com/grafana/grafana/pkg/services/apiserver"
|
||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
|
func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
|
||||||
// Register the actual handlers
|
// Register the actual handlers
|
||||||
apiRoute.Group("/playlists", func(playlistRoute routing.RouteRegister) {
|
apiRoute.Group("/playlists", func(playlistRoute routing.RouteRegister) {
|
||||||
|
// TODO: remove kubernetesPlaylists feature flag
|
||||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesPlaylists) {
|
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesPlaylists) {
|
||||||
// Use k8s client to implement legacy API
|
// Use k8s client to implement legacy API
|
||||||
handler := newPlaylistK8sHandler(hs)
|
handler := newPlaylistK8sHandler(hs)
|
||||||
@@ -330,7 +331,7 @@ type playlistK8sHandler struct {
|
|||||||
|
|
||||||
func newPlaylistK8sHandler(hs *HTTPServer) *playlistK8sHandler {
|
func newPlaylistK8sHandler(hs *HTTPServer) *playlistK8sHandler {
|
||||||
return &playlistK8sHandler{
|
return &playlistK8sHandler{
|
||||||
gvr: v0alpha1.PlaylistResourceInfo.GroupVersionResource(),
|
gvr: playlistalpha1.PlaylistResourceInfo.GroupVersionResource(),
|
||||||
namespacer: request.GetNamespaceMapper(hs.Cfg),
|
namespacer: request.GetNamespaceMapper(hs.Cfg),
|
||||||
clientConfigProvider: hs.clientConfigProvider,
|
clientConfigProvider: hs.clientConfigProvider,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ app_mode = development
|
|||||||
[feature_toggles]
|
[feature_toggles]
|
||||||
grafanaAPIServerEnsureKubectlAccess = true
|
grafanaAPIServerEnsureKubectlAccess = true
|
||||||
kubernetesPlaylists = true
|
kubernetesPlaylists = true
|
||||||
|
|
||||||
|
[unified_storage.playlists.playlist.grafana.app]
|
||||||
|
DualWriterMode = 2
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create a development kubeconfig and start a parallel ssl listener. It can be registered by
|
This will create a development kubeconfig and start a parallel ssl listener. It can be registered by
|
||||||
|
|||||||
@@ -165,7 +165,11 @@ func InstallAPIs(
|
|||||||
|
|
||||||
// Get the option from custom.ini/command line
|
// Get the option from custom.ini/command line
|
||||||
// when missing this will default to mode zero (legacy only)
|
// when missing this will default to mode zero (legacy only)
|
||||||
mode := storageOpts.DualWriterDesiredModes[key]
|
var mode = grafanarest.DualWriterMode(0)
|
||||||
|
resourceConfig, resourceExists := storageOpts.UnifiedStorageConfig[key]
|
||||||
|
if resourceExists {
|
||||||
|
mode = resourceConfig.DualWriterMode
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: inherited context from main Grafana process
|
// TODO: inherited context from main Grafana process
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
playlist "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
|
|
||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/options"
|
"github.com/grafana/grafana/pkg/services/apiserver/options"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@@ -55,20 +53,18 @@ func applyGrafanaConfig(cfg *setting.Cfg, features featuremgmt.FeatureToggles, o
|
|||||||
o.StorageOptions.StorageType = options.StorageType(apiserverCfg.Key("storage_type").MustString(string(options.StorageTypeLegacy)))
|
o.StorageOptions.StorageType = options.StorageType(apiserverCfg.Key("storage_type").MustString(string(options.StorageTypeLegacy)))
|
||||||
o.StorageOptions.DataPath = apiserverCfg.Key("storage_path").MustString(filepath.Join(cfg.DataPath, "grafana-apiserver"))
|
o.StorageOptions.DataPath = apiserverCfg.Key("storage_path").MustString(filepath.Join(cfg.DataPath, "grafana-apiserver"))
|
||||||
o.StorageOptions.Address = apiserverCfg.Key("address").MustString(o.StorageOptions.Address)
|
o.StorageOptions.Address = apiserverCfg.Key("address").MustString(o.StorageOptions.Address)
|
||||||
o.StorageOptions.DualWriterDesiredModes = map[string]grafanarest.DualWriterMode{
|
|
||||||
// TODO: use the new config from HGAPI after https://github.com/grafana/hosted-grafana/pull/5707
|
// unified storage configs look like
|
||||||
playlist.GROUPRESOURCE: 2,
|
// [unified_storage.<group>.<resource>]
|
||||||
}
|
// config = <value>
|
||||||
|
unifiedStorageCfg := cfg.UnifiedStorage
|
||||||
|
o.StorageOptions.UnifiedStorageConfig = unifiedStorageCfg
|
||||||
|
|
||||||
o.StorageOptions.DualWriterDataSyncJobEnabled = map[string]bool{
|
o.StorageOptions.DualWriterDataSyncJobEnabled = map[string]bool{
|
||||||
// TODO: This will be enabled later, when we get a dedicated config section for unified_storage
|
// TODO: This will be enabled later, when we get a dedicated config section for unified_storage
|
||||||
// playlist.RESOURCE + "." + playlist.GROUP: true,
|
// playlist.RESOURCE + "." + playlist.GROUP: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ensure backwards compatibility with production
|
|
||||||
// remove this after changing the unified_storage_mode key format in HGAPI
|
|
||||||
o.StorageOptions.DualWriterDesiredModes[playlist.RESOURCE+"."+playlist.GROUP] = o.StorageOptions.DualWriterDesiredModes[playlist.GROUPRESOURCE]
|
|
||||||
|
|
||||||
o.ExtraOptions.DevMode = features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerEnsureKubectlAccess)
|
o.ExtraOptions.DevMode = features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerEnsureKubectlAccess)
|
||||||
o.ExtraOptions.ExternalAddress = host
|
o.ExtraOptions.ExternalAddress = host
|
||||||
o.ExtraOptions.APIURL = apiURL
|
o.ExtraOptions.APIURL = apiURL
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import (
|
|||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/apiserver/pkg/server/options"
|
"k8s.io/apiserver/pkg/server/options"
|
||||||
|
|
||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageType string
|
type StorageType string
|
||||||
@@ -25,7 +26,7 @@ type StorageOptions struct {
|
|||||||
StorageType StorageType
|
StorageType StorageType
|
||||||
DataPath string
|
DataPath string
|
||||||
Address string
|
Address string
|
||||||
DualWriterDesiredModes map[string]grafanarest.DualWriterMode
|
UnifiedStorageConfig map[string]setting.UnifiedStorageConfig
|
||||||
DualWriterDataSyncJobEnabled map[string]bool
|
DualWriterDataSyncJobEnabled map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,3 +62,21 @@ func (o *StorageOptions) ApplyTo(serverConfig *genericapiserver.RecommendedConfi
|
|||||||
// TODO: move storage setup here
|
// TODO: move storage setup here
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnforceFeatureToggleAfterMode1 makes sure there is a feature toggle set for resources with DualWriterMode > 1.
|
||||||
|
// This is needed to ensure that we use the K8s client before enabling dual writing.
|
||||||
|
func (o *StorageOptions) EnforceFeatureToggleAfterMode1(features featuremgmt.FeatureToggles) error {
|
||||||
|
if o.StorageType != StorageTypeLegacy {
|
||||||
|
for rg, s := range o.UnifiedStorageConfig {
|
||||||
|
if s.DualWriterMode > 1 {
|
||||||
|
switch rg {
|
||||||
|
case "playlists.playlist.grafana.app":
|
||||||
|
if !features.IsEnabledGlobally(featuremgmt.FlagKubernetesPlaylists) {
|
||||||
|
return fmt.Errorf("feature toggle FlagKubernetesPlaylists to be set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
64
pkg/services/apiserver/options/storage_test.go
Normal file
64
pkg/services/apiserver/options/storage_test.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package options
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStorageOptions_CheckFeatureToggle(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
StorageType StorageType
|
||||||
|
UnifiedStorageConfig map[string]setting.UnifiedStorageConfig
|
||||||
|
features any
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "with legacy storage",
|
||||||
|
StorageType: StorageTypeLegacy,
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{"playlists.playlist.grafana.app": {DualWriterMode: 2}},
|
||||||
|
features: featuremgmt.WithFeatures(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with unified storage and without config for resource",
|
||||||
|
StorageType: StorageTypeUnified,
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{},
|
||||||
|
features: featuremgmt.WithFeatures(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with unified storage, mode > 1 and with toggle for resource",
|
||||||
|
StorageType: StorageTypeUnified,
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{"playlists.playlist.grafana.app": {DualWriterMode: 2}},
|
||||||
|
features: featuremgmt.WithFeatures(featuremgmt.FlagKubernetesPlaylists),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with unified storage, mode > 1 and without toggle for resource",
|
||||||
|
StorageType: StorageTypeUnified,
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{"playlists.playlist.grafana.app": {DualWriterMode: 2}},
|
||||||
|
features: featuremgmt.WithFeatures(),
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with unified storage and mode = 1",
|
||||||
|
StorageType: StorageTypeUnified,
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{"playlists.playlist.grafana.app": {DualWriterMode: 1}},
|
||||||
|
features: featuremgmt.WithFeatures(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
o := &StorageOptions{
|
||||||
|
StorageType: tt.StorageType,
|
||||||
|
UnifiedStorageConfig: tt.UnifiedStorageConfig,
|
||||||
|
}
|
||||||
|
err := o.EnforceFeatureToggleAfterMode1(tt.features.(featuremgmt.FeatureToggles))
|
||||||
|
if tt.wantErr {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -263,6 +263,14 @@ func (s *service) start(ctx context.Context) error {
|
|||||||
return errs[0]
|
return errs[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This will check that required feature toggles are enabled for more advanced storage modes
|
||||||
|
// Any required preconditions should be hardcoded here
|
||||||
|
if o.StorageOptions != nil {
|
||||||
|
if err := o.StorageOptions.EnforceFeatureToggleAfterMode1(s.features); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
serverConfig := genericapiserver.NewRecommendedConfig(Codecs)
|
serverConfig := genericapiserver.NewRecommendedConfig(Codecs)
|
||||||
if err := o.ApplyTo(serverConfig); err != nil {
|
if err := o.ApplyTo(serverConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
|
"github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
"github.com/grafana/grafana/pkg/util/osutil"
|
"github.com/grafana/grafana/pkg/util/osutil"
|
||||||
@@ -523,6 +524,13 @@ type Cfg struct {
|
|||||||
|
|
||||||
//Short Links
|
//Short Links
|
||||||
ShortLinkExpiration int
|
ShortLinkExpiration int
|
||||||
|
|
||||||
|
// Unified Storage
|
||||||
|
UnifiedStorage map[string]UnifiedStorageConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnifiedStorageConfig struct {
|
||||||
|
DualWriterMode rest.DualWriterMode
|
||||||
}
|
}
|
||||||
|
|
||||||
type InstallPlugin struct {
|
type InstallPlugin struct {
|
||||||
@@ -1324,6 +1332,9 @@ func (cfg *Cfg) parseINIFile(iniFile *ini.File) error {
|
|||||||
cfg.ScopesListScopesURL = scopesSection.Key("list_scopes_endpoint").MustString("")
|
cfg.ScopesListScopesURL = scopesSection.Key("list_scopes_endpoint").MustString("")
|
||||||
cfg.ScopesListDashboardsURL = scopesSection.Key("list_dashboards_endpoint").MustString("")
|
cfg.ScopesListDashboardsURL = scopesSection.Key("list_dashboards_endpoint").MustString("")
|
||||||
|
|
||||||
|
// read unifed storage config
|
||||||
|
cfg.setUnifiedStorageConfig()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
pkg/setting/setting_unified_storage.go
Normal file
31
pkg/setting/setting_unified_storage.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package setting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
// read storage configs from ini file. They look like:
|
||||||
|
// [unified_storage.<group>.<resource>]
|
||||||
|
// <field> = <value>
|
||||||
|
// e.g.
|
||||||
|
// [unified_storage.playlists.playlist.grafana.app]
|
||||||
|
// dualWriterMode = 2
|
||||||
|
func (cfg *Cfg) setUnifiedStorageConfig() {
|
||||||
|
storageConfig := make(map[string]UnifiedStorageConfig)
|
||||||
|
sections := cfg.Raw.Sections()
|
||||||
|
for _, section := range sections {
|
||||||
|
sectionName := section.Name()
|
||||||
|
if !strings.HasPrefix(sectionName, "unified_storage.") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// the resource name is the part after the first dot
|
||||||
|
resourceName := strings.SplitAfterN(sectionName, ".", 2)[1]
|
||||||
|
|
||||||
|
// parse dualWriter modes from the section
|
||||||
|
dualWriterMode := section.Key("dualWriterMode").MustInt(0)
|
||||||
|
storageConfig[resourceName] = UnifiedStorageConfig{DualWriterMode: rest.DualWriterMode(dualWriterMode)}
|
||||||
|
}
|
||||||
|
cfg.UnifiedStorage = storageConfig
|
||||||
|
}
|
||||||
28
pkg/setting/setting_unified_storage_test.go
Normal file
28
pkg/setting/setting_unified_storage_test.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package setting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCfg_setUnifiedStorageConfig(t *testing.T) {
|
||||||
|
t.Run("read unified_storage configs", func(t *testing.T) {
|
||||||
|
cfg := NewCfg()
|
||||||
|
err := cfg.Load(CommandLineArgs{HomePath: "../../", Config: "../../conf/defaults.ini"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
s, err := cfg.Raw.NewSection("unified_storage.playlists.playlist.grafana.app")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = s.NewKey("dualWriterMode", "2")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
cfg.setUnifiedStorageConfig()
|
||||||
|
|
||||||
|
value, exists := cfg.UnifiedStorage["playlists.playlist.grafana.app"]
|
||||||
|
|
||||||
|
assert.Equal(t, exists, true)
|
||||||
|
assert.Equal(t, value, UnifiedStorageConfig{DualWriterMode: 2})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/playlist"
|
"github.com/grafana/grafana/pkg/services/playlist"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/tests/apis"
|
"github.com/grafana/grafana/pkg/tests/apis"
|
||||||
"github.com/grafana/grafana/pkg/tests/testinfra"
|
"github.com/grafana/grafana/pkg/tests/testinfra"
|
||||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||||
@@ -92,12 +93,14 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
AppModeProduction: true,
|
AppModeProduction: true,
|
||||||
DisableAnonymous: true,
|
DisableAnonymous: true,
|
||||||
APIServerStorageType: "file", // write the files to disk
|
APIServerStorageType: "file", // write the files to disk
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode0,
|
||||||
|
},
|
||||||
|
},
|
||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode0,
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -106,12 +109,14 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
AppModeProduction: true,
|
AppModeProduction: true,
|
||||||
DisableAnonymous: true,
|
DisableAnonymous: true,
|
||||||
APIServerStorageType: "file", // write the files to disk
|
APIServerStorageType: "file", // write the files to disk
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode1,
|
||||||
|
},
|
||||||
|
},
|
||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode1,
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -120,12 +125,14 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
AppModeProduction: true,
|
AppModeProduction: true,
|
||||||
DisableAnonymous: true,
|
DisableAnonymous: true,
|
||||||
APIServerStorageType: "file", // write the files to disk
|
APIServerStorageType: "file", // write the files to disk
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode2,
|
||||||
|
},
|
||||||
|
},
|
||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode2,
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -134,12 +141,14 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
AppModeProduction: true,
|
AppModeProduction: true,
|
||||||
DisableAnonymous: true,
|
DisableAnonymous: true,
|
||||||
APIServerStorageType: "file", // write the files to disk
|
APIServerStorageType: "file", // write the files to disk
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode3,
|
||||||
|
},
|
||||||
|
},
|
||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode3,
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -151,8 +160,10 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode0,
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@@ -162,12 +173,7 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
AppModeProduction: false, // required for unified storage
|
AppModeProduction: false, // required for unified storage
|
||||||
DisableAnonymous: true,
|
DisableAnonymous: true,
|
||||||
APIServerStorageType: "unified", // use the entity api tables
|
APIServerStorageType: "unified", // use the entity api tables
|
||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{},
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
|
||||||
},
|
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode1,
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -179,8 +185,10 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode2,
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@@ -193,8 +201,10 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode3,
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode3,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@@ -207,12 +217,14 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
AppModeProduction: true,
|
AppModeProduction: true,
|
||||||
DisableAnonymous: true,
|
DisableAnonymous: true,
|
||||||
APIServerStorageType: "etcd", // requires etcd running on localhost:2379
|
APIServerStorageType: "etcd", // requires etcd running on localhost:2379
|
||||||
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode0,
|
||||||
|
},
|
||||||
|
},
|
||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode0,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Clear the collection before starting (etcd)
|
// Clear the collection before starting (etcd)
|
||||||
@@ -237,8 +249,10 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode1,
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -264,8 +278,10 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode2,
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -291,8 +307,10 @@ func TestIntegrationPlaylist(t *testing.T) {
|
|||||||
EnableFeatureToggles: []string{
|
EnableFeatureToggles: []string{
|
||||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||||
},
|
},
|
||||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
|
||||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode3,
|
playlistv0alpha1.GROUPRESOURCE: {
|
||||||
|
DualWriterMode: grafanarest.Mode3,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import (
|
|||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api"
|
"github.com/grafana/grafana/pkg/api"
|
||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
|
||||||
"github.com/grafana/grafana/pkg/extensions"
|
"github.com/grafana/grafana/pkg/extensions"
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/infra/fs"
|
"github.com/grafana/grafana/pkg/infra/fs"
|
||||||
@@ -390,12 +389,11 @@ func CreateGrafDir(t *testing.T, opts ...GrafanaOpts) (string, string) {
|
|||||||
_, err = grafanaComSection.NewKey("api_url", o.GrafanaComAPIURL)
|
_, err = grafanaComSection.NewKey("api_url", o.GrafanaComAPIURL)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
if o.UnifiedStorageConfig != nil {
|
||||||
if o.DualWriterDesiredModes != nil {
|
for k, v := range o.UnifiedStorageConfig {
|
||||||
unifiedStorageMode, err := getOrCreateSection("unified_storage_mode")
|
section, err := getOrCreateSection(fmt.Sprintf("unified_storage.%s", k))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
for k, v := range o.DualWriterDesiredModes {
|
_, err = section.NewKey("dualWriterMode", fmt.Sprintf("%d", v.DualWriterMode))
|
||||||
_, err = unifiedStorageMode.NewKey(k, fmt.Sprint(v))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,7 +444,7 @@ type GrafanaOpts struct {
|
|||||||
QueryRetries int64
|
QueryRetries int64
|
||||||
APIServerStorageType string
|
APIServerStorageType string
|
||||||
GrafanaComAPIURL string
|
GrafanaComAPIURL string
|
||||||
DualWriterDesiredModes map[string]grafanarest.DualWriterMode
|
UnifiedStorageConfig map[string]setting.UnifiedStorageConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUser(t *testing.T, store db.DB, cfg *setting.Cfg, cmd user.CreateUserCommand) *user.User {
|
func CreateUser(t *testing.T, store db.DB, cfg *setting.Cfg, cmd user.CreateUserCommand) *user.User {
|
||||||
|
|||||||
Reference in New Issue
Block a user