19
19
import io .csviri .operator .resourceglue .templating .GenericTemplateHandler ;
20
20
import io .fabric8 .kubernetes .api .model .GenericKubernetesResource ;
21
21
import io .fabric8 .kubernetes .client .KubernetesClientException ;
22
+ import io .fabric8 .kubernetes .client .dsl .base .PatchContext ;
23
+ import io .fabric8 .kubernetes .client .dsl .base .PatchType ;
22
24
import io .javaoperatorsdk .operator .api .reconciler .*;
23
25
import io .javaoperatorsdk .operator .processing .GroupVersionKind ;
24
26
import io .javaoperatorsdk .operator .processing .dependent .workflow .Condition ;
27
29
import io .javaoperatorsdk .operator .processing .event .ResourceID ;
28
30
import io .javaoperatorsdk .operator .processing .event .source .informer .InformerEventSource ;
29
31
32
+ import static io .csviri .operator .resourceglue .Utils .getResourceForSSAFrom ;
33
+ import static io .csviri .operator .resourceglue .reconciler .operator .GlueOperatorReconciler .PARENT_RELATED_RESOURCE_NAME ;
34
+
30
35
@ ControllerConfiguration
31
36
public class GlueReconciler implements Reconciler <Glue >, Cleaner <Glue > {
32
37
33
38
private static final Logger log = LoggerFactory .getLogger (GlueReconciler .class );
34
39
public static final String DEPENDENT_NAME_ANNOTATION_KEY = "io.csviri.operator.resourceflow/name" ;
40
+ public static final String PARENT_GLUE_FINALIZER_PREFIX = "io.csviri.operator.resourceflow.glue/" ;
35
41
36
42
private final KubernetesResourceDeletedCondition deletePostCondition =
37
43
new KubernetesResourceDeletedCondition ();
@@ -44,8 +50,8 @@ public UpdateControl<Glue> reconcile(Glue primary,
44
50
45
51
log .debug ("Reconciling glue. name: {} namespace: {}" ,
46
52
primary .getMetadata ().getName (), primary .getMetadata ().getNamespace ());
47
- addFinalizersToParentResource (primary );
48
53
registerRelatedResourceInformers (context , primary );
54
+ addFinalizersToParentResource (primary , context );
49
55
if (ownersBeingDeleted (primary , context )) {
50
56
return UpdateControl .noUpdate ();
51
57
}
@@ -57,12 +63,6 @@ public UpdateControl<Glue> reconcile(Glue primary,
57
63
return UpdateControl .noUpdate ();
58
64
}
59
65
60
- // todo issue, condition if resource exists (related resource exists)
61
- // todo, also remove finalizer on cleanup
62
- // add just
63
- private void addFinalizersToParentResource (Glue primary ) {
64
-
65
- }
66
66
67
67
/**
68
68
* If a parent gets deleted, the glue is reconciled still, but we don't want that in that case.
@@ -92,9 +92,6 @@ private boolean ownersBeingDeleted(Glue primary, Context<Glue> context) {
92
92
93
93
@ Override
94
94
public DeleteControl cleanup (Glue primary , Context <Glue > context ) {
95
- // todo if related resource referenced to name the resource (name / namespace) the related
96
- // resource might be deleted
97
- // at this point - shall we add finalizer?
98
95
99
96
var actualWorkflow = buildWorkflowAndRegisterInformers (primary , context );
100
97
var result = actualWorkflow .cleanup (primary , context );
@@ -103,6 +100,7 @@ public DeleteControl cleanup(Glue primary, Context<Glue> context) {
103
100
if (!result .allPostConditionsMet ()) {
104
101
return DeleteControl .noFinalizerRemoval ();
105
102
} else {
103
+ removeFinalizerForParent (primary , context );
106
104
actualWorkflow .getDependentResourcesByNameWithoutActivationCondition ().forEach ((n , dr ) -> {
107
105
var genericDependentResource = (GenericDependentResource ) dr ;
108
106
informerRegister .deRegisterInformer (genericDependentResource .getGroupVersionKind (),
@@ -217,4 +215,73 @@ private Condition toCondition(ConditionSpec condition) {
217
215
throw new IllegalStateException ("Unknown condition: " + condition );
218
216
}
219
217
218
+ // todo docs
219
+ private void addFinalizersToParentResource (Glue primary , Context <Glue > context ) {
220
+ var parentRelated = primary .getSpec ().getRelatedResources ().stream ()
221
+ .filter (r -> r .getName ().equals (PARENT_RELATED_RESOURCE_NAME ))
222
+ .findAny ();
223
+ parentRelated .ifPresent (r -> {
224
+ var relatedResources = Utils .getRelatedResources (primary , r , context );
225
+ if (relatedResources .size () > 1 ) {
226
+ throw new IllegalStateException (
227
+ "parent related resource contains more resourceNames for glue name: "
228
+ + primary .getMetadata ().getName ()
229
+ + " namespace: " + primary .getMetadata ().getNamespace ());
230
+ }
231
+ // theoretically can happen that parent was deleted meanwhile
232
+ if (relatedResources .isEmpty ()) {
233
+ return ;
234
+ }
235
+ var parent = relatedResources .entrySet ().iterator ().next ().getValue ();
236
+ String finalizer = parentFinalizer (primary .getMetadata ().getName ());
237
+ if (!parent .getMetadata ().getFinalizers ().contains (finalizer )) {
238
+ var res = getResourceForSSAFrom (parent );
239
+ res .getMetadata ().getFinalizers ().add (finalizer );
240
+ context .getClient ().resource (res )
241
+ .patch (new PatchContext .Builder ()
242
+ .withFieldManager (context .getControllerConfiguration ().fieldManager ())
243
+ .withForce (true )
244
+ .withPatchType (PatchType .SERVER_SIDE_APPLY )
245
+ .build ());
246
+ }
247
+ });
248
+ }
249
+
250
+ private void removeFinalizerForParent (Glue primary , Context <Glue > context ) {
251
+ var parentRelated = primary .getSpec ().getRelatedResources ().stream ()
252
+ .filter (r -> r .getName ().equals (PARENT_RELATED_RESOURCE_NAME ))
253
+ .findAny ();
254
+ parentRelated .ifPresent (r -> {
255
+ var relatedResources = Utils .getRelatedResources (primary , r , context );
256
+ if (relatedResources .size () > 1 ) {
257
+ throw new IllegalStateException (
258
+ "parent related resource contains more resourceNames for glue name: "
259
+ + primary .getMetadata ().getName ()
260
+ + " namespace: " + primary .getMetadata ().getNamespace ());
261
+ }
262
+ // theoretically can happen that parent was deleted meanwhile
263
+ if (relatedResources .isEmpty ()) {
264
+ log .warn ("Parent resource expected to be present on cleanup. Glue name: {} namespace: {}" ,
265
+ primary .getMetadata ().getName (), primary .getMetadata ().getNamespace ());
266
+ return ;
267
+ }
268
+ var parent = relatedResources .entrySet ().iterator ().next ().getValue ();
269
+ String finalizer = parentFinalizer (primary .getMetadata ().getName ());
270
+ if (parent .getMetadata ().getFinalizers ().contains (finalizer )) {
271
+ var res = getResourceForSSAFrom (parent );
272
+ context .getClient ().resource (res )
273
+ .patch (new PatchContext .Builder ()
274
+ .withFieldManager (context .getControllerConfiguration ().fieldManager ())
275
+ .withForce (true )
276
+ .withPatchType (PatchType .SERVER_SIDE_APPLY )
277
+ .build ());
278
+ }
279
+ });
280
+ }
281
+
282
+ private String parentFinalizer (String glueName ) {
283
+ return PARENT_GLUE_FINALIZER_PREFIX + glueName ;
284
+ }
285
+
286
+
220
287
}
0 commit comments