diff --git a/src/lib/capability.ts b/src/lib/capability.ts index a10ac6abc..bca88f114 100644 --- a/src/lib/capability.ts +++ b/src/lib/capability.ts @@ -347,7 +347,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 bda05857a..fed2c7aff 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -276,7 +276,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 9fbadf35a..7761127b1 100644 --- a/src/lib/watch-processor.ts +++ b/src/lib/watch-processor.ts @@ -107,12 +107,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);