mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
NestedFolders: Add folder service registry with dashboard service implementation (#65033)
* Delete folders, dashboards with registry service Co-authored-by: Serge Zaitsev <hello@zserge.com> * Update signature of ProvideDashboardServiceImpl * Regenerate mockery file * Add test for DeleteInFolder * Add test for DeleteDashboardsInFolder * Delete child dashboard associations via registry * Add validation of folder uid and org id --------- Co-authored-by: Serge Zaitsev <hello@zserge.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@@ -36,6 +37,9 @@ type Service struct {
|
||||
|
||||
// bus is currently used to publish event in case of title change
|
||||
bus bus.Bus
|
||||
|
||||
mutex sync.RWMutex
|
||||
registry map[string]folder.RegistryService
|
||||
}
|
||||
|
||||
func ProvideService(
|
||||
@@ -58,6 +62,7 @@ func ProvideService(
|
||||
accessControl: ac,
|
||||
bus: bus,
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
}
|
||||
if features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
srv.DBMigration(db)
|
||||
@@ -437,6 +442,12 @@ func (s *Service) Delete(ctx context.Context, cmd *folder.DeleteFolderCommand) e
|
||||
if cmd.SignedInUser == nil {
|
||||
return folder.ErrBadRequest.Errorf("missing signed in user")
|
||||
}
|
||||
if cmd.UID == "" {
|
||||
return folder.ErrBadRequest.Errorf("missing UID")
|
||||
}
|
||||
if cmd.OrgID < 1 {
|
||||
return folder.ErrBadRequest.Errorf("invalid orgID")
|
||||
}
|
||||
result := []string{cmd.UID}
|
||||
err := s.db.InTransaction(ctx, func(ctx context.Context) error {
|
||||
if s.features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
@@ -466,6 +477,11 @@ func (s *Service) Delete(ctx context.Context, cmd *folder.DeleteFolderCommand) e
|
||||
}
|
||||
return dashboards.ErrFolderAccessDenied
|
||||
}
|
||||
|
||||
if err := s.deleteChildrenInFolder(ctx, dashFolder.OrgID, dashFolder.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.legacyDelete(ctx, cmd, dashFolder)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -477,6 +493,15 @@ func (s *Service) Delete(ctx context.Context, cmd *folder.DeleteFolderCommand) e
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Service) deleteChildrenInFolder(ctx context.Context, orgID int64, UID string) error {
|
||||
for _, v := range s.registry {
|
||||
if err := v.DeleteInFolder(ctx, orgID, UID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) legacyDelete(ctx context.Context, cmd *folder.DeleteFolderCommand, dashFolder *folder.Folder) error {
|
||||
deleteCmd := dashboards.DeleteDashboardCommand{OrgID: cmd.OrgID, ID: dashFolder.ID, ForceDeleteFolderRules: cmd.ForceDeleteRules}
|
||||
|
||||
@@ -588,7 +613,8 @@ func (s *Service) nestedFolderDelete(ctx context.Context, cmd *folder.DeleteFold
|
||||
}
|
||||
result = append(result, subfolders...)
|
||||
}
|
||||
logger.Info("deleting folder", "org_id", cmd.OrgID, "uid", cmd.UID)
|
||||
|
||||
logger.Info("deleting folder and its contents", "org_id", cmd.OrgID, "uid", cmd.UID)
|
||||
err = s.store.Delete(ctx, cmd.UID, cmd.OrgID)
|
||||
if err != nil {
|
||||
logger.Info("failed deleting folder", "org_id", cmd.OrgID, "uid", cmd.UID, "err", err)
|
||||
@@ -794,3 +820,17 @@ func toFolderError(err error) error {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Service) RegisterService(r folder.RegistryService) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
_, ok := s.registry[r.Kind()]
|
||||
if ok {
|
||||
return folder.ErrTargetRegistrySrvConflict.Errorf("target registry service: %s already exists", r.Kind())
|
||||
}
|
||||
|
||||
s.registry[r.Kind()] = r
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user