Storage: Read desired mode from config instead of feature flags (#88353)
* Read desired mode from config * Update playlist integration tests * Add mode 1 playlist integration tests * Add mode 0 dual writing to playlist integration tests * Add documentation for the different dual writing modes
This commit is contained in:
@@ -14,6 +14,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
playlistv0alpha1 "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
|
||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/tests/apis"
|
||||
@@ -85,20 +87,51 @@ func TestIntegrationPlaylist(t *testing.T) {
|
||||
}))
|
||||
})
|
||||
|
||||
// #TODO add equivalent tests for the other modes
|
||||
t.Run("with dual write (file)", func(t *testing.T) {
|
||||
t.Run("with dual write (file, mode 0)", func(t *testing.T) {
|
||||
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true,
|
||||
DisableAnonymous: true,
|
||||
APIServerStorageType: "file", // write the files to disk
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
featuremgmt.FlagDualWritePlaylistsMode2,
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode0,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("with dual write (unified storage)", func(t *testing.T) {
|
||||
// #TODO Enable this test once we have fixed dual writing mode 1 behavior
|
||||
// Do_CRUD_via_k8s_(and_check_that_legacy_api_still_works) breaks
|
||||
// t.Run("with dual write (file, mode 1)", func(t *testing.T) {
|
||||
// doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
// AppModeProduction: true,
|
||||
// DisableAnonymous: true,
|
||||
// APIServerStorageType: "file", // write the files to disk
|
||||
// EnableFeatureToggles: []string{
|
||||
// featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
// },
|
||||
// DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
// playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode1,
|
||||
// },
|
||||
// }))
|
||||
// })
|
||||
|
||||
t.Run("with dual write (file, mode 2)", func(t *testing.T) {
|
||||
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true,
|
||||
DisableAnonymous: true,
|
||||
APIServerStorageType: "file", // write the files to disk
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode2,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("with dual write (unified storage, mode 0)", func(t *testing.T) {
|
||||
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: false, // required for unified storage
|
||||
DisableAnonymous: true,
|
||||
@@ -106,12 +139,46 @@ func TestIntegrationPlaylist(t *testing.T) {
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagUnifiedStorage,
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
featuremgmt.FlagDualWritePlaylistsMode2,
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode0,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("with dual write (etcd)", func(t *testing.T) {
|
||||
// #TODO Enable this test once we have fixed dual writing mode 1 behavior
|
||||
// Do_CRUD_via_k8s_(and_check_that_legacy_api_still_works) breaks
|
||||
// t.Run("with dual write (unified storage, mode 1)", func(t *testing.T) {
|
||||
// doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
// AppModeProduction: false, // required for unified storage
|
||||
// DisableAnonymous: true,
|
||||
// APIServerStorageType: "unified", // use the entity api tables
|
||||
// EnableFeatureToggles: []string{
|
||||
// featuremgmt.FlagUnifiedStorage,
|
||||
// featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
// },
|
||||
// DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
// playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode1,
|
||||
// },
|
||||
// }))
|
||||
// })
|
||||
|
||||
t.Run("with dual write (unified storage, mode 2)", func(t *testing.T) {
|
||||
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: false, // required for unified storage
|
||||
DisableAnonymous: true,
|
||||
APIServerStorageType: "unified", // use the entity api tables
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagUnifiedStorage,
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode2,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("with dual write (etcd, mode 0)", func(t *testing.T) {
|
||||
// NOTE: running local etcd, that will be wiped clean!
|
||||
t.Skip("local etcd testing")
|
||||
|
||||
@@ -121,7 +188,63 @@ func TestIntegrationPlaylist(t *testing.T) {
|
||||
APIServerStorageType: "etcd", // requires etcd running on localhost:2379
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
featuremgmt.FlagDualWritePlaylistsMode2,
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode0,
|
||||
},
|
||||
})
|
||||
|
||||
// Clear the collection before starting (etcd)
|
||||
client := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
GVR: gvr,
|
||||
})
|
||||
err := client.Resource.DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
doPlaylistTests(t, helper)
|
||||
})
|
||||
|
||||
t.Run("with dual write (etcd, mode 1)", func(t *testing.T) {
|
||||
// NOTE: running local etcd, that will be wiped clean!
|
||||
t.Skip("local etcd testing")
|
||||
|
||||
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true,
|
||||
DisableAnonymous: true,
|
||||
APIServerStorageType: "etcd", // requires etcd running on localhost:2379
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode1,
|
||||
},
|
||||
})
|
||||
|
||||
// Clear the collection before starting (etcd)
|
||||
client := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
GVR: gvr,
|
||||
})
|
||||
err := client.Resource.DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
doPlaylistTests(t, helper)
|
||||
})
|
||||
|
||||
t.Run("with dual write (etcd, mode 2)", func(t *testing.T) {
|
||||
// NOTE: running local etcd, that will be wiped clean!
|
||||
t.Skip("local etcd testing")
|
||||
|
||||
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true,
|
||||
DisableAnonymous: true,
|
||||
APIServerStorageType: "etcd", // requires etcd running on localhost:2379
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
|
||||
},
|
||||
DualWriterDesiredModes: map[string]grafanarest.DualWriterMode{
|
||||
playlistv0alpha1.GROUPRESOURCE: grafanarest.Mode2,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"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/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
@@ -384,6 +385,15 @@ func CreateGrafDir(t *testing.T, opts ...GrafanaOpts) (string, string) {
|
||||
_, err = grafanaComSection.NewKey("api_url", o.GrafanaComAPIURL)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if o.DualWriterDesiredModes != nil {
|
||||
unifiedStorageMode, err := getOrCreateSection("unified_storage_mode")
|
||||
require.NoError(t, err)
|
||||
for k, v := range o.DualWriterDesiredModes {
|
||||
_, err = unifiedStorageMode.NewKey(k, fmt.Sprint(v))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
logSection, err := getOrCreateSection("database")
|
||||
require.NoError(t, err)
|
||||
@@ -431,6 +441,7 @@ type GrafanaOpts struct {
|
||||
QueryRetries int64
|
||||
APIServerStorageType string
|
||||
GrafanaComAPIURL string
|
||||
DualWriterDesiredModes map[string]grafanarest.DualWriterMode
|
||||
}
|
||||
|
||||
func CreateUser(t *testing.T, store db.DB, cfg *setting.Cfg, cmd user.CreateUserCommand) *user.User {
|
||||
|
||||
Reference in New Issue
Block a user