Skip to content

Commit f03d178

Browse files
committed
Refactor status condition logic of DT/DTC
1 parent 3b1db57 commit f03d178

File tree

12 files changed

+358
-220
lines changed

12 files changed

+358
-220
lines changed

appstudio-controller/controllers/appstudio.redhat.com/deploymenttarget_controller.go

Lines changed: 89 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ type DeploymentTargetReconciler struct {
4747

4848
const (
4949
FinalizerDT = "dt.appstudio.redhat.com/finalizer"
50-
DeploymentTargetConditionTypeErrorOccurred = "ValidDeploymentTargetClaim"
50+
DeploymentTargetConditionTypeErrorOccurred = "ErrorOccurred"
5151
DeploymentTargetReasonErrorOccurred = "ErrorOccurred"
52-
DeploymentTargetReasonBound = "Bound"
52+
DeploymentTargetReasonSuccess = "Success"
5353
)
5454

5555
//+kubebuilder:rbac:groups=appstudio.redhat.com,resources=deploymenttargetclaims,verbs=get;list;watch;update;patch
@@ -78,6 +78,62 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
7878
logutil.Log_K8s_Request_Name, req.Name,
7979
logutil.Log_Component, logutil.Log_Component_Appstudio_Controller)
8080

81+
res, condition, err := r.reconcileInternal(ctx, req, log)
82+
83+
if condition != nil {
84+
85+
// User error occurred
86+
if err := updateStatusConditionOfDeploymentTarget(ctx, *condition, &applicationv1alpha1.DeploymentTarget{
87+
ObjectMeta: metav1.ObjectMeta{
88+
Name: req.Name,
89+
Namespace: req.Namespace,
90+
},
91+
}, r.Client, log); err != nil {
92+
log.Error(err, "unable to update status of DeploymentTarget")
93+
return ctrl.Result{}, err
94+
}
95+
96+
return ctrl.Result{}, err
97+
98+
} else if err != nil {
99+
100+
// Generic error occurred
101+
102+
condition := createCondition(DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionTrue, DeploymentTargetReasonErrorOccurred, "unexpected internal error occurred in DT controller")
103+
104+
if err := updateStatusConditionOfDeploymentTarget(ctx, *condition, &applicationv1alpha1.DeploymentTarget{
105+
ObjectMeta: metav1.ObjectMeta{
106+
Name: req.Name,
107+
Namespace: req.Namespace,
108+
},
109+
}, r.Client, log); err != nil {
110+
log.Error(err, "unable to update status of DeploymentTarget")
111+
return ctrl.Result{}, err
112+
}
113+
114+
return ctrl.Result{}, err
115+
116+
}
117+
118+
// No error occurred, so set the condition to false
119+
120+
condition = createCondition(DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionFalse, DeploymentTargetReasonSuccess, "")
121+
122+
if err := updateStatusConditionOfDeploymentTarget(ctx, *condition, &applicationv1alpha1.DeploymentTarget{
123+
ObjectMeta: metav1.ObjectMeta{
124+
Name: req.Name,
125+
Namespace: req.Namespace,
126+
},
127+
}, r.Client, log); err != nil {
128+
log.Error(err, "unable to update status of DeploymentTarget")
129+
return ctrl.Result{}, err
130+
}
131+
132+
return res, err
133+
}
134+
135+
func (r *DeploymentTargetReconciler) reconcileInternal(ctx context.Context, req ctrl.Request, log logr.Logger) (ctrl.Result, *metav1.Condition, error) {
136+
81137
dt := applicationv1alpha1.DeploymentTarget{
82138
ObjectMeta: metav1.ObjectMeta{
83139
Name: req.Name,
@@ -86,45 +142,36 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
86142
}
87143
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(&dt), &dt); err != nil {
88144
if apierr.IsNotFound(err) {
89-
return ctrl.Result{}, nil
145+
return ctrl.Result{}, nil, nil
90146
}
91-
return ctrl.Result{}, err
147+
return ctrl.Result{}, nil, err
92148
}
93149

94150
// Add the deletion finalizer if it is absent.
95151
if addFinalizer(&dt, FinalizerDT) {
96152
if err := r.Client.Update(ctx, &dt); err != nil {
97-
return ctrl.Result{}, fmt.Errorf("failed to add finalizer %s to DeploymentTarget %s in namespace %s: %v", FinalizerDT, dt.Name, dt.Namespace, err)
153+
return ctrl.Result{}, nil, fmt.Errorf("failed to add finalizer %s to DeploymentTarget %s in namespace %s: %v", FinalizerDT, dt.Name, dt.Namespace, err)
98154
}
99155
log.Info("Added finalizer to DeploymentTarget", "finalizer", FinalizerDT)
100156
}
101157

102158
// Retrieve and sanity check the DeploymentTargetClass of the DT
103159
dtClass, err := findMatchingDTClassForDT(ctx, dt, r.Client)
104-
// Update Status.Conditions field of DeploymentTarget.
105-
if err := updateStatusConditionOfDeploymentTarget(ctx, r.Client, "failed to retrieve DeploymentTargetClass of DeploymentTarget",
106-
&dt, DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionFalse, DeploymentTargetReasonErrorOccurred, log); err != nil {
107-
return ctrl.Result{}, fmt.Errorf("unable to update deployment target status condition. %v", err)
108-
}
109-
110160
if err != nil {
111161
if apierr.IsNotFound(err) {
112-
return ctrl.Result{}, nil
162+
return ctrl.Result{}, nil, nil
113163
}
114-
return ctrl.Result{}, err
164+
165+
return ctrl.Result{}, createCondition(DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionTrue, DeploymentTargetReasonErrorOccurred, "failed to retrieve DeploymentTargetClass of DeploymentTarget"), nil
115166
}
167+
116168
if dtClass.Spec.ReclaimPolicy != applicationv1alpha1.ReclaimPolicy_Delete &&
117169
dtClass.Spec.ReclaimPolicy != applicationv1alpha1.ReclaimPolicy_Retain {
118170

119171
log.Error(nil, "unexpected reclaim policy value on DTClass", "reclaimPolicy", dtClass.Spec.ReclaimPolicy)
120172

121-
// Update Status.Conditions field of DeploymentTarget.
122-
if err := updateStatusConditionOfDeploymentTarget(ctx, r.Client, "unexpected reclaim policy value on DeploymentTargetClass",
123-
&dt, DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionFalse, DeploymentTargetReasonErrorOccurred, log); err != nil {
124-
return ctrl.Result{}, fmt.Errorf("unable to update deployment target status condition. %v", err)
125-
}
173+
return ctrl.Result{}, createCondition(DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionTrue, DeploymentTargetReasonErrorOccurred, "unexpected reclaim policy value on DeploymentTargetClass"), nil
126174

127-
return ctrl.Result{}, nil
128175
}
129176

130177
// If the DeploymentTarget is not deleted, verify if it has a corresponding DTC
@@ -138,14 +185,14 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
138185

139186
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(dtc), dtc); err != nil {
140187
if !apierr.IsNotFound(err) {
141-
return ctrl.Result{}, err
188+
return ctrl.Result{}, nil, err
142189
}
143190

144191
// If the DTC is already deleted and the reclaim policy is Retain, unset the claimRef field of the DeploymentTarget.
145192
if dtClass.Spec.ReclaimPolicy == applicationv1alpha1.ReclaimPolicy_Retain {
146193
dt.Spec.ClaimRef = ""
147194
if err := r.Client.Update(ctx, &dt); err != nil {
148-
return ctrl.Result{}, err
195+
return ctrl.Result{}, nil, err
149196
}
150197

151198
log.Info("ClaimRef of DeploymentTarget is unset since its corresponding DeploymentTargetClaim is already deleted", "DeploymentTarget", dt.Name)
@@ -158,12 +205,8 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
158205
if dt.DeletionTimestamp == nil {
159206
// The DeploymentTarget is not currently being deleted, so no more work to do.
160207
// Update Status.Conditions field of DeploymentTarget.
161-
if err := updateStatusConditionOfDeploymentTarget(ctx, r.Client, "",
162-
&dt, DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionTrue, DeploymentTargetReasonBound, log); err != nil {
163-
return ctrl.Result{}, fmt.Errorf("unable to update deployment target status condition. %v", err)
164-
}
165208

166-
return ctrl.Result{}, nil
209+
return ctrl.Result{}, nil, nil
167210
}
168211

169212
// From this point on in this function, the DeletionTimestamp is necessarily set
@@ -172,38 +215,33 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
172215
var sr *codereadytoolchainv1alpha1.SpaceRequest
173216
if sr, err = findMatchingSpaceRequestForDT(ctx, r.Client, dt); err != nil {
174217
if !apierr.IsNotFound(err) {
175-
return ctrl.Result{}, err
218+
return ctrl.Result{}, nil, err
176219
}
177220
}
178221

179222
// If the SpaceRequest no longer exists, OR if the class has a Retain policy, then there is no more work to do.
180223
if sr == nil || dtClass.Spec.ReclaimPolicy == applicationv1alpha1.ReclaimPolicy_Retain {
181224
if removeFinalizer(&dt, FinalizerDT) {
182225
if err := r.Client.Update(ctx, &dt); err != nil {
183-
return ctrl.Result{}, fmt.Errorf("failed to remove finalizer %s from DeploymentTarget %s in namespace %s: %v", FinalizerDT, dt.Name, dt.Namespace, err)
226+
return ctrl.Result{}, nil, fmt.Errorf("failed to remove finalizer %s from DeploymentTarget %s in namespace %s: %v", FinalizerDT, dt.Name, dt.Namespace, err)
184227
}
185228
log.Info("Removed finalizer from DeploymentTarget", "finalizer", FinalizerDT)
186229
}
187-
return ctrl.Result{}, nil
230+
return ctrl.Result{}, nil, nil
188231
}
189232

190233
if dtClass.Spec.ReclaimPolicy != applicationv1alpha1.ReclaimPolicy_Delete {
191234
log.Error(nil, "Unexpected reclaimPolicy: neither Retain nor Delete.")
192235

193-
// Update Status.Conditions field of DeploymentTarget.
194-
if err := updateStatusConditionOfDeploymentTarget(ctx, r.Client, "unexpected reclaimPolicy: neither Retain nor Delete.",
195-
&dt, DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionFalse, DeploymentTargetReasonErrorOccurred, log); err != nil {
196-
return ctrl.Result{}, fmt.Errorf("unable to update deployment target status condition. %v", err)
197-
}
236+
return ctrl.Result{}, createCondition(DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionTrue, DeploymentTargetReasonErrorOccurred, "unexpected reclaimPolicy: neither Retain nor Delete."), nil
198237

199-
return ctrl.Result{}, nil
200238
}
201239

202240
// The ReclaimPolicy is necessarily equal to 'Delete', from this point on in the function
203241

204242
if addFinalizer(sr, codereadytoolchainv1alpha1.FinalizerName) {
205243
if err := r.Client.Update(ctx, sr); err != nil {
206-
return ctrl.Result{}, fmt.Errorf("failed to add finalizer %s for SpaceRequest %s in namespace %s: %v", codereadytoolchainv1alpha1.FinalizerName, sr.Name, sr.Namespace, err)
244+
return ctrl.Result{}, nil, fmt.Errorf("failed to add finalizer %s for SpaceRequest %s in namespace %s: %v", codereadytoolchainv1alpha1.FinalizerName, sr.Name, sr.Namespace, err)
207245
}
208246
log.Info("Added finalizer for SpaceRequest", "finalizer", codereadytoolchainv1alpha1.FinalizerName)
209247
}
@@ -212,13 +250,7 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
212250
var found bool
213251
if readyCond, found = condition.FindConditionByType(sr.Status.Conditions, codereadytoolchainv1alpha1.ConditionReady); !found {
214252

215-
// Update Status.Conditions field of DeploymentTarget.
216-
if err := updateStatusConditionOfDeploymentTarget(ctx, r.Client, fmt.Sprint("failed to find ConditionReady for SpaceRequest: ", sr.Name),
217-
&dt, DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionFalse, DeploymentTargetReasonErrorOccurred, log); err != nil {
218-
return ctrl.Result{}, fmt.Errorf("unable to update deployment target status condition. %v", err)
219-
}
220-
221-
return ctrl.Result{}, fmt.Errorf("failed to find ConditionReady for SpaceRequest %s from %s", sr.Name, sr.Namespace)
253+
return ctrl.Result{}, createCondition(DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionTrue, DeploymentTargetReasonErrorOccurred, "failed to find ConditionReady for SpaceRequest: "+sr.Name), nil
222254
}
223255

224256
// Delete the SpaceRequest if it has not been deleted
@@ -227,22 +259,18 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
227259
log.Info("Deleting SpaceRequest", "spaceRequest", sr)
228260
if err := r.Client.Delete(ctx, sr); err != nil {
229261

230-
// Update Status.Conditions field of DeploymentTarget.
231-
if err := updateStatusConditionOfDeploymentTarget(ctx, r.Client, fmt.Sprint("failed to delete SpaceRequest: ", sr.Name),
232-
&dt, DeploymentTargetConditionTypeErrorOccurred, metav1.ConditionFalse, DeploymentTargetReasonErrorOccurred, log); err != nil {
233-
return ctrl.Result{}, fmt.Errorf("unable to update deployment target status condition. %v", err)
234-
}
262+
log.Error(err, "Failed to delete SpaceRequest")
235263

236-
return ctrl.Result{}, err
264+
return ctrl.Result{}, nil, err
237265
}
238266
logutil.LogAPIResourceChangeEvent(sr.Namespace, sr.Name, sr, logutil.ResourceDeleted, log)
239267

240-
return ctrl.Result{Requeue: true}, nil
268+
return ctrl.Result{Requeue: true}, nil, nil
241269
}
242270

243271
if dt.Status.Phase == applicationv1alpha1.DeploymentTargetPhase_Failed {
244272
// No more work: the DT is already reported as failed
245-
return ctrl.Result{}, nil
273+
return ctrl.Result{}, nil, nil
246274
}
247275

248276
// Initialize the clock if it isn't already to avoid panic.
@@ -256,16 +284,16 @@ func (r *DeploymentTargetReconciler) Reconcile(ctx context.Context, req ctrl.Req
256284

257285
dt.Status.Phase = applicationv1alpha1.DeploymentTargetPhase_Failed
258286
if err := r.Client.Status().Update(ctx, &dt); err != nil {
259-
return ctrl.Result{}, err
287+
return ctrl.Result{}, nil, err
260288
}
261289
log.Info("The status of DT is updated to Failed", "dtName", dt.Name, "dtNamespace", dt.Namespace)
262-
return ctrl.Result{}, nil
290+
return ctrl.Result{}, nil, nil
263291
}
264292

265293
log.Info("Requeuing DeploymentTarget, since SpaceRequest is still terminating", "spaceRequestStatusPhase", dt.Status.Phase, "deletionTimestamp", sr.GetDeletionTimestamp())
266294

267295
// OTOH, if the SpaceRequest has not timed out yet, then requeue
268-
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
296+
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil, nil
269297

270298
}
271299

