Playlists: Remove kubernetesPlaylists flag (#104171)

This commit is contained in:
Ryan McKinley
2025-04-22 10:39:40 +02:00
committed by GitHub
parent 64e9f9bf44
commit 17e4a3b386
10 changed files with 77 additions and 345 deletions
@@ -45,7 +45,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
| `externalCorePlugins` | Allow core plugins to be loaded as external | Yes |
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
| `formatString` | Enable format string transformer | Yes |
| `kubernetesPlaylists` | Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s | Yes |
| `kubernetesClientDashboardsFolders` | Route the folder and dashboard service requests to k8s | Yes |
| `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes |
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
@@ -309,11 +309,6 @@ export interface FeatureToggles {
*/
formatString?: boolean;
/**
* Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s
* @default true
*/
kubernetesPlaylists?: boolean;
/**
* Routes snapshot requests from /api to the /apis endpoint
*/
kubernetesSnapshots?: boolean;
+77 -194
View File
@@ -11,14 +11,11 @@ import (
"github.com/grafana/grafana/apps/playlist/pkg/apis/playlist/v0alpha1"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
internalplaylist "github.com/grafana/grafana/pkg/registry/apps/playlist"
grafanaapiserver "github.com/grafana/grafana/pkg/services/apiserver"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/playlist"
"github.com/grafana/grafana/pkg/util/errhttp"
"github.com/grafana/grafana/pkg/web"
@@ -28,200 +25,17 @@ func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
// Register the actual handlers
// TODO: remove kubernetesPlaylists feature flag
apiRoute.Group("/playlists", func(playlistRoute routing.RouteRegister) {
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesPlaylists) {
// Use k8s client to implement legacy API
handler := newPlaylistK8sHandler(hs)
playlistRoute.Get("/", handler.searchPlaylists)
playlistRoute.Get("/:uid", handler.getPlaylist)
playlistRoute.Get("/:uid/items", handler.getPlaylistItems)
playlistRoute.Delete("/:uid", handler.deletePlaylist)
playlistRoute.Put("/:uid", handler.updatePlaylist)
playlistRoute.Post("/", handler.createPlaylist)
} else {
// Legacy handlers
playlistRoute.Get("/", routing.Wrap(hs.SearchPlaylists))
playlistRoute.Get("/:uid", hs.validateOrgPlaylist, routing.Wrap(hs.GetPlaylist))
playlistRoute.Get("/:uid/items", hs.validateOrgPlaylist, routing.Wrap(hs.GetPlaylistItems))
playlistRoute.Delete("/:uid", middleware.ReqEditorRole, hs.validateOrgPlaylist, routing.Wrap(hs.DeletePlaylist))
playlistRoute.Put("/:uid", middleware.ReqEditorRole, hs.validateOrgPlaylist, routing.Wrap(hs.UpdatePlaylist))
playlistRoute.Post("/", middleware.ReqEditorRole, routing.Wrap(hs.CreatePlaylist))
}
// Use k8s client to implement legacy API
handler := newPlaylistK8sHandler(hs)
playlistRoute.Get("/", handler.searchPlaylists)
playlistRoute.Get("/:uid", handler.getPlaylist)
playlistRoute.Get("/:uid/items", handler.getPlaylistItems)
playlistRoute.Delete("/:uid", handler.deletePlaylist)
playlistRoute.Put("/:uid", handler.updatePlaylist)
playlistRoute.Post("/", handler.createPlaylist)
})
}
func (hs *HTTPServer) validateOrgPlaylist(c *contextmodel.ReqContext) {
uid := web.Params(c.Req)[":uid"]
query := playlist.GetPlaylistByUidQuery{UID: uid, OrgId: c.GetOrgID()}
p, err := hs.playlistService.GetWithoutItems(c.Req.Context(), &query)
if err != nil {
c.JsonApiErr(404, "Playlist not found", err)
return
}
if p.OrgId == 0 {
c.JsonApiErr(404, "Playlist not found", err)
return
}
if p.OrgId != c.GetOrgID() {
c.JsonApiErr(403, "You are not allowed to edit/view playlist", nil)
return
}
}
// swagger:route GET /playlists playlists searchPlaylists
//
// Get playlists.
//
// Responses:
// 200: searchPlaylistsResponse
// 500: internalServerError
func (hs *HTTPServer) SearchPlaylists(c *contextmodel.ReqContext) response.Response {
query := c.Query("query")
limit := c.QueryInt("limit")
if limit == 0 {
limit = 1000
}
searchQuery := playlist.GetPlaylistsQuery{
Name: query,
Limit: limit,
OrgId: c.GetOrgID(),
}
playlists, err := hs.playlistService.Search(c.Req.Context(), &searchQuery)
if err != nil {
return response.Error(http.StatusInternalServerError, "Search failed", err)
}
return response.JSON(http.StatusOK, playlists)
}
// swagger:route GET /playlists/{uid} playlists getPlaylist
//
// Get playlist.
//
// Responses:
// 200: getPlaylistResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) GetPlaylist(c *contextmodel.ReqContext) response.Response {
uid := web.Params(c.Req)[":uid"]
cmd := playlist.GetPlaylistByUidQuery{UID: uid, OrgId: c.GetOrgID()}
dto, err := hs.playlistService.Get(c.Req.Context(), &cmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Playlist not found", err)
}
return response.JSON(http.StatusOK, dto)
}
// swagger:route GET /playlists/{uid}/items playlists getPlaylistItems
//
// Get playlist items.
//
// Responses:
// 200: getPlaylistItemsResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) GetPlaylistItems(c *contextmodel.ReqContext) response.Response {
uid := web.Params(c.Req)[":uid"]
cmd := playlist.GetPlaylistByUidQuery{UID: uid, OrgId: c.GetOrgID()}
dto, err := hs.playlistService.Get(c.Req.Context(), &cmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Playlist not found", err)
}
return response.JSON(http.StatusOK, dto.Items)
}
// swagger:route DELETE /playlists/{uid} playlists deletePlaylist
//
// Delete playlist.
//
// Responses:
// 200: okResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) DeletePlaylist(c *contextmodel.ReqContext) response.Response {
uid := web.Params(c.Req)[":uid"]
cmd := playlist.DeletePlaylistCommand{UID: uid, OrgId: c.GetOrgID()}
if err := hs.playlistService.Delete(c.Req.Context(), &cmd); err != nil {
return response.Error(http.StatusInternalServerError, "Failed to delete playlist", err)
}
return response.JSON(http.StatusOK, "")
}
// swagger:route POST /playlists playlists createPlaylist
//
// Create playlist.
//
// Responses:
// 200: createPlaylistResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) CreatePlaylist(c *contextmodel.ReqContext) response.Response {
cmd := playlist.CreatePlaylistCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.GetOrgID()
p, err := hs.playlistService.Create(c.Req.Context(), &cmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to create playlist", err)
}
return response.JSON(http.StatusOK, p)
}
// swagger:route PUT /playlists/{uid} playlists updatePlaylist
//
// Update playlist.
//
// Responses:
// 200: updatePlaylistResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) UpdatePlaylist(c *contextmodel.ReqContext) response.Response {
cmd := playlist.UpdatePlaylistCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd.OrgId = c.GetOrgID()
cmd.UID = web.Params(c.Req)[":uid"]
_, err := hs.playlistService.Update(c.Req.Context(), &cmd)
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to save playlist", err)
}
dto, err := hs.playlistService.Get(c.Req.Context(), &playlist.GetPlaylistByUidQuery{
UID: cmd.UID,
OrgId: c.GetOrgID(),
})
if err != nil {
return response.Error(http.StatusInternalServerError, "Failed to load playlist", err)
}
return response.JSON(http.StatusOK, dto)
}
// swagger:parameters searchPlaylists
type SearchPlaylistsParams struct {
// in:query
@@ -342,6 +156,15 @@ func newPlaylistK8sHandler(hs *HTTPServer) *playlistK8sHandler {
}
}
// swagger:route GET /playlists playlists searchPlaylists
//
// Get playlists.
//
// Responses:
// 200: searchPlaylistsResponse
// 500: internalServerError
//
// Deprecated: use /apis/playlist.grafana.app/
func (pk8s *playlistK8sHandler) searchPlaylists(c *contextmodel.ReqContext) {
client, ok := pk8s.getClient(c)
if !ok {
@@ -368,6 +191,18 @@ func (pk8s *playlistK8sHandler) searchPlaylists(c *contextmodel.ReqContext) {
c.JSON(http.StatusOK, playlists)
}
// swagger:route GET /playlists/{uid} playlists getPlaylist
//
// Get playlist.
//
// Responses:
// 200: getPlaylistResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
//
// Deprecated: use /apis/playlist.grafana.app/
func (pk8s *playlistK8sHandler) getPlaylist(c *contextmodel.ReqContext) {
client, ok := pk8s.getClient(c)
if !ok {
@@ -382,6 +217,18 @@ func (pk8s *playlistK8sHandler) getPlaylist(c *contextmodel.ReqContext) {
c.JSON(http.StatusOK, internalplaylist.UnstructuredToLegacyPlaylistDTO(*out))
}
// swagger:route GET /playlists/{uid}/items playlists getPlaylistItems
//
// Get playlist items.
//
// Responses:
// 200: getPlaylistItemsResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
//
// Deprecated: use /apis/playlist.grafana.app/
func (pk8s *playlistK8sHandler) getPlaylistItems(c *contextmodel.ReqContext) {
client, ok := pk8s.getClient(c)
if !ok {
@@ -396,6 +243,18 @@ func (pk8s *playlistK8sHandler) getPlaylistItems(c *contextmodel.ReqContext) {
c.JSON(http.StatusOK, internalplaylist.UnstructuredToLegacyPlaylistDTO(*out).Items)
}
// swagger:route DELETE /playlists/{uid} playlists deletePlaylist
//
// Delete playlist.
//
// Responses:
// 200: okResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
//
// Deprecated: use /apis/playlist.grafana.app/
func (pk8s *playlistK8sHandler) deletePlaylist(c *contextmodel.ReqContext) {
client, ok := pk8s.getClient(c)
if !ok {
@@ -410,6 +269,18 @@ func (pk8s *playlistK8sHandler) deletePlaylist(c *contextmodel.ReqContext) {
c.JSON(http.StatusOK, "")
}
// swagger:route PUT /playlists/{uid} playlists updatePlaylist
//
// Update playlist.
//
// Responses:
// 200: updatePlaylistResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
//
// Deprecated: use /apis/playlist.grafana.app/
func (pk8s *playlistK8sHandler) updatePlaylist(c *contextmodel.ReqContext) {
client, ok := pk8s.getClient(c)
if !ok {
@@ -437,6 +308,18 @@ func (pk8s *playlistK8sHandler) updatePlaylist(c *contextmodel.ReqContext) {
c.JSON(http.StatusOK, internalplaylist.UnstructuredToLegacyPlaylistDTO(*out))
}
// swagger:route POST /playlists playlists createPlaylist
//
// Create playlist.
//
// Responses:
// 200: createPlaylistResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
//
// Deprecated: use /apis/playlist.grafana.app/
func (pk8s *playlistK8sHandler) createPlaylist(c *contextmodel.ReqContext) {
client, ok := pk8s.getClient(c)
if !ok {
-20
View File
@@ -14,7 +14,6 @@ import (
"k8s.io/client-go/rest"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/storage/unified/apistore"
"github.com/grafana/grafana/pkg/storage/unified/resource"
@@ -153,22 +152,3 @@ func (o *StorageOptions) ApplyTo(serverConfig *genericapiserver.RecommendedConfi
serverConfig.RESTOptionsGetter = getter
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 {
// nolint:staticcheck
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
}
@@ -4,66 +4,8 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
)
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, // nolint:staticcheck
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)
})
}
}
func TestStorageOptions_Validate(t *testing.T) {
tests := []struct {
name string
-8
View File
@@ -271,14 +271,6 @@ func (s *service) start(ctx context.Context) error {
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(s.codecs)
if err := o.ApplyTo(serverConfig); err != nil {
return err
-8
View File
@@ -517,14 +517,6 @@ var (
Owner: grafanaDatavizSquad,
Expression: "true", // enabled by default
},
{
Name: "kubernetesPlaylists",
Description: "Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s",
Stage: FeatureStageGeneralAvailability,
Owner: grafanaAppPlatformSquad,
Expression: "true",
RequiresRestart: true, // changes the API routing
},
{
Name: "kubernetesSnapshots",
Description: "Routes snapshot requests from /api to the /apis endpoint",
-1
View File
@@ -66,7 +66,6 @@ panelMonitoring,GA,@grafana/dataviz-squad,false,false,true
enableNativeHTTPHistogram,experimental,@grafana/grafana-backend-services-squad,false,true,false
disableClassicHTTPHistogram,experimental,@grafana/grafana-backend-services-squad,false,true,false
formatString,GA,@grafana/dataviz-squad,false,false,true
kubernetesPlaylists,GA,@grafana/grafana-app-platform-squad,false,true,false
kubernetesSnapshots,experimental,@grafana/grafana-app-platform-squad,false,true,false
kubernetesDashboards,experimental,@grafana/grafana-app-platform-squad,false,false,true
kubernetesClientDashboardsFolders,GA,@grafana/grafana-app-platform-squad,false,false,false
1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
66 enableNativeHTTPHistogram experimental @grafana/grafana-backend-services-squad false true false
67 disableClassicHTTPHistogram experimental @grafana/grafana-backend-services-squad false true false
68 formatString GA @grafana/dataviz-squad false false true
kubernetesPlaylists GA @grafana/grafana-app-platform-squad false true false
69 kubernetesSnapshots experimental @grafana/grafana-app-platform-squad false true false
70 kubernetesDashboards experimental @grafana/grafana-app-platform-squad false false true
71 kubernetesClientDashboardsFolders GA @grafana/grafana-app-platform-squad false false false
-4
View File
@@ -275,10 +275,6 @@ const (
// Enable format string transformer
FlagFormatString = "formatString"
// FlagKubernetesPlaylists
// Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s
FlagKubernetesPlaylists = "kubernetesPlaylists"
// FlagKubernetesSnapshots
// Routes snapshot requests from /api to the /apis endpoint
FlagKubernetesSnapshots = "kubernetesSnapshots"
-46
View File
@@ -19,7 +19,6 @@ import (
"github.com/grafana/grafana/pkg/apimachinery/utils"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/options"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/playlist"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tests/apis"
@@ -87,9 +86,6 @@ func TestIntegrationPlaylist(t *testing.T) {
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
AppModeProduction: true, // do not start extra port 6443
DisableAnonymous: true,
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // <<< The change we are testing!
},
}))
})
@@ -103,9 +99,6 @@ func TestIntegrationPlaylist(t *testing.T) {
DualWriterMode: grafanarest.Mode0,
},
},
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
}))
})
@@ -119,9 +112,6 @@ func TestIntegrationPlaylist(t *testing.T) {
DualWriterMode: grafanarest.Mode1,
},
},
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
}))
})
@@ -135,9 +125,6 @@ func TestIntegrationPlaylist(t *testing.T) {
DualWriterMode: grafanarest.Mode2,
},
},
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
}))
})
@@ -151,9 +138,6 @@ func TestIntegrationPlaylist(t *testing.T) {
DualWriterMode: grafanarest.Mode3,
},
},
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
}))
})
@@ -167,9 +151,6 @@ func TestIntegrationPlaylist(t *testing.T) {
DualWriterMode: grafanarest.Mode5,
},
},
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
}))
client := helper.GetResourceClient(apis.ResourceClientArgs{
@@ -205,9 +186,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: false, // required for unified storage
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeUnified, // use the entity api tables
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode0,
@@ -230,9 +208,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: false, // required for unified storage
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeUnified, // use the entity api tables
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode2,
@@ -246,9 +221,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: false, // required for unified storage
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeUnified, // use the entity api tables
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode3,
@@ -262,9 +234,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: false, // required for unified storage
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeUnified, // use the entity api tables
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode5,
@@ -286,9 +255,6 @@ func TestIntegrationPlaylist(t *testing.T) {
DualWriterMode: grafanarest.Mode0,
},
},
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
})
// Clear the collection before starting (etcd)
@@ -310,9 +276,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: true,
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeEtcd, // requires etcd running on localhost:2379
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode1,
@@ -339,9 +302,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: true,
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeEtcd, // requires etcd running on localhost:2379
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode2,
@@ -368,9 +328,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: true,
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeEtcd, // requires etcd running on localhost:2379
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode3,
@@ -397,9 +354,6 @@ func TestIntegrationPlaylist(t *testing.T) {
AppModeProduction: true,
DisableAnonymous: true,
APIServerStorageType: options.StorageTypeEtcd, // requires etcd running on localhost:2379
EnableFeatureToggles: []string{
featuremgmt.FlagKubernetesPlaylists, // Required so that legacy calls are also written
},
UnifiedStorageConfig: map[string]setting.UnifiedStorageConfig{
RESOURCEGROUP: {
DualWriterMode: grafanarest.Mode5,