From 17e4a3b38639b30ad4d3493b857af752c7bbc4ec Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 22 Apr 2025 11:39:40 +0300 Subject: [PATCH] Playlists: Remove kubernetesPlaylists flag (#104171) --- .../feature-toggles/index.md | 1 - .../src/types/featureToggles.gen.ts | 5 - pkg/api/playlist.go | 271 +++++------------- pkg/services/apiserver/options/storage.go | 20 -- .../apiserver/options/storage_test.go | 58 ---- pkg/services/apiserver/service.go | 8 - pkg/services/featuremgmt/registry.go | 8 - pkg/services/featuremgmt/toggles_gen.csv | 1 - pkg/services/featuremgmt/toggles_gen.go | 4 - pkg/tests/apis/playlist/playlist_test.go | 46 --- 10 files changed, 77 insertions(+), 345 deletions(-) diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 44f575fdba0..a0a36e07813 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -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 | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 5334d20edba..2bb29c441a8 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -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; diff --git a/pkg/api/playlist.go b/pkg/api/playlist.go index 0f0eea701a3..4108bba14f9 100644 --- a/pkg/api/playlist.go +++ b/pkg/api/playlist.go @@ -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 { diff --git a/pkg/services/apiserver/options/storage.go b/pkg/services/apiserver/options/storage.go index e1baed17fe5..15199252146 100644 --- a/pkg/services/apiserver/options/storage.go +++ b/pkg/services/apiserver/options/storage.go @@ -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 -} diff --git a/pkg/services/apiserver/options/storage_test.go b/pkg/services/apiserver/options/storage_test.go index 658acd0bfb0..4710442c65b 100644 --- a/pkg/services/apiserver/options/storage_test.go +++ b/pkg/services/apiserver/options/storage_test.go @@ -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 diff --git a/pkg/services/apiserver/service.go b/pkg/services/apiserver/service.go index 98226a1754e..ee82a148919 100644 --- a/pkg/services/apiserver/service.go +++ b/pkg/services/apiserver/service.go @@ -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 diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 50587c68e72..2ea014cbb0c 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -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", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 8f9412f67a2..f7481981212 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -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 diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 4f656c09256..09378c3e93c 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -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" diff --git a/pkg/tests/apis/playlist/playlist_test.go b/pkg/tests/apis/playlist/playlist_test.go index f977ad79fba..6d06e9c306d 100644 --- a/pkg/tests/apis/playlist/playlist_test.go +++ b/pkg/tests/apis/playlist/playlist_test.go @@ -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,