diff --git a/test/integration/cluster_placement_test.go b/test/integration/cluster_placement_test.go index 114cd41ac..efe61f052 100644 --- a/test/integration/cluster_placement_test.go +++ b/test/integration/cluster_placement_test.go @@ -1023,8 +1023,144 @@ var _ = Describe("Test Cluster Resource Placement Controller", func() { markInternalMCJoined(clusterA) }) - XIt("Test cluster scoped resource change unpick by a placement", func() { + It("Test cluster scoped resource change unpick by a placement", func() { + By("create cluster role binding") + crb := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster-role-binding", + Labels: map[string]string{ + "fleet.azure.com/name": "test", + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: ClusterRoleKind, + Name: "test-cluster-role", + }, + } + Expect(k8sClient.Create(ctx, crb)).Should(Succeed()) + + By("create cluster resource placement") + crp = &fleetv1alpha1.ClusterResourcePlacement{ + ObjectMeta: metav1.ObjectMeta{ + Name: "resource-select", + }, + Spec: fleetv1alpha1.ClusterResourcePlacementSpec{ + ResourceSelectors: []fleetv1alpha1.ClusterResourceSelector{ + { + Group: rbacv1.GroupName, + Version: "v1", + Kind: "ClusterRoleBinding", + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "fleet.azure.com/name": "test", + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, crp)).Should(Succeed()) + By("Select resource by label clusterResourcePlacement created") + + // verify that we have created the work object + var clusterWork workv1alpha1.Work + Eventually(func() error { + if err := k8sClient.Get(ctx, types.NamespacedName{ + Name: crp.Name, Namespace: fmt.Sprintf(utils.NamespaceNameFormat, clusterA.Name)}, &clusterWork); err != nil { + return err + } + return nil + }, timeout, interval).Should(Succeed(), "Failed to retrieve %s work", crp.Name) + + // Apply is Pending because work api controller is not being run for this test suite + fleetResourceIdentifier := fleetv1alpha1.ResourceIdentifier{ + Group: rbacv1.GroupName, + Version: "v1", + Kind: "ClusterRoleBinding", + Name: "test-cluster-role-binding", + } + wantCRPStatus := fleetv1alpha1.ClusterResourcePlacementStatus{ + Conditions: []metav1.Condition{ + { + Type: string(fleetv1alpha1.ResourcePlacementConditionTypeScheduled), + Status: metav1.ConditionTrue, + ObservedGeneration: 1, + Reason: "ScheduleSucceeded", + }, + { + Type: string(fleetv1alpha1.ResourcePlacementStatusConditionTypeApplied), + Status: metav1.ConditionUnknown, + ObservedGeneration: 1, + Reason: "ApplyPending", + }, + }, + SelectedResources: []fleetv1alpha1.ResourceIdentifier{fleetResourceIdentifier}, + TargetClusters: []string{clusterA.Name}, + } + + crpStatusCmpOptions := []cmp.Option{ + cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime", "Message"), + cmpopts.SortSlices(func(ref1, ref2 metav1.Condition) bool { return ref1.Type < ref2.Type }), + } + + Eventually(func() error { + if err := k8sClient.Get(ctx, types.NamespacedName{Name: crp.Name}, crp); err != nil { + return err + } + if diff := cmp.Diff(wantCRPStatus, crp.Status, crpStatusCmpOptions...); diff != "" { + return fmt.Errorf("CRP status(%s) mismatch (-want +got):\n%s", crp.Name, diff) + } + return nil + }, timeout, interval).Should(Succeed(), "Failed to compare actual and expected CRP status in hub cluster") + + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crp.Name}, crp)).Should(Succeed()) + By("Update cluster role binding such that CRP doesn't pick it up") + crb.ObjectMeta.Labels = map[string]string{ + "fleet.azure.com/env": "prod", + } + Expect(k8sClient.Update(ctx, crb)).Should(Succeed()) + + // verify that the work object created is not present anymore since we are not picking the cluster role binding + nsName := fmt.Sprintf(utils.NamespaceNameFormat, clusterA.Name) + Eventually(func() bool { + var clusterWork workv1alpha1.Work + return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{ + Name: crp.Name, + Namespace: nsName, + }, &clusterWork)) + }, timeout, interval).Should(BeTrue()) + By("Verified the work object is removed") + + wantCRPStatus = fleetv1alpha1.ClusterResourcePlacementStatus{ + Conditions: []metav1.Condition{ + { + Type: string(fleetv1alpha1.ResourcePlacementConditionTypeScheduled), + Status: metav1.ConditionFalse, + ObservedGeneration: 1, + Reason: "ScheduleFailed", + }, + { + Type: string(fleetv1alpha1.ResourcePlacementStatusConditionTypeApplied), + Status: metav1.ConditionUnknown, + ObservedGeneration: 1, + Reason: "ApplyPending", + }, + }, + } + + Eventually(func() error { + if err := k8sClient.Get(ctx, types.NamespacedName{Name: crp.Name}, crp); err != nil { + return err + } + if diff := cmp.Diff(wantCRPStatus, crp.Status, crpStatusCmpOptions...); diff != "" { + return fmt.Errorf("CRP status(%s) mismatch (-want +got):\n%s", crp.Name, diff) + } + return nil + }, timeout, interval).Should(Succeed(), "Failed to compare actual and expected CRP status in hub cluster") + By("Delete cluster role binding") + Expect(k8sClient.Delete(ctx, crb)).Should(Succeed()) }) It("Test a cluster scoped resource selected by multiple placements", func() {