Skip to content

Commit

Permalink
feat: add ability to exit Finalize() callback WITHOUT removing the fi…
Browse files Browse the repository at this point in the history
…nalizer (#1321)

## Description

Adds ability for Module Author to "opt out" of removing Pepr's
metadata.finalizers entry.

End to End Test:  <!-- if applicable -->  
[pepr-excellent-examples
#172](defenseunicorns/pepr-excellent-examples#172)

## Related Issue

Fixes #1316 

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Other (security config, docs update, etc)

## Checklist before merging
- [ ] Unit,
[Journey](https://github.com/defenseunicorns/pepr/tree/main/journey),
[E2E Tests](https://github.com/defenseunicorns/pepr-excellent-examples),
[docs](https://github.com/defenseunicorns/pepr/tree/main/docs),
[adr](https://github.com/defenseunicorns/pepr/tree/main/adr) added or
updated as needed
- [ ] [Contributor Guide
Steps](https://docs.pepr.dev/main/contribute/#submitting-a-pull-request)
followed

---------

Co-authored-by: Case Wylie <cmwylie19@defenseunicorns.com>
Co-authored-by: schaeferka <kim@defenseunicorns.com>
  • Loading branch information
3 people authored Oct 28, 2024
1 parent 055a8f4 commit 7bc80d5
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/lib/capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ export class Capability implements CapabilityExport {
event: Event.Update,
finalizeCallback: async (update: InstanceType<T>, 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);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export type ValidateActionResponse = {
export type FinalizeAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
update: K,
logger?: Logger,
) => Promise<void> | void;
) => Promise<boolean | void> | boolean | void;

export type FinalizeActionChain<T extends GenericClass> = {
/**
Expand Down
16 changes: 13 additions & 3 deletions src/lib/watch-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7bc80d5

Please sign in to comment.