@@ -378,22 +406,21 @@ func (r *DeploymentTargetReconciler) findDeploymentTargetsForSpaceRequests(sr cl
378406

379407
}
380408

381-
// updateStatusConditionOfDeploymentTarget calls SetCondition() with DeploymentTarget conditions
382-
func updateStatusConditionOfDeploymentTarget(ctx context.Context, k8sClient client.Client,
383-
message string, deploymentTarget *applicationv1alpha1.DeploymentTarget, conditionType string,
384-
status metav1.ConditionStatus, reason string, log logr.Logger) error {
409+
func createCondition(conditionType string, status metav1.ConditionStatus, reason string, message string) *metav1.Condition {
385410

386-
newCondition := metav1.Condition{
411+
return &metav1.Condition{
387412
Type: conditionType,
413+
Reason: reason,
388414
Message: message,
389415
Status: status,
390-
Reason: reason,
391416
}
417+
}
392418

393-
dt := deploymentTarget
419+
// updateStatusConditionOfDeploymentTarget calls SetCondition() with DeploymentTarget conditions
420+
func updateStatusConditionOfDeploymentTarget(ctx context.Context, newCondition metav1.Condition, dt *applicationv1alpha1.DeploymentTarget, k8sClient client.Client, log logr.Logger) error {
394421

395422
if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dt), dt); err != nil {
396-
log.Error(err, "unable to fetch deploymentTargetClaim.")
423+
log.Error(err, "unable to fetch deploymentTarget")
397424
return nil
398425
}
399426

0 commit comments

Comments
 (0)