Skip to content

Commit dfaf06f

Browse files
authored
docs: blog post on SSA (#2689)
Signed-off-by: Attila Mészáros <[email protected]>
1 parent ea57fed commit dfaf06f

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

Diff for: docs/content/en/blog/news/_index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
---
2-
title: News
2+
title: Posts
33
weight: 20
44
---

Diff for: docs/content/en/blog/news/nonssa-vs-ssa.md

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
title: From legacy approach to server-side apply
3+
date: 2025-02-25
4+
---
5+
6+
From version 5 of Java Operator SDK [server side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/)
7+
is a first-class feature and is used by default to update resources.
8+
As we will see, unfortunately (or fortunately), using it requires changes for your reconciler implementation.
9+
10+
For this reason, we prepared a feature flag, which you can flip if you are not prepared to migrate yet:
11+
[`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)
12+
13+
Setting this flag to false will make the operations done by `UpdateControl` using the former approach (not SSA).
14+
Similarly, the finalizer handling won't utilize SSA handling.
15+
The plan is to keep this flag and allow the use of the former approach (non-SSA) also in future releases.
16+
17+
For dependent resources, a separate flag exists (this was true also before v5) to use SSA or not:
18+
[`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)
19+
20+
21+
## Resource handling without and with SSA
22+
23+
Until version 5, changing primary resources through `UpdateControl` did not use server-side apply.
24+
So usually, the implementation of the reconciler looked something like this:
25+
26+
```java
27+
28+
@Override
29+
public UpdateControl<WebPage> reconcile(WebPage webPage, Context<WebPage> context) {
30+
31+
reconcileLogicForManagedResources(webPage);
32+
webPage.setStatus(updatedStatusForWebPage(webPage));
33+
34+
return UpdateControl.patchStatus(webPage);
35+
}
36+
37+
```
38+
39+
In other words, after the reconciliation of managed resources, the reconciler updates the status of the
40+
primary resource passed as an argument to the reconciler.
41+
Such changes on the primary are fine since we don't work directly with the cached object, the argument is
42+
already cloned.
43+
44+
So, how does this change with SSA?
45+
For SSA, the updates should contain (only) the "fully specified intent".
46+
In other words, we should only fill in the values we care about.
47+
In practice, it means creating a **fresh copy** of the resource and setting only what is necessary:
48+
49+
```java
50+
51+
@Override
52+
public UpdateControl<WebPage> reconcile(WebPage webPage, Context<WebPage> context) {
53+
54+
reconcileLogicForManagedResources(webPage);
55+
56+
WebPage statusPatch = new WebPage();
57+
statusPatch.setMetadata(new ObjectMetaBuilder()
58+
.withName(webPage.getMetadata().getName())
59+
.withNamespace(webPage.getMetadata().getNamespace())
60+
.build());
61+
statusPatch.setStatus(updatedStatusForWebPage(webPage));
62+
63+
return UpdateControl.patchStatus(statusPatch);
64+
}
65+
```
66+
67+
Note that we just filled out the status here since we patched the status (not the resource spec).
68+
Since the status is a sub-resource in Kubernetes, it will only update the status part.
69+
70+
Every controller you register will have its default [field manager](https://kubernetes.io/docs/reference/using-api/server-side-apply/#managers).
71+
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).
72+
That will set the field manager for the primary resource and dependent resources as well.
73+
74+
## Migrating to SSA
75+
76+
Using the legacy or the new SSA way of resource management works well.
77+
However, migrating existing resources to SSA might be a challenge.
78+
We strongly recommend testing the migration, thus implementing an integration test where
79+
a custom resource is created using the legacy approach and is managed by the new approach.
80+
81+
We prepared an integration test to demonstrate how such migration, even in a simple case, can go wrong,
82+
and how to fix it.
83+
84+
To fix some cases, you might need to [strip managed fields](https://kubernetes.io/docs/reference/using-api/server-side-apply/#clearing-managedfields)
85+
from the custom resource.
86+
87+
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.
88+
89+
Feel free to report common issues, so we can prepare some utilities to handle them.

Diff for: docs/content/en/blog/releases/v5-release.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ to `false`.
4141
See some identified problematic migration cases and how to handle them
4242
in [StatusPatchSSAMigrationIT](https://github.com/operator-framework/java-operator-sdk/blob/1635c9ea338f8e89bacc547808d2b409de8734cf/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuspatchnonlocking/StatusPatchSSAMigrationIT.java).
4343

44-
TODO using new instance to update status always,
44+
For more detailed description, see our [blog post](../news/nonssa-vs-ssa.md) on SSA.
4545

4646
### Event Sources related changes
4747

0 commit comments

Comments
 (0)