diff --git a/src/lib/capability.ts b/src/lib/capability.ts index 1e4e13da8..b26d3e59d 100644 --- a/src/lib/capability.ts +++ b/src/lib/capability.ts @@ -337,7 +337,7 @@ export class Capability implements CapabilityExport { event: Event.Update, finalizeCallback: async (update: InstanceType, logger = aliasLogger) => { Log.info(`Executing finalize action with alias: ${binding.alias || "no alias provided"}`); - await finalizeCallback(update, logger); + return await finalizeCallback(update, logger); }, }; bindings.push(watchBinding); diff --git a/src/lib/types.ts b/src/lib/types.ts index d2625901f..dc21782dc 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -255,7 +255,7 @@ export type ValidateActionResponse = { export type FinalizeAction> = ( update: K, logger?: Logger, -) => Promise | void; +) => Promise | boolean | void; export type FinalizeActionChain = { /** diff --git a/src/lib/watch-processor.ts b/src/lib/watch-processor.ts index c75ced5c1..145f70537 100644 --- a/src/lib/watch-processor.ts +++ b/src/lib/watch-processor.ts @@ -106,12 +106,22 @@ async function runBinding(binding: Binding, capabilityNamespaces: string[], igno if (!obj.metadata?.deletionTimestamp) { return; } + + let shouldRemoveFinalizer: boolean | void | undefined = true; try { - await binding.finalizeCallback?.(obj); + shouldRemoveFinalizer = await binding.finalizeCallback?.(obj); - // irrespective of callback success / failure, remove pepr finalizer + // if not opt'ed out of / if in error state, remove pepr finalizer } finally { - await removeFinalizer(binding, obj); + const peprFinal = "pepr.dev/finalizer"; + const meta = obj.metadata!; + const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`; + + // [ true, void, undefined ] SHOULD remove finalizer + // [ false ] should NOT remove finalizer + shouldRemoveFinalizer === false + ? Log.debug({ obj }, `Skipping removal of finalizer '${peprFinal}' from '${resource}'`) + : await removeFinalizer(binding, obj); } } else { await binding.watchCallback?.(obj, phase);