Skip to content
This repository has been archived by the owner on Sep 14, 2020. It is now read-only.

Optionally remove the Status handler_id prefix #319

Open
lack opened this issue Mar 2, 2020 · 0 comments
Open

Optionally remove the Status handler_id prefix #319

lack opened this issue Mar 2, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@lack
Copy link

lack commented Mar 2, 2020

Problem

I want to write an operator where multiple handlers update the same Status fields in my object. The reason for this is twofold:

First I don't want the status object's schema to be defined on-the-fly in code, but by the CRD itself. This is especially important in apiVersion: apiextensions.k8s.io/v1 where extra measures need to be taken in order to allow arbitrary data to be added to the status subresource.

Secondly I want to have a single Status subresource area that is updated by multiple handlers. I want both my create handler and my update handler to set a shared Status field, such as object.status.result - The create handler would set this to "created" and the update handler would set this to "created". Again, this allows the definition of the object schema to be properly independent from the framework I choose to implement the operator.

Consider an example CRD where this would be relevant:

# A demo CRD for the Kopf example operators.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: kopfexamples.zalando.org
spec:
  scope: Namespaced
  group: zalando.org
  versions:
    - name: v1
      served: true
      storage: true
      subresources:
        status: {}
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                duration:
                  type: integer
                  description: For how long the pod should sleep.
            status:
              type: object
              properties:
                result:
                  type: string
                  description: The result from the handler
                kopf:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true
  names:
    kind: KopfExample
    plural: kopfexamples
    singular: kopfexample
    shortNames:
      - kopfexes
      - kopfex
      - kexes
      - kex

In other words, because of the schema enforced by the new apiVersion: apiextensions.k8s.io/v1, we could only ever have a single handler with an ID of 'result', and this is cumbersome. It would be much more convenient to tell kopf to just use the return value from a handler as given without injecting in the handler ID, allowing any handler to adhere to the defined status subresource schema.

Proposal

Introduce an optional flag when defining a handler (I suggest status_prefix=False) that would change the way the return value is used from the handler. When set to True (the default), behavior would be as currently defined, for backwards compatibility:

import kopf

@kopf.on.create("zalando.org", "v1", "kopfexamples")
async def created(spec, **kwargs):
    return {"result": "Created"}

@kopf.on.update("zalando.org", "v1", "kopfexamples")
async def updated(spec, **kwargs):
    return {"result": "Updated"}

Doing a create and then an update results in an object that contains:

Name:         kopf-example-1
...
Status:
  Created:
    Result:  Created
  Updated:
    Result:  Updated

With the new flag set:

import kopf

@kopf.on.create("zalando.org", "v1", "kopfexamples", status_prefix=False)
async def created(spec, **kwargs):
    return {"result": "Created"}

@kopf.on.update("zalando.org", "v1", "kopfexamples", status_prefix=False)
async def updated(spec, **kwargs):
    return {"result": "Updated"}

Resulting object is as follows:

Name:         kopf-example-2
  ...
Status:
  Result:  Updated

Alternatives?

  • For the issue of schema restrictions, as far as I can see the only way to do this under apiVersion: apiextensions.k8s.io/v1 is to go with a completely wide-open and unvalidated status subreource.
  • For the issue of having multiple handlers all setting the same subresource object, I don't think there's a way at all in the current implementation, because multiple handlers cannot share the same ID.
@lack lack added the enhancement New feature or request label Mar 2, 2020
lack added a commit to lack/kopf that referenced this issue Mar 2, 2020
As proposed in issue zalando-incubator#319, this introduces an optional status_prefix boolean that can be added to any resource handler definition. If set to True (or omitted), status returned by the handler is still placed beneath the handler_id in the resulting object's status subresource. If set to False, the status returned by the handler is use at the top-level of the status subresource.

Default handler with status_prefix=True:
  @kopf.on.create('zalando.org', 'v1', 'kopfexamples')
  def create(...):
    return {'my': 'result}

Result:
  ...
  Status:
    Create:
      My: Result

Handler with status_prefix=False:
  @kopf.on.create('zalando.org', 'v1', 'kopfexamples', status_prefix=False)
  def create(...):
    return {'my': 'result}

Result:
  ...
  Status:
    My: Result
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant