You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As of apiextensions.k8s.io/v1 it is much more difficult to create a CRD that allows unvalidated information, as an openapi schema is required for even the status subresource. Tracking the handler progress in an annotation instead of the status subresource means it's easier to use kopf to write operators for CRDs that we don't own.
To define a wide-open status subresource in a v1 CRD, you can do the following:
Or for something more structured you can allow only the kopf property of the status subresource to be unvalidated as follows:
apiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata:
name: kopfexamples.zalando.orgspec:
scope: Namespacedgroup: zalando.orgversions:
- name: v1served: truestorage: truesubresources:
status: {}schema:
openAPIV3Schema:
type: objectproperties:
spec:
type: objectproperties:
# Main spec validation schema...status:
type: objectproperties:
result:
type: stringdescription: The result from the handlerenum:
- created
- updated# Other structured subresource schema data...kopf:
type: objectx-kubernetes-preserve-unknown-fields: true
Proposal
Kopf already stores important metadata in annotations including kopf.zalando.org/last-handled-configuration and kubectl.kubernetes.io/last-applied-configuration. Setting up the state.py mechanism to similarly use an annotation instead of the status subresource for its progress data should, I hope, be relatively straight-forward.
For resources whose CRDs can be altered, the other mechanisms to allow status.kopf.progress is an okay work-around. But the v1 schema enforcement means that kopf can't store its progress data there any more if the CRD cannot be altered.
Checklist
Many users can benefit from this feature, it is not a one-time case
The proposal is related to the K8s operator framework, not to the K8s client libraries
Commented by flo-02-mu at 2020-03-04 07:18:17+00:00
I am running into this issue when watching a k8s service object. The patch command does not return any error, but no kopf status is added. Thus, no retry attempt is made in case of exceptions.
I also had the same issues, but in an other context.
Seems, that the CustomResourceDefinition API silently ignores fields, which are not explicitly preserved.
Commented by gtsystem at 2020-03-24 14:38:21+00:00
Related to bug #308 where the same issue is visible for standard resources
Workaround for persisting the handler return values:
from functools import wraps
import json
def annotate_results(function=None, key='kopf.zalando.org/handler-results'):
"""A decorator that persists handler results as annotations on the
resource.
Before calling a handler, load any existing results from
annotations and pass them as the keyword argument 'results'
to the handler.
Store any outcome returned by the handler in the annotation.
Note that this implementation does not (yet) work with async handlers.
"""
def actual_decorator(f):
[wraps](https://github.com/wraps)(f)
def wrapper(*args, **kwargs):
meta = kwargs['meta']
results_json = meta['annotations'].get(key, None)
if results_json:
results = json.loads(results_json)
else:
results = {}
kwargs['results'] = results
result = f(*args, **kwargs)
if result:
results[f.__name__] = result
patch = kwargs['patch']
patch.metadata.annotations[key] = json.dumps(results)
# We don't return the result as we have handled it ourself.
# Otherwise kopf tries to store it again in the objects status
# which doesn't work anyway on k8s >= 1.16.
#return result
return wrapper
if function:
return actual_decorator(function)
return actual_decorator
Annotations are used for progress & diff-based storage for quite some time already (long time, actually). See the attached PRs above. In addition, when the patch is attempted to be applied but lost, a warning is issued.
I assume, all problems in this issue are solved by now, so I can close it.
If not, please open a new issue with the exact details (this archived issue is locked).
Problem
As of
apiextensions.k8s.io/v1
it is much more difficult to create a CRD that allows unvalidated information, as an openapi schema is required for even the status subresource. Tracking the handler progress in an annotation instead of the status subresource means it's easier to use kopf to write operators for CRDs that we don't own.To define a wide-open status subresource in a v1 CRD, you can do the following:
Or for something more structured you can allow only the kopf property of the status subresource to be unvalidated as follows:
Proposal
Kopf already stores important metadata in annotations including
kopf.zalando.org/last-handled-configuration
andkubectl.kubernetes.io/last-applied-configuration
. Setting up the state.py mechanism to similarly use an annotation instead of the status subresource for its progress data should, I hope, be relatively straight-forward.For resources whose CRDs can be altered, the other mechanisms to allow status.kopf.progress is an okay work-around. But the v1 schema enforcement means that kopf can't store its progress data there any more if the CRD cannot be altered.
Checklist
I am running into this issue when watching a k8s service object. The patch command does not return any error, but no kopf status is added. Thus, no retry attempt is made in case of exceptions.
I also had the same issues, but in an other context.
Seems, that the
CustomResourceDefinition
API silently ignores fields, which are not explicitly preserved.Related to bug #308 where the same issue is visible for standard resources
Workaround for persisting the handler return values:
Example usage with default annotation key:
Example usage with custom annotation key:
The text was updated successfully, but these errors were encountered: