mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: GetDashboardQuery should be dispatched using DispatchCtx (#36877)
* Chore: GetDashboardQuery should be dispatched using DispatchCtx * Fix after merge * Changes after review * Various fixes * Use GetDashboardCtx function instead of GetDashboard
This commit is contained in:
parent
2b1d3d27e4
commit
fa9857499b
@ -276,12 +276,13 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboardCommand) response.Response {
|
||||
ctx := c.Req.Context()
|
||||
var err error
|
||||
cmd.OrgId = c.OrgId
|
||||
cmd.UserId = c.UserId
|
||||
if cmd.FolderUid != "" {
|
||||
folders := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := folders.GetFolderByUID(cmd.FolderUid)
|
||||
folder, err := folders.GetFolderByUID(ctx, cmd.FolderUid)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrFolderNotFound) {
|
||||
return response.Error(400, "Folder not found", err)
|
||||
@ -361,7 +362,7 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
||||
|
||||
if hs.Cfg.EditorsCanAdmin && newDashboard {
|
||||
inFolder := cmd.FolderId > 0
|
||||
err := dashSvc.MakeUserAdmin(cmd.OrgId, cmd.UserId, dashboard.Id, !inFolder)
|
||||
err := dashSvc.MakeUserAdmin(ctx, cmd.OrgId, cmd.UserId, dashboard.Id, !inFolder)
|
||||
if err != nil {
|
||||
hs.log.Error("Could not make user admin", "dashboard", dashboard.Title, "user", c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
|
||||
func (hs *HTTPServer) GetFolders(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folders, err := s.GetFolders(c.QueryInt64("limit"), c.QueryInt64("page"))
|
||||
folders, err := s.GetFolders(c.Req.Context(), c.QueryInt64("limit"), c.QueryInt64("page"))
|
||||
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
@ -38,7 +38,7 @@ func (hs *HTTPServer) GetFolders(c *models.ReqContext) response.Response {
|
||||
|
||||
func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Params(":uid"))
|
||||
folder, err := s.GetFolderByUID(c.Req.Context(), c.Params(":uid"))
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@ -49,7 +49,7 @@ func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
|
||||
func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByID(c.ParamsInt64(":id"))
|
||||
folder, err := s.GetFolderByID(c.Req.Context(), c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@ -60,13 +60,13 @@ func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
|
||||
func (hs *HTTPServer) CreateFolder(c *models.ReqContext, cmd models.CreateFolderCommand) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.CreateFolder(cmd.Title, cmd.Uid)
|
||||
folder, err := s.CreateFolder(c.Req.Context(), cmd.Title, cmd.Uid)
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
if hs.Cfg.EditorsCanAdmin {
|
||||
if err := s.MakeUserAdmin(c.OrgId, c.SignedInUser.UserId, folder.Id, true); err != nil {
|
||||
if err := s.MakeUserAdmin(c.Req.Context(), c.OrgId, c.SignedInUser.UserId, folder.Id, true); err != nil {
|
||||
hs.log.Error("Could not make user admin", "folder", folder.Title, "user",
|
||||
c.SignedInUser.UserId, "error", err)
|
||||
}
|
||||
@ -78,7 +78,7 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext, cmd models.CreateFolder
|
||||
|
||||
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext, cmd models.UpdateFolderCommand) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
err := s.UpdateFolder(c.Params(":uid"), &cmd)
|
||||
err := s.UpdateFolder(c.Req.Context(), c.Params(":uid"), &cmd)
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
@ -97,7 +97,7 @@ func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { //
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
f, err := s.DeleteFolder(c.Params(":uid"), c.QueryBool("forceDeleteRules"))
|
||||
f, err := s.DeleteFolder(c.Req.Context(), c.Params(":uid"), c.QueryBool("forceDeleteRules"))
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
|
||||
func (hs *HTTPServer) GetFolderPermissionList(c *models.ReqContext) response.Response {
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Params(":uid"))
|
||||
folder, err := s.GetFolderByUID(c.Req.Context(), c.Params(":uid"))
|
||||
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
@ -63,7 +63,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
}
|
||||
|
||||
s := dashboards.NewFolderService(c.OrgId, c.SignedInUser, hs.SQLStore)
|
||||
folder, err := s.GetFolderByUID(c.Params(":uid"))
|
||||
folder, err := s.GetFolderByUID(c.Req.Context(), c.Params(":uid"))
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
@ -217,28 +218,28 @@ type fakeFolderService struct {
|
||||
DeletedFolderUids []string
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) GetFolders(limit int64, page int64) ([]*models.Folder, error) {
|
||||
func (s *fakeFolderService) GetFolders(ctx context.Context, limit int64, page int64) ([]*models.Folder, error) {
|
||||
return s.GetFoldersResult, s.GetFoldersError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) GetFolderByID(id int64) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) GetFolderByID(ctx context.Context, id int64) (*models.Folder, error) {
|
||||
return s.GetFolderByIDResult, s.GetFolderByIDError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) GetFolderByUID(uid string) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) GetFolderByUID(ctx context.Context, uid string) (*models.Folder, error) {
|
||||
return s.GetFolderByUIDResult, s.GetFolderByUIDError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) CreateFolder(title, uid string) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) CreateFolder(ctx context.Context, title, uid string) (*models.Folder, error) {
|
||||
return s.CreateFolderResult, s.CreateFolderError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) UpdateFolder(existingUID string, cmd *models.UpdateFolderCommand) error {
|
||||
func (s *fakeFolderService) UpdateFolder(ctx context.Context, existingUID string, cmd *models.UpdateFolderCommand) error {
|
||||
cmd.Result = s.UpdateFolderResult
|
||||
return s.UpdateFolderError
|
||||
}
|
||||
|
||||
func (s *fakeFolderService) DeleteFolder(uid string, forceDeleteRules bool) (*models.Folder, error) {
|
||||
func (s *fakeFolderService) DeleteFolder(ctx context.Context, uid string, forceDeleteRules bool) (*models.Folder, error) {
|
||||
s.DeletedFolderUids = append(s.DeletedFolderUids, uid)
|
||||
return s.DeleteFolderResult, s.DeleteFolderError
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func (dr *dashboardServiceImpl) MakeUserAdmin(orgID int64, userID int64, dashboardID int64, setViewAndEditPermissions bool) error {
|
||||
func (dr *dashboardServiceImpl) MakeUserAdmin(ctx context.Context, orgID int64, userID int64, dashboardID int64, setViewAndEditPermissions bool) error {
|
||||
rtEditor := models.ROLE_EDITOR
|
||||
rtViewer := models.ROLE_VIEWER
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@ -23,7 +24,7 @@ type DashboardService interface {
|
||||
SaveDashboard(dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error)
|
||||
ImportDashboard(dto *SaveDashboardDTO) (*models.Dashboard, error)
|
||||
DeleteDashboard(dashboardId int64, orgId int64) error
|
||||
MakeUserAdmin(orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
|
||||
MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
|
||||
}
|
||||
|
||||
// DashboardProvisioningService is a service for operating on provisioned dashboards.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
@ -13,14 +14,14 @@ import (
|
||||
|
||||
// FolderService is a service for operating on folders.
|
||||
type FolderService interface {
|
||||
GetFolders(limit int64, page int64) ([]*models.Folder, error)
|
||||
GetFolderByID(id int64) (*models.Folder, error)
|
||||
GetFolderByUID(uid string) (*models.Folder, error)
|
||||
GetFolderByTitle(title string) (*models.Folder, error)
|
||||
CreateFolder(title, uid string) (*models.Folder, error)
|
||||
UpdateFolder(uid string, cmd *models.UpdateFolderCommand) error
|
||||
DeleteFolder(uid string, forceDeleteRules bool) (*models.Folder, error)
|
||||
MakeUserAdmin(orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error
|
||||
GetFolders(ctx context.Context, limit int64, page int64) ([]*models.Folder, error)
|
||||
GetFolderByID(ctx context.Context, id int64) (*models.Folder, error)
|
||||
GetFolderByUID(ctx context.Context, uid string) (*models.Folder, error)
|
||||
GetFolderByTitle(ctx context.Context, title string) (*models.Folder, error)
|
||||
CreateFolder(ctx context.Context, title, uid string) (*models.Folder, error)
|
||||
UpdateFolder(ctx context.Context, uid string, cmd *models.UpdateFolderCommand) error
|
||||
DeleteFolder(ctx context.Context, uid string, forceDeleteRules bool) (*models.Folder, error)
|
||||
MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error
|
||||
}
|
||||
|
||||
// NewFolderService is a factory for creating a new folder service.
|
||||
@ -32,7 +33,7 @@ var NewFolderService = func(orgID int64, user *models.SignedInUser, store dashbo
|
||||
}
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) GetFolders(limit int64, page int64) ([]*models.Folder, error) {
|
||||
func (dr *dashboardServiceImpl) GetFolders(ctx context.Context, limit int64, page int64) ([]*models.Folder, error) {
|
||||
searchQuery := search.Query{
|
||||
SignedInUser: dr.user,
|
||||
DashboardIds: make([]int64, 0),
|
||||
@ -61,12 +62,12 @@ func (dr *dashboardServiceImpl) GetFolders(limit int64, page int64) ([]*models.F
|
||||
return folders, nil
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) GetFolderByID(id int64) (*models.Folder, error) {
|
||||
func (dr *dashboardServiceImpl) GetFolderByID(ctx context.Context, id int64) (*models.Folder, error) {
|
||||
if id == 0 {
|
||||
return &models.Folder{Id: id, Title: "General"}, nil
|
||||
}
|
||||
query := models.GetDashboardQuery{OrgId: dr.orgId, Id: id}
|
||||
dashFolder, err := getFolder(query)
|
||||
dashFolder, err := getFolder(ctx, query)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
@ -82,9 +83,9 @@ func (dr *dashboardServiceImpl) GetFolderByID(id int64) (*models.Folder, error)
|
||||
return dashToFolder(dashFolder), nil
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) GetFolderByUID(uid string) (*models.Folder, error) {
|
||||
func (dr *dashboardServiceImpl) GetFolderByUID(ctx context.Context, uid string) (*models.Folder, error) {
|
||||
query := models.GetDashboardQuery{OrgId: dr.orgId, Uid: uid}
|
||||
dashFolder, err := getFolder(query)
|
||||
dashFolder, err := getFolder(ctx, query)
|
||||
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
@ -101,7 +102,7 @@ func (dr *dashboardServiceImpl) GetFolderByUID(uid string) (*models.Folder, erro
|
||||
return dashToFolder(dashFolder), nil
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) GetFolderByTitle(title string) (*models.Folder, error) {
|
||||
func (dr *dashboardServiceImpl) GetFolderByTitle(ctx context.Context, title string) (*models.Folder, error) {
|
||||
dashFolder, err := dr.dashboardStore.GetFolderByTitle(dr.orgId, title)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
@ -118,7 +119,7 @@ func (dr *dashboardServiceImpl) GetFolderByTitle(title string) (*models.Folder,
|
||||
return dashToFolder(dashFolder), nil
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) CreateFolder(title, uid string) (*models.Folder, error) {
|
||||
func (dr *dashboardServiceImpl) CreateFolder(ctx context.Context, title, uid string) (*models.Folder, error) {
|
||||
dashFolder := models.NewDashboardFolder(title)
|
||||
dashFolder.OrgId = dr.orgId
|
||||
dashFolder.SetUid(strings.TrimSpace(uid))
|
||||
@ -147,7 +148,7 @@ func (dr *dashboardServiceImpl) CreateFolder(title, uid string) (*models.Folder,
|
||||
}
|
||||
|
||||
query := models.GetDashboardQuery{OrgId: dr.orgId, Id: dash.Id}
|
||||
dashFolder, err = getFolder(query)
|
||||
dashFolder, err = getFolder(ctx, query)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
@ -155,9 +156,9 @@ func (dr *dashboardServiceImpl) CreateFolder(title, uid string) (*models.Folder,
|
||||
return dashToFolder(dashFolder), nil
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) UpdateFolder(existingUid string, cmd *models.UpdateFolderCommand) error {
|
||||
func (dr *dashboardServiceImpl) UpdateFolder(ctx context.Context, existingUid string, cmd *models.UpdateFolderCommand) error {
|
||||
query := models.GetDashboardQuery{OrgId: dr.orgId, Uid: existingUid}
|
||||
dashFolder, err := getFolder(query)
|
||||
dashFolder, err := getFolder(ctx, query)
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
}
|
||||
@ -182,7 +183,7 @@ func (dr *dashboardServiceImpl) UpdateFolder(existingUid string, cmd *models.Upd
|
||||
}
|
||||
|
||||
query = models.GetDashboardQuery{OrgId: dr.orgId, Id: dash.Id}
|
||||
dashFolder, err = getFolder(query)
|
||||
dashFolder, err = getFolder(ctx, query)
|
||||
if err != nil {
|
||||
return toFolderError(err)
|
||||
}
|
||||
@ -192,9 +193,9 @@ func (dr *dashboardServiceImpl) UpdateFolder(existingUid string, cmd *models.Upd
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dr *dashboardServiceImpl) DeleteFolder(uid string, forceDeleteRules bool) (*models.Folder, error) {
|
||||
func (dr *dashboardServiceImpl) DeleteFolder(ctx context.Context, uid string, forceDeleteRules bool) (*models.Folder, error) {
|
||||
query := models.GetDashboardQuery{OrgId: dr.orgId, Uid: uid}
|
||||
dashFolder, err := getFolder(query)
|
||||
dashFolder, err := getFolder(ctx, query)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
@ -215,8 +216,8 @@ func (dr *dashboardServiceImpl) DeleteFolder(uid string, forceDeleteRules bool)
|
||||
return dashToFolder(dashFolder), nil
|
||||
}
|
||||
|
||||
func getFolder(query models.GetDashboardQuery) (*models.Dashboard, error) {
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
func getFolder(ctx context.Context, query models.GetDashboardQuery) (*models.Dashboard, error) {
|
||||
if err := bus.DispatchCtx(ctx, &query); err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@ -38,28 +39,28 @@ func TestFolderService(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("When get folder by id should return access denied error", func(t *testing.T) {
|
||||
_, err := service.GetFolderByID(1)
|
||||
_, err := service.GetFolderByID(context.Background(), 1)
|
||||
require.Equal(t, err, models.ErrFolderAccessDenied)
|
||||
})
|
||||
|
||||
t.Run("When get folder by id, with id = 0 should return default folder", func(t *testing.T) {
|
||||
folder, err := service.GetFolderByID(0)
|
||||
folder, err := service.GetFolderByID(context.Background(), 0)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, folder, &models.Folder{Id: 0, Title: "General"})
|
||||
})
|
||||
|
||||
t.Run("When get folder by uid should return access denied error", func(t *testing.T) {
|
||||
_, err := service.GetFolderByUID("uid")
|
||||
_, err := service.GetFolderByUID(context.Background(), "uid")
|
||||
require.Equal(t, err, models.ErrFolderAccessDenied)
|
||||
})
|
||||
|
||||
t.Run("When creating folder should return access denied error", func(t *testing.T) {
|
||||
_, err := service.CreateFolder("Folder", "")
|
||||
_, err := service.CreateFolder(context.Background(), "Folder", "")
|
||||
require.Equal(t, err, models.ErrFolderAccessDenied)
|
||||
})
|
||||
|
||||
t.Run("When updating folder should return access denied error", func(t *testing.T) {
|
||||
err := service.UpdateFolder("uid", &models.UpdateFolderCommand{
|
||||
err := service.UpdateFolder(context.Background(), "uid", &models.UpdateFolderCommand{
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
})
|
||||
@ -67,7 +68,7 @@ func TestFolderService(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("When deleting folder by uid should return access denied error", func(t *testing.T) {
|
||||
_, err := service.DeleteFolder("uid", false)
|
||||
_, err := service.DeleteFolder(context.Background(), "uid", false)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, err, models.ErrFolderAccessDenied)
|
||||
})
|
||||
@ -108,12 +109,12 @@ func TestFolderService(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("When creating folder should not return access denied error", func(t *testing.T) {
|
||||
_, err := service.CreateFolder("Folder", "")
|
||||
_, err := service.CreateFolder(context.Background(), "Folder", "")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("When updating folder should not return access denied error", func(t *testing.T) {
|
||||
err := service.UpdateFolder("uid", &models.UpdateFolderCommand{
|
||||
err := service.UpdateFolder(context.Background(), "uid", &models.UpdateFolderCommand{
|
||||
Uid: "uid",
|
||||
Title: "Folder",
|
||||
})
|
||||
@ -121,7 +122,7 @@ func TestFolderService(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("When deleting folder by uid should not return access denied error", func(t *testing.T) {
|
||||
_, err := service.DeleteFolder("uid", false)
|
||||
_, err := service.DeleteFolder(context.Background(), "uid", false)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
@ -144,14 +145,14 @@ func TestFolderService(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("When get folder by id should return folder", func(t *testing.T) {
|
||||
f, _ := service.GetFolderByID(1)
|
||||
f, _ := service.GetFolderByID(context.Background(), 1)
|
||||
require.Equal(t, f.Id, dashFolder.Id)
|
||||
require.Equal(t, f.Uid, dashFolder.Uid)
|
||||
require.Equal(t, f.Title, dashFolder.Title)
|
||||
})
|
||||
|
||||
t.Run("When get folder by uid should return folder", func(t *testing.T) {
|
||||
f, _ := service.GetFolderByUID("uid")
|
||||
f, _ := service.GetFolderByUID(context.Background(), "uid")
|
||||
require.Equal(t, f.Id, dashFolder.Id)
|
||||
require.Equal(t, f.Uid, dashFolder.Uid)
|
||||
require.Equal(t, f.Title, dashFolder.Title)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package libraryelements
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -123,8 +124,8 @@ func (l *LibraryElementService) createLibraryElement(c *models.ReqContext, cmd C
|
||||
return LibraryElementDTO{}, err
|
||||
}
|
||||
|
||||
err := l.SQLStore.WithTransactionalDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
if err := l.requirePermissionsOnFolder(c.SignedInUser, cmd.FolderID); err != nil {
|
||||
err := l.SQLStore.WithTransactionalDbSession(c.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
if err := l.requirePermissionsOnFolder(c.Req.Context(), c.SignedInUser, cmd.FolderID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := session.Insert(&element); err != nil {
|
||||
@ -169,12 +170,12 @@ func (l *LibraryElementService) createLibraryElement(c *models.ReqContext, cmd C
|
||||
|
||||
// deleteLibraryElement deletes a library element.
|
||||
func (l *LibraryElementService) deleteLibraryElement(c *models.ReqContext, uid string) error {
|
||||
return l.SQLStore.WithTransactionalDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
return l.SQLStore.WithTransactionalDbSession(c.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
element, err := getLibraryElement(l.SQLStore.Dialect, session, uid, c.SignedInUser.OrgId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := l.requirePermissionsOnFolder(c.SignedInUser, element.FolderID); err != nil {
|
||||
if err := l.requirePermissionsOnFolder(c.Req.Context(), c.SignedInUser, element.FolderID); err != nil {
|
||||
return err
|
||||
}
|
||||
var connectionIDs []struct {
|
||||
@ -408,7 +409,7 @@ func (l *LibraryElementService) getAllLibraryElements(c *models.ReqContext, quer
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (l *LibraryElementService) handleFolderIDPatches(elementToPatch *LibraryElement, fromFolderID int64, toFolderID int64, user *models.SignedInUser) error {
|
||||
func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, elementToPatch *LibraryElement, fromFolderID int64, toFolderID int64, user *models.SignedInUser) error {
|
||||
// FolderID was not provided in the PATCH request
|
||||
if toFolderID == -1 {
|
||||
toFolderID = fromFolderID
|
||||
@ -416,13 +417,13 @@ func (l *LibraryElementService) handleFolderIDPatches(elementToPatch *LibraryEle
|
||||
|
||||
// FolderID was provided in the PATCH request
|
||||
if toFolderID != -1 && toFolderID != fromFolderID {
|
||||
if err := l.requirePermissionsOnFolder(user, toFolderID); err != nil {
|
||||
if err := l.requirePermissionsOnFolder(ctx, user, toFolderID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Always check permissions for the folder where library element resides
|
||||
if err := l.requirePermissionsOnFolder(user, fromFolderID); err != nil {
|
||||
if err := l.requirePermissionsOnFolder(ctx, user, fromFolderID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -437,7 +438,7 @@ func (l *LibraryElementService) patchLibraryElement(c *models.ReqContext, cmd pa
|
||||
if err := l.requireSupportedElementKind(cmd.Kind); err != nil {
|
||||
return LibraryElementDTO{}, err
|
||||
}
|
||||
err := l.SQLStore.WithTransactionalDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
err := l.SQLStore.WithTransactionalDbSession(c.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
elementInDB, err := getLibraryElement(l.SQLStore.Dialect, session, uid, c.SignedInUser.OrgId)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -484,7 +485,7 @@ func (l *LibraryElementService) patchLibraryElement(c *models.ReqContext, cmd pa
|
||||
if cmd.Model == nil {
|
||||
libraryElement.Model = elementInDB.Model
|
||||
}
|
||||
if err := l.handleFolderIDPatches(&libraryElement, elementInDB.FolderID, cmd.FolderID, c.SignedInUser); err != nil {
|
||||
if err := l.handleFolderIDPatches(c.Req.Context(), &libraryElement, elementInDB.FolderID, cmd.FolderID, c.SignedInUser); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := syncFieldsWithModel(&libraryElement); err != nil {
|
||||
@ -633,7 +634,7 @@ func (l *LibraryElementService) getElementsForDashboardID(c *models.ReqContext,
|
||||
|
||||
// connectElementsToDashboardID adds connections for all elements Library Elements in a Dashboard.
|
||||
func (l *LibraryElementService) connectElementsToDashboardID(c *models.ReqContext, elementUIDs []string, dashboardID int64) error {
|
||||
err := l.SQLStore.WithTransactionalDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
err := l.SQLStore.WithTransactionalDbSession(c.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
_, err := session.Exec("DELETE FROM "+models.LibraryElementConnectionTableName+" WHERE kind=1 AND connection_id=?", dashboardID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -643,7 +644,7 @@ func (l *LibraryElementService) connectElementsToDashboardID(c *models.ReqContex
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := l.requirePermissionsOnFolder(c.SignedInUser, element.FolderID); err != nil {
|
||||
if err := l.requirePermissionsOnFolder(c.Req.Context(), c.SignedInUser, element.FolderID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -680,7 +681,7 @@ func (l *LibraryElementService) disconnectElementsFromDashboardID(c *models.ReqC
|
||||
|
||||
// deleteLibraryElementsInFolderUID deletes all Library Elements in a folder.
|
||||
func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c *models.ReqContext, folderUID string) error {
|
||||
return l.SQLStore.WithTransactionalDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
return l.SQLStore.WithTransactionalDbSession(c.Req.Context(), func(session *sqlstore.DBSession) error {
|
||||
var folderUIDs []struct {
|
||||
ID int64 `xorm:"id"`
|
||||
}
|
||||
@ -693,7 +694,7 @@ func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c *models.ReqCo
|
||||
}
|
||||
folderID := folderUIDs[0].ID
|
||||
|
||||
if err := l.requirePermissionsOnFolder(c.SignedInUser, folderID); err != nil {
|
||||
if err := l.requirePermissionsOnFolder(c.Req.Context(), c.SignedInUser, folderID); err != nil {
|
||||
return err
|
||||
}
|
||||
var connectionIDs []struct {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package libraryelements
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
@ -22,7 +24,7 @@ func (l *LibraryElementService) requireSupportedElementKind(kindAsInt int64) err
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LibraryElementService) requirePermissionsOnFolder(user *models.SignedInUser, folderID int64) error {
|
||||
func (l *LibraryElementService) requirePermissionsOnFolder(ctx context.Context, user *models.SignedInUser, folderID int64) error {
|
||||
if isGeneralFolder(folderID) && user.HasRole(models.ROLE_EDITOR) {
|
||||
return nil
|
||||
}
|
||||
@ -32,7 +34,7 @@ func (l *LibraryElementService) requirePermissionsOnFolder(user *models.SignedIn
|
||||
}
|
||||
|
||||
s := dashboards.NewFolderService(user.OrgId, user, l.SQLStore)
|
||||
folder, err := s.GetFolderByID(folderID)
|
||||
folder, err := s.GetFolderByID(ctx, folderID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
|
||||
|
||||
s := dashboards.NewFolderService(user.OrgId, &user, sqlStore)
|
||||
t.Logf("Creating folder with title and UID %q", title)
|
||||
folder, err := s.CreateFolder(title, title)
|
||||
folder, err := s.CreateFolder(context.Background(), title, title)
|
||||
require.NoError(t, err)
|
||||
|
||||
updateFolderACL(t, sqlStore, folder.Id, items)
|
||||
|
@ -1111,7 +1111,7 @@ func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string
|
||||
|
||||
s := dashboards.NewFolderService(user.OrgId, &user, sqlStore)
|
||||
t.Logf("Creating folder with title and UID %q", title)
|
||||
folder, err := s.CreateFolder(title, title)
|
||||
folder, err := s.CreateFolder(context.Background(), title, title)
|
||||
require.NoError(t, err)
|
||||
|
||||
updateFolderACL(t, sqlStore, folder.Id, items)
|
||||
|
@ -47,7 +47,7 @@ func (h *DashboardHandler) GetHandlerForPath(_ string) (models.ChannelHandler, e
|
||||
}
|
||||
|
||||
// OnSubscribe for now allows anyone to subscribe to any dashboard
|
||||
func (h *DashboardHandler) OnSubscribe(_ context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
|
||||
func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
|
||||
parts := strings.Split(e.Path, "/")
|
||||
if parts[0] == "gitops" {
|
||||
// gitops gets all changes for everything, so lets make sure it is an admin user
|
||||
@ -62,7 +62,7 @@ func (h *DashboardHandler) OnSubscribe(_ context.Context, user *models.SignedInU
|
||||
// make sure can view this dashboard
|
||||
if len(parts) == 2 && parts[0] == "uid" {
|
||||
query := models.GetDashboardQuery{Uid: parts[1], OrgId: user.OrgId}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
if err := bus.DispatchCtx(ctx, &query); err != nil {
|
||||
logger.Error("Error getting dashboard", "query", query, "error", err)
|
||||
return models.SubscribeReply{}, backend.SubscribeStreamStatusNotFound, nil
|
||||
}
|
||||
@ -85,7 +85,7 @@ func (h *DashboardHandler) OnSubscribe(_ context.Context, user *models.SignedInU
|
||||
}
|
||||
|
||||
// OnPublish is called when someone begins to edit a dashboard
|
||||
func (h *DashboardHandler) OnPublish(_ context.Context, user *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
|
||||
func (h *DashboardHandler) OnPublish(ctx context.Context, user *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
|
||||
parts := strings.Split(e.Path, "/")
|
||||
if parts[0] == "gitops" {
|
||||
// gitops gets all changes for everything, so lets make sure it is an admin user
|
||||
@ -109,7 +109,7 @@ func (h *DashboardHandler) OnPublish(_ context.Context, user *models.SignedInUse
|
||||
return models.PublishReply{}, backend.PublishStreamStatusNotFound, fmt.Errorf("ignore???")
|
||||
}
|
||||
query := models.GetDashboardQuery{Uid: parts[1], OrgId: user.OrgId}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
if err := bus.DispatchCtx(ctx, &query); err != nil {
|
||||
logger.Error("Unknown dashboard", "query", query)
|
||||
return models.PublishReply{}, backend.PublishStreamStatusNotFound, nil
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func (srv PrometheusSrv) RouteGetRuleStatuses(c *models.ReqContext) response.Res
|
||||
},
|
||||
}
|
||||
|
||||
namespaceMap, err := srv.store.GetNamespaces(c.OrgId, c.SignedInUser)
|
||||
namespaceMap, err := srv.store.GetNamespaces(c.Req.Context(), c.OrgId, c.SignedInUser)
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusInternalServerError, err, "failed to get namespaces visible to the user")
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ type RulerSrv struct {
|
||||
|
||||
func (srv RulerSrv) RouteDeleteNamespaceRulesConfig(c *models.ReqContext) response.Response {
|
||||
namespaceTitle := c.Params(":Namespace")
|
||||
namespace, err := srv.store.GetNamespaceByTitle(namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, true)
|
||||
namespace, err := srv.store.GetNamespaceByTitle(c.Req.Context(), namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, true)
|
||||
if err != nil {
|
||||
return toNamespaceErrorResponse(err)
|
||||
}
|
||||
@ -50,7 +50,7 @@ func (srv RulerSrv) RouteDeleteNamespaceRulesConfig(c *models.ReqContext) respon
|
||||
|
||||
func (srv RulerSrv) RouteDeleteRuleGroupConfig(c *models.ReqContext) response.Response {
|
||||
namespaceTitle := c.Params(":Namespace")
|
||||
namespace, err := srv.store.GetNamespaceByTitle(namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, true)
|
||||
namespace, err := srv.store.GetNamespaceByTitle(c.Req.Context(), namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, true)
|
||||
if err != nil {
|
||||
return toNamespaceErrorResponse(err)
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (srv RulerSrv) RouteDeleteRuleGroupConfig(c *models.ReqContext) response.Re
|
||||
|
||||
func (srv RulerSrv) RouteGetNamespaceRulesConfig(c *models.ReqContext) response.Response {
|
||||
namespaceTitle := c.Params(":Namespace")
|
||||
namespace, err := srv.store.GetNamespaceByTitle(namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, false)
|
||||
namespace, err := srv.store.GetNamespaceByTitle(c.Req.Context(), namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, false)
|
||||
if err != nil {
|
||||
return toNamespaceErrorResponse(err)
|
||||
}
|
||||
@ -114,7 +114,7 @@ func (srv RulerSrv) RouteGetNamespaceRulesConfig(c *models.ReqContext) response.
|
||||
|
||||
func (srv RulerSrv) RouteGetRulegGroupConfig(c *models.ReqContext) response.Response {
|
||||
namespaceTitle := c.Params(":Namespace")
|
||||
namespace, err := srv.store.GetNamespaceByTitle(namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, false)
|
||||
namespace, err := srv.store.GetNamespaceByTitle(c.Req.Context(), namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, false)
|
||||
if err != nil {
|
||||
return toNamespaceErrorResponse(err)
|
||||
}
|
||||
@ -147,7 +147,7 @@ func (srv RulerSrv) RouteGetRulegGroupConfig(c *models.ReqContext) response.Resp
|
||||
}
|
||||
|
||||
func (srv RulerSrv) RouteGetRulesConfig(c *models.ReqContext) response.Response {
|
||||
namespaceMap, err := srv.store.GetNamespaces(c.OrgId, c.SignedInUser)
|
||||
namespaceMap, err := srv.store.GetNamespaces(c.Req.Context(), c.OrgId, c.SignedInUser)
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusInternalServerError, err, "failed to get namespaces visible to the user")
|
||||
}
|
||||
@ -214,7 +214,7 @@ func (srv RulerSrv) RouteGetRulesConfig(c *models.ReqContext) response.Response
|
||||
|
||||
func (srv RulerSrv) RoutePostNameRulesConfig(c *models.ReqContext, ruleGroupConfig apimodels.PostableRuleGroupConfig) response.Response {
|
||||
namespaceTitle := c.Params(":Namespace")
|
||||
namespace, err := srv.store.GetNamespaceByTitle(namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, true)
|
||||
namespace, err := srv.store.GetNamespaceByTitle(c.Req.Context(), namespaceTitle, c.SignedInUser.OrgId, c.SignedInUser, true)
|
||||
if err != nil {
|
||||
return toNamespaceErrorResponse(err)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -109,10 +110,10 @@ func (f *fakeRuleStore) GetRuleGroupAlertRules(q *models.ListRuleGroupAlertRules
|
||||
|
||||
return nil
|
||||
}
|
||||
func (f *fakeRuleStore) GetNamespaces(_ int64, _ *models2.SignedInUser) (map[string]*models2.Folder, error) {
|
||||
func (f *fakeRuleStore) GetNamespaces(_ context.Context, _ int64, _ *models2.SignedInUser) (map[string]*models2.Folder, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeRuleStore) GetNamespaceByTitle(_ string, _ int64, _ *models2.SignedInUser, _ bool) (*models2.Folder, error) {
|
||||
func (f *fakeRuleStore) GetNamespaceByTitle(_ context.Context, _ string, _ int64, _ *models2.SignedInUser, _ bool) (*models2.Folder, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeRuleStore) GetOrgRuleGroups(_ *models.ListOrgRuleGroupsQuery) error { return nil }
|
||||
|
@ -1,6 +1,7 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
@ -251,7 +252,7 @@ func (st *Manager) createAlertAnnotation(new eval.State, alertRule *ngModels.Ale
|
||||
OrgId: alertRule.OrgID,
|
||||
}
|
||||
|
||||
err = sqlstore.GetDashboard(query)
|
||||
err = sqlstore.GetDashboardCtx(context.TODO(), query)
|
||||
if err != nil {
|
||||
st.log.Error("error getting dashboard for alert annotation", "dashboardUID", dashUid, "alertRuleUID", alertRule.UID, "error", err.Error())
|
||||
return
|
||||
|
@ -47,8 +47,8 @@ type RuleStore interface {
|
||||
GetOrgAlertRules(query *ngmodels.ListAlertRulesQuery) error
|
||||
GetNamespaceAlertRules(query *ngmodels.ListNamespaceAlertRulesQuery) error
|
||||
GetRuleGroupAlertRules(query *ngmodels.ListRuleGroupAlertRulesQuery) error
|
||||
GetNamespaces(int64, *models.SignedInUser) (map[string]*models.Folder, error)
|
||||
GetNamespaceByTitle(string, int64, *models.SignedInUser, bool) (*models.Folder, error)
|
||||
GetNamespaces(context.Context, int64, *models.SignedInUser) (map[string]*models.Folder, error)
|
||||
GetNamespaceByTitle(context.Context, string, int64, *models.SignedInUser, bool) (*models.Folder, error)
|
||||
GetOrgRuleGroups(query *ngmodels.ListOrgRuleGroupsQuery) error
|
||||
UpsertAlertRules([]UpsertRule) error
|
||||
UpdateRuleGroup(UpdateRuleGroupCmd) error
|
||||
@ -372,13 +372,13 @@ func (st DBstore) GetRuleGroupAlertRules(query *ngmodels.ListRuleGroupAlertRules
|
||||
}
|
||||
|
||||
// GetNamespaces returns the folders that are visible to the user
|
||||
func (st DBstore) GetNamespaces(orgID int64, user *models.SignedInUser) (map[string]*models.Folder, error) {
|
||||
func (st DBstore) GetNamespaces(ctx context.Context, orgID int64, user *models.SignedInUser) (map[string]*models.Folder, error) {
|
||||
s := dashboards.NewFolderService(orgID, user, st.SQLStore)
|
||||
namespaceMap := make(map[string]*models.Folder)
|
||||
var page int64 = 1
|
||||
for {
|
||||
// if limit is negative; it fetches at most 1000
|
||||
folders, err := s.GetFolders(-1, page)
|
||||
folders, err := s.GetFolders(ctx, -1, page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -396,9 +396,9 @@ func (st DBstore) GetNamespaces(orgID int64, user *models.SignedInUser) (map[str
|
||||
}
|
||||
|
||||
// GetNamespaceByTitle is a handler for retrieving a namespace by its title. Alerting rules follow a Grafana folder-like structure which we call namespaces.
|
||||
func (st DBstore) GetNamespaceByTitle(namespace string, orgID int64, user *models.SignedInUser, withCanSave bool) (*models.Folder, error) {
|
||||
func (st DBstore) GetNamespaceByTitle(ctx context.Context, namespace string, orgID int64, user *models.SignedInUser, withCanSave bool) (*models.Folder, error) {
|
||||
s := dashboards.NewFolderService(orgID, user, st.SQLStore)
|
||||
folder, err := s.GetFolderByTitle(namespace)
|
||||
folder, err := s.GetFolderByTitle(ctx, namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
// DashboardProvisioner is responsible for syncing dashboard from disk to
|
||||
// Grafana's database.
|
||||
type DashboardProvisioner interface {
|
||||
Provision() error
|
||||
Provision(ctx context.Context) error
|
||||
PollChanges(ctx context.Context)
|
||||
GetProvisionerResolvedPath(name string) string
|
||||
GetAllowUIUpdatesFromConfig(name string) bool
|
||||
@ -59,9 +59,9 @@ func New(configDirectory string, store dashboards.Store) (DashboardProvisioner,
|
||||
|
||||
// Provision scans the disk for dashboards and updates
|
||||
// the database with the latest versions of those dashboards.
|
||||
func (provider *Provisioner) Provision() error {
|
||||
func (provider *Provisioner) Provision(ctx context.Context) error {
|
||||
for _, reader := range provider.fileReaders {
|
||||
if err := reader.walkDisk(); err != nil {
|
||||
if err := reader.walkDisk(ctx); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// don't stop the provisioning service in case the folder is missing. The folder can appear after the startup
|
||||
provider.log.Warn("Failed to provision config", "name", reader.Cfg.Name, "error", err)
|
||||
|
@ -13,7 +13,7 @@ type calls struct {
|
||||
// ProvisionerMock is a mock implementation of `Provisioner`
|
||||
type ProvisionerMock struct {
|
||||
Calls *calls
|
||||
ProvisionFunc func() error
|
||||
ProvisionFunc func(ctx context.Context) error
|
||||
PollChangesFunc func(ctx context.Context)
|
||||
GetProvisionerResolvedPathFunc func(name string) string
|
||||
GetAllowUIUpdatesFromConfigFunc func(name string) bool
|
||||
@ -27,10 +27,10 @@ func NewDashboardProvisionerMock() *ProvisionerMock {
|
||||
}
|
||||
|
||||
// Provision is a mock implementation of `Provisioner.Provision`
|
||||
func (dpm *ProvisionerMock) Provision() error {
|
||||
func (dpm *ProvisionerMock) Provision(ctx context.Context) error {
|
||||
dpm.Calls.Provision = append(dpm.Calls.Provision, nil)
|
||||
if dpm.ProvisionFunc != nil {
|
||||
return dpm.ProvisionFunc()
|
||||
return dpm.ProvisionFunc(ctx)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func (fr *FileReader) pollChanges(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
if err := fr.walkDisk(); err != nil {
|
||||
if err := fr.walkDisk(ctx); err != nil {
|
||||
fr.log.Error("failed to search for dashboards", "error", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
@ -85,7 +85,7 @@ func (fr *FileReader) pollChanges(ctx context.Context) {
|
||||
|
||||
// walkDisk traverses the file system for the defined path, reading dashboard definition files,
|
||||
// and applies any change to the database.
|
||||
func (fr *FileReader) walkDisk() error {
|
||||
func (fr *FileReader) walkDisk(ctx context.Context) error {
|
||||
fr.log.Debug("Start walking disk", "path", fr.Path)
|
||||
resolvedPath := fr.resolvedPath()
|
||||
if _, err := os.Stat(resolvedPath); err != nil {
|
||||
@ -107,9 +107,9 @@ func (fr *FileReader) walkDisk() error {
|
||||
|
||||
usageTracker := newUsageTracker()
|
||||
if fr.FoldersFromFilesStructure {
|
||||
err = fr.storeDashboardsInFoldersFromFileStructure(filesFoundOnDisk, provisionedDashboardRefs, resolvedPath, usageTracker)
|
||||
err = fr.storeDashboardsInFoldersFromFileStructure(ctx, filesFoundOnDisk, provisionedDashboardRefs, resolvedPath, usageTracker)
|
||||
} else {
|
||||
err = fr.storeDashboardsInFolder(filesFoundOnDisk, provisionedDashboardRefs, usageTracker)
|
||||
err = fr.storeDashboardsInFolder(ctx, filesFoundOnDisk, provisionedDashboardRefs, usageTracker)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -137,9 +137,9 @@ func (fr *FileReader) isDatabaseAccessRestricted() bool {
|
||||
}
|
||||
|
||||
// storeDashboardsInFolder saves dashboards from the filesystem on disk to the folder from config
|
||||
func (fr *FileReader) storeDashboardsInFolder(filesFoundOnDisk map[string]os.FileInfo,
|
||||
func (fr *FileReader) storeDashboardsInFolder(ctx context.Context, filesFoundOnDisk map[string]os.FileInfo,
|
||||
dashboardRefs map[string]*models.DashboardProvisioning, usageTracker *usageTracker) error {
|
||||
folderID, err := getOrCreateFolderID(fr.Cfg, fr.dashboardProvisioningService, fr.Cfg.Folder)
|
||||
folderID, err := getOrCreateFolderID(ctx, fr.Cfg, fr.dashboardProvisioningService, fr.Cfg.Folder)
|
||||
if err != nil && !errors.Is(err, ErrFolderNameMissing) {
|
||||
return err
|
||||
}
|
||||
@ -159,7 +159,7 @@ func (fr *FileReader) storeDashboardsInFolder(filesFoundOnDisk map[string]os.Fil
|
||||
|
||||
// storeDashboardsInFoldersFromFilesystemStructure saves dashboards from the filesystem on disk to the same folder
|
||||
// in Grafana as they are in on the filesystem.
|
||||
func (fr *FileReader) storeDashboardsInFoldersFromFileStructure(filesFoundOnDisk map[string]os.FileInfo,
|
||||
func (fr *FileReader) storeDashboardsInFoldersFromFileStructure(ctx context.Context, filesFoundOnDisk map[string]os.FileInfo,
|
||||
dashboardRefs map[string]*models.DashboardProvisioning, resolvedPath string, usageTracker *usageTracker) error {
|
||||
for path, fileInfo := range filesFoundOnDisk {
|
||||
folderName := ""
|
||||
@ -169,7 +169,7 @@ func (fr *FileReader) storeDashboardsInFoldersFromFileStructure(filesFoundOnDisk
|
||||
folderName = filepath.Base(dashboardsFolder)
|
||||
}
|
||||
|
||||
folderID, err := getOrCreateFolderID(fr.Cfg, fr.dashboardProvisioningService, folderName)
|
||||
folderID, err := getOrCreateFolderID(ctx, fr.Cfg, fr.dashboardProvisioningService, folderName)
|
||||
if err != nil && !errors.Is(err, ErrFolderNameMissing) {
|
||||
return fmt.Errorf("can't provision folder %q from file system structure: %w", folderName, err)
|
||||
}
|
||||
@ -291,13 +291,13 @@ func getProvisionedDashboardsByPath(service dashboards.DashboardProvisioningServ
|
||||
return byPath, nil
|
||||
}
|
||||
|
||||
func getOrCreateFolderID(cfg *config, service dashboards.DashboardProvisioningService, folderName string) (int64, error) {
|
||||
func getOrCreateFolderID(ctx context.Context, cfg *config, service dashboards.DashboardProvisioningService, folderName string) (int64, error) {
|
||||
if folderName == "" {
|
||||
return 0, ErrFolderNameMissing
|
||||
}
|
||||
|
||||
cmd := &models.GetDashboardQuery{Slug: models.SlugifyTitle(folderName), OrgId: cfg.OrgID}
|
||||
err := bus.Dispatch(cmd)
|
||||
err := bus.DispatchCtx(ctx, cmd)
|
||||
|
||||
if err != nil && !errors.Is(err, models.ErrDashboardNotFound) {
|
||||
return 0, err
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
@ -115,7 +116,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
folders := 0
|
||||
@ -146,7 +147,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(fakeService.inserted), ShouldEqual, 1)
|
||||
@ -181,7 +182,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
So(len(fakeService.inserted), ShouldEqual, 0)
|
||||
})
|
||||
@ -207,7 +208,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
So(len(fakeService.inserted), ShouldEqual, 1)
|
||||
})
|
||||
@ -241,7 +242,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
So(len(fakeService.inserted), ShouldEqual, 0)
|
||||
})
|
||||
@ -267,7 +268,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
So(len(fakeService.inserted), ShouldEqual, 1)
|
||||
})
|
||||
@ -278,7 +279,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(fakeService.inserted), ShouldEqual, 1)
|
||||
@ -291,7 +292,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(fakeService.inserted), ShouldEqual, 5)
|
||||
@ -350,13 +351,13 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader1.walkDisk()
|
||||
err = reader1.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader2.walkDisk()
|
||||
err = reader2.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
var folderCount int
|
||||
@ -385,7 +386,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
_, err := getOrCreateFolderID(cfg, fakeService, cfg.Folder)
|
||||
_, err := getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
|
||||
So(err, ShouldEqual, ErrFolderNameMissing)
|
||||
})
|
||||
|
||||
@ -400,7 +401,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
folderID, err := getOrCreateFolderID(cfg, fakeService, cfg.Folder)
|
||||
folderID, err := getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
|
||||
So(err, ShouldBeNil)
|
||||
inserted := false
|
||||
for _, d := range fakeService.inserted {
|
||||
@ -460,7 +461,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(fakeService.provisioned["Default"]), ShouldEqual, 1)
|
||||
@ -471,7 +472,7 @@ func TestDashboardFileReader(t *testing.T) {
|
||||
reader, err := NewDashboardFileReader(cfg, logger, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = reader.walkDisk()
|
||||
err = reader.walkDisk(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(fakeService.provisioned["Default"]), ShouldEqual, 1)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
@ -31,7 +32,7 @@ func TestDuplicatesValidator(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"
|
||||
folderID, err := getOrCreateFolderID(cfg, fakeService, folderName)
|
||||
folderID, err := getOrCreateFolderID(context.Background(), cfg, fakeService, folderName)
|
||||
require.NoError(t, err)
|
||||
|
||||
identity := dashboardIdentity{folderID: folderID, title: "Grafana"}
|
||||
@ -53,10 +54,10 @@ func TestDuplicatesValidator(t *testing.T) {
|
||||
|
||||
duplicateValidator := newDuplicateValidator(logger, []*FileReader{reader1, reader2})
|
||||
|
||||
err = reader1.walkDisk()
|
||||
err = reader1.walkDisk(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
err = reader2.walkDisk()
|
||||
err = reader2.walkDisk(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
duplicates := duplicateValidator.getDuplicates()
|
||||
@ -94,15 +95,15 @@ func TestDuplicatesValidator(t *testing.T) {
|
||||
|
||||
duplicateValidator := newDuplicateValidator(logger, []*FileReader{reader1, reader2})
|
||||
|
||||
err = reader1.walkDisk()
|
||||
err = reader1.walkDisk(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
err = reader2.walkDisk()
|
||||
err = reader2.walkDisk(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
duplicates := duplicateValidator.getDuplicates()
|
||||
|
||||
folderID, err := getOrCreateFolderID(cfg, fakeService, cfg1.Folder)
|
||||
folderID, err := getOrCreateFolderID(context.Background(), cfg, fakeService, cfg1.Folder)
|
||||
require.NoError(t, err)
|
||||
|
||||
identity := dashboardIdentity{folderID: folderID, title: "Grafana"}
|
||||
|
@ -163,7 +163,7 @@ func (ps *ProvisioningServiceImpl) ProvisionDashboards() error {
|
||||
ps.cancelPolling()
|
||||
dashProvisioner.CleanUpOrphanedDashboards()
|
||||
|
||||
err = dashProvisioner.Provision()
|
||||
err = dashProvisioner.Provision(context.TODO())
|
||||
if err != nil {
|
||||
// If we fail to provision with the new provisioner, the mutex will unlock and the polling will restart with the
|
||||
// old provisioner as we did not switch them yet.
|
||||
|
@ -48,7 +48,7 @@ func TestProvisioningServiceImpl(t *testing.T) {
|
||||
serviceTest.waitForPollChanges()
|
||||
assert.Equal(t, 1, len(serviceTest.mock.Calls.PollChanges), "PollChanges should have been called")
|
||||
|
||||
serviceTest.mock.ProvisionFunc = func() error {
|
||||
serviceTest.mock.ProvisionFunc = func(ctx context.Context) error {
|
||||
return errors.New("Test error")
|
||||
}
|
||||
err = serviceTest.service.ProvisionDashboards()
|
||||
|
@ -234,7 +234,7 @@ func (ss *SQLStore) GetFolderByTitle(orgID int64, title string) (*models.Dashboa
|
||||
|
||||
// TODO: Remove me
|
||||
func GetDashboard(query *models.GetDashboardQuery) error {
|
||||
return GetDashboardCtx(context.Background(), query)
|
||||
return GetDashboardCtx(context.TODO(), query)
|
||||
}
|
||||
|
||||
func GetDashboardCtx(ctx context.Context, query *models.GetDashboardQuery) error {
|
||||
|
@ -56,7 +56,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err := GetDashboard(&query)
|
||||
err := GetDashboardCtx(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(query.Result.Title, ShouldEqual, "test dash 23")
|
||||
@ -72,7 +72,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err := GetDashboard(&query)
|
||||
err := GetDashboardCtx(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(query.Result.Title, ShouldEqual, "test dash 23")
|
||||
@ -88,7 +88,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err := GetDashboard(&query)
|
||||
err := GetDashboardCtx(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(query.Result.Title, ShouldEqual, "test dash 23")
|
||||
@ -103,7 +103,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err := GetDashboard(&query)
|
||||
err := GetDashboardCtx(context.Background(), &query)
|
||||
So(err, ShouldEqual, models.ErrDashboardIdentifierNotSet)
|
||||
})
|
||||
|
||||
@ -191,7 +191,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err = GetDashboard(&query)
|
||||
err = GetDashboardCtx(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
So(query.Result.FolderId, ShouldEqual, 0)
|
||||
So(query.Result.CreatedBy, ShouldEqual, savedDash.CreatedBy)
|
||||
|
@ -4,6 +4,7 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@ -51,7 +52,7 @@ func TestGetDashboardVersion(t *testing.T) {
|
||||
Uid: savedDash.Uid,
|
||||
}
|
||||
|
||||
err = GetDashboard(&dashCmd)
|
||||
err = GetDashboardCtx(context.Background(), &dashCmd)
|
||||
So(err, ShouldBeNil)
|
||||
eq := reflect.DeepEqual(dashCmd.Result.Data, query.Result.Data)
|
||||
So(eq, ShouldEqual, true)
|
||||
|
Loading…
Reference in New Issue
Block a user