diff --git a/docs/content/en/blog/news/_index.md b/docs/content/en/blog/news/_index.md index c609aa2543..646c97f954 100644 --- a/docs/content/en/blog/news/_index.md +++ b/docs/content/en/blog/news/_index.md @@ -1,4 +1,4 @@ --- -title: News +title: Posts weight: 20 --- diff --git a/docs/content/en/blog/news/nonssa-vs-ssa.md b/docs/content/en/blog/news/nonssa-vs-ssa.md new file mode 100644 index 0000000000..241828d3e3 --- /dev/null +++ b/docs/content/en/blog/news/nonssa-vs-ssa.md @@ -0,0 +1,89 @@ +--- +title: From legacy approach to server-side apply +date: 2025-02-25 +--- + +From version 5 of Java Operator SDK [server side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/) +is a first-class feature and is used by default to update resources. +As we will see, unfortunately (or fortunately), using it requires changes for your reconciler implementation. + +For this reason, we prepared a feature flag, which you can flip if you are not prepared to migrate yet: +[`ConfigurationService.useSSAToPatchPrimaryResource`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L493) + +Setting this flag to false will make the operations done by `UpdateControl` using the former approach (not SSA). +Similarly, the finalizer handling won't utilize SSA handling. +The plan is to keep this flag and allow the use of the former approach (non-SSA) also in future releases. + +For dependent resources, a separate flag exists (this was true also before v5) to use SSA or not: +[`ConfigurationService.ssaBasedCreateUpdateMatchForDependentResources`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L373) + + +## Resource handling without and with SSA + +Until version 5, changing primary resources through `UpdateControl` did not use server-side apply. +So usually, the implementation of the reconciler looked something like this: + +```java + + @Override + public UpdateControl reconcile(WebPage webPage, Context context) { + + reconcileLogicForManagedResources(webPage); + webPage.setStatus(updatedStatusForWebPage(webPage)); + + return UpdateControl.patchStatus(webPage); + } + +``` + +In other words, after the reconciliation of managed resources, the reconciler updates the status of the +primary resource passed as an argument to the reconciler. +Such changes on the primary are fine since we don't work directly with the cached object, the argument is +already cloned. + +So, how does this change with SSA? +For SSA, the updates should contain (only) the "fully specified intent". +In other words, we should only fill in the values we care about. +In practice, it means creating a **fresh copy** of the resource and setting only what is necessary: + +```java + +@Override +public UpdateControl reconcile(WebPage webPage, Context context) { + + reconcileLogicForManagedResources(webPage); + + WebPage statusPatch = new WebPage(); + statusPatch.setMetadata(new ObjectMetaBuilder() + .withName(webPage.getMetadata().getName()) + .withNamespace(webPage.getMetadata().getNamespace()) + .build()); + statusPatch.setStatus(updatedStatusForWebPage(webPage)); + + return UpdateControl.patchStatus(statusPatch); +} +``` + +Note that we just filled out the status here since we patched the status (not the resource spec). +Since the status is a sub-resource in Kubernetes, it will only update the status part. + +Every controller you register will have its default [field manager](https://kubernetes.io/docs/reference/using-api/server-side-apply/#managers). +You can override the field manager name using [`ControllerConfiguration.fieldManager`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java#L89). +That will set the field manager for the primary resource and dependent resources as well. + +## Migrating to SSA + +Using the legacy or the new SSA way of resource management works well. +However, migrating existing resources to SSA might be a challenge. +We strongly recommend testing the migration, thus implementing an integration test where +a custom resource is created using the legacy approach and is managed by the new approach. + +We prepared an integration test to demonstrate how such migration, even in a simple case, can go wrong, +and how to fix it. + +To fix some cases, you might need to [strip managed fields](https://kubernetes.io/docs/reference/using-api/server-side-apply/#clearing-managedfields) +from the custom resource. + +See [`StatusPatchSSAMigrationIT`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuspatchnonlocking/StatusPatchSSAMigrationIT.java) for details. + +Feel free to report common issues, so we can prepare some utilities to handle them. diff --git a/docs/content/en/blog/releases/v5-release.md b/docs/content/en/blog/releases/v5-release.md index 8d5fe36dbe..6d14dfb73a 100644 --- a/docs/content/en/blog/releases/v5-release.md +++ b/docs/content/en/blog/releases/v5-release.md @@ -41,7 +41,7 @@ to `false`. See some identified problematic migration cases and how to handle them in [StatusPatchSSAMigrationIT](https://github.com/operator-framework/java-operator-sdk/blob/1635c9ea338f8e89bacc547808d2b409de8734cf/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuspatchnonlocking/StatusPatchSSAMigrationIT.java). -TODO using new instance to update status always, +For more detailed description, see our [blog post](../news/nonssa-vs-ssa.md) on SSA. ### Event Sources related changes