Skip to content

Commit 8cada6d

Browse files
committed
fix: requeue the request when the override has been changed
1 parent 3a1dde9 commit 8cada6d

3 files changed

Lines changed: 98 additions & 6 deletions

File tree

pkg/controllers/workgenerator/controller.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req controllerruntime.Reques
144144

145145
workUpdated := false
146146
overrideSucceeded := false
147-
// list all the corresponding works
147+
// list all the correspo/nding works
148148
works, syncErr := r.listAllWorksAssociated(ctx, &resourceBinding)
149149
if syncErr == nil {
150150
// generate and apply the workUpdated works if we have all the works
@@ -1530,16 +1530,30 @@ func (r *Reconciler) SetupWithManager(mgr controllerruntime.Manager) error {
15301530
newResourceSnapshot := newWork.Labels[fleetv1beta1.ParentResourceSnapshotIndexLabel]
15311531
if oldResourceSnapshot == "" || newResourceSnapshot == "" {
15321532
klog.ErrorS(controller.NewUnexpectedBehaviorError(errors.New("found an invalid work without parent-resource-snapshot-index")),
1533-
"Could not find the parent resource snapshot index label", "oldWork", klog.KObj(oldWork), "oldResourceSnapshotLabelValue", oldResourceSnapshot,
1534-
"newWork", klog.KObj(newWork), "newResourceSnapshotLabelValue", newResourceSnapshot)
1533+
"Could not find the parent resource snapshot index label", "oldWork", klog.KObj(oldWork), "oldWorkLabels", oldWork.Labels,
1534+
"newWork", klog.KObj(newWork), "newWorkLabels", newWork.Labels)
15351535
return
15361536
}
1537-
// There is an edge case that, the work spec is the same but from different resourceSnapshots.
1538-
// WorkGenerator will update the work because of the label changes, but the generation is the same.
1537+
oldClusterResourceOverrideSnapshotHash := oldWork.Annotations[fleetv1beta1.ParentClusterResourceOverrideSnapshotHashAnnotation]
1538+
newClusterResourceOverrideSnapshotHash := newWork.Annotations[fleetv1beta1.ParentClusterResourceOverrideSnapshotHashAnnotation]
1539+
oldResourceOverrideSnapshotHash := oldWork.Annotations[fleetv1beta1.ParentResourceOverrideSnapshotHashAnnotation]
1540+
newResourceOverrideSnapshotHash := newWork.Annotations[fleetv1beta1.ParentResourceOverrideSnapshotHashAnnotation]
1541+
if oldClusterResourceOverrideSnapshotHash == "" || newClusterResourceOverrideSnapshotHash == "" ||
1542+
oldResourceOverrideSnapshotHash == "" || newResourceOverrideSnapshotHash == "" {
1543+
klog.ErrorS(controller.NewUnexpectedBehaviorError(errors.New("found an invalid work without override-snapshot-hash")),
1544+
"Could not find the override-snapshot-hash annotation", "oldWork", klog.KObj(oldWork), "oldWorkAnnotations", oldWork.Annotations,
1545+
"newWork", klog.KObj(newWork), "newWorkAnnotations", newWork.Annotations)
1546+
return
1547+
}
1548+
1549+
// There is an edge case that, the work spec is the same but from different resourceSnapshots or resourceOverrideSnapshots.
1550+
// WorkGenerator will update the work because of the label/annotation changes, but the generation is the same.
15391551
// When the normal update happens, the controller will set the applied condition as false and wait
15401552
// until the work condition has been changed.
15411553
// In this edge case, we need to requeue the binding to update the binding status.
1542-
if oldResourceSnapshot == newResourceSnapshot {
1554+
if oldResourceSnapshot == newResourceSnapshot &&
1555+
oldClusterResourceOverrideSnapshotHash == newClusterResourceOverrideSnapshotHash &&
1556+
oldResourceOverrideSnapshotHash == newResourceOverrideSnapshotHash {
15431557
klog.V(2).InfoS("The work applied or available condition stayed as true, no need to reconcile", "oldWork", klog.KObj(oldWork), "newWork", klog.KObj(newWork))
15441558
return
15451559
}

test/e2e/placement_cro_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,44 @@ var _ = Context("creating clusterResourceOverride (selecting all clusters) to ov
144144
checkIfOverrideAnnotationsOnAllMemberClusters(true, want)
145145
})
146146

147+
It("update cro attached to this CRP only and no updates on the namespace", func() {
148+
Eventually(func() error {
149+
cro := &placementv1alpha1.ClusterResourceOverride{}
150+
if err := hubClient.Get(ctx, types.NamespacedName{Name: croName}, cro); err != nil {
151+
return err
152+
}
153+
cro.Spec.Policy.OverrideRules = append(cro.Spec.Policy.OverrideRules, placementv1alpha1.OverrideRule{
154+
ClusterSelector: &placementv1beta1.ClusterSelector{
155+
ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{
156+
{
157+
LabelSelector: &metav1.LabelSelector{
158+
MatchLabels: map[string]string{
159+
"invalid-key": "invalid-value",
160+
},
161+
},
162+
},
163+
},
164+
},
165+
OverrideType: placementv1alpha1.DeleteOverrideType,
166+
})
167+
return hubClient.Update(ctx, cro)
168+
}, eventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to update cro as expected", crpName)
169+
})
170+
171+
It("should update CRP status on demand as expected", func() {
172+
wantCRONames := []string{fmt.Sprintf(placementv1alpha1.OverrideSnapshotNameFmt, croName, 2)}
173+
crpStatusUpdatedActual := crpStatusWithOverrideUpdatedActual(workResourceIdentifiers(), allMemberClusterNames, "0", wantCRONames, nil)
174+
Eventually(crpStatusUpdatedActual, eventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to update CRP %s status as expected", crpName)
175+
})
176+
177+
// This check will ignore the annotation of resources.
178+
It("should place the selected resources on member clusters", checkIfPlacedWorkResourcesOnAllMemberClusters)
179+
180+
It("should have new override annotation value on the placed resources", func() {
181+
want := map[string]string{croTestAnnotationKey: croTestAnnotationValue1}
182+
checkIfOverrideAnnotationsOnAllMemberClusters(true, want)
183+
})
184+
147185
It("delete the cro attached to this CRP", func() {
148186
cleanupClusterResourceOverride(croName)
149187
})

test/e2e/placement_ro_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,46 @@ var _ = Context("creating resourceOverride (selecting all clusters) to override
143143
want := map[string]string{roTestAnnotationKey: roTestAnnotationValue1}
144144
checkIfOverrideAnnotationsOnAllMemberClusters(false, want)
145145
})
146+
147+
It("update ro attached to this CRP only and no update on the configmap itself", func() {
148+
Eventually(func() error {
149+
ro := &placementv1alpha1.ResourceOverride{}
150+
if err := hubClient.Get(ctx, types.NamespacedName{Name: roName, Namespace: roNamespace}, ro); err != nil {
151+
return err
152+
}
153+
ro.Spec.Policy.OverrideRules = append(ro.Spec.Policy.OverrideRules, placementv1alpha1.OverrideRule{
154+
ClusterSelector: &placementv1beta1.ClusterSelector{
155+
ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{
156+
{
157+
LabelSelector: &metav1.LabelSelector{
158+
MatchLabels: map[string]string{
159+
"invalid-key": "invalid-value",
160+
},
161+
},
162+
},
163+
},
164+
},
165+
OverrideType: placementv1alpha1.DeleteOverrideType,
166+
})
167+
return hubClient.Update(ctx, ro)
168+
}, eventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to update ro as expected", crpName)
169+
})
170+
171+
It("should update CRP status as expected", func() {
172+
wantRONames := []placementv1beta1.NamespacedName{
173+
{Namespace: roNamespace, Name: fmt.Sprintf(placementv1alpha1.OverrideSnapshotNameFmt, roName, 2)},
174+
}
175+
crpStatusUpdatedActual := crpStatusWithOverrideUpdatedActual(workResourceIdentifiers(), allMemberClusterNames, "0", nil, wantRONames)
176+
Eventually(crpStatusUpdatedActual, eventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to update CRP %s status as expected", crpName)
177+
})
178+
179+
// This check will ignore the annotation of resources.
180+
It("should place the selected resources on member clusters", checkIfPlacedWorkResourcesOnAllMemberClusters)
181+
182+
It("should have override annotations on the configmap", func() {
183+
want := map[string]string{roTestAnnotationKey: roTestAnnotationValue1}
184+
checkIfOverrideAnnotationsOnAllMemberClusters(false, want)
185+
})
146186
})
147187

148188
var _ = Context("creating resourceOverride with multiple jsonPatchOverrides to override configMap", Ordered, func() {

0 commit comments

Comments
 (0)