func()

in pkg/controllers/workv1alpha1/applied_work_syncer.go [53:119]


func (r *ApplyWorkReconciler) generateDiff(ctx context.Context, work *workapi.Work, appliedWork *workapi.AppliedWork) ([]workapi.AppliedResourceMeta, []workapi.AppliedResourceMeta, error) {
	var staleRes, newRes []workapi.AppliedResourceMeta
	// for every resource applied in cluster, check if it's still in the work's manifest condition
	// we keep the applied resource in the appliedWork status even if it is not applied successfully
	// to make sure that it is safe to delete the resource from the member cluster.
	for _, resourceMeta := range appliedWork.Status.AppliedResources {
		resStillExist := false
		for _, manifestCond := range work.Status.ManifestConditions {
			if isSameResourceIdentifier(resourceMeta.ResourceIdentifier, manifestCond.Identifier) {
				resStillExist = true
				break
			}
		}
		if !resStillExist {
			klog.V(2).InfoS("find an orphaned resource in the member cluster",
				"parent resource", work.GetName(), "orphaned resource", resourceMeta.ResourceIdentifier)
			staleRes = append(staleRes, resourceMeta)
		}
	}
	// add every resource in the work's manifest condition that is applied successfully back to the appliedWork status
	for _, manifestCond := range work.Status.ManifestConditions {
		ac := meta.FindStatusCondition(manifestCond.Conditions, ConditionTypeApplied)
		if ac == nil {
			// should not happen
			klog.ErrorS(fmt.Errorf("resource is missing  applied condition"), "applied condition missing", "resource", manifestCond.Identifier)
			continue
		}
		// we only add the applied one to the appliedWork status
		if ac.Status == metav1.ConditionTrue {
			resRecorded := false
			// we update the identifier
			// TODO: this UID may not be the current one if the resource is deleted and recreated
			for _, resourceMeta := range appliedWork.Status.AppliedResources {
				if isSameResourceIdentifier(resourceMeta.ResourceIdentifier, manifestCond.Identifier) {
					resRecorded = true
					newRes = append(newRes, workapi.AppliedResourceMeta{
						ResourceIdentifier: manifestCond.Identifier,
						UID:                resourceMeta.UID,
					})
					break
				}
			}
			if !resRecorded {
				klog.V(2).InfoS("discovered a new manifest resource",
					"parent Work", work.GetName(), "manifest", manifestCond.Identifier)
				obj, err := r.spokeDynamicClient.Resource(schema.GroupVersionResource{
					Group:    manifestCond.Identifier.Group,
					Version:  manifestCond.Identifier.Version,
					Resource: manifestCond.Identifier.Resource,
				}).Namespace(manifestCond.Identifier.Namespace).Get(ctx, manifestCond.Identifier.Name, metav1.GetOptions{})
				switch {
				case apierrors.IsNotFound(err):
					klog.V(2).InfoS("the new manifest resource is already deleted", "parent Work", work.GetName(), "manifest", manifestCond.Identifier)
					continue
				case err != nil:
					klog.ErrorS(err, "failed to retrieve the manifest", "parent Work", work.GetName(), "manifest", manifestCond.Identifier)
					return nil, nil, err
				}
				newRes = append(newRes, workapi.AppliedResourceMeta{
					ResourceIdentifier: manifestCond.Identifier,
					UID:                obj.GetUID(),
				})
			}
		}
	}
	return newRes, staleRes, nil
}