Skip to content

Releases: SAP/component-operator-runtime

v0.3.9

12 Mar 16:39

Choose a tag to compare

Incompatible changes

  • New fields were added to component.InventoryItem; as this struct is used in the status include, all consumers must regenerate their CRDs.
  • The annotation mycomponent-operator.mydomain.io/order was renamed to mycomponent-operator.mydomain.io/apply-order; also the according constant types.AnnotationKeySuffixOrder was renamed to types.AnnotationKeySuffixApplyOrder.
  • The internal standard backoff was changed from a purely per-item exponential backoff to a more agile backoff: in detail, it is a combined per-item backoff of a 300-times-20ms-then-maxDelay limiter, and an overall 10-per-second-burst-20 bucket limiter; as a consequence, we have up to 20 almost immediate retries, then a phase of 10 retries per second for approximately 30s, and then slow retries at the rate given by maxDelay; as a consequence, retries (e.g. happening during a multi-wave apply or delete activity) will happen faster, and, on the other hand, be potentially more demanding for the API server.

Enhancements

  • Delete waves; there is a new annotation mycomponent-operator.mydomain.io/delete-order which can be used to delete dependents in waves; valid values are between -32768 and 32767; if unspecified, the default of 0 is assumed.

  • Status hints; many custom resource types nowadays have a status.observedGeneration fields, and a Ready condition; unfortunately some controllers are not populating these in a proper way; which means: they do it too late, which makes it difficult to observe the according instances; for example, kstatus assumes that an object which has no status.observedGeneration, and no Ready condition is ready, although it just might not yet have been seen or updated by its responsible controller. To overcome this problem, the manifests of dependent objects can be annotated such as

    annotations:
      mycomponent-operator.mydomain.io/status-hint: has-observed-generation,has-ready-condition

    (supplying only one of the two hints is also possible, of course); in that case, the framework will add an observedGeneration, or a Ready condition with Unknown state to the object, before passing it to kstatus, which will then detect and return the proper state of the object.

Version updates

  • controller-tools was updated to 0.14.0
  • go was updated to 1.22
  • various dependencies got updates

v0.3.8

11 Mar 07:15

Choose a tag to compare

fix(deps): update node.js to v21.7.0

v0.3.7

04 Mar 07:40

Choose a tag to compare

add remarks

v0.3.6

03 Mar 11:50

Choose a tag to compare

Changes

  • A builtin function kubernetesVersion was added to KustomizeGenerator; this builtin returns the deployment target cluster's server version as a version.Info struct. As version.Info is a Stringer, is is possible to use just kubernetesVersion as template pipeline value, such as {{ kubernetesVersion }}, which would result in something like 'v1.27.3`.

v0.3.5

29 Feb 18:20

Choose a tag to compare

Changes

  • Previously when a component was to be deleted, the following checks were performed:

    • check that there are no instances of managed types (such as CRO's ...)
    • check that the component does not have foreign finalizers
    • run the pre-delete hooks.

    This release changes the order in which these checks happen; now, pre-delete hooks are evaluated first.
    This allows pre-delete hooks to set the component into a DeletionPending state early.

v0.3.4

28 Feb 09:25

Choose a tag to compare

Enhancements

  • Support for server-side-apply: so far, updates to dependent objects happened through an replace/update (i.e. PUT) request. This approach has some drawbacks; most importantly, replace will revert all concurrent changes done on the object; while this is desirable for some kinds of changes( e..g somebody changing dependents manually by kubectl), there are other (legal) changes which should be preserved; such as changes done by HPA. Using server-side-apply PATCH (ssa) addresses this problem (see https://kubernetes.io/docs/reference/using-api/server-side-apply/). However, ssa never reverts foreign changes, if the declared manifest has no opinion about the corresponding fields. This means that manual changes (such as done by somebody using kubectl) might not get reverted. To overcome this, two server-side-apply modes are offered by component-operator-runtime:

    • ssa-merge: which is the standard server-side-apply behavior
    • ssa-override: claim ownership of all fields owned by either kubectl or helm (identified by having field manager starting with the prefix 'kubectl' or 'helm'), and then, doing a regular server-side-apply.
  • Server-side-apply can be enabled on reconciler level by setting the according option field UpdatePolicy:

      // ReconcilerOptions are creation options for a Reconciler.
    type ReconcilerOptions struct {
        // Whether namespaces are auto-created if missing.
        // If unspecified, true is assumed.
        CreateMissingNamespaces *bool
        // How to react if a dependent object exists but has no or a different owner.
        // If unspecified, AdoptionPolicyIfUnowned is assumed.
        // Can be overridden by annotation on object level.
        AdoptionPolicy *AdoptionPolicy
        // How to perform updates to dependent objects.
        // If unspecified, UpdatePolicyReplace is assumed.
        // Can be overridden by annotation on object level.
        UpdatePolicy *UpdatePolicy
        // Schemebuilder allows to define additional schemes to be made available in the
        // target client.
        SchemeBuilder types.SchemeBuilder
    }

    to one of the constants UpdatePolicySsaMerge or UpdatePolicySsaMerge, as defined in pkg/component. If this field is not specified in options, the default of UpdatePolicyReplace is assumed by the framework.
    Furthermore, the update policy can be overridden on a per-object level, by setting the annotation
    mycomponent-operator.example.io/update-policy to ssa-merge or ssa-override.

  • Now, also the adoption policy can be overridden on a per-object level by setting the annotation
    mycomponent-operator.example.io/adoption-policy to one of never, if-unowned, always. If not specified on an object level, the reconciler default counts, which in turn is defaulted as component.AdoptionPolicyIfUnowned.

v0.3.3

26 Feb 07:16

Choose a tag to compare

update docs

v0.3.2

18 Feb 23:23
f1ec537

Choose a tag to compare

Incompatible changes

  • The helm/kustomize generators were carved out of pkg/manifests, and moved into dedicated packages pkg/manifests/helm and pkg/manifests/kustomize, respectively.
  • Package pkg/utils was removed; the *FromContext() methods are now in pkg/component.
  • The field field manager of dependent objects (metadata.managedFields) is now set to the reconciler name passed to NewReconciler().

Enhancements

  • New component states Pending and DeletionPending are introduced; they will be set, if a RetriableError is thrown during the reconciliation, for example by generators or hooks.
  • A new method Reconciler.SetupWithManagerAndBuilder() was added. This allows to use an own controller-runtime builder for building the controller, which is useful for example if additional watches shall be set up, or custom controller options shall be used. The existing method Reconciler.SetupWithManager() remains unaffected, and should still be the best choice for most consumers.
  • The retry period in case of missing configmap/secret references is always set to 10s, independently of any RetryConfiguration implemented by the component.

Fixes

  • Previously, dependent objects were updated by the reconciler, even if they were in deleting state. During such an update, finalizers would probably get removed, leading to an immediate deletion of the object. This should not happen like this; to overcome, the reconciler no longer updates objects which are in a deletion state; in addition, to make the situation safe for objects without deletion timestamp, finalizers are copied over from the existing object during update.
  • A fix was applied to scaffold (calling go mod tidy in various places), in order to avoid issues with missing go.sum entries.

Version updates

  • Go was updated to 1.27, and various modules were upgraded.
  • Default versions in scaffold were updated.

v0.3.1

08 Feb 12:09

Choose a tag to compare

Changes

  • add more accurate kubebuilder:validation tags to CRD generation

v0.3.0

07 Feb 22:07

Choose a tag to compare

Incompatible changes

This release finalizes various announced deprecations:

  • remove deprecated parameters from component.NewReconciler()
  • remove deprecated parameters from manifests.NewHelmGenerator() and affiliated functions
  • remove deprecated parameters from the operator.Operator interface.

In addition, component.Reconciler() has a new parameter option that allows to tune the reconciler behavior (e.g. auto-creation of namespaces, adoption of existing resources, ...):

type ReconcilerOptions struct {
	// Whether namespaces are auto-created if missing.
	// If unspecified, true is assumed.
	CreateMissingNamespaces *bool
	// How to react if a dependent object exists but has no or a different owner.
	// If unspecified, AdoptionPolicyAdoptUnowned is assumed.
	AdoptionPolicy *AdoptionPolicy
	// Schemebuilder allows to define additional schemes to be made available in the
	// target client.
	SchemeBuilder types.SchemeBuilder
}

Enhancements

  • It is now possible (through reconciler options, see above) to tune whether or not missing namespaces will be automatically created; previously, they were always auto-created, which is the default behavior now.
  • It is now possible (through reconciler options, see above) to tune the reconciler behavior in case dependent objects already exist in the deployment target; previously, existing dependents were adopted if they had no owner-id label, and an error was raised if they had a different owner; this behavior is still the default, but it is now possible to optionally adopt all objects (even those with a foreign owner), or to always fail in case an object is already present.
  • Similar to generators, hooks can now retrieve a client for the deployment target from their context, by calling utils.ClientFromContext(). To be precise, this holds true for reconcile and delete hooks, but not for the post-read hook.
  • Generators can now retrieve a digest of the triggering component from their context, by calling utils.ComponentDigestFromContext(); note that this digest honors loaded references (i.e. occurrences of the ConfigMapReference, ConfigMapKeyReference, SecretReference, SecretKeyReference types).