GoogleCloudPlatform / metacontroller

Lightweight Kubernetes controllers as a service
https://metacontroller.app/
Apache License 2.0
792 stars 111 forks source link

Event type on sync payload #157

Closed luisdavim closed 5 years ago

luisdavim commented 5 years ago

I would it be possible to add a field to the sync payload sent to the hook including an event type (add, delete, update)? I'm using a CompositeController and I'd like to be able to take different actions if the CRD instance was created added or updated, delete is already covered by the finalizing property.

enisoc commented 5 years ago

Can you give an example of what you'd want to do differently for add vs. update?

To give some background: the cause of the event is intentionally hidden because relying on knowing the cause is typically an anti-pattern for k8s controllers. To see why that is, a good case to consider is a controller upgrade:

  1. Stop old controller version.
  2. Some object gets created.
  3. Start new controller version.

When the new controller starts up, it will only see an update event for the object, as part of a full resync. The controller has forever missed the add event, so controllers shouldn't rely on knowing whether or not an object has just been created.

Instead of distinguishing add vs. update, controllers should look at the actual "state of the world" to determine whether it needs to take action. As a simple example, if you want to create a Bar (perhaps in an external system, so Metacontroller can't do it for you) whenever a Foo (in k8s) gets created, run this logic whenever your sync hook gets called for a Foo:

  1. Compute a deterministic name/ID for the desired Bar, based on the contents of the Foo.
  2. If the desired Bar doesn't exist, try to create it, using an API that will be a no-op if it already exists.

In this way, the controller will make progress towards the desired state no matter what happened prior to this instance of the controller starting up.

luisdavim commented 5 years ago

I understand the advantages of level triggering, in my case I'm, managing an external component (external to the cluster) and there are some action that I can only do on creation but I think I can work around that by adding some flag to the state of the resource and that should be more reliable. thanks