Skip to content

Commit 42cc657

Browse files
authored
Merge branch 'main' into pr-template
2 parents 82b158a + 463ebc0 commit 42cc657

File tree

5 files changed

+336
-37
lines changed

5 files changed

+336
-37
lines changed

api/v1alpha1/operator_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const (
3333
// TODO(user): add more Types, here and into init()
3434
TypeReady = "Ready"
3535

36-
ReasonResolutionSucceeded = "ResolutionSucceeded"
36+
ReasonInstallationSucceeded = "InstallationSucceeded"
3737
ReasonResolutionFailed = "ResolutionFailed"
3838
ReasonBundleLookupFailed = "BundleLookupFailed"
3939
ReasonBundleDeploymentFailed = "BundleDeploymentFailed"
@@ -46,7 +46,7 @@ func init() {
4646
)
4747
// TODO(user): add Reasons from above
4848
operatorutil.ConditionReasons = append(operatorutil.ConditionReasons,
49-
ReasonResolutionSucceeded,
49+
ReasonInstallationSucceeded,
5050
ReasonResolutionFailed,
5151
ReasonBundleLookupFailed,
5252
ReasonBundleDeploymentFailed,

controllers/operator_controller.go

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,21 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
162162
return ctrl.Result{}, err
163163
}
164164

165-
// update operator status
166-
apimeta.SetStatusCondition(&op.Status.Conditions, metav1.Condition{
167-
Type: operatorsv1alpha1.TypeReady,
168-
Status: metav1.ConditionTrue,
169-
Reason: operatorsv1alpha1.ReasonResolutionSucceeded,
170-
Message: "resolution was successful",
171-
ObservedGeneration: op.GetGeneration(),
172-
})
165+
// convert existing unstructured object into bundleDeployment for easier mapping of status.
166+
existingTypedBundleDeployment := &rukpakv1alpha1.BundleDeployment{}
167+
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(dep.UnstructuredContent(), existingTypedBundleDeployment); err != nil {
168+
apimeta.SetStatusCondition(&op.Status.Conditions, metav1.Condition{
169+
Type: operatorsv1alpha1.TypeReady,
170+
Status: metav1.ConditionUnknown,
171+
Reason: operatorsv1alpha1.ReasonInstallationSucceeded,
172+
Message: err.Error(),
173+
ObservedGeneration: op.GetGeneration(),
174+
})
175+
return ctrl.Result{}, err
176+
}
177+
178+
// set the status of the operator based on the respective bundle deployment status conditions.
179+
apimeta.SetStatusCondition(&op.Status.Conditions, mapBDStatusToReadyCondition(existingTypedBundleDeployment, op.GetGeneration()))
173180
return ctrl.Result{}, nil
174181
}
175182

@@ -257,9 +264,12 @@ func (r *OperatorReconciler) ensureBundleDeployment(ctx context.Context, desired
257264
}
258265

259266
// If the existing BD already has everything that the desired BD has, no need to contact the API server.
267+
// Make sure the status of the existingBD from the server is as expected.
260268
if equality.Semantic.DeepDerivative(desiredBundleDeployment, existingBundleDeployment) {
269+
*desiredBundleDeployment = *existingBundleDeployment
261270
return nil
262271
}
272+
263273
return r.Client.Patch(ctx, desiredBundleDeployment, client.Apply, client.ForceOwnership, client.FieldOwner("operator-controller"))
264274
}
265275

@@ -277,3 +287,51 @@ func (r *OperatorReconciler) existingBundleDeploymentUnstructured(ctx context.Co
277287
}
278288
return &unstructured.Unstructured{Object: unstrExistingBundleDeploymentObj}, nil
279289
}
290+
291+
// verifyBDStatus reads the various possibilities of status in bundle deployment and translates
292+
// into corresponding operator condition status and message.
293+
func verifyBDStatus(dep *rukpakv1alpha1.BundleDeployment) (metav1.ConditionStatus, string) {
294+
isValidBundleCond := apimeta.FindStatusCondition(dep.Status.Conditions, rukpakv1alpha1.TypeHasValidBundle)
295+
isInstalledCond := apimeta.FindStatusCondition(dep.Status.Conditions, rukpakv1alpha1.TypeInstalled)
296+
297+
if isValidBundleCond == nil && isInstalledCond == nil {
298+
return metav1.ConditionUnknown, fmt.Sprintf("waiting for bundleDeployment %q status to be updated", dep.Name)
299+
}
300+
301+
if isValidBundleCond != nil && isValidBundleCond.Status == metav1.ConditionFalse {
302+
return metav1.ConditionFalse, isValidBundleCond.Message
303+
}
304+
305+
if isInstalledCond != nil && isInstalledCond.Status == metav1.ConditionFalse {
306+
return metav1.ConditionFalse, isInstalledCond.Message
307+
}
308+
309+
if isInstalledCond != nil && isInstalledCond.Status == metav1.ConditionTrue {
310+
return metav1.ConditionTrue, "install was successful"
311+
}
312+
return metav1.ConditionUnknown, fmt.Sprintf("could not determine the state of bundleDeployment %s", dep.Name)
313+
}
314+
315+
// mapBDStatusToReadyCondition returns the operator object's "TypeReady" condition based on the bundle deployment statuses.
316+
func mapBDStatusToReadyCondition(existingBD *rukpakv1alpha1.BundleDeployment, observedGeneration int64) metav1.Condition {
317+
// update operator status:
318+
// 1. If the Operator "Ready" status is "Unknown": The status of successful bundleDeployment is unknown, wait till Rukpak updates the BD status.
319+
// 2. If the Operator "Ready" status is "True": Update the "successful resolution" status and return the result.
320+
// 3. If the Operator "Ready" status is "False": There is error observed from Rukpak. Update the status accordingly.
321+
status, message := verifyBDStatus(existingBD)
322+
var reason string
323+
// TODO: introduce a new reason for condition Unknown, instead of defaulting it to Installation Succeeded.
324+
if status == metav1.ConditionTrue {
325+
reason = operatorsv1alpha1.ReasonInstallationSucceeded
326+
} else {
327+
reason = operatorsv1alpha1.ReasonBundleDeploymentFailed
328+
}
329+
330+
return metav1.Condition{
331+
Type: operatorsv1alpha1.TypeReady,
332+
Status: status,
333+
Reason: reason,
334+
Message: message,
335+
ObservedGeneration: observedGeneration,
336+
}
337+
}

0 commit comments

Comments
 (0)