@@ -32,6 +32,7 @@ import (
3232
3333 "github.com/sap/component-operator-runtime/internal/backoff"
3434 "github.com/sap/component-operator-runtime/internal/cluster"
35+ "github.com/sap/component-operator-runtime/internal/kstatus"
3536 "github.com/sap/component-operator-runtime/pkg/manifests"
3637 "github.com/sap/component-operator-runtime/pkg/types"
3738)
@@ -86,86 +87,13 @@ type ReconcilerOptions struct {
8687 SchemeBuilder types.SchemeBuilder
8788}
8889
89- // AdoptionPolicy defines how the reconciler reacts if a dependent object exists but has no or a different owner.
90- type AdoptionPolicy string
91-
92- const (
93- // Fail if the dependent object exists but has no or a different owner.
94- AdoptionPolicyNever AdoptionPolicy = "Never"
95- // Adopt existing dependent objects if they have no owner set.
96- AdoptionPolicyIfUnowned AdoptionPolicy = "IfUnowned"
97- // Adopt existing dependent objects, even if they have a conflicting owner.
98- AdoptionPolicyAlways AdoptionPolicy = "Always"
99- )
100-
101- var adoptionPolicyByAnnotation = map [string ]AdoptionPolicy {
102- types .AdoptionPolicyNever : AdoptionPolicyNever ,
103- types .AdoptionPolicyIfUnowned : AdoptionPolicyIfUnowned ,
104- types .AdoptionPolicyAlways : AdoptionPolicyAlways ,
105- }
106-
107- // ReconcilePolicy defines when the reconciler will reconcile the dependent object.
108- type ReconcilePolicy string
109-
110- const (
111- // Reconcile the dependent object if its manifest, as produced by the generator, changes.
112- ReconcilePolicyOnObjectChange ReconcilePolicy = "OnObjectChange"
113- // Reconcile the dependent object if its manifest, as produced by the generator, changes, or if the owning
114- // component changes (identified by a change of its metadata.generation).
115- ReconcilePolicyOnObjectOrComponentChange ReconcilePolicy = "OnObjectOrComponentChange"
116- // Reconcile the dependent object only once; afterwards it will never be touched again by the reconciler.
117- ReconcilePolicyOnce ReconcilePolicy = "Once"
118- )
119-
120- var reconcilePolicyByAnnotation = map [string ]ReconcilePolicy {
121- types .ReconcilePolicyOnObjectChange : ReconcilePolicyOnObjectChange ,
122- types .ReconcilePolicyOnObjectOrComponentChange : ReconcilePolicyOnObjectOrComponentChange ,
123- types .ReconcilePolicyOnce : ReconcilePolicyOnce ,
124- }
125-
126- // UpdatePolicy defines how the reconciler will update dependent objects.
127- type UpdatePolicy string
128-
129- const (
130- // Recreate (that is: delete and create) existing dependent objects.
131- UpdatePolicyRecreate UpdatePolicy = "Recreate"
132- // Replace existing dependent objects.
133- UpdatePolicyReplace UpdatePolicy = "Replace"
134- // Use server side apply to update existing dependents.
135- UpdatePolicySsaMerge UpdatePolicy = "SsaMerge"
136- // Use server side apply to update existing dependents and, in addition, reclaim fields owned by certain
137- // field owners, such as kubectl or helm.
138- UpdatePolicySsaOverride UpdatePolicy = "SsaOverride"
139- )
140-
141- var updatePolicyByAnnotation = map [string ]UpdatePolicy {
142- types .UpdatePolicyRecreate : UpdatePolicyRecreate ,
143- types .UpdatePolicyReplace : UpdatePolicyReplace ,
144- types .UpdatePolicySsaMerge : UpdatePolicySsaMerge ,
145- types .UpdatePolicySsaOverride : UpdatePolicySsaOverride ,
146- }
147-
148- // DeletePolicy defines how the reconciler will delete dependent objects.
149- type DeletePolicy string
150-
151- const (
152- // Delete dependent objects.
153- DeletePolicyDelete DeletePolicy = "Delete"
154- // Orphan dependent objects.
155- DeletePolicyOrphan DeletePolicy = "Orphan"
156- )
157-
158- var deletePolicyByAnnotation = map [string ]DeletePolicy {
159- types .DeletePolicyDelete : DeletePolicyDelete ,
160- types .DeletePolicyOrphan : DeletePolicyOrphan ,
161- }
162-
16390// Reconciler provides the implementation of controller-runtime's Reconciler interface, for a given Component type T.
16491type Reconciler [T Component ] struct {
16592 name string
16693 id string
16794 client cluster.Client
16895 resourceGenerator manifests.Generator
96+ statusAnalyzer kstatus.StatusAnalyzer
16997 options ReconcilerOptions
17098 clients * cluster.ClientFactory
17199 backoff * backoff.Backoff
@@ -196,6 +124,7 @@ func NewReconciler[T Component](name string, resourceGenerator manifests.Generat
196124 return & Reconciler [T ]{
197125 name : name ,
198126 resourceGenerator : resourceGenerator ,
127+ statusAnalyzer : kstatus .NewStatusAnalyzer (name ),
199128 options : options ,
200129 backoff : backoff .NewBackoff (10 * time .Second ),
201130 postReadHooks : []HookFunc [T ]{resolveReferences [T ]},
@@ -249,6 +178,11 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result
249178 // always attempt to update the status
250179 skipStatusUpdate := false
251180 defer func () {
181+ if r := recover (); r != nil {
182+ log .Error (fmt .Errorf ("panic occurred during reconcile" ), "panic" , r )
183+ // re-panic in order skip the remaining steps
184+ panic (r )
185+ }
252186 log .V (1 ).Info ("reconcile done" , "withError" , err != nil , "requeue" , result .Requeue || result .RequeueAfter > 0 , "requeueAfter" , result .RequeueAfter .String ())
253187 if status .State == StateReady || err != nil {
254188 r .backoff .Forget (req )
@@ -314,7 +248,7 @@ func (r *Reconciler[T]) Reconcile(ctx context.Context, req ctrl.Request) (result
314248 if err != nil {
315249 return ctrl.Result {}, errors .Wrap (err , "error getting client for component" )
316250 }
317- target := newReconcileTarget [T ](r .name , r .id , targetClient , r .resourceGenerator , * r .options .CreateMissingNamespaces , * r .options .AdoptionPolicy , * r .options .UpdatePolicy )
251+ target := newReconcileTarget [T ](r .name , r .id , targetClient , r .resourceGenerator , r . statusAnalyzer , * r .options .CreateMissingNamespaces , * r .options .AdoptionPolicy , * r .options .UpdatePolicy )
318252 hookCtx := newContext (ctx ).WithClient (targetClient )
319253
320254 // do the reconciliation
0 commit comments