Skip to content

Commit e267802

Browse files
committed
wip
Signed-off-by: Attila Mészáros <[email protected]>
1 parent 3dfdda5 commit e267802

File tree

4 files changed

+213
-157
lines changed

4 files changed

+213
-157
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.api.reconciler;
17+
18+
import java.util.function.UnaryOperator;
19+
20+
import io.fabric8.kubernetes.api.model.HasMetadata;
21+
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
22+
import io.fabric8.kubernetes.client.dsl.base.PatchType;
23+
import io.javaoperatorsdk.operator.processing.event.source.informer.ManagedInformerEventSource;
24+
25+
public class ReconcileUtils {
26+
27+
private ReconcileUtils() {}
28+
29+
// todo javadoc
30+
// todo move finalizers mtehods & deprecate
31+
// todo namespace handling
32+
// todo compare resource version if multiple event sources provide the same resource
33+
// for json patch make sense to retry for ?
34+
35+
public static <R extends HasMetadata> R serverSideApply(
36+
Context<? extends HasMetadata> context, R resource) {
37+
return resourcePatch(
38+
context,
39+
resource,
40+
r ->
41+
context
42+
.getClient()
43+
.resource(r)
44+
.patch(
45+
new PatchContext.Builder()
46+
.withForce(true)
47+
.withFieldManager(context.getControllerConfiguration().fieldManager())
48+
.withPatchType(PatchType.SERVER_SIDE_APPLY)
49+
.build()));
50+
}
51+
52+
public static <R extends HasMetadata> R serverSideApplyStatus(
53+
Context<? extends HasMetadata> context, R resource) {
54+
return resourcePatch(
55+
context,
56+
resource,
57+
r ->
58+
context
59+
.getClient()
60+
.resource(r)
61+
.subresource("status")
62+
.patch(
63+
new PatchContext.Builder()
64+
.withForce(true)
65+
.withFieldManager(context.getControllerConfiguration().fieldManager())
66+
.withPatchType(PatchType.SERVER_SIDE_APPLY)
67+
.build()));
68+
}
69+
70+
public static <P extends HasMetadata> P serverSideApplyPrimary(Context<P> context, P resource) {
71+
return resourcePatch(
72+
resource,
73+
r ->
74+
context
75+
.getClient()
76+
.resource(r)
77+
.patch(
78+
new PatchContext.Builder()
79+
.withForce(true)
80+
.withFieldManager(context.getControllerConfiguration().fieldManager())
81+
.withPatchType(PatchType.SERVER_SIDE_APPLY)
82+
.build()),
83+
context.eventSourceRetriever().getControllerEventSource());
84+
}
85+
86+
public static <P extends HasMetadata> P serverSideApplyPrimaryStatus(
87+
Context<P> context, P resource) {
88+
return resourcePatch(
89+
resource,
90+
r ->
91+
context
92+
.getClient()
93+
.resource(r)
94+
.subresource("status")
95+
.patch(
96+
new PatchContext.Builder()
97+
.withForce(true)
98+
.withFieldManager(context.getControllerConfiguration().fieldManager())
99+
.withPatchType(PatchType.SERVER_SIDE_APPLY)
100+
.build()),
101+
context.eventSourceRetriever().getControllerEventSource());
102+
}
103+
104+
public static <R extends HasMetadata> R update(
105+
Context<? extends HasMetadata> context, R resource) {
106+
return resourcePatch(context, resource, r -> context.getClient().resource(r).update());
107+
}
108+
109+
public static <R extends HasMetadata> R updateStatus(
110+
Context<? extends HasMetadata> context, R resource) {
111+
return resourcePatch(context, resource, r -> context.getClient().resource(r).updateStatus());
112+
}
113+
114+
public static <R extends HasMetadata> R jsonPatch(
115+
Context<? extends HasMetadata> context, R resource, UnaryOperator<R> unaryOperator) {
116+
return resourcePatch(
117+
context, resource, r -> context.getClient().resource(r).edit(unaryOperator));
118+
}
119+
120+
public static <R extends HasMetadata> R jsonPatchStatus(
121+
Context<? extends HasMetadata> context, R resource, UnaryOperator<R> unaryOperator) {
122+
return resourcePatch(
123+
context, resource, r -> context.getClient().resource(r).editStatus(unaryOperator));
124+
}
125+
126+
public static <R extends HasMetadata> R jsonPatchPrimary(
127+
Context<? extends HasMetadata> context, R resource, UnaryOperator<R> unaryOperator) {
128+
return resourcePatch(
129+
resource,
130+
r -> context.getClient().resource(r).edit(unaryOperator),
131+
context.eventSourceRetriever().getControllerEventSource());
132+
}
133+
134+
public static <R extends HasMetadata> R jsonPatchPrimaryStatus(
135+
Context<? extends HasMetadata> context, R resource, UnaryOperator<R> unaryOperator) {
136+
return resourcePatch(
137+
resource,
138+
r -> context.getClient().resource(r).editStatus(unaryOperator),
139+
context.eventSourceRetriever().getControllerEventSource());
140+
}
141+
142+
public static <R extends HasMetadata> R jsonMergePatch(
143+
Context<? extends HasMetadata> context, R resource) {
144+
return resourcePatch(context, resource, r -> context.getClient().resource(r).patch());
145+
}
146+
147+
public static <R extends HasMetadata> R jsonMergePatchStatus(
148+
Context<? extends HasMetadata> context, R resource) {
149+
return resourcePatch(context, resource, r -> context.getClient().resource(r).patchStatus());
150+
}
151+
152+
public static <R extends HasMetadata> R resourcePatch(
153+
Context<?> context, R resource, UnaryOperator<R> updateOperation) {
154+
var esList = context.eventSourceRetriever().getEventSourcesFor(resource.getClass());
155+
if (esList.isEmpty()) {
156+
throw new IllegalStateException("No event source found for type: " + resource.getClass());
157+
}
158+
if (esList.size() > 1) {
159+
throw new IllegalStateException(
160+
"Multiple event sources found for: "
161+
+ resource.getClass()
162+
+ " please provide the target event source");
163+
}
164+
var es = esList.get(0);
165+
if (es instanceof ManagedInformerEventSource mes) {
166+
return resourcePatch(resource, updateOperation, mes);
167+
} else {
168+
throw new IllegalStateException(
169+
"Target event source must be a subclass off "
170+
+ ManagedInformerEventSource.class.getName());
171+
}
172+
}
173+
174+
@SuppressWarnings("unchecked")
175+
public static <R extends HasMetadata> R resourcePatch(
176+
R resource, UnaryOperator<R> updateOperation, ManagedInformerEventSource ies) {
177+
return (R) ies.updateAndCacheResource(resource, updateOperation);
178+
}
179+
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ReconcilerUtils.java

Lines changed: 0 additions & 124 deletions
This file was deleted.

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import io.javaoperatorsdk.operator.api.reconciler.Context;
4141
import io.javaoperatorsdk.operator.api.reconciler.DefaultContext;
4242
import io.javaoperatorsdk.operator.api.reconciler.DeleteControl;
43-
import io.javaoperatorsdk.operator.api.reconciler.ReconcilerUtils;
43+
import io.javaoperatorsdk.operator.api.reconciler.ReconcileUtils;
4444
import io.javaoperatorsdk.operator.api.reconciler.RetryInfo;
4545
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
4646
import io.javaoperatorsdk.operator.processing.Controller;
@@ -195,7 +195,7 @@ private PostExecutionControl<P> reconcileExecution(
195195
}
196196

197197
if (updateControl.isPatchResource()) {
198-
updatedCustomResource = patchResource(toUpdate, originalResource);
198+
updatedCustomResource = patchResource(context, toUpdate, originalResource);
199199
if (!useSSA) {
200200
toUpdate
201201
.getMetadata()
@@ -381,7 +381,7 @@ private P addFinalizerWithSSA(P originalResource) {
381381
objectMeta.setNamespace(originalResource.getMetadata().getNamespace());
382382
resource.setMetadata(objectMeta);
383383
resource.addFinalizer(configuration().getFinalizerName());
384-
return customResourceFacade.patchResourceWithSSA(resource);
384+
return customResourceFacade.simpleServerSideApply(resource);
385385
} catch (InstantiationException
386386
| IllegalAccessException
387387
| InvocationTargetException
@@ -406,7 +406,7 @@ private P updateCustomResourceWithFinalizer(P resourceForExecution, P originalRe
406406
false);
407407
}
408408

409-
private P patchResource(P resource, P originalResource) {
409+
private P patchResource(Context<P> context, P resource, P originalResource) {
410410
log.debug(
411411
"Updating resource: {} with version: {}; SSA: {}",
412412
getUID(resource),
@@ -419,7 +419,7 @@ private P patchResource(P resource, P originalResource) {
419419
// addFinalizer already prevents adding an already present finalizer so no need to check
420420
resource.addFinalizer(finalizerName);
421421
}
422-
return customResourceFacade.patchResource(resource, originalResource);
422+
return customResourceFacade.patchResource(context, resource, originalResource);
423423
}
424424

425425
ControllerConfiguration<P> configuration() {
@@ -444,7 +444,7 @@ public P conflictRetryingPatch(
444444
if (forceNotUseSSA) {
445445
return customResourceFacade.patchResourceWithoutSSA(resource, originalResource);
446446
} else {
447-
return customResourceFacade.patchResource(resource, originalResource);
447+
return customResourceFacade.simpleServerSideApply(resource);
448448
}
449449
} catch (KubernetesClientException e) {
450450
log.trace("Exception during patch for resource: {}", resource);
@@ -516,17 +516,17 @@ public R patchResourceWithoutSSA(R resource, R originalResource) {
516516
return resource(originalResource).edit(r -> resource);
517517
}
518518

519-
public R patchResource(R resource, R originalResource) {
519+
public R patchResource(Context<R> context, R resource, R originalResource) {
520520
if (log.isDebugEnabled()) {
521521
log.debug(
522522
"Trying to replace resource {}, version: {}",
523523
ResourceID.fromResource(resource),
524524
resource.getMetadata().getResourceVersion());
525525
}
526526
if (useSSA) {
527-
return patchResourceWithSSA(resource);
527+
return ReconcileUtils.serverSideApplyPrimary(context, resource);
528528
} else {
529-
return resource(originalResource).edit(r -> resource);
529+
return ReconcileUtils.jsonPatchPrimary(context, originalResource, r -> resource);
530530
}
531531
}
532532

@@ -537,7 +537,7 @@ public R patchStatus(Context<R> context, R resource, R originalResource) {
537537
try {
538538
resource.getMetadata().setManagedFields(null);
539539
var res = resource(resource);
540-
return ReconcilerUtils.ssaStatusPrimary(context, resource);
540+
return ReconcileUtils.serverSideApplyPrimaryStatus(context, resource);
541541
} finally {
542542
resource.getMetadata().setManagedFields(managedFields);
543543
}
@@ -567,7 +567,7 @@ private R editStatus(R resource, R originalResource) {
567567
}
568568
}
569569

570-
public R patchResourceWithSSA(R resource) {
570+
public R simpleServerSideApply(R resource) {
571571
return resource(resource)
572572
.patch(
573573
new PatchContext.Builder()

0 commit comments

Comments
 (0)