func()

in pkg/controllers/clusterinventory/clusterprofile/controller.go [66:168]


func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	mcRef := klog.KRef(req.Namespace, req.Name)
	startTime := time.Now()
	klog.V(2).InfoS("Reconciliation starts (cluster profile controller)", "memberCluster", mcRef)
	defer func() {
		latency := time.Since(startTime).Milliseconds()
		klog.V(2).InfoS("Reconciliation ends (cluster profile controller)", "memberCluster", mcRef, "latency", latency)
	}()

	// Retrieve the MemberCluster object.
	mc := &clusterv1beta1.MemberCluster{}
	if err := r.Get(ctx, req.NamespacedName, mc); err != nil {
		if errors.IsNotFound(err) {
			klog.InfoS("Member cluster object is not found", "memberCluster", mcRef)
			// To address the case where a member cluster is deleted before its cluster profile is cleaned up
			// since we didn't put the logic in the member cluster controller
			// or a cluster profile has been created without the acknowledgment of this controller.
			if err = r.cleanupClusterProfile(ctx, req.Name); err != nil {
				klog.ErrorS(err, "Failed to clean up the cluster profile when the member cluster is already gone", "memberCluster", mcRef)
				return ctrl.Result{}, err
			}
			return ctrl.Result{}, nil
		}
		klog.ErrorS(err, "Failed to get member cluster", "memberCluster", mcRef)
		return ctrl.Result{}, err
	}

	// Check if the member cluster object has been marked for deletion.
	if mc.DeletionTimestamp != nil {
		klog.V(2).InfoS("Member cluster object is being deleted; remove the corresponding cluster profile", "memberCluster", mcRef)
		// Delete the corresponding ClusterProfile object.
		if err := r.cleanupClusterProfile(ctx, mc.Name); err != nil {
			klog.ErrorS(err, "Failed to clean up cluster profile when member cluster is marked for deletion", "memberCluster", mcRef)
			return ctrl.Result{}, err
		}

		// Remove the cleanup finalizer from the MemberCluster object.
		controllerutil.RemoveFinalizer(mc, clusterProfileCleanupFinalizer)
		if err := r.Update(ctx, mc); err != nil {
			klog.ErrorS(err, "Failed to remove cleanup finalizer", "memberCluster", mcRef)
			return ctrl.Result{}, err
		}
		return ctrl.Result{}, nil
	}

	// Check if the MemberCluster object has the cleanup finalizer; if not, add it.
	if !controllerutil.ContainsFinalizer(mc, clusterProfileCleanupFinalizer) {
		mc.Finalizers = append(mc.Finalizers, clusterProfileCleanupFinalizer)
		if err := r.Update(ctx, mc); err != nil {
			klog.ErrorS(err, "Failed to add cleanup finalizer", "memberCluster", mcRef)
			return ctrl.Result{}, err
		}
	}

	// Retrieve the corresponding ClusterProfile object. If the object does not exist, create it.
	cp := &clusterinventory.ClusterProfile{
		ObjectMeta: metav1.ObjectMeta{
			Namespace: r.ClusterProfileNamespace,
			Name:      mc.Name,
		},
	}
	// Note that if the object already exists and its spec matches with the desired space, no
	// update op will be performed.
	createOrUpdateRes, err := controllerutil.CreateOrUpdate(ctx, r, cp, func() error {
		if cp.CreationTimestamp.IsZero() {
			// Only set the ClusterManager field if the object is being created; this field
			// is immutable by definition.
			cp.Spec = clusterinventory.ClusterProfileSpec{
				ClusterManager: clusterinventory.ClusterManager{
					Name: controller.ClusterManagerName,
				},
			}
		}
		// log an unexpected error if the cluster profile is under the management of a different platform.
		if cp.Spec.ClusterManager.Name != controller.ClusterManagerName {
			klog.ErrorS(controller.NewUnexpectedBehaviorError(fmt.Errorf("found another clustrer Manager: `%s`", cp.Spec.ClusterManager.Name)),
				"Cluster profile is under the management of a different platform", "memberCluster", mcRef, "clusterProfile", klog.KObj(cp))
			return nil
		}

		// Set the labels.
		if cp.Labels == nil {
			cp.Labels = make(map[string]string)
		}
		cp.Labels[clusterinventory.LabelClusterManagerKey] = controller.ClusterManagerName

		// Set the display name.
		cp.Spec.DisplayName = mc.Name
		return nil
	})
	if err != nil {
		klog.ErrorS(err, "Failed to create or update cluster profile", "memberCluster", mcRef, "clusterProfile", klog.KObj(cp), "operation", createOrUpdateRes)
		return ctrl.Result{}, err
	}
	klog.V(2).InfoS("Cluster profile object is created or updated", "memberCluster", mcRef, "clusterProfile", klog.KObj(cp), "operation", createOrUpdateRes)
	// sync the cluster profile condition from the member cluster condition
	r.syncClusterProfileCondition(mc, cp)
	if err = r.Status().Update(ctx, cp); err != nil {
		klog.ErrorS(err, "Failed to update cluster profile status", "memberCluster", mcRef, "clusterProfile", klog.KObj(cp))
		return ctrl.Result{}, err
	}
	return ctrl.Result{}, nil
}