diff --git a/pkg/controllers/feature/feature_controller.go b/pkg/controllers/feature/feature_controller.go index 8e01d27ae..bb5f83018 100644 --- a/pkg/controllers/feature/feature_controller.go +++ b/pkg/controllers/feature/feature_controller.go @@ -332,38 +332,86 @@ func (r *frReconciler) checkRequiredResourcesExistence(ctx context.Context) (boo } func (r *frReconciler) checkRequiredWorkloadExistence(ctx context.Context) (*requirementStatus, error) { - status := &requirementStatus{} + groups := map[string][]uiapi.WorkloadInfo{} for _, w := range r.feature.Spec.ReadinessChecks.Workloads { - objList := unstructured.UnstructuredList{} - objList.SetGroupVersionKind(schema.GroupVersionKind{ - Group: w.Group, - Version: w.Version, - Kind: w.Kind, - }) - selector := labels.SelectorFromSet(w.Selector) - if err := r.apiReader.List(ctx, &objList, &client.ListOptions{Limit: 1, LabelSelector: selector}); err != nil { - if meta.IsNoMatchError(err) { - status.reason = fmt.Sprintf("Required resource %q is not registered.", w.String()) - return status, nil + groups[w.Optional] = append(groups[w.Optional], w) + } + + const requiredGroup = "" + for _, w := range groups[requiredGroup] { + status, err := r.checkWorkload(ctx, w) + if err != nil || !status.found || !status.ready { + return status, err + } + } + for _, workloads := range groups { + var found, ready bool + for _, w := range workloads { + status, err := r.checkWorkload(ctx, w) + if err != nil { + return status, err + } else if status.found && status.ready { + found = true + ready = true + break + } + if status.found { + found = true } - return nil, err } - if len(objList.Items) == 0 { - status.reason = "Required workload does not exist" - return status, nil + + if !found { + return &requirementStatus{ + found: false, + ready: false, + reason: "Required workload does not exist", + }, nil + } else if !ready { + return &requirementStatus{ + found: true, + ready: false, + reason: "Required workload is not ready", + }, nil } + } - if !isWorkLoadsReady(objList) { - status.found = true - status.reason = "Required workload is not ready" - return status, nil + return &requirementStatus{ + found: true, + ready: true, + }, nil +} + +func (r *frReconciler) checkWorkload(ctx context.Context, w uiapi.WorkloadInfo) (*requirementStatus, error) { + var status requirementStatus + + objList := unstructured.UnstructuredList{} + objList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: w.Group, + Version: w.Version, + Kind: w.Kind, + }) + selector := labels.SelectorFromSet(w.Selector) + if err := r.apiReader.List(ctx, &objList, &client.ListOptions{Limit: 1, LabelSelector: selector}); err != nil { + if meta.IsNoMatchError(err) { + status.reason = fmt.Sprintf("Required resource %q is not registered.", w.String()) + return &status, nil } + return nil, err + } + if len(objList.Items) == 0 { + status.reason = "Required workload does not exist" + return &status, nil + } + + if !isWorkLoadsReady(objList) { + status.found = true + status.reason = "Required workload is not ready" + return &status, nil } status.ready = true status.found = true - - return status, nil + return &status, nil } func (r *frReconciler) updateFeatureSetAndRemoveFinalizer(ctx context.Context) error {