k8s: add feature toggle and stub to save dashboards k8s (#62053)

pull/62153/head
Ryan McKinley 2 years ago committed by GitHub
parent a0405912a8
commit 4965cf2eda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
  2. 1
      packages/grafana-data/src/types/featureToggles.gen.ts
  3. 8
      pkg/cmd/grafana-cli/runner/wire.go
  4. 8
      pkg/server/wire.go
  5. 5
      pkg/services/dashboards/service/dashboard_service.go
  6. 35
      pkg/services/dashboards/service/service.go
  7. 6
      pkg/services/featuremgmt/registry.go
  8. 4
      pkg/services/featuremgmt/toggles_gen.go
  9. 3
      pkg/services/featuremgmt/toggles_gen_test.go
  10. 93
      pkg/services/store/k8saccess/dashboard_service.go

@ -109,6 +109,7 @@ The following toggles require explicitly setting Grafana's [app mode]({{< relref
| `showFeatureFlagsInUI` | Show feature flags in the settings UI |
| `publicDashboardsEmailSharing` | Allows public dashboard sharing to be restricted to only allowed emails |
| `k8s` | Explore native k8s integrations |
| `k8sDashboards` | Save dashboards via k8s |
| `dashboardsFromStorage` | Load dashboards from the generic storage interface |
| `export` | Export grafana instance (to git, etc) |
| `azureMonitorResourcePickerForMetrics` | New UI for Azure Monitor Metrics Query |

@ -43,6 +43,7 @@ export interface FeatureToggles {
migrationLocking?: boolean;
storage?: boolean;
k8s?: boolean;
k8sDashboards?: boolean;
supportBundles?: boolean;
dashboardsFromStorage?: boolean;
export?: boolean;

@ -251,11 +251,11 @@ var wireSet = wire.NewSet(
teamguardianDatabase.ProvideTeamGuardianStore,
wire.Bind(new(teamguardian.Store), new(*teamguardianDatabase.TeamGuardianStoreImpl)),
teamguardianManager.ProvideService,
dashboardservice.ProvideDashboardService,
dashboardservice.ProvideDashboardService, //DashboardServiceImpl
dashboardstore.ProvideDashboardStore,
wire.Bind(new(dashboards.DashboardService), new(*dashboardservice.DashboardServiceImpl)),
wire.Bind(new(dashboards.DashboardProvisioningService), new(*dashboardservice.DashboardServiceImpl)),
wire.Bind(new(dashboards.PluginService), new(*dashboardservice.DashboardServiceImpl)),
dashboardservice.ProvideSimpleDashboardService,
dashboardservice.ProvideDashboardProvisioningService,
dashboardservice.ProvideDashboardPluginService,
wire.Bind(new(dashboards.Store), new(*dashboardstore.DashboardStore)),
wire.Bind(new(dashboards.FolderStore), new(*dashboardstore.DashboardStore)),
dashboardimportservice.ProvideService,

@ -287,12 +287,12 @@ var wireBasicSet = wire.NewSet(
teamguardianManager.ProvideService,
featuremgmt.ProvideManagerService,
featuremgmt.ProvideToggles,
dashboardservice.ProvideDashboardService,
dashboardservice.ProvideDashboardService, // DashboardServiceImpl
dashboardstore.ProvideDashboardStore,
folderimpl.ProvideService,
wire.Bind(new(dashboards.DashboardService), new(*dashboardservice.DashboardServiceImpl)),
wire.Bind(new(dashboards.DashboardProvisioningService), new(*dashboardservice.DashboardServiceImpl)),
wire.Bind(new(dashboards.PluginService), new(*dashboardservice.DashboardServiceImpl)),
dashboardservice.ProvideSimpleDashboardService,
dashboardservice.ProvideDashboardProvisioningService,
dashboardservice.ProvideDashboardPluginService,
wire.Bind(new(dashboards.Store), new(*dashboardstore.DashboardStore)),
wire.Bind(new(dashboards.FolderStore), new(*dashboardstore.DashboardStore)),
dashboardimportservice.ProvideService,

@ -31,7 +31,9 @@ var (
{Action: dashboards.ActionDashboardsWrite, Scope: dashboards.ScopeFoldersAll},
}
// DashboardServiceImpl implements the DashboardService interface
_ dashboards.DashboardService = (*DashboardServiceImpl)(nil)
_ dashboards.DashboardService = (*DashboardServiceImpl)(nil)
_ dashboards.DashboardProvisioningService = (*DashboardServiceImpl)(nil)
_ dashboards.PluginService = (*DashboardServiceImpl)(nil)
)
type DashboardServiceImpl struct {
@ -46,6 +48,7 @@ type DashboardServiceImpl struct {
ac accesscontrol.AccessControl
}
// This is the uber service that implements a three smaller services
func ProvideDashboardService(
cfg *setting.Cfg, dashboardStore dashboards.Store, folderStore dashboards.FolderStore, dashAlertExtractor alerting.DashAlertExtractor,
features featuremgmt.FeatureToggles, folderPermissionsService accesscontrol.FolderPermissionsService,

@ -0,0 +1,35 @@
package service
import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/store/entity"
"github.com/grafana/grafana/pkg/services/store/k8saccess"
)
func ProvideSimpleDashboardService(
features featuremgmt.FeatureToggles,
svc *DashboardServiceImpl,
k8s k8saccess.K8SAccess,
store entity.EntityStoreServer,
) dashboards.DashboardService {
if features.IsEnabled(featuremgmt.FlagK8sDashboards) {
if k8s.GetSystemClient() == nil {
panic("k8s dashboards requires the k8s client registered")
}
return k8saccess.NewDashboardService(svc, store)
}
return svc
}
func ProvideDashboardProvisioningService(
features featuremgmt.FeatureToggles, orig *DashboardServiceImpl,
) dashboards.DashboardProvisioningService {
return orig
}
func ProvideDashboardPluginService(
features featuremgmt.FeatureToggles, orig *DashboardServiceImpl,
) dashboards.PluginService {
return orig
}

@ -154,6 +154,12 @@ var (
State: FeatureStateAlpha,
RequiresDevMode: true,
},
{
Name: "k8sDashboards",
Description: "Save dashboards via k8s",
State: FeatureStateAlpha,
RequiresDevMode: true,
},
{
Name: "supportBundles",
Description: "Support bundles for troubleshooting",

@ -115,6 +115,10 @@ const (
// Explore native k8s integrations
FlagK8s = "k8s"
// FlagK8sDashboards
// Save dashboards via k8s
FlagK8sDashboards = "k8sDashboards"
// FlagSupportBundles
// Support bundles for troubleshooting
FlagSupportBundles = "supportBundles"

@ -25,7 +25,8 @@ func TestFeatureToggleFiles(t *testing.T) {
"live-config": true,
"live-pipeline": true,
"live-service-web-worker": true,
"k8s": true, // Camle case does not like this one
"k8s": true, // Camel case does not like this one
"k8sDashboards": true, // or this one
}
t.Run("check registry constraints", func(t *testing.T) {

@ -0,0 +1,93 @@
package k8saccess
import (
"context"
"fmt"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/store/entity"
)
type k8sDashboardService struct {
orig dashboards.DashboardService
store entity.EntityStoreServer
}
var _ dashboards.DashboardService = (*k8sDashboardService)(nil)
func NewDashboardService(orig dashboards.DashboardService, store entity.EntityStoreServer) dashboards.DashboardService {
return &k8sDashboardService{
orig: orig,
store: store,
}
}
func (s *k8sDashboardService) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards.SaveDashboardDTO, shouldValidateAlerts bool, validateProvisionedDashboard bool) (*dashboards.SaveDashboardCommand, error) {
return s.orig.BuildSaveDashboardCommand(ctx, dto, shouldValidateAlerts, validateProvisionedDashboard)
}
func (s *k8sDashboardService) DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error {
return s.orig.DeleteDashboard(ctx, dashboardId, orgId)
}
func (s *k8sDashboardService) FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) {
return s.orig.FindDashboards(ctx, query)
}
func (s *k8sDashboardService) GetDashboard(ctx context.Context, query *dashboards.GetDashboardQuery) error {
return s.orig.GetDashboard(ctx, query)
}
func (s *k8sDashboardService) GetDashboardACLInfoList(ctx context.Context, query *dashboards.GetDashboardACLInfoListQuery) error {
return s.orig.GetDashboardACLInfoList(ctx, query)
}
func (s *k8sDashboardService) GetDashboards(ctx context.Context, query *dashboards.GetDashboardsQuery) error {
return s.orig.GetDashboards(ctx, query)
}
func (s *k8sDashboardService) GetDashboardTags(ctx context.Context, query *dashboards.GetDashboardTagsQuery) error {
return s.orig.GetDashboardTags(ctx, query)
}
func (s *k8sDashboardService) GetDashboardUIDByID(ctx context.Context, query *dashboards.GetDashboardRefByIDQuery) error {
return s.orig.GetDashboardUIDByID(ctx, query)
}
func (s *k8sDashboardService) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
return s.orig.HasAdminPermissionInDashboardsOrFolders(ctx, query)
}
func (s *k8sDashboardService) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
return s.orig.HasEditPermissionInFolders(ctx, query)
}
func (s *k8sDashboardService) ImportDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*dashboards.Dashboard, error) {
return s.orig.ImportDashboard(ctx, dto)
}
func (s *k8sDashboardService) MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error {
return s.orig.MakeUserAdmin(ctx, orgID, userID, dashboardID, setViewAndEditPermissions)
}
func (s *k8sDashboardService) SaveDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO, allowUiUpdate bool) (*dashboards.Dashboard, error) {
fmt.Printf("SAVE: " + dto.Dashboard.UID)
return s.orig.SaveDashboard(ctx, dto, allowUiUpdate)
}
func (s *k8sDashboardService) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
return s.orig.SearchDashboards(ctx, query)
}
func (s *k8sDashboardService) UpdateDashboardACL(ctx context.Context, uid int64, items []*dashboards.DashboardACL) error {
return s.orig.UpdateDashboardACL(ctx, uid, items)
}
func (s *k8sDashboardService) DeleteACLByUser(ctx context.Context, userID int64) error {
return s.orig.DeleteACLByUser(ctx, userID)
}
func (s *k8sDashboardService) CountDashboardsInFolder(ctx context.Context, query *dashboards.CountDashboardsInFolderQuery) (int64, error) {
return s.orig.CountDashboardsInFolder(ctx, query)
}
Loading…
Cancel
Save