in pkg/controllers/workgenerator/controller.go [635:716]
func (r *Reconciler) getConfigMapEnvelopWorkObj(ctx context.Context, workNamePrefix string, resourceBinding *fleetv1beta1.ClusterResourceBinding,
resourceSnapshot *fleetv1beta1.ClusterResourceSnapshot, envelopeObj *unstructured.Unstructured, resourceOverrideSnapshotHash, clusterResourceOverrideSnapshotHash string) (*fleetv1beta1.Work, error) {
// we group all the resources in one configMap to one work
manifest, err := extractResFromConfigMap(envelopeObj)
if err != nil {
klog.ErrorS(err, "configMap has invalid content", "snapshot", klog.KObj(resourceSnapshot),
"resourceBinding", klog.KObj(resourceBinding), "configMapWrapper", klog.KObj(envelopeObj))
return nil, controller.NewUserError(err)
}
klog.V(2).InfoS("Successfully extract the enveloped resources from the configMap", "numOfResources", len(manifest),
"snapshot", klog.KObj(resourceSnapshot), "resourceBinding", klog.KObj(resourceBinding), "configMapWrapper", klog.KObj(envelopeObj))
// Try to see if we already have a work represent the same enveloped object for this CRP in the same cluster
// The ParentResourceSnapshotIndexLabel can change between snapshots so we have to exclude that label in the match
envelopWorkLabelMatcher := client.MatchingLabels{
fleetv1beta1.ParentBindingLabel: resourceBinding.Name,
fleetv1beta1.CRPTrackingLabel: resourceBinding.Labels[fleetv1beta1.CRPTrackingLabel],
fleetv1beta1.EnvelopeTypeLabel: string(fleetv1beta1.ConfigMapEnvelopeType),
fleetv1beta1.EnvelopeNameLabel: envelopeObj.GetName(),
fleetv1beta1.EnvelopeNamespaceLabel: envelopeObj.GetNamespace(),
}
workList := &fleetv1beta1.WorkList{}
if err := r.Client.List(ctx, workList, envelopWorkLabelMatcher); err != nil {
return nil, controller.NewAPIServerError(true, err)
}
// we need to create a new work object
if len(workList.Items) == 0 {
// we limit the CRP name length to be 63 (DNS1123LabelMaxLength) characters,
// so we have plenty of characters left to fit into 253 (DNS1123SubdomainMaxLength) characters for a CR
workName := fmt.Sprintf(fleetv1beta1.WorkNameWithConfigEnvelopeFmt, workNamePrefix, uuid.NewUUID())
return &fleetv1beta1.Work{
ObjectMeta: metav1.ObjectMeta{
Name: workName,
Namespace: fmt.Sprintf(utils.NamespaceNameFormat, resourceBinding.Spec.TargetCluster),
Labels: map[string]string{
fleetv1beta1.ParentBindingLabel: resourceBinding.Name,
fleetv1beta1.CRPTrackingLabel: resourceBinding.Labels[fleetv1beta1.CRPTrackingLabel],
fleetv1beta1.ParentResourceSnapshotIndexLabel: resourceSnapshot.Labels[fleetv1beta1.ResourceIndexLabel],
fleetv1beta1.EnvelopeTypeLabel: string(fleetv1beta1.ConfigMapEnvelopeType),
fleetv1beta1.EnvelopeNameLabel: envelopeObj.GetName(),
fleetv1beta1.EnvelopeNamespaceLabel: envelopeObj.GetNamespace(),
},
Annotations: map[string]string{
fleetv1beta1.ParentResourceSnapshotNameAnnotation: resourceBinding.Spec.ResourceSnapshotName,
fleetv1beta1.ParentResourceOverrideSnapshotHashAnnotation: resourceOverrideSnapshotHash,
fleetv1beta1.ParentClusterResourceOverrideSnapshotHashAnnotation: clusterResourceOverrideSnapshotHash,
},
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: fleetv1beta1.GroupVersion.String(),
Kind: resourceBinding.Kind,
Name: resourceBinding.Name,
UID: resourceBinding.UID,
BlockOwnerDeletion: ptr.To(true), // make sure that the k8s will call work delete when the binding is deleted
},
},
},
Spec: fleetv1beta1.WorkSpec{
Workload: fleetv1beta1.WorkloadTemplate{
Manifests: manifest,
},
ApplyStrategy: resourceBinding.Spec.ApplyStrategy,
},
}, nil
}
if len(workList.Items) > 1 {
// return error here won't get us out of this
klog.ErrorS(controller.NewUnexpectedBehaviorError(fmt.Errorf("find %d work representing configMap", len(workList.Items))),
"snapshot", klog.KObj(resourceSnapshot), "resourceBinding", klog.KObj(resourceBinding), "configMapWrapper", klog.KObj(envelopeObj))
}
work := workList.Items[0]
work.Labels[fleetv1beta1.ParentResourceSnapshotIndexLabel] = resourceSnapshot.Labels[fleetv1beta1.ResourceIndexLabel]
if work.Annotations == nil {
work.Annotations = make(map[string]string)
}
work.Annotations[fleetv1beta1.ParentResourceSnapshotNameAnnotation] = resourceBinding.Spec.ResourceSnapshotName
work.Annotations[fleetv1beta1.ParentResourceOverrideSnapshotHashAnnotation] = resourceOverrideSnapshotHash
work.Annotations[fleetv1beta1.ParentClusterResourceOverrideSnapshotHashAnnotation] = clusterResourceOverrideSnapshotHash
work.Spec.Workload.Manifests = manifest
work.Spec.ApplyStrategy = resourceBinding.Spec.ApplyStrategy
return &work, nil
}