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
}