Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1b849dd

Browse files
authoredApr 8, 2024··
feat: using SSA for finalizer and primary patch (#2305)
Signed-off-by: Attila Mészáros <csviri@gmail.com>
1 parent f62ba49 commit 1b849dd

File tree

48 files changed

+642
-419
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+642
-419
lines changed
 

‎docs/documentation/features.md

+35-16
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,31 @@ Those are the typical use cases of resource updates, however in some cases there
9191
the controller wants to update the resource itself (for example to add annotations) or not perform
9292
any updates, which is also supported.
9393

94-
It is also possible to update both the status and the resource with the
95-
`updateResourceAndStatus` method. In this case, the resource is updated first followed by the
96-
status, using two separate requests to the Kubernetes API.
97-
98-
You should always state your intent using `UpdateControl` and let the SDK deal with the actual
99-
updates instead of performing these updates yourself using the actual Kubernetes client so that
100-
the SDK can update its internal state accordingly.
101-
102-
Resource updates are protected using optimistic version control, to make sure that other updates
103-
that might have occurred in the mean time on the server are not overwritten. This is ensured by
104-
setting the `resourceVersion` field on the processed resources.
94+
It is also possible to update both the status and the resource with the `patchResourceAndStatus` method. In this case,
95+
the resource is updated first followed by the status, using two separate requests to the Kubernetes API.
96+
97+
From v5 `UpdateControl` only supports patching the resources, by default
98+
using [Server Side Apply (SSA)](https://kubernetes.io/docs/reference/using-api/server-side-apply/).
99+
It is important to understand how SSA works in Kubernetes. Mainly, resources applied using SSA
100+
should contain only the fields identifying the resource and those the user is interested in (a 'fully specified intent'
101+
in Kubernetes parlance), thus usually using a resource created from scratch, see
102+
[sample](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/patchresourcewithssa/PatchResourceWithSSAReconciler.java#L18-L22).
103+
To contrast, see the same sample, this time [without SSA](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/patchresourceandstatusnossa/PatchResourceAndStatusNoSSAReconciler.java#L16-L16).
104+
105+
Non-SSA based patch is still supported.
106+
You can control whether or not to use SSA
107+
using [`ConfigurationServcice.useSSAToPatchPrimaryResource()`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L385-L385)
108+
and the related `ConfigurationServiceOverrider.withUseSSAToPatchPrimaryResource` method.
109+
Related integration test can be
110+
found [here](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/patchresourceandstatusnossa/PatchResourceAndStatusNoSSAReconciler.java).
111+
112+
Handling resources directly using the client, instead of delegating these updates operations to JOSDK by returning
113+
an `UpdateControl` at the end of your reconciliation, should work appropriately. However, we do recommend to
114+
use `UpdateControl` instead since JOSDK makes sure that the operations are handled properly, since there are subtleties
115+
to be aware of. For example, if you are using a finalizer, JOSDK makes sure to include it in your fully specified intent
116+
so that it is not unintentionally removed from the resource (which would happen if you omit it, since your controller is
117+
the designated manager for that field and Kubernetes interprets the finalizer being gone from the specified intent as a
118+
request for removal).
105119

106120
[`DeleteControl`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java)
107121
typically instructs the framework to remove the finalizer after the dependent
@@ -170,6 +184,8 @@ You can specify the name of the finalizer to use for your `Reconciler` using the
170184
[`@ControllerConfiguration`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java)
171185
annotation. If you do not specify a finalizer name, one will be automatically generated for you.
172186

187+
From v5 by default finalizer is added using Served Side Apply. See also UpdateControl in docs.
188+
173189
## Automatic Observed Generation Handling
174190

175191
Having an `.observedGeneration` value on your resources' status is a best practice to
@@ -187,11 +203,14 @@ In order to have this feature working:
187203
So the status should be instantiated when the object is returned using the `UpdateControl`.
188204

189205
If these conditions are fulfilled and generation awareness is activated, the observed generation
190-
is automatically set by the framework after the `reconcile` method is called. Note that the
191-
observed generation is also updated even when `UpdateControl.noUpdate()` is returned from the
192-
reconciler. See this feature at work in
193-
the [WebPage example](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStatus.java#L5)
194-
.
206+
is automatically set by the framework after the `reconcile` method is called.
207+
208+
When using SSA based patches, the observed generation is only updated when `UpdateControl.patchStatus` or
209+
`UpdateControl.patchResourceAndStatus` is returned. In case the of non-SSA based patches
210+
the observed generation is also updated even when `UpdateControl.noUpdate()` is returned from the
211+
reconciler.
212+
See this feature at work in the [WebPage example](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStatus.java#L5).
213+
See turning off an on the SSA based patching at [`ConfigurationServcice.useSSAToPatchPrimaryResource()`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L385-L385).
195214

196215
```java
197216
public class WebPageStatus extends ObservedGenerationAwareStatus {

‎docs/documentation/v5-0-migration.md

+12-6
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,21 @@ permalink: /docs/v5-0-migration
1717
[`EventSourceUtils`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceUtils.java#L11-L11)
1818
now contains all the utility methods used for event sources naming that were previously defined in
1919
the `EventSourceInitializer` interface.
20-
3. Patching status through `UpdateControl` like the `patchStatus` method now by default
21-
uses Server Side Apply instead of simple patch. To use the former approach, use the feature flag
22-
in [`ConfigurationService`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L400-L400)
20+
3. Updates through `UpdateControl` now use [Server Side Apply (SSA)](https://kubernetes.io/docs/reference/using-api/server-side-apply/) by default to add the finalizer and for all
21+
the patch operations in `UpdateControl`. The update operations were removed. If you do not wish to use SSA, you can deactivate the feature using `ConfigurationService.useSSAToPatchPrimaryResource` and related `ConfigurationServiceOverrider.withUseSSAToPatchPrimaryResource`.
22+
2323
!!! IMPORTANT !!!
24-
Migration from a non-SSA based controller to SSA based controller can cause problems, due to known issues.
25-
See the
26-
following [integration test](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/StatusPatchSSAMigrationIT.java#L71-L82)
24+
25+
See known issues with migration from non-SSA to SSA based status updates here:
26+
[integration test](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/StatusPatchSSAMigrationIT.java#L71-L82)
2727
where it is demonstrated. Also, the related part of
2828
a [workaround](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/StatusPatchSSAMigrationIT.java#L110-L116).
29+
30+
Related automatic observed generation handling changes:
31+
Automated Observed Generation (see features in docs), is automatically handled for non-SSA, even if
32+
the status sub-resource is not instructed to be updated. This is not true for SSA, observed generation is updated
33+
only when patch status is instructed by `UpdateControl`.
34+
2935
4. `ManagedDependentResourceContext` has been renamed to `ManagedWorkflowAndDependentResourceContext` and is accessed
3036
via the accordingly renamed `managedWorkflowAndDependentResourceContext` method.
3137
5. `ResourceDiscriminator` was removed. In most of the cases you can just delete the discriminator, everything should

0 commit comments

Comments
 (0)
Please sign in to comment.