nolar / kopf

A Python framework to write Kubernetes operators in just a few lines of code
https://kopf.readthedocs.io/
MIT License
2.15k stars 163 forks source link

Only add finalizers for specific sub-types of resources #1024

Open eelkoniovb opened 1 year ago

eelkoniovb commented 1 year ago

Keywords

kopf finalizers filter

Problem

Context We are using cert-manager to generate certificates. We have several issuer systems for certificates. When a certificate is removed, we want to use a kopf.on.delete() to call these systems to perform some actions. All external certificates need these calls while the certificates from the local cert-manager do not need external calls.

Problem When removing a cluster, all applications and their certificates are deleted. This works great as with each deleted certificate, kopf.on.delete() is called and our handler is triggered. However, for one specific type of certificates -the ones from cert-manager itself- no finalizer should be added. Cert-manager is removed as the last application, after our kopf-operator (due to sync-waves). But at that point the finalizer cannot be called and the deletion of the certificates is pending forever.

Attempts We have tried to change the finalizers list of specific certificate resources at on.create(), on.update(), on.resume() and on.event() but Kopf puts them back as soon as it notices the finalizer has been removed.

We have thought about going for an on.event() call instead of on.delete(), thus making the call non-blocking ('optional=True'). But that could lead to a resource that has already been deleted being fed to the operator, which then cannot determine what actions to take. This is gambling, which we don't like in our production systems.

Wishes Can we somehow turn off finalizers from specific types of resources? In our case: certificates that have spec.issuerRef.name="some-issuer" should not have finalizers, while certificates that have spec.issuerRef.name="other-issuer" do need the finalizer.

This feature does not seem to be part of the documentation nor has it been posed as a question here on GitHub yet, as far as I can see.

Hope to hear from you!

Cheers, Eelko

asteven commented 1 year ago

Can't you do this with filtering? e.g.

@kopf.on.delete('cert-manager.io', 'v1', 'certificate', field='spec.issuerRef.name', value='other-issuer')
def on_delete_certificate(**_):
    pass

Or use a callback for more control and flexibility.

nolar commented 1 year ago

This can also be achieved with when= callback filters. If you exclude some issuer(s) from the condition, Kopf will not "see" such resources, so it will not put finalizers on them and will remove those already added earlier.