mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 15:32:08 +08:00
Access control: Move call to create default permissions into folder and dashboard service (#46186)
* Move call to create permissions into folder service * Inject cfg, feature toggles and permissions services into dashboard service * Move logic to set default permissions on create dashboard from api to service * Move call to set default permissions on import dashboard to dashboard service * Set permissions for provisioned dashboard and folders in service
This commit is contained in:
@ -378,7 +378,7 @@ func setupHTTPServerWithCfgDb(t *testing.T, useFakeAccessControl, enableAccessCo
|
|||||||
RouteRegister: routeRegister,
|
RouteRegister: routeRegister,
|
||||||
SQLStore: store,
|
SQLStore: store,
|
||||||
searchUsersService: searchusers.ProvideUsersService(db, filters.ProvideOSSSearchUserFilter()),
|
searchUsersService: searchusers.ProvideUsersService(db, filters.ProvideOSSSearchUserFilter()),
|
||||||
dashboardService: dashboardservice.ProvideDashboardService(dashboardsStore, nil),
|
dashboardService: dashboardservice.ProvideDashboardService(cfg, dashboardsStore, nil, features, accesscontrolmock.NewPermissionsServicesMock()),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defining the accesscontrol service has to be done before registering routes
|
// Defining the accesscontrol service has to be done before registering routes
|
||||||
|
@ -17,10 +17,8 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
"github.com/grafana/grafana/pkg/web"
|
"github.com/grafana/grafana/pkg/web"
|
||||||
@ -360,12 +358,6 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
|||||||
return apierrors.ToDashboardErrorResponse(ctx, hs.pluginStore, err)
|
return apierrors.ToDashboardErrorResponse(ctx, hs.pluginStore, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if newDashboard {
|
|
||||||
if err := hs.setDashboardPermissions(c, cmd, dashboard); err != nil {
|
|
||||||
hs.log.Error("Could not make user admin", "dashboard", dashboard.Title, "user", c.SignedInUser.UserId, "error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect library panels for this dashboard after the dashboard is stored and has an ID
|
// connect library panels for this dashboard after the dashboard is stored and has an ID
|
||||||
err = hs.LibraryPanelService.ConnectLibraryPanelsForDashboard(ctx, c.SignedInUser, dashboard)
|
err = hs.LibraryPanelService.ConnectLibraryPanelsForDashboard(ctx, c.SignedInUser, dashboard)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -383,35 +375,6 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) setDashboardPermissions(c *models.ReqContext, cmd models.SaveDashboardCommand, dash *models.Dashboard) error {
|
|
||||||
inFolder := dash.FolderId > 0
|
|
||||||
if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
|
||||||
resourceID := strconv.FormatInt(dash.Id, 10)
|
|
||||||
svc := hs.permissionServices.GetDashboardService()
|
|
||||||
|
|
||||||
permissions := []accesscontrol.SetResourcePermissionCommand{
|
|
||||||
{UserID: c.UserId, Permission: models.PERMISSION_ADMIN.String()},
|
|
||||||
}
|
|
||||||
|
|
||||||
if !inFolder {
|
|
||||||
permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{
|
|
||||||
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
|
|
||||||
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
|
|
||||||
}...)
|
|
||||||
}
|
|
||||||
_, err := svc.SetPermissions(c.Req.Context(), c.OrgId, resourceID, permissions...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if hs.Cfg.EditorsCanAdmin {
|
|
||||||
if err := hs.dashboardService.MakeUserAdmin(c.Req.Context(), cmd.OrgId, cmd.UserId, dash.Id, !inFolder); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHomeDashboard returns the home dashboard.
|
// GetHomeDashboard returns the home dashboard.
|
||||||
func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
|
func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
|
||||||
prefsQuery := models.GetPreferencesWithDefaultsQuery{User: c.SignedInUser}
|
prefsQuery := models.GetPreferencesWithDefaultsQuery{User: c.SignedInUser}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"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/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
@ -26,13 +27,16 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
|||||||
dashboardStore := &database.FakeDashboardStore{}
|
dashboardStore := &database.FakeDashboardStore{}
|
||||||
defer dashboardStore.AssertExpectations(t)
|
defer dashboardStore.AssertExpectations(t)
|
||||||
|
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||||
|
|
||||||
hs := &HTTPServer{
|
hs := &HTTPServer{
|
||||||
Cfg: settings,
|
Cfg: settings,
|
||||||
dashboardService: dashboardservice.ProvideDashboardService(dashboardStore, nil),
|
SQLStore: mockSQLStore,
|
||||||
SQLStore: mockSQLStore,
|
Features: features,
|
||||||
Features: featuremgmt.WithFeatures(),
|
dashboardService: dashboardservice.ProvideDashboardService(
|
||||||
|
settings, dashboardStore, nil, features, accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("Given user has no admin permissions", func(t *testing.T) {
|
t.Run("Given user has no admin permissions", func(t *testing.T) {
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
@ -214,14 +215,18 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
|||||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||||
mockSQLStore.ExpectedDashboard = fakeDash
|
mockSQLStore.ExpectedDashboard = fakeDash
|
||||||
|
|
||||||
|
cfg := setting.NewCfg()
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlstore.InitTestDB(t))
|
dashboardStore := database.ProvideDashboardStore(sqlstore.InitTestDB(t))
|
||||||
hs := &HTTPServer{
|
hs := &HTTPServer{
|
||||||
Cfg: setting.NewCfg(),
|
Cfg: cfg,
|
||||||
Live: newTestLive(t),
|
Live: newTestLive(t),
|
||||||
LibraryPanelService: &mockLibraryPanelService{},
|
LibraryPanelService: &mockLibraryPanelService{},
|
||||||
LibraryElementService: &mockLibraryElementService{},
|
LibraryElementService: &mockLibraryElementService{},
|
||||||
dashboardService: service.ProvideDashboardService(dashboardStore, nil),
|
|
||||||
SQLStore: mockSQLStore,
|
SQLStore: mockSQLStore,
|
||||||
|
dashboardService: service.ProvideDashboardService(
|
||||||
|
cfg, dashboardStore, nil, features, accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
hs.SQLStore = mockSQLStore
|
hs.SQLStore = mockSQLStore
|
||||||
|
|
||||||
@ -934,14 +939,18 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
|
|||||||
|
|
||||||
libraryPanelsService := mockLibraryPanelService{}
|
libraryPanelsService := mockLibraryPanelService{}
|
||||||
libraryElementsService := mockLibraryElementService{}
|
libraryElementsService := mockLibraryElementService{}
|
||||||
|
cfg := setting.NewCfg()
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
|
|
||||||
hs := &HTTPServer{
|
hs := &HTTPServer{
|
||||||
Cfg: setting.NewCfg(),
|
Cfg: cfg,
|
||||||
LibraryPanelService: &libraryPanelsService,
|
LibraryPanelService: &libraryPanelsService,
|
||||||
LibraryElementService: &libraryElementsService,
|
LibraryElementService: &libraryElementsService,
|
||||||
ProvisioningService: provisioningService,
|
SQLStore: sc.sqlStore,
|
||||||
dashboardProvisioningService: service.ProvideDashboardService(dashboardStore, nil),
|
ProvisioningService: provisioningService,
|
||||||
SQLStore: sc.sqlStore,
|
dashboardProvisioningService: service.ProvideDashboardService(
|
||||||
|
cfg, dashboardStore, nil, features, accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.callGetDashboard(sc)
|
hs.callGetDashboard(sc)
|
||||||
|
@ -11,8 +11,6 @@ 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/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
@ -73,36 +71,10 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
|
|||||||
return apierrors.ToFolderErrorResponse(err)
|
return apierrors.ToFolderErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := hs.setFolderPermission(c, folder.Id); err != nil {
|
|
||||||
hs.log.Error("Could not make user admin", "folder", folder.Title, "user",
|
|
||||||
c.SignedInUser.UserId, "error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||||
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, folder))
|
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, folder))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) setFolderPermission(c *models.ReqContext, folderID int64) error {
|
|
||||||
if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
|
||||||
resourceID := strconv.FormatInt(folderID, 10)
|
|
||||||
svc := hs.permissionServices.GetFolderService()
|
|
||||||
|
|
||||||
_, err := svc.SetPermissions(c.Req.Context(), c.OrgId, resourceID, []accesscontrol.SetResourcePermissionCommand{
|
|
||||||
{UserID: c.UserId, Permission: models.PERMISSION_ADMIN.String()},
|
|
||||||
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
|
|
||||||
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
|
|
||||||
}...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if hs.Cfg.EditorsCanAdmin {
|
|
||||||
if err := hs.folderService.MakeUserAdmin(c.Req.Context(), c.OrgId, c.UserId, folderID, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
|
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
|
||||||
cmd := models.UpdateFolderCommand{}
|
cmd := models.UpdateFolderCommand{}
|
||||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
@ -32,7 +34,18 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
|||||||
dashboardStore := &database.FakeDashboardStore{}
|
dashboardStore := &database.FakeDashboardStore{}
|
||||||
defer dashboardStore.AssertExpectations(t)
|
defer dashboardStore.AssertExpectations(t)
|
||||||
|
|
||||||
hs := &HTTPServer{Cfg: settings, folderService: folderService, dashboardService: service.ProvideDashboardService(dashboardStore, nil), Features: featuremgmt.WithFeatures()}
|
features := featuremgmt.WithFeatures()
|
||||||
|
permissionsServices := accesscontrolmock.NewPermissionsServicesMock()
|
||||||
|
|
||||||
|
hs := &HTTPServer{
|
||||||
|
Cfg: settings,
|
||||||
|
Features: features,
|
||||||
|
folderService: folderService,
|
||||||
|
permissionServices: permissionsServices,
|
||||||
|
dashboardService: service.ProvideDashboardService(
|
||||||
|
settings, dashboardStore, nil, features, permissionsServices,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Given folder not exists", func(t *testing.T) {
|
t.Run("Given folder not exists", func(t *testing.T) {
|
||||||
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, models.ErrFolderNotFound).Twice()
|
folderService.On("GetFolderByUID", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, models.ErrFolderNotFound).Twice()
|
||||||
|
@ -2,7 +2,6 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
@ -12,7 +11,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/dashboardimport/api"
|
"github.com/grafana/grafana/pkg/services/dashboardimport/api"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboardimport/utils"
|
"github.com/grafana/grafana/pkg/services/dashboardimport/utils"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/librarypanels"
|
"github.com/grafana/grafana/pkg/services/librarypanels"
|
||||||
"github.com/grafana/grafana/pkg/services/quota"
|
"github.com/grafana/grafana/pkg/services/quota"
|
||||||
"github.com/grafana/grafana/pkg/services/schemaloader"
|
"github.com/grafana/grafana/pkg/services/schemaloader"
|
||||||
@ -22,14 +20,12 @@ func ProvideService(routeRegister routing.RouteRegister,
|
|||||||
quotaService *quota.QuotaService, schemaLoaderService *schemaloader.SchemaLoaderService,
|
quotaService *quota.QuotaService, schemaLoaderService *schemaloader.SchemaLoaderService,
|
||||||
pluginDashboardManager plugins.PluginDashboardManager, pluginStore plugins.Store,
|
pluginDashboardManager plugins.PluginDashboardManager, pluginStore plugins.Store,
|
||||||
libraryPanelService librarypanels.Service, dashboardService dashboards.DashboardService,
|
libraryPanelService librarypanels.Service, dashboardService dashboards.DashboardService,
|
||||||
ac accesscontrol.AccessControl, permissionsServices accesscontrol.PermissionsServices, features featuremgmt.FeatureToggles,
|
ac accesscontrol.AccessControl,
|
||||||
) *ImportDashboardService {
|
) *ImportDashboardService {
|
||||||
s := &ImportDashboardService{
|
s := &ImportDashboardService{
|
||||||
features: features,
|
pluginDashboardManager: pluginDashboardManager,
|
||||||
pluginDashboardManager: pluginDashboardManager,
|
dashboardService: dashboardService,
|
||||||
dashboardService: dashboardService,
|
libraryPanelService: libraryPanelService,
|
||||||
libraryPanelService: libraryPanelService,
|
|
||||||
dashboardPermissionsService: permissionsServices.GetDashboardService(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboardImportAPI := api.New(s, quotaService, schemaLoaderService, pluginStore, ac)
|
dashboardImportAPI := api.New(s, quotaService, schemaLoaderService, pluginStore, ac)
|
||||||
@ -39,11 +35,9 @@ func ProvideService(routeRegister routing.RouteRegister,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ImportDashboardService struct {
|
type ImportDashboardService struct {
|
||||||
features featuremgmt.FeatureToggles
|
pluginDashboardManager plugins.PluginDashboardManager
|
||||||
pluginDashboardManager plugins.PluginDashboardManager
|
dashboardService dashboards.DashboardService
|
||||||
dashboardService dashboards.DashboardService
|
libraryPanelService librarypanels.Service
|
||||||
libraryPanelService librarypanels.Service
|
|
||||||
dashboardPermissionsService accesscontrol.PermissionsService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ImportDashboardService) ImportDashboard(ctx context.Context, req *dashboardimport.ImportDashboardRequest) (*dashboardimport.ImportDashboardResponse, error) {
|
func (s *ImportDashboardService) ImportDashboard(ctx context.Context, req *dashboardimport.ImportDashboardRequest) (*dashboardimport.ImportDashboardResponse, error) {
|
||||||
@ -94,12 +88,6 @@ func (s *ImportDashboardService) ImportDashboard(ctx context.Context, req *dashb
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
|
||||||
if err := s.setDashboardPermissions(ctx, req.User, savedDash); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &dashboardimport.ImportDashboardResponse{
|
return &dashboardimport.ImportDashboardResponse{
|
||||||
UID: savedDash.Uid,
|
UID: savedDash.Uid,
|
||||||
PluginId: req.PluginId,
|
PluginId: req.PluginId,
|
||||||
@ -115,24 +103,3 @@ func (s *ImportDashboardService) ImportDashboard(ctx context.Context, req *dashb
|
|||||||
Slug: savedDash.Slug,
|
Slug: savedDash.Slug,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ImportDashboardService) setDashboardPermissions(ctx context.Context, user *models.SignedInUser, dashboard *models.Dashboard) error {
|
|
||||||
resourceID := strconv.FormatInt(dashboard.Id, 10)
|
|
||||||
|
|
||||||
permissions := []accesscontrol.SetResourcePermissionCommand{
|
|
||||||
{UserID: user.UserId, Permission: models.PERMISSION_ADMIN.String()},
|
|
||||||
}
|
|
||||||
|
|
||||||
if dashboard.FolderId == 0 {
|
|
||||||
permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{
|
|
||||||
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
|
|
||||||
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
|
|
||||||
}...)
|
|
||||||
}
|
|
||||||
_, err := s.dashboardPermissionsService.SetPermissions(ctx, user.OrgId, resourceID, permissions...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/librarypanels"
|
"github.com/grafana/grafana/pkg/services/librarypanels"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -56,7 +55,6 @@ func TestImportDashboardService(t *testing.T) {
|
|||||||
pluginDashboardManager: pluginDashboardManager,
|
pluginDashboardManager: pluginDashboardManager,
|
||||||
dashboardService: dashboardService,
|
dashboardService: dashboardService,
|
||||||
libraryPanelService: libraryPanelService,
|
libraryPanelService: libraryPanelService,
|
||||||
features: featuremgmt.WithFeatures(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &dashboardimport.ImportDashboardRequest{
|
req := &dashboardimport.ImportDashboardRequest{
|
||||||
@ -106,7 +104,6 @@ func TestImportDashboardService(t *testing.T) {
|
|||||||
}
|
}
|
||||||
libraryPanelService := &libraryPanelServiceMock{}
|
libraryPanelService := &libraryPanelServiceMock{}
|
||||||
s := &ImportDashboardService{
|
s := &ImportDashboardService{
|
||||||
features: featuremgmt.WithFeatures(),
|
|
||||||
dashboardService: dashboardService,
|
dashboardService: dashboardService,
|
||||||
libraryPanelService: libraryPanelService,
|
libraryPanelService: libraryPanelService,
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
m "github.com/grafana/grafana/pkg/services/dashboards"
|
m "github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
@ -30,16 +32,27 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DashboardServiceImpl struct {
|
type DashboardServiceImpl struct {
|
||||||
dashboardStore m.Store
|
cfg *setting.Cfg
|
||||||
dashAlertExtractor alerting.DashAlertExtractor
|
log log.Logger
|
||||||
log log.Logger
|
dashboardStore m.Store
|
||||||
|
dashAlertExtractor alerting.DashAlertExtractor
|
||||||
|
features featuremgmt.FeatureToggles
|
||||||
|
folderPermissions accesscontrol.PermissionsService
|
||||||
|
dashboardPermissions accesscontrol.PermissionsService
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideDashboardService(store m.Store, dashAlertExtractor alerting.DashAlertExtractor) *DashboardServiceImpl {
|
func ProvideDashboardService(
|
||||||
|
cfg *setting.Cfg, store m.Store, dashAlertExtractor alerting.DashAlertExtractor,
|
||||||
|
features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
|
||||||
|
) *DashboardServiceImpl {
|
||||||
return &DashboardServiceImpl{
|
return &DashboardServiceImpl{
|
||||||
dashboardStore: store,
|
cfg: cfg,
|
||||||
dashAlertExtractor: dashAlertExtractor,
|
log: log.New("dashboard-service"),
|
||||||
log: log.New("dashboard-service"),
|
dashboardStore: store,
|
||||||
|
dashAlertExtractor: dashAlertExtractor,
|
||||||
|
features: features,
|
||||||
|
folderPermissions: permissionsServices.GetFolderService(),
|
||||||
|
dashboardPermissions: permissionsServices.GetDashboardService(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +247,12 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dto.Dashboard.Id == 0 {
|
||||||
|
if err := dr.setDefaultPermissions(ctx, dto, dash, true); err != nil {
|
||||||
|
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserId, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dash, nil
|
return dash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +288,12 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dto.Dashboard.Id == 0 {
|
||||||
|
if err := dr.setDefaultPermissions(ctx, dto, dash, true); err != nil {
|
||||||
|
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserId, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dash, nil
|
return dash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +332,13 @@ func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *m.SaveDa
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new dashboard created
|
||||||
|
if dto.Dashboard.Id == 0 {
|
||||||
|
if err := dr.setDefaultPermissions(ctx, dto, dash, false); err != nil {
|
||||||
|
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserId, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dash, nil
|
return dash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,6 +430,10 @@ func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *m.Save
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := dr.setDefaultPermissions(ctx, dto, dash, false); err != nil {
|
||||||
|
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserId, "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
return dash, nil
|
return dash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,3 +442,39 @@ func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *m.Save
|
|||||||
func (dr *DashboardServiceImpl) UnprovisionDashboard(ctx context.Context, dashboardId int64) error {
|
func (dr *DashboardServiceImpl) UnprovisionDashboard(ctx context.Context, dashboardId int64) error {
|
||||||
return dr.dashboardStore.UnprovisionDashboard(ctx, dashboardId)
|
return dr.dashboardStore.UnprovisionDashboard(ctx, dashboardId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *m.SaveDashboardDTO, dash *models.Dashboard, provisioned bool) error {
|
||||||
|
inFolder := dash.FolderId > 0
|
||||||
|
if dr.features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
||||||
|
resourceID := strconv.FormatInt(dash.Id, 10)
|
||||||
|
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||||
|
if !provisioned {
|
||||||
|
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||||
|
UserID: dto.User.UserId, Permission: models.PERMISSION_ADMIN.String(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if !inFolder {
|
||||||
|
permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{
|
||||||
|
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
|
||||||
|
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
|
||||||
|
}...)
|
||||||
|
}
|
||||||
|
|
||||||
|
svc := dr.dashboardPermissions
|
||||||
|
if dash.IsFolder {
|
||||||
|
svc = dr.folderPermissions
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := svc.SetPermissions(ctx, dto.OrgId, resourceID, permissions...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if dr.cfg.EditorsCanAdmin && !provisioned {
|
||||||
|
if err := dr.MakeUserAdmin(ctx, dto.OrgId, dto.User.UserId, dash.Id, !inFolder); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -5,15 +5,18 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
dashbboardservice "github.com/grafana/grafana/pkg/services/dashboards"
|
dashbboardservice "github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -854,7 +857,11 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
|
|||||||
|
|
||||||
dto := toSaveDashboardDto(cmd)
|
dto := toSaveDashboardDto(cmd)
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
res, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
|
service := ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, &dummyDashAlertExtractor{},
|
||||||
|
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
|
res, err := service.SaveDashboard(context.Background(), &dto, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -863,7 +870,11 @@ func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore
|
|||||||
func callSaveWithError(cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLStore) error {
|
func callSaveWithError(cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLStore) error {
|
||||||
dto := toSaveDashboardDto(cmd)
|
dto := toSaveDashboardDto(cmd)
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
_, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
|
service := ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, &dummyDashAlertExtractor{},
|
||||||
|
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
|
_, err := service.SaveDashboard(context.Background(), &dto, false)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,7 +901,11 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto
|
|||||||
}
|
}
|
||||||
|
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
res, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
|
service := ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, &dummyDashAlertExtractor{},
|
||||||
|
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
|
res, err := service.SaveDashboard(context.Background(), &dto, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -918,7 +933,11 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.
|
|||||||
}
|
}
|
||||||
|
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
res, err := ProvideDashboardService(dashboardStore, &dummyDashAlertExtractor{}).SaveDashboard(context.Background(), &dto, false)
|
service := ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, &dummyDashAlertExtractor{},
|
||||||
|
featuremgmt.WithFeatures(), accesscontrolmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
|
res, err := service.SaveDashboard(context.Background(), &dto, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
@ -3,29 +3,43 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
"github.com/grafana/grafana/pkg/services/search"
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FolderServiceImpl struct {
|
type FolderServiceImpl struct {
|
||||||
|
log log.Logger
|
||||||
|
cfg *setting.Cfg
|
||||||
dashboardService dashboards.DashboardService
|
dashboardService dashboards.DashboardService
|
||||||
dashboardStore dashboards.Store
|
dashboardStore dashboards.Store
|
||||||
searchService *search.SearchService
|
searchService *search.SearchService
|
||||||
log log.Logger
|
features featuremgmt.FeatureToggles
|
||||||
|
permissions accesscontrol.PermissionsService
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideFolderService(dashboardService dashboards.DashboardService, dashboardStore dashboards.Store, searchService *search.SearchService) *FolderServiceImpl {
|
func ProvideFolderService(
|
||||||
|
cfg *setting.Cfg, dashboardService dashboards.DashboardService, dashboardStore dashboards.Store,
|
||||||
|
searchService *search.SearchService, features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
|
||||||
|
) *FolderServiceImpl {
|
||||||
return &FolderServiceImpl{
|
return &FolderServiceImpl{
|
||||||
|
cfg: cfg,
|
||||||
|
log: log.New("folder-service"),
|
||||||
dashboardService: dashboardService,
|
dashboardService: dashboardService,
|
||||||
dashboardStore: dashboardStore,
|
dashboardStore: dashboardStore,
|
||||||
searchService: searchService,
|
searchService: searchService,
|
||||||
log: log.New("folder-service"),
|
features: features,
|
||||||
|
permissions: permissionsServices.GetFolderService(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +163,22 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.Signe
|
|||||||
return nil, toFolderError(err)
|
return nil, toFolderError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var permissionErr error
|
||||||
|
if f.features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
||||||
|
resourceID := strconv.FormatInt(dashFolder.Id, 10)
|
||||||
|
_, permissionErr = f.permissions.SetPermissions(ctx, orgID, resourceID, []accesscontrol.SetResourcePermissionCommand{
|
||||||
|
{UserID: userID, Permission: models.PERMISSION_ADMIN.String()},
|
||||||
|
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
|
||||||
|
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
|
||||||
|
}...)
|
||||||
|
} else if f.cfg.EditorsCanAdmin {
|
||||||
|
permissionErr = f.MakeUserAdmin(ctx, orgID, userID, dashFolder.Id, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if permissionErr != nil {
|
||||||
|
f.log.Error("Could not make user admin", "folder", dashFolder.Title, "user", userID, "error", permissionErr)
|
||||||
|
}
|
||||||
|
|
||||||
return dashToFolder(dashFolder), nil
|
return dashToFolder(dashFolder), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,12 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -24,10 +27,13 @@ func TestFolderService(t *testing.T) {
|
|||||||
t.Run("Folder service tests", func(t *testing.T) {
|
t.Run("Folder service tests", func(t *testing.T) {
|
||||||
store := &database.FakeDashboardStore{}
|
store := &database.FakeDashboardStore{}
|
||||||
defer store.AssertExpectations(t)
|
defer store.AssertExpectations(t)
|
||||||
|
cfg := setting.NewCfg()
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
|
permissionsServices := acmock.NewPermissionsServicesMock()
|
||||||
|
dashboardService := ProvideDashboardService(cfg, store, nil, features, permissionsServices)
|
||||||
service := ProvideFolderService(
|
service := ProvideFolderService(
|
||||||
&dashboards.FakeDashboardService{DashboardService: ProvideDashboardService(store, nil)},
|
cfg, &dashboards.FakeDashboardService{DashboardService: dashboardService},
|
||||||
store,
|
store, nil, features, permissionsServices,
|
||||||
nil,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
t.Run("Given user has no permissions", func(t *testing.T) {
|
t.Run("Given user has no permissions", func(t *testing.T) {
|
||||||
|
@ -13,10 +13,12 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/response"
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/web"
|
"github.com/grafana/grafana/pkg/web"
|
||||||
@ -197,7 +199,11 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.Sign
|
|||||||
|
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
dashAlertExtractor := alerting.ProvideDashAlertExtractorService(nil, nil)
|
dashAlertExtractor := alerting.ProvideDashAlertExtractorService(nil, nil)
|
||||||
dashboard, err := dashboardservice.ProvideDashboardService(dashboardStore, dashAlertExtractor).SaveDashboard(context.Background(), dashItem, true)
|
service := dashboardservice.ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, dashAlertExtractor,
|
||||||
|
featuremgmt.WithFeatures(), acmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
|
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return dashboard
|
return dashboard
|
||||||
@ -207,9 +213,19 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
|
|||||||
items []folderACLItem) *models.Folder {
|
items []folderACLItem) *models.Folder {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
cfg := setting.NewCfg()
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
|
permissionsServices := acmock.NewPermissionsServicesMock()
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
d := dashboardservice.ProvideDashboardService(dashboardStore, nil)
|
|
||||||
s := dashboardservice.ProvideFolderService(d, dashboardStore, nil)
|
d := dashboardservice.ProvideDashboardService(
|
||||||
|
cfg, dashboardStore, nil,
|
||||||
|
features, permissionsServices,
|
||||||
|
)
|
||||||
|
s := dashboardservice.ProvideFolderService(
|
||||||
|
cfg, d, dashboardStore, nil,
|
||||||
|
features, permissionsServices,
|
||||||
|
)
|
||||||
t.Logf("Creating folder with title and UID %q", title)
|
t.Logf("Creating folder with title and UID %q", title)
|
||||||
folder, err := s.CreateFolder(context.Background(), &user, user.OrgId, title, title)
|
folder, err := s.CreateFolder(context.Background(), &user, user.OrgId, title, title)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -294,11 +310,17 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
|||||||
role := models.ROLE_ADMIN
|
role := models.ROLE_ADMIN
|
||||||
sqlStore := sqlstore.InitTestDB(t)
|
sqlStore := sqlstore.InitTestDB(t)
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
dashboardService := dashboardservice.ProvideDashboardService(dashboardStore, &alerting.DashAlertExtractorService{})
|
dashboardService := dashboardservice.ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, nil,
|
||||||
|
featuremgmt.WithFeatures(), acmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
service := LibraryElementService{
|
service := LibraryElementService{
|
||||||
Cfg: setting.NewCfg(),
|
Cfg: setting.NewCfg(),
|
||||||
SQLStore: sqlStore,
|
SQLStore: sqlStore,
|
||||||
folderService: dashboardservice.ProvideFolderService(dashboardService, dashboardStore, nil),
|
folderService: dashboardservice.ProvideFolderService(
|
||||||
|
setting.NewCfg(), dashboardService, dashboardStore, nil,
|
||||||
|
featuremgmt.WithFeatures(), acmock.NewPermissionsServicesMock(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
user := models.SignedInUser{
|
user := models.SignedInUser{
|
||||||
|
@ -11,10 +11,12 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@ -1416,9 +1418,13 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.Sig
|
|||||||
Overwrite: false,
|
Overwrite: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboadStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
dashAlertService := alerting.ProvideDashAlertExtractorService(nil, nil)
|
dashAlertService := alerting.ProvideDashAlertExtractorService(nil, nil)
|
||||||
dashboard, err := dashboardservice.ProvideDashboardService(dashboadStore, dashAlertService).SaveDashboard(context.Background(), dashItem, true)
|
service := dashboardservice.ProvideDashboardService(
|
||||||
|
setting.NewCfg(), dashboardStore, dashAlertService,
|
||||||
|
featuremgmt.WithFeatures(), acmock.NewPermissionsServicesMock(),
|
||||||
|
)
|
||||||
|
dashboard, err := service.SaveDashboard(context.Background(), dashItem, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return dashboard
|
return dashboard
|
||||||
@ -1428,9 +1434,13 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
|
|||||||
items []folderACLItem) *models.Folder {
|
items []folderACLItem) *models.Folder {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
cfg := setting.NewCfg()
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
|
permissionsServices := acmock.NewPermissionsServicesMock()
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
d := dashboardservice.ProvideDashboardService(dashboardStore, nil)
|
d := dashboardservice.ProvideDashboardService(cfg, dashboardStore, nil, features, permissionsServices)
|
||||||
s := dashboardservice.ProvideFolderService(d, dashboardStore, nil)
|
s := dashboardservice.ProvideFolderService(cfg, d, dashboardStore, nil, features, permissionsServices)
|
||||||
|
|
||||||
t.Logf("Creating folder with title and UID %q", title)
|
t.Logf("Creating folder with title and UID %q", title)
|
||||||
folder, err := s.CreateFolder(context.Background(), user, user.OrgId, title, title)
|
folder, err := s.CreateFolder(context.Background(), user, user.OrgId, title, title)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -1518,7 +1528,18 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
|
|||||||
role := models.ROLE_ADMIN
|
role := models.ROLE_ADMIN
|
||||||
sqlStore := sqlstore.InitTestDB(t)
|
sqlStore := sqlstore.InitTestDB(t)
|
||||||
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
dashboardStore := database.ProvideDashboardStore(sqlStore)
|
||||||
folderService := dashboardservice.ProvideFolderService(dashboardservice.ProvideDashboardService(dashboardStore, &alerting.DashAlertExtractorService{}), dashboardStore, nil)
|
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
|
permissionsServices := acmock.NewPermissionsServicesMock()
|
||||||
|
|
||||||
|
dashboardService := dashboardservice.ProvideDashboardService(
|
||||||
|
cfg, dashboardStore, &alerting.DashAlertExtractorService{},
|
||||||
|
features, permissionsServices,
|
||||||
|
)
|
||||||
|
folderService := dashboardservice.ProvideFolderService(
|
||||||
|
cfg, dashboardService, dashboardStore, nil,
|
||||||
|
features, permissionsServices,
|
||||||
|
)
|
||||||
|
|
||||||
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService)
|
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService)
|
||||||
service := LibraryPanelService{
|
service := LibraryPanelService{
|
||||||
|
@ -9,9 +9,10 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
databasestore "github.com/grafana/grafana/pkg/services/dashboards/database"
|
databasestore "github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/manager"
|
||||||
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert"
|
"github.com/grafana/grafana/pkg/services/ngalert"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
@ -42,8 +43,20 @@ func SetupTestEnv(t *testing.T, baseInterval time.Duration) (*ngalert.AlertNG, *
|
|||||||
sqlStore := sqlstore.InitTestDB(t)
|
sqlStore := sqlstore.InitTestDB(t)
|
||||||
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
|
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
|
||||||
dashboardStore := databasestore.ProvideDashboardStore(sqlStore)
|
dashboardStore := databasestore.ProvideDashboardStore(sqlStore)
|
||||||
folderService := dashboardservice.ProvideFolderService(dashboardservice.ProvideDashboardService(dashboardStore, nil), dashboardStore, nil)
|
|
||||||
ac := mock.New()
|
ac := acmock.New()
|
||||||
|
features := featuremgmt.WithFeatures()
|
||||||
|
permissionsServices := acmock.NewPermissionsServicesMock()
|
||||||
|
|
||||||
|
dashboardService := dashboardservice.ProvideDashboardService(
|
||||||
|
cfg, dashboardStore, nil,
|
||||||
|
features, permissionsServices,
|
||||||
|
)
|
||||||
|
folderService := dashboardservice.ProvideFolderService(
|
||||||
|
cfg, dashboardService, dashboardStore, nil,
|
||||||
|
features, permissionsServices,
|
||||||
|
)
|
||||||
|
|
||||||
ng, err := ngalert.ProvideService(
|
ng, err := ngalert.ProvideService(
|
||||||
cfg, nil, routing.NewRouteRegister(), sqlStore,
|
cfg, nil, routing.NewRouteRegister(), sqlStore,
|
||||||
nil, nil, nil, nil, secretsService, nil, m, folderService, ac,
|
nil, nil, nil, nil, secretsService, nil, m, folderService, ac,
|
||||||
|
@ -7,9 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||||
"github.com/grafana/grafana/pkg/util/errutil"
|
"github.com/grafana/grafana/pkg/util/errutil"
|
||||||
)
|
)
|
||||||
@ -25,10 +23,7 @@ type DashboardProvisioner interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DashboardProvisionerFactory creates DashboardProvisioners based on input
|
// DashboardProvisionerFactory creates DashboardProvisioners based on input
|
||||||
type DashboardProvisionerFactory func(
|
type DashboardProvisionerFactory func(context.Context, string, dashboards.DashboardProvisioningService, utils.OrgStore) (DashboardProvisioner, error)
|
||||||
context.Context, string, dashboards.DashboardProvisioningService, utils.OrgStore,
|
|
||||||
featuremgmt.FeatureToggles, accesscontrol.PermissionsServices,
|
|
||||||
) (DashboardProvisioner, error)
|
|
||||||
|
|
||||||
// Provisioner is responsible for syncing dashboard from disk to Grafana's database.
|
// Provisioner is responsible for syncing dashboard from disk to Grafana's database.
|
||||||
type Provisioner struct {
|
type Provisioner struct {
|
||||||
@ -40,10 +35,7 @@ type Provisioner struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new DashboardProvisioner
|
// New returns a new DashboardProvisioner
|
||||||
func New(
|
func New(ctx context.Context, configDirectory string, provisioner dashboards.DashboardProvisioningService, orgStore utils.OrgStore) (DashboardProvisioner, error) {
|
||||||
ctx context.Context, configDirectory string, provisioner dashboards.DashboardProvisioningService, orgStore utils.OrgStore,
|
|
||||||
features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
|
|
||||||
) (DashboardProvisioner, error) {
|
|
||||||
logger := log.New("provisioning.dashboard")
|
logger := log.New("provisioning.dashboard")
|
||||||
cfgReader := &configReader{path: configDirectory, log: logger, orgStore: orgStore}
|
cfgReader := &configReader{path: configDirectory, log: logger, orgStore: orgStore}
|
||||||
configs, err := cfgReader.readConfig(ctx)
|
configs, err := cfgReader.readConfig(ctx)
|
||||||
@ -51,7 +43,7 @@ func New(
|
|||||||
return nil, errutil.Wrap("Failed to read dashboards config", err)
|
return nil, errutil.Wrap("Failed to read dashboards config", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileReaders, err := getFileReaders(configs, logger, provisioner, features, permissionsServices)
|
fileReaders, err := getFileReaders(configs, logger, provisioner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errutil.Wrap("Failed to initialize file readers", err)
|
return nil, errutil.Wrap("Failed to initialize file readers", err)
|
||||||
}
|
}
|
||||||
@ -132,14 +124,13 @@ func (provider *Provisioner) GetAllowUIUpdatesFromConfig(name string) bool {
|
|||||||
|
|
||||||
func getFileReaders(
|
func getFileReaders(
|
||||||
configs []*config, logger log.Logger, service dashboards.DashboardProvisioningService,
|
configs []*config, logger log.Logger, service dashboards.DashboardProvisioningService,
|
||||||
features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
|
|
||||||
) ([]*FileReader, error) {
|
) ([]*FileReader, error) {
|
||||||
var readers []*FileReader
|
var readers []*FileReader
|
||||||
|
|
||||||
for _, config := range configs {
|
for _, config := range configs {
|
||||||
switch config.Type {
|
switch config.Type {
|
||||||
case "file":
|
case "file":
|
||||||
fileReader, err := NewDashboardFileReader(config, logger.New("type", config.Type, "name", config.Name), service, features, permissionsServices)
|
fileReader, err := NewDashboardFileReader(config, logger.New("type", config.Type, "name", config.Name), service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errutil.Wrapf(err, "Failed to create file reader for config %v", config.Name)
|
return nil, errutil.Wrapf(err, "Failed to create file reader for config %v", config.Name)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -16,9 +15,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,15 +37,10 @@ type FileReader struct {
|
|||||||
mux sync.RWMutex
|
mux sync.RWMutex
|
||||||
usageTracker *usageTracker
|
usageTracker *usageTracker
|
||||||
dbWriteAccessRestricted bool
|
dbWriteAccessRestricted bool
|
||||||
permissionsServices accesscontrol.PermissionsServices
|
|
||||||
features featuremgmt.FeatureToggles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDashboardFileReader returns a new filereader based on `config`
|
// NewDashboardFileReader returns a new filereader based on `config`
|
||||||
func NewDashboardFileReader(
|
func NewDashboardFileReader(cfg *config, log log.Logger, service dashboards.DashboardProvisioningService) (*FileReader, error) {
|
||||||
cfg *config, log log.Logger, service dashboards.DashboardProvisioningService,
|
|
||||||
features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
|
|
||||||
) (*FileReader, error) {
|
|
||||||
var path string
|
var path string
|
||||||
path, ok := cfg.Options["path"].(string)
|
path, ok := cfg.Options["path"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -72,8 +64,6 @@ func NewDashboardFileReader(
|
|||||||
dashboardProvisioningService: service,
|
dashboardProvisioningService: service,
|
||||||
FoldersFromFilesStructure: foldersFromFilesStructure,
|
FoldersFromFilesStructure: foldersFromFilesStructure,
|
||||||
usageTracker: newUsageTracker(),
|
usageTracker: newUsageTracker(),
|
||||||
features: features,
|
|
||||||
permissionsServices: permissionsServices,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,24 +264,10 @@ func (fr *FileReader) saveDashboard(ctx context.Context, path string, folderID i
|
|||||||
Updated: resolvedFileInfo.ModTime().Unix(),
|
Updated: resolvedFileInfo.ModTime().Unix(),
|
||||||
CheckSum: jsonFile.checkSum,
|
CheckSum: jsonFile.checkSum,
|
||||||
}
|
}
|
||||||
savedDash, err := fr.dashboardProvisioningService.SaveProvisionedDashboard(ctx, dash, dp)
|
_, err := fr.dashboardProvisioningService.SaveProvisionedDashboard(ctx, dash, dp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return provisioningMetadata, err
|
return provisioningMetadata, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !alreadyProvisioned && fr.features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
|
||||||
svc := fr.permissionsServices.GetDashboardService()
|
|
||||||
_, err := svc.SetPermissions(ctx, savedDash.OrgId, strconv.FormatInt(savedDash.Id, 10), accesscontrol.SetResourcePermissionCommand{
|
|
||||||
BuiltinRole: "Viewer",
|
|
||||||
Permission: "View",
|
|
||||||
}, accesscontrol.SetResourcePermissionCommand{
|
|
||||||
BuiltinRole: "Editor",
|
|
||||||
Permission: "Edit",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fr.log.Warn("failed to set permissions for provisioned dashboard", "dashboardId", savedDash.Id, "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fr.log.Warn("Not saving new dashboard due to restricted database access", "provisioner", fr.Cfg.Name,
|
fr.log.Warn("Not saving new dashboard due to restricted database access", "provisioner", fr.Cfg.Name,
|
||||||
"file", path, "folderId", dash.Dashboard.FolderId)
|
"file", path, "folderId", dash.Dashboard.FolderId)
|
||||||
@ -341,19 +317,6 @@ func (fr *FileReader) getOrCreateFolderID(ctx context.Context, cfg *config, serv
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if fr.features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
|
||||||
_, err = fr.permissionsServices.GetFolderService().SetPermissions(ctx, dbDash.OrgId, strconv.FormatInt(dbDash.Id, 10), accesscontrol.SetResourcePermissionCommand{
|
|
||||||
BuiltinRole: "Viewer",
|
|
||||||
Permission: "View",
|
|
||||||
}, accesscontrol.SetResourcePermissionCommand{
|
|
||||||
BuiltinRole: "Editor",
|
|
||||||
Permission: "Edit",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dbDash.Id, nil
|
return dbDash.Id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -26,7 +25,7 @@ func TestProvisionedSymlinkedFolder(t *testing.T) {
|
|||||||
Options: map[string]interface{}{"path": symlinkedFolder},
|
Options: map[string]interface{}{"path": symlinkedFolder},
|
||||||
}
|
}
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("expected err to be nil")
|
t.Error("expected err to be nil")
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@ -43,7 +42,7 @@ func TestCreatingNewDashboardFileReader(t *testing.T) {
|
|||||||
t.Run("using path parameter", func(t *testing.T) {
|
t.Run("using path parameter", func(t *testing.T) {
|
||||||
cfg := setup()
|
cfg := setup()
|
||||||
cfg.Options["path"] = defaultDashboards
|
cfg.Options["path"] = defaultDashboards
|
||||||
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEqual(t, reader.Path, "")
|
require.NotEqual(t, reader.Path, "")
|
||||||
})
|
})
|
||||||
@ -51,7 +50,7 @@ func TestCreatingNewDashboardFileReader(t *testing.T) {
|
|||||||
t.Run("using folder as options", func(t *testing.T) {
|
t.Run("using folder as options", func(t *testing.T) {
|
||||||
cfg := setup()
|
cfg := setup()
|
||||||
cfg.Options["folder"] = defaultDashboards
|
cfg.Options["folder"] = defaultDashboards
|
||||||
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEqual(t, reader.Path, "")
|
require.NotEqual(t, reader.Path, "")
|
||||||
})
|
})
|
||||||
@ -60,7 +59,7 @@ func TestCreatingNewDashboardFileReader(t *testing.T) {
|
|||||||
cfg := setup()
|
cfg := setup()
|
||||||
cfg.Options["path"] = foldersFromFilesStructure
|
cfg.Options["path"] = foldersFromFilesStructure
|
||||||
cfg.Options["foldersFromFilesStructure"] = true
|
cfg.Options["foldersFromFilesStructure"] = true
|
||||||
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEqual(t, reader.Path, "")
|
require.NotEqual(t, reader.Path, "")
|
||||||
})
|
})
|
||||||
@ -73,7 +72,7 @@ func TestCreatingNewDashboardFileReader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg.Options["folder"] = fullPath
|
cfg.Options["folder"] = fullPath
|
||||||
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, reader.Path, fullPath)
|
require.Equal(t, reader.Path, fullPath)
|
||||||
@ -83,7 +82,7 @@ func TestCreatingNewDashboardFileReader(t *testing.T) {
|
|||||||
t.Run("using relative path", func(t *testing.T) {
|
t.Run("using relative path", func(t *testing.T) {
|
||||||
cfg := setup()
|
cfg := setup()
|
||||||
cfg.Options["folder"] = defaultDashboards
|
cfg.Options["folder"] = defaultDashboards
|
||||||
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, log.New("test-logger"), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
resolvedPath := reader.resolvedPath()
|
resolvedPath := reader.resolvedPath()
|
||||||
@ -119,7 +118,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{Id: 1}, nil).Once()
|
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{Id: 1}, nil).Once()
|
||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{Id: 2}, nil).Times(2)
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{Id: 2}, nil).Times(2)
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -139,7 +138,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
inserted++
|
inserted++
|
||||||
})
|
})
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -176,7 +175,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
|
|
||||||
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -204,7 +203,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -239,7 +238,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
|
|
||||||
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -267,7 +266,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
fakeService.On("GetProvisionedDashboardData", configName).Return(provisionedDashboard, nil).Once()
|
||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("GetProvisionedDashboardData", configName).Return(nil, nil).Once()
|
fakeService.On("GetProvisionedDashboardData", configName).Return(nil, nil).Once()
|
||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -299,7 +298,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(2)
|
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(2)
|
||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(3)
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(3)
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -316,7 +315,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
Folder: "",
|
Folder: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
_, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NotNil(t, err)
|
require.NotNil(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -324,7 +323,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
cfg.Options["path"] = brokenDashboards
|
cfg.Options["path"] = brokenDashboards
|
||||||
|
|
||||||
_, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
_, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -337,14 +336,14 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(2)
|
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(2)
|
||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(2)
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(2)
|
||||||
|
|
||||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||||
reader1.dashboardProvisioningService = fakeService
|
reader1.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = reader1.walkDisk(context.Background())
|
err = reader1.walkDisk(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||||
reader2.dashboardProvisioningService = fakeService
|
reader2.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -364,7 +363,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
"folder": defaultDashboards,
|
"folder": defaultDashboards,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
r, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
r, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
|
_, err = r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
|
||||||
@ -384,7 +383,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{Id: 1}, nil).Once()
|
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{Id: 1}, nil).Once()
|
||||||
|
|
||||||
r, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
r, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
|
_, err = r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
|
||||||
@ -439,7 +438,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
|
|
||||||
cfg.DisableDeletion = true
|
cfg.DisableDeletion = true
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -454,7 +453,7 @@ func TestDashboardFileReader(t *testing.T) {
|
|||||||
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Once()
|
||||||
fakeService.On("DeleteProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
fakeService.On("DeleteProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||||
|
|
||||||
reader, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
reader.dashboardProvisioningService = fakeService
|
reader.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -37,7 +36,7 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
t.Run("Duplicates validator should collect info about duplicate UIDs and titles within folders", func(t *testing.T) {
|
t.Run("Duplicates validator should collect info about duplicate UIDs and titles within folders", func(t *testing.T) {
|
||||||
const folderName = "duplicates-validator-folder"
|
const folderName = "duplicates-validator-folder"
|
||||||
|
|
||||||
r, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
r, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(6)
|
fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&models.Dashboard{}, nil).Times(6)
|
||||||
fakeService.On("GetProvisionedDashboardData", mock.Anything).Return([]*models.DashboardProvisioning{}, nil).Times(4)
|
fakeService.On("GetProvisionedDashboardData", mock.Anything).Return([]*models.DashboardProvisioning{}, nil).Times(4)
|
||||||
@ -56,11 +55,11 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
Options: map[string]interface{}{"path": dashboardContainingUID},
|
Options: map[string]interface{}{"path": dashboardContainingUID},
|
||||||
}
|
}
|
||||||
|
|
||||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||||
reader1.dashboardProvisioningService = fakeService
|
reader1.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||||
reader2.dashboardProvisioningService = fakeService
|
reader2.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
t.Run("Duplicates validator should not collect info about duplicate UIDs and titles within folders for different orgs", func(t *testing.T) {
|
t.Run("Duplicates validator should not collect info about duplicate UIDs and titles within folders for different orgs", func(t *testing.T) {
|
||||||
const folderName = "duplicates-validator-folder"
|
const folderName = "duplicates-validator-folder"
|
||||||
|
|
||||||
r, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
r, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
folderID, err := r.getOrCreateFolderID(context.Background(), cfg, fakeService, folderName)
|
folderID, err := r.getOrCreateFolderID(context.Background(), cfg, fakeService, folderName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -108,11 +107,11 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
Options: map[string]interface{}{"path": dashboardContainingUID},
|
Options: map[string]interface{}{"path": dashboardContainingUID},
|
||||||
}
|
}
|
||||||
|
|
||||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||||
reader1.dashboardProvisioningService = fakeService
|
reader1.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||||
reader2.dashboardProvisioningService = fakeService
|
reader2.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -168,15 +167,15 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
Name: "third", Type: "file", OrgID: 2, Folder: "duplicates-validator-folder",
|
Name: "third", Type: "file", OrgID: 2, Folder: "duplicates-validator-folder",
|
||||||
Options: map[string]interface{}{"path": twoDashboardsWithUID},
|
Options: map[string]interface{}{"path": twoDashboardsWithUID},
|
||||||
}
|
}
|
||||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||||
reader1.dashboardProvisioningService = fakeService
|
reader1.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||||
reader2.dashboardProvisioningService = fakeService
|
reader2.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reader3, err := NewDashboardFileReader(cfg3, logger, nil, featuremgmt.WithFeatures(), nil)
|
reader3, err := NewDashboardFileReader(cfg3, logger, nil)
|
||||||
reader3.dashboardProvisioningService = fakeService
|
reader3.dashboardProvisioningService = fakeService
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
|
|
||||||
duplicates := duplicateValidator.getDuplicates()
|
duplicates := duplicateValidator.getDuplicates()
|
||||||
|
|
||||||
r, err := NewDashboardFileReader(cfg, logger, nil, featuremgmt.WithFeatures(), nil)
|
r, err := NewDashboardFileReader(cfg, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
folderID, err := r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg1.Folder)
|
folderID, err := r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg1.Folder)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -210,7 +209,7 @@ func TestDuplicatesValidator(t *testing.T) {
|
|||||||
sort.Strings(titleUsageReaders)
|
sort.Strings(titleUsageReaders)
|
||||||
require.Equal(t, []string{"first"}, titleUsageReaders)
|
require.Equal(t, []string{"first"}, titleUsageReaders)
|
||||||
|
|
||||||
r, err = NewDashboardFileReader(cfg3, logger, nil, featuremgmt.WithFeatures(), nil)
|
r, err = NewDashboardFileReader(cfg3, logger, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
folderID, err = r.getOrCreateFolderID(context.Background(), cfg3, fakeService, cfg3.Folder)
|
folderID, err = r.getOrCreateFolderID(context.Background(), cfg3, fakeService, cfg3.Folder)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -8,12 +8,10 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
plugifaces "github.com/grafana/grafana/pkg/plugins"
|
plugifaces "github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/registry"
|
"github.com/grafana/grafana/pkg/registry"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards"
|
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
datasourceservice "github.com/grafana/grafana/pkg/services/datasources"
|
datasourceservice "github.com/grafana/grafana/pkg/services/datasources"
|
||||||
"github.com/grafana/grafana/pkg/services/encryption"
|
"github.com/grafana/grafana/pkg/services/encryption"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/notifications"
|
"github.com/grafana/grafana/pkg/services/notifications"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
|
"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
|
||||||
@ -31,7 +29,6 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, pluginStore p
|
|||||||
dashboardService dashboardservice.DashboardProvisioningService,
|
dashboardService dashboardservice.DashboardProvisioningService,
|
||||||
datasourceService datasourceservice.DataSourceService,
|
datasourceService datasourceservice.DataSourceService,
|
||||||
alertingService *alerting.AlertNotificationService, pluginSettings pluginsettings.Service,
|
alertingService *alerting.AlertNotificationService, pluginSettings pluginsettings.Service,
|
||||||
features featuremgmt.FeatureToggles, permissionsServices accesscontrol.PermissionsServices,
|
|
||||||
) (*ProvisioningServiceImpl, error) {
|
) (*ProvisioningServiceImpl, error) {
|
||||||
s := &ProvisioningServiceImpl{
|
s := &ProvisioningServiceImpl{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
@ -48,8 +45,6 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, pluginStore p
|
|||||||
datasourceService: datasourceService,
|
datasourceService: datasourceService,
|
||||||
alertingService: alertingService,
|
alertingService: alertingService,
|
||||||
pluginsSettings: pluginSettings,
|
pluginsSettings: pluginSettings,
|
||||||
features: features,
|
|
||||||
permissionsServices: permissionsServices,
|
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
@ -110,8 +105,6 @@ type ProvisioningServiceImpl struct {
|
|||||||
datasourceService datasourceservice.DataSourceService
|
datasourceService datasourceservice.DataSourceService
|
||||||
alertingService *alerting.AlertNotificationService
|
alertingService *alerting.AlertNotificationService
|
||||||
pluginsSettings pluginsettings.Service
|
pluginsSettings pluginsettings.Service
|
||||||
features featuremgmt.FeatureToggles
|
|
||||||
permissionsServices accesscontrol.PermissionsServices
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *ProvisioningServiceImpl) RunInitProvisioners(ctx context.Context) error {
|
func (ps *ProvisioningServiceImpl) RunInitProvisioners(ctx context.Context) error {
|
||||||
@ -194,7 +187,7 @@ func (ps *ProvisioningServiceImpl) ProvisionNotifications(ctx context.Context) e
|
|||||||
|
|
||||||
func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
|
func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
|
||||||
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
|
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
|
||||||
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardService, ps.SQLStore, ps.features, ps.permissionsServices)
|
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardService, ps.SQLStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errutil.Wrap("Failed to create provisioner", err)
|
return errutil.Wrap("Failed to create provisioner", err)
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
||||||
dashboardstore "github.com/grafana/grafana/pkg/services/dashboards"
|
dashboardstore "github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
|
"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@ -95,7 +93,7 @@ func setup() *serviceTestStruct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
serviceTest.service = newProvisioningServiceImpl(
|
serviceTest.service = newProvisioningServiceImpl(
|
||||||
func(context.Context, string, dashboardstore.DashboardProvisioningService, utils.OrgStore, featuremgmt.FeatureToggles, accesscontrol.PermissionsServices) (dashboards.DashboardProvisioner, error) {
|
func(context.Context, string, dashboardstore.DashboardProvisioningService, utils.OrgStore) (dashboards.DashboardProvisioner, error) {
|
||||||
return serviceTest.mock, nil
|
return serviceTest.mock, nil
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
|
Reference in New Issue
Block a user