Alerting: update rule versions on folder move (#88376)
* Alerting: update rule versions on folder move (#88361) * Add tracing to folder.Move and folder.Update
This commit is contained in:
committed by
GitHub
parent
8044cb50f1
commit
b2eeb0dd6e
@@ -13,6 +13,8 @@ import (
|
||||
|
||||
"github.com/grafana/dskit/concurrency"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
@@ -20,6 +22,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
|
||||
@@ -44,12 +47,14 @@ type Service struct {
|
||||
dashboardFolderStore folder.FolderStore
|
||||
features featuremgmt.FeatureToggles
|
||||
accessControl accesscontrol.AccessControl
|
||||
// bus is currently used to publish event in case of title change
|
||||
// bus is currently used to publish event in case of folder full path change.
|
||||
// For example when a folder is moved to another folder or when a folder is renamed.
|
||||
bus bus.Bus
|
||||
|
||||
mutex sync.RWMutex
|
||||
registry map[string]folder.RegistryService
|
||||
metrics *foldersMetrics
|
||||
tracer tracing.Tracer
|
||||
}
|
||||
|
||||
func ProvideService(
|
||||
@@ -61,6 +66,7 @@ func ProvideService(
|
||||
features featuremgmt.FeatureToggles,
|
||||
supportBundles supportbundles.Service,
|
||||
r prometheus.Registerer,
|
||||
tracer tracing.Tracer,
|
||||
) folder.Service {
|
||||
store := ProvideStore(db)
|
||||
srv := &Service{
|
||||
@@ -74,6 +80,7 @@ func ProvideService(
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(r),
|
||||
tracer: tracer,
|
||||
}
|
||||
srv.DBMigration(db)
|
||||
|
||||
@@ -655,6 +662,9 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
|
||||
}
|
||||
|
||||
func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (*folder.Folder, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "folder.Update")
|
||||
defer span.End()
|
||||
|
||||
if cmd.SignedInUser == nil {
|
||||
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
|
||||
}
|
||||
@@ -679,14 +689,8 @@ func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (
|
||||
|
||||
if cmd.NewTitle != nil {
|
||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc()
|
||||
if err := s.bus.Publish(ctx, &events.FolderTitleUpdated{
|
||||
Timestamp: foldr.Updated,
|
||||
Title: foldr.Title,
|
||||
ID: dashFolder.ID, // nolint:staticcheck
|
||||
UID: dashFolder.UID,
|
||||
OrgID: cmd.OrgID,
|
||||
}); err != nil {
|
||||
s.log.ErrorContext(ctx, "failed to publish FolderTitleUpdated event", "folder", foldr.Title, "user", cmd.SignedInUser.GetID(), "error", err)
|
||||
|
||||
if err := s.publishFolderFullPathUpdatedEvent(ctx, foldr.Updated, cmd.OrgID, cmd.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -873,6 +877,9 @@ func (s *Service) legacyDelete(ctx context.Context, cmd *folder.DeleteFolderComm
|
||||
}
|
||||
|
||||
func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*folder.Folder, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "folder.Move")
|
||||
defer span.End()
|
||||
|
||||
if cmd.SignedInUser == nil {
|
||||
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
|
||||
}
|
||||
@@ -947,6 +954,10 @@ func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*fol
|
||||
return folder.ErrInternal.Errorf("failed to move legacy folder: %w", err)
|
||||
}
|
||||
|
||||
if err := s.publishFolderFullPathUpdatedEvent(ctx, f.Updated, cmd.OrgID, cmd.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
@@ -954,6 +965,36 @@ func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*fol
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (s *Service) publishFolderFullPathUpdatedEvent(ctx context.Context, timestamp time.Time, orgID int64, folderUID string) error {
|
||||
ctx, span := s.tracer.Start(ctx, "folder.publishFolderFullPathUpdatedEvent")
|
||||
defer span.End()
|
||||
|
||||
descFolders, err := s.store.GetDescendants(ctx, orgID, folderUID)
|
||||
if err != nil {
|
||||
s.log.ErrorContext(ctx, "Failed to get descendants of the folder", "folderUID", folderUID, "orgID", orgID, "error", err)
|
||||
return err
|
||||
}
|
||||
uids := make([]string, 0, len(descFolders)+1)
|
||||
uids = append(uids, folderUID)
|
||||
for _, f := range descFolders {
|
||||
uids = append(uids, f.UID)
|
||||
}
|
||||
span.AddEvent("found folder descendants", trace.WithAttributes(
|
||||
attribute.Int64("folders", int64(len(uids))),
|
||||
))
|
||||
|
||||
if err := s.bus.Publish(ctx, &events.FolderFullPathUpdated{
|
||||
Timestamp: timestamp,
|
||||
UIDs: uids,
|
||||
OrgID: orgID,
|
||||
}); err != nil {
|
||||
s.log.ErrorContext(ctx, "Failed to publish FolderFullPathUpdated event", "folderUID", folderUID, "orgID", orgID, "descendantsUIDs", uids, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) canMove(ctx context.Context, cmd *folder.MoveFolderCommand) (bool, error) {
|
||||
// Check that the user is allowed to move the folder to the destination folder
|
||||
var evaluator accesscontrol.Evaluator
|
||||
|
||||
Reference in New Issue
Block a user