diff --git a/pkg/registry/apis/folders/hooks.go b/pkg/registry/apis/folders/hooks.go index f0c954ecfeb..38942c19c5b 100644 --- a/pkg/registry/apis/folders/hooks.go +++ b/pkg/registry/apis/folders/hooks.go @@ -11,7 +11,10 @@ import ( "github.com/grafana/grafana/pkg/apimachinery/utils" ) -// "Almost nobody should use this hook" but we do because we need ctx and AfterCreate doesn't have it. +// K8S docs say "Almost nobody should use this hook" about the "begin" hooks, but we do because we only need to +// propagate if unistore write is successful. It also allows us to be a bit smarter about when to propagate, e.g. +// skipping root-level folders, skipping updates that don't change parent, etc. + func (b *FolderAPIBuilder) beginCreate(ctx context.Context, obj runtime.Object, _ *metav1.CreateOptions) (registry.FinishFunc, error) { log := logging.FromContext(ctx) meta, err := utils.MetaAccessor(obj) @@ -36,7 +39,6 @@ func (b *FolderAPIBuilder) beginCreate(ctx context.Context, obj runtime.Object, }, nil } -// "Almost nobody should use this hook" but we do because we need ctx and AfterUpdate doesn't have it. func (b *FolderAPIBuilder) beginUpdate(ctx context.Context, obj runtime.Object, old runtime.Object, _ *metav1.UpdateOptions) (registry.FinishFunc, error) { log := logging.FromContext(ctx) updatedMeta, err := utils.MetaAccessor(obj) @@ -66,6 +68,22 @@ func (b *FolderAPIBuilder) beginUpdate(ctx context.Context, obj runtime.Object, }, nil } +func (b *FolderAPIBuilder) afterDelete(obj runtime.Object, _ *metav1.DeleteOptions) { + ctx := context.Background() + log := logging.DefaultLogger + meta, err := utils.MetaAccessor(obj) + if err != nil { + log.Error("Failed to access deleted folder object metadata", "error", err) + return + } + + log.Info("Propagating deleted folder to Zanzana", "folder", meta.GetName(), "parent", meta.GetFolder()) + err = b.permissionStore.DeleteFolderParents(ctx, meta.GetNamespace(), meta.GetName()) + if err != nil { + log.Warn("failed to propagate folder to zanzana", "err", err) + } +} + func (b *FolderAPIBuilder) writeFolderToZanzana(ctx context.Context, folder utils.GrafanaMetaAccessor) { err := b.permissionStore.SetFolderParent(ctx, folder.GetNamespace(), folder.GetName(), folder.GetFolder()) if err != nil { diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index bce852eb66b..12ac60b46de 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -200,6 +200,7 @@ func (b *FolderAPIBuilder) registerPermissionHooks(store *genericregistry.Store) log.Info("Enabling Zanzana folder propagation hooks") store.BeginCreate = b.beginCreate store.BeginUpdate = b.beginUpdate + store.AfterDelete = b.afterDelete } else { log.Info("Zanzana is not enabled; skipping folder propagation hooks") }