Skip to content

Commit

Permalink
Added checking for MachineDeployments availability to update ManagedC…
Browse files Browse the repository at this point in the history
…luster status
  • Loading branch information
Slava Lysunkin authored and Kshatrix committed Nov 14, 2024
1 parent f02f5e5 commit ca22e30
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 23 deletions.
68 changes: 54 additions & 14 deletions internal/controller/managedcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -103,32 +104,35 @@ func (r *ManagedClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return r.Update(ctx, managedCluster)
}

func (r *ManagedClusterReconciler) setStatusFromClusterStatus(ctx context.Context, managedCluster *hmc.ManagedCluster) (requeue bool, _ error) {
func (r *ManagedClusterReconciler) setStatusFromChildObjects(
ctx context.Context, managedCluster *hmc.ManagedCluster, gvr schema.GroupVersionResource, conditions []string,
) (requeue bool, _ error) {
l := ctrl.LoggerFrom(ctx)

resourceConditions, err := status.GetResourceConditions(ctx, managedCluster.Namespace, r.DynamicClient, schema.GroupVersionResource{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Resource: "clusters",
}, labels.SelectorFromSet(map[string]string{hmc.FluxHelmChartNameKey: managedCluster.Name}).String())
resourceConditions, err := status.GetResourceConditions(ctx, managedCluster.Namespace, r.DynamicClient, gvr,
labels.SelectorFromSet(map[string]string{hmc.FluxHelmChartNameKey: managedCluster.Name}).String())
if err != nil {
if errors.As(err, &status.ResourceNotFoundError{}) {
l.Info(err.Error())
return true, nil
// don't error or retry if nothing is available
return false, nil
}
return false, fmt.Errorf("failed to get conditions: %w", err)
}

allConditionsComplete := true
for _, metaCondition := range resourceConditions.Conditions {
if metaCondition.Status != "True" {
allConditionsComplete = false
}
if slices.Contains(conditions, metaCondition.Type) {
if metaCondition.Status != "True" {
allConditionsComplete = false
}

if metaCondition.Reason == "" && metaCondition.Status == "True" {
metaCondition.Reason = hmc.SucceededReason
if metaCondition.Reason == "" && metaCondition.Status == "True" {
metaCondition.Message += " is Ready"
metaCondition.Reason = "Succeeded"
}
apimeta.SetStatusCondition(managedCluster.GetConditions(), metaCondition)
}
apimeta.SetStatusCondition(managedCluster.GetConditions(), metaCondition)
}

return !allConditionsComplete, nil
Expand Down Expand Up @@ -305,7 +309,7 @@ func (r *ManagedClusterReconciler) Update(ctx context.Context, managedCluster *h
})
}

requeue, err := r.setStatusFromClusterStatus(ctx, managedCluster)
requeue, err := r.aggregateCapoConditions(ctx, managedCluster)
if err != nil {
if requeue {
return ctrl.Result{RequeueAfter: DefaultRequeueInterval}, err
Expand Down Expand Up @@ -333,6 +337,42 @@ func (r *ManagedClusterReconciler) Update(ctx context.Context, managedCluster *h
return ctrl.Result{}, nil
}

func (r *ManagedClusterReconciler) aggregateCapoConditions(ctx context.Context, managedCluster *hmc.ManagedCluster) (bool, error) {
type objectToCheck struct {
gvr schema.GroupVersionResource
conditions []string
}

var needToRequeue bool
var errs error
for _, obj := range []objectToCheck{
{
gvr: schema.GroupVersionResource{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Resource: "clusters",
},
conditions: []string{"ControlPlaneInitialized", "ControlPlaneReady", "InfrastructureReady"},
},
{
gvr: schema.GroupVersionResource{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Resource: "machinedeployments",
},
conditions: []string{"Available"},
},
} {
requeue, err := r.setStatusFromChildObjects(ctx, managedCluster, obj.gvr, obj.conditions)
errs = errors.Join(errs, err)
if requeue {
needToRequeue = true
}
}

return needToRequeue, errs
}

// updateServices reconciles services provided in ManagedCluster.Spec.Services.
func (r *ManagedClusterReconciler) updateServices(ctx context.Context, mc *hmc.ManagedCluster) (_ ctrl.Result, err error) {
// servicesErr is handled separately from err because we do not want
Expand Down
24 changes: 15 additions & 9 deletions internal/utils/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ func ConditionsFromUnstructured(unstrObj *unstructured.Unstructured) ([]metav1.C
return nil, fmt.Errorf("failed to convert condition map to metav1.Condition: %w", err)
}

// add some extra information for the origin of the message, i.e. what object reports this
if c.Message != "" {
c.Message = objName + ": " + c.Message
} else {
c.Message = objName
}

conditions = append(conditions, *c)
}

Expand Down Expand Up @@ -89,7 +96,7 @@ func GetResourceConditions(
gvr schema.GroupVersionResource, labelSelector string,
) (resourceConditions *ResourceConditions, err error) {
list, err := dynamicClient.Resource(gvr).Namespace(namespace).List(ctx, metav1.ListOptions{
LabelSelector: labelSelector, Limit: 2,
LabelSelector: labelSelector,
})
if err != nil {
if apierrors.IsNotFound(err) {
Expand All @@ -103,15 +110,14 @@ func GetResourceConditions(
return nil, ResourceNotFoundError{Resource: gvr.Resource}
}

if len(list.Items) > 1 {
return nil, fmt.Errorf("expected to find only one of resource: %s with label: %q, found: %d",
gvr.Resource, labelSelector, len(list.Items))
}

var conditions []metav1.Condition
kind, name := ObjKindName(&list.Items[0])
conditions, err := ConditionsFromUnstructured(&list.Items[0])
if err != nil {
return nil, fmt.Errorf("failed to get conditions: %w", err)
for _, item := range list.Items {
c, err := ConditionsFromUnstructured(&item)
if err != nil {
return nil, fmt.Errorf("failed to get conditions: %w", err)
}
conditions = append(conditions, c...)
}

return &ResourceConditions{
Expand Down
5 changes: 5 additions & 0 deletions templates/provider/hmc/templates/rbac/controller/roles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ rules:
resources:
- clusters
verbs: {{ include "rbac.viewerVerbs" . | nindent 4 }}
- apiGroups:
- cluster.x-k8s.io
resources:
- machinedeployments
verbs: {{ include "rbac.viewerVerbs" . | nindent 4 }}
- apiGroups:
- helm.toolkit.fluxcd.io
resources:
Expand Down

0 comments on commit ca22e30

Please sign in to comment.