From 42794c80a4534688758dbcc54f39456a8e86c1e7 Mon Sep 17 00:00:00 2001 From: Zhiying Lin <54013513+zhiying-lin@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:50:35 +0800 Subject: [PATCH] fix: use the override snapshot when looking for matched overrides (#738) --- ...tes-fleet.io_clusterresourceoverrides.yaml | 1 - ...kubernetes-fleet.io_resourceoverrides.yaml | 1 - ...t.io_clusterresourceoverridesnapshots.yaml | 1 + ...es-fleet.io_resourceoverridesnapshots.yaml | 1 + pkg/controllers/rollout/controller.go | 2 +- pkg/controllers/rollout/controller_test.go | 176 +-- pkg/controllers/rollout/override.go | 64 +- pkg/controllers/rollout/override_test.go | 1007 +++++++++++------ 8 files changed, 796 insertions(+), 457 deletions(-) delete mode 120000 charts/hub-agent/crdbases/placement.kubernetes-fleet.io_clusterresourceoverrides.yaml delete mode 120000 charts/hub-agent/crdbases/placement.kubernetes-fleet.io_resourceoverrides.yaml create mode 120000 charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_clusterresourceoverridesnapshots.yaml create mode 120000 charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_resourceoverridesnapshots.yaml diff --git a/charts/hub-agent/crdbases/placement.kubernetes-fleet.io_clusterresourceoverrides.yaml b/charts/hub-agent/crdbases/placement.kubernetes-fleet.io_clusterresourceoverrides.yaml deleted file mode 120000 index 055185264..000000000 --- a/charts/hub-agent/crdbases/placement.kubernetes-fleet.io_clusterresourceoverrides.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../config/crd/bases/placement.kubernetes-fleet.io_clusterresourceoverrides.yaml \ No newline at end of file diff --git a/charts/hub-agent/crdbases/placement.kubernetes-fleet.io_resourceoverrides.yaml b/charts/hub-agent/crdbases/placement.kubernetes-fleet.io_resourceoverrides.yaml deleted file mode 120000 index cd430d5d6..000000000 --- a/charts/hub-agent/crdbases/placement.kubernetes-fleet.io_resourceoverrides.yaml +++ /dev/null @@ -1 +0,0 @@ -../../../config/crd/bases/placement.kubernetes-fleet.io_resourceoverrides.yaml \ No newline at end of file diff --git a/charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_clusterresourceoverridesnapshots.yaml b/charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_clusterresourceoverridesnapshots.yaml new file mode 120000 index 000000000..7dd7cd111 --- /dev/null +++ b/charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_clusterresourceoverridesnapshots.yaml @@ -0,0 +1 @@ +../../../../config/crd/bases/placement.kubernetes-fleet.io_clusterresourceoverridesnapshots.yaml \ No newline at end of file diff --git a/charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_resourceoverridesnapshots.yaml b/charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_resourceoverridesnapshots.yaml new file mode 120000 index 000000000..dc01c97d6 --- /dev/null +++ b/charts/hub-agent/templates/crds/placement.kubernetes-fleet.io_resourceoverridesnapshots.yaml @@ -0,0 +1 @@ +../../../../config/crd/bases/placement.kubernetes-fleet.io_resourceoverridesnapshots.yaml \ No newline at end of file diff --git a/pkg/controllers/rollout/controller.go b/pkg/controllers/rollout/controller.go index 5f5e532db..1b49f0850 100644 --- a/pkg/controllers/rollout/controller.go +++ b/pkg/controllers/rollout/controller.go @@ -277,7 +277,7 @@ func createUpdateInfo(binding *fleetv1beta1.ClusterResourceBinding, crp *fleetv1 // Thus, it also returns a bool indicating whether there are out of sync bindings to be rolled to differentiate those // two cases. func (r *Reconciler) pickBindingsToRoll(ctx context.Context, allBindings []*fleetv1beta1.ClusterResourceBinding, latestResourceSnapshot *fleetv1beta1.ClusterResourceSnapshot, crp *fleetv1beta1.ClusterResourcePlacement, - matchedCROs []*fleetv1alpha1.ClusterResourceOverride, matchedROs []*fleetv1alpha1.ResourceOverride) ([]toBeUpdatedBinding, []toBeUpdatedBinding, bool, error) { + matchedCROs []*fleetv1alpha1.ClusterResourceOverrideSnapshot, matchedROs []*fleetv1alpha1.ResourceOverrideSnapshot) ([]toBeUpdatedBinding, []toBeUpdatedBinding, bool, error) { // Those are the bindings that are chosen by the scheduler to be applied to selected clusters. // They include the bindings that are already applied to the clusters and the bindings that are newly selected by the scheduler. schedulerTargetedBinds := make([]*fleetv1beta1.ClusterResourceBinding, 0) diff --git a/pkg/controllers/rollout/controller_test.go b/pkg/controllers/rollout/controller_test.go index 207a20ab3..b987713d3 100644 --- a/pkg/controllers/rollout/controller_test.go +++ b/pkg/controllers/rollout/controller_test.go @@ -738,8 +738,8 @@ func TestPickBindingsToRoll(t *testing.T) { allBindings []*fleetv1beta1.ClusterResourceBinding latestResourceSnapshotName string crp *fleetv1beta1.ClusterResourcePlacement - matchedCROs []*fleetv1alpha1.ClusterResourceOverride - matchedROs []*fleetv1alpha1.ResourceOverride + matchedCROs []*fleetv1alpha1.ClusterResourceOverrideSnapshot + matchedROs []*fleetv1alpha1.ResourceOverrideSnapshot clusters []clusterv1beta1.MemberCluster wantTobeUpdatedBindings []int wantDesiredBindingsSpec []fleetv1beta1.ResourceBindingSpec // used to construct the want toBeUpdatedBindings @@ -791,8 +791,8 @@ func TestPickBindingsToRoll(t *testing.T) { latestResourceSnapshotName: "snapshot-2", crp: clusterResourcePlacementForTest("test", createPlacementPolicyForTest(fleetv1beta1.PickAllPlacementType, 0)), - matchedROs: []*fleetv1alpha1.ResourceOverride{}, - matchedCROs: []*fleetv1alpha1.ClusterResourceOverride{}, + matchedROs: []*fleetv1alpha1.ResourceOverrideSnapshot{}, + matchedCROs: []*fleetv1alpha1.ClusterResourceOverrideSnapshot{}, wantTobeUpdatedBindings: []int{0}, wantDesiredBindingsSpec: []fleetv1beta1.ResourceBindingSpec{ { @@ -810,21 +810,23 @@ func TestPickBindingsToRoll(t *testing.T) { latestResourceSnapshotName: "snapshot-2", crp: clusterResourcePlacementForTest("test", createPlacementPolicyForTest(fleetv1beta1.PickAllPlacementType, 0)), - matchedCROs: []*fleetv1alpha1.ClusterResourceOverride{ + matchedCROs: []*fleetv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: fleetv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ClusterResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, @@ -836,22 +838,24 @@ func TestPickBindingsToRoll(t *testing.T) { }, }, }, - matchedROs: []*fleetv1alpha1.ResourceOverride{ + matchedROs: []*fleetv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "test", }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key2": "value2", + Spec: fleetv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key2": "value2", + }, }, }, }, @@ -898,21 +902,23 @@ func TestPickBindingsToRoll(t *testing.T) { latestResourceSnapshotName: "snapshot-2", crp: clusterResourcePlacementForTest("test", createPlacementPolicyForTest(fleetv1beta1.PickAllPlacementType, 0)), - matchedCROs: []*fleetv1alpha1.ClusterResourceOverride{ + matchedCROs: []*fleetv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: fleetv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ClusterResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, @@ -924,22 +930,24 @@ func TestPickBindingsToRoll(t *testing.T) { }, }, }, - matchedROs: []*fleetv1alpha1.ResourceOverride{ + matchedROs: []*fleetv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "test", }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key2": "value2", + Spec: fleetv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key2": "value2", + }, }, }, }, @@ -975,21 +983,23 @@ func TestPickBindingsToRoll(t *testing.T) { latestResourceSnapshotName: "snapshot-1", crp: clusterResourcePlacementForTest("test", createPlacementPolicyForTest(fleetv1beta1.PickAllPlacementType, 0)), - matchedCROs: []*fleetv1alpha1.ClusterResourceOverride{ + matchedCROs: []*fleetv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: fleetv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ClusterResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, @@ -1001,22 +1011,24 @@ func TestPickBindingsToRoll(t *testing.T) { }, }, }, - matchedROs: []*fleetv1alpha1.ResourceOverride{ + matchedROs: []*fleetv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "test", }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key2": "value2", + Spec: fleetv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key2": "value2", + }, }, }, }, @@ -1282,21 +1294,23 @@ func TestPickBindingsToRoll(t *testing.T) { generateClusterResourceBinding(fleetv1beta1.BindingStateBound, "snapshot-1", cluster1), }, latestResourceSnapshotName: "snapshot-1", - matchedCROs: []*fleetv1alpha1.ClusterResourceOverride{ + matchedCROs: []*fleetv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: fleetv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: fleetv1alpha1.ClusterResourceOverrideSpec{ + Policy: &fleetv1alpha1.OverridePolicy{ + OverrideRules: []fleetv1alpha1.OverrideRule{ + { + ClusterSelector: &fleetv1beta1.ClusterSelector{ + ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, diff --git a/pkg/controllers/rollout/override.go b/pkg/controllers/rollout/override.go index 8aa8895cd..5b2b0d15b 100644 --- a/pkg/controllers/rollout/override.go +++ b/pkg/controllers/rollout/override.go @@ -9,6 +9,9 @@ import ( "context" "errors" "sort" + "strconv" + + "sigs.k8s.io/controller-runtime/pkg/client" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -18,23 +21,26 @@ import ( "k8s.io/klog/v2" clusterv1beta1 "go.goms.io/fleet/apis/cluster/v1beta1" - fleetv1alpha1 "go.goms.io/fleet/apis/placement/v1alpha1" - fleetv1beta1 "go.goms.io/fleet/apis/placement/v1beta1" + placementv1alpha1 "go.goms.io/fleet/apis/placement/v1alpha1" + placementv1beta1 "go.goms.io/fleet/apis/placement/v1beta1" "go.goms.io/fleet/pkg/utils" "go.goms.io/fleet/pkg/utils/controller" ) // fetchAllMatchingOverridesForResourceSnapshot fetches all the matching overrides which are attached to the selected resources. -func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Context, crp string, masterResourceSnapshot *fleetv1beta1.ClusterResourceSnapshot) ([]*fleetv1alpha1.ClusterResourceOverride, []*fleetv1alpha1.ResourceOverride, error) { - // fetch the cro and ro list first before finding the matched ones. - croList := &fleetv1alpha1.ClusterResourceOverrideList{} - if err := r.Client.List(ctx, croList); err != nil { - klog.ErrorS(err, "Failed to list all the clusterResourceOverrides") +func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Context, crp string, masterResourceSnapshot *placementv1beta1.ClusterResourceSnapshot) ([]*placementv1alpha1.ClusterResourceOverrideSnapshot, []*placementv1alpha1.ResourceOverrideSnapshot, error) { + // fetch the cro and ro snapshot list first before finding the matched ones. + latestSnapshotLabelMatcher := client.MatchingLabels{ + placementv1beta1.IsLatestSnapshotLabel: strconv.FormatBool(true), + } + croList := &placementv1alpha1.ClusterResourceOverrideSnapshotList{} + if err := r.Client.List(ctx, croList, latestSnapshotLabelMatcher); err != nil { + klog.ErrorS(err, "Failed to list all the clusterResourceOverrideSnapshots") return nil, nil, err } - roList := &fleetv1alpha1.ResourceOverrideList{} - if err := r.Client.List(ctx, roList); err != nil { - klog.ErrorS(err, "Failed to list all the resourceOverrides") + roList := &placementv1alpha1.ResourceOverrideSnapshotList{} + if err := r.Client.List(ctx, roList, latestSnapshotLabelMatcher); err != nil { + klog.ErrorS(err, "Failed to list all the resourceOverrideSnapshots") return nil, nil, err } @@ -47,8 +53,8 @@ func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Co return nil, nil, err } - possibleCROs := make(map[fleetv1beta1.ResourceIdentifier]bool) - possibleROs := make(map[fleetv1beta1.ResourceIdentifier]bool) + possibleCROs := make(map[placementv1beta1.ResourceIdentifier]bool) + possibleROs := make(map[placementv1beta1.ResourceIdentifier]bool) // List all the possible CROs and ROs based on the selected resources. for _, snapshot := range resourceSnapshots { for _, res := range snapshot.Spec.SelectedResources { @@ -60,14 +66,14 @@ func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Co // If the resource is namespaced scope resource, the resource could be selected by the namespace or selected // by the object itself. if !r.InformerManager.IsClusterScopedResources(uResource.GroupVersionKind()) { - croKey := fleetv1beta1.ResourceIdentifier{ + croKey := placementv1beta1.ResourceIdentifier{ Group: utils.NamespaceMetaGVK.Group, Version: utils.NamespaceMetaGVK.Version, Kind: utils.NamespaceMetaGVK.Kind, Name: uResource.GetNamespace(), } possibleCROs[croKey] = true // selected by the namespace - roKey := fleetv1beta1.ResourceIdentifier{ + roKey := placementv1beta1.ResourceIdentifier{ Group: uResource.GetObjectKind().GroupVersionKind().Group, Version: uResource.GetObjectKind().GroupVersionKind().Version, Kind: uResource.GetObjectKind().GroupVersionKind().Kind, @@ -76,7 +82,7 @@ func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Co } possibleROs[roKey] = true // selected by the object itself } else { - croKey := fleetv1beta1.ResourceIdentifier{ + croKey := placementv1beta1.ResourceIdentifier{ Group: uResource.GetObjectKind().GroupVersionKind().Group, Version: uResource.GetObjectKind().GroupVersionKind().Version, Kind: uResource.GetObjectKind().GroupVersionKind().Kind, @@ -87,11 +93,11 @@ func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Co } } - filteredCRO := make([]*fleetv1alpha1.ClusterResourceOverride, 0, len(croList.Items)) - filteredRO := make([]*fleetv1alpha1.ResourceOverride, 0, len(roList.Items)) + filteredCRO := make([]*placementv1alpha1.ClusterResourceOverrideSnapshot, 0, len(croList.Items)) + filteredRO := make([]*placementv1alpha1.ResourceOverrideSnapshot, 0, len(roList.Items)) for i := range croList.Items { - for _, selector := range croList.Items[i].Spec.ClusterResourceSelectors { - croKey := fleetv1beta1.ResourceIdentifier{ + for _, selector := range croList.Items[i].Spec.OverrideSpec.ClusterResourceSelectors { + croKey := placementv1beta1.ResourceIdentifier{ Group: selector.Group, Version: selector.Version, Kind: selector.Kind, @@ -104,8 +110,8 @@ func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Co } } for i := range roList.Items { - for _, selector := range roList.Items[i].Spec.ResourceSelectors { - roKey := fleetv1beta1.ResourceIdentifier{ + for _, selector := range roList.Items[i].Spec.OverrideSpec.ResourceSelectors { + roKey := placementv1beta1.ResourceIdentifier{ Group: selector.Group, Version: selector.Version, Kind: selector.Kind, @@ -126,7 +132,7 @@ func (r *Reconciler) fetchAllMatchingOverridesForResourceSnapshot(ctx context.Co // roList is a list of resourceOverrides attached to the selected resources. // It returns names of cro and ro attached to the target cluster, and they're ordered by its namespace (if present) and // then name. -func (r *Reconciler) pickFromResourceMatchedOverridesForTargetCluster(ctx context.Context, binding *fleetv1beta1.ClusterResourceBinding, croList []*fleetv1alpha1.ClusterResourceOverride, roList []*fleetv1alpha1.ResourceOverride) ([]string, []fleetv1beta1.NamespacedName, error) { +func (r *Reconciler) pickFromResourceMatchedOverridesForTargetCluster(ctx context.Context, binding *placementv1beta1.ClusterResourceBinding, croList []*placementv1alpha1.ClusterResourceOverrideSnapshot, roList []*placementv1alpha1.ResourceOverrideSnapshot) ([]string, []placementv1beta1.NamespacedName, error) { if len(croList) == 0 && len(roList) == 0 { return nil, nil, nil } @@ -141,9 +147,9 @@ func (r *Reconciler) pickFromResourceMatchedOverridesForTargetCluster(ctx contex return nil, nil, controller.NewAPIServerError(true, err) } - croFiltered := make([]*fleetv1alpha1.ClusterResourceOverride, 0, len(croList)) + croFiltered := make([]*placementv1alpha1.ClusterResourceOverrideSnapshot, 0, len(croList)) for i, cro := range croList { - matched, err := isClusterMatched(cluster, cro.Spec.Policy) + matched, err := isClusterMatched(cluster, cro.Spec.OverrideSpec.Policy) if err != nil { klog.ErrorS(err, "Invalid clusterResourceOverride", "clusterResourceOverride", klog.KObj(cro)) return nil, nil, controller.NewUnexpectedBehaviorError(err) @@ -157,9 +163,9 @@ func (r *Reconciler) pickFromResourceMatchedOverridesForTargetCluster(ctx contex return croFiltered[i].Name < croFiltered[j].Name }) - roFiltered := make([]*fleetv1alpha1.ResourceOverride, 0, len(roList)) + roFiltered := make([]*placementv1alpha1.ResourceOverrideSnapshot, 0, len(roList)) for i, ro := range roList { - matched, err := isClusterMatched(cluster, ro.Spec.Policy) + matched, err := isClusterMatched(cluster, ro.Spec.OverrideSpec.Policy) if err != nil { klog.ErrorS(err, "Invalid resourceOverride", "resourceOverride", klog.KObj(ro)) return nil, nil, controller.NewUnexpectedBehaviorError(err) @@ -179,15 +185,15 @@ func (r *Reconciler) pickFromResourceMatchedOverridesForTargetCluster(ctx contex for i, o := range croFiltered { croNames[i] = o.Name } - roNames := make([]fleetv1beta1.NamespacedName, len(roFiltered)) + roNames := make([]placementv1beta1.NamespacedName, len(roFiltered)) for i, o := range roFiltered { - roNames[i] = fleetv1beta1.NamespacedName{Name: o.Name, Namespace: o.Namespace} + roNames[i] = placementv1beta1.NamespacedName{Name: o.Name, Namespace: o.Namespace} } klog.V(2).InfoS("Found matched overrides for the binding", "binding", klog.KObj(binding), "matchedCROCount", len(croNames), "matchedROCount", len(roNames)) return croNames, roNames, nil } -func isClusterMatched(cluster clusterv1beta1.MemberCluster, policy *fleetv1alpha1.OverridePolicy) (bool, error) { +func isClusterMatched(cluster clusterv1beta1.MemberCluster, policy *placementv1alpha1.OverridePolicy) (bool, error) { if policy == nil { return false, errors.New("policy is nil") } diff --git a/pkg/controllers/rollout/override_test.go b/pkg/controllers/rollout/override_test.go index 9bc5e036e..bc911a387 100644 --- a/pkg/controllers/rollout/override_test.go +++ b/pkg/controllers/rollout/override_test.go @@ -20,8 +20,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" clusterv1beta1 "go.goms.io/fleet/apis/cluster/v1beta1" - fleetv1alpha1 "go.goms.io/fleet/apis/placement/v1alpha1" - fleetv1beta1 "go.goms.io/fleet/apis/placement/v1beta1" + placementv1alpha1 "go.goms.io/fleet/apis/placement/v1alpha1" + placementv1beta1 "go.goms.io/fleet/apis/placement/v1beta1" "go.goms.io/fleet/pkg/utils/controller" "go.goms.io/fleet/test/utils/informer" "go.goms.io/fleet/test/utils/resource" @@ -33,13 +33,13 @@ var ( func serviceScheme(t *testing.T) *runtime.Scheme { scheme := runtime.NewScheme() - if err := fleetv1beta1.AddToScheme(scheme); err != nil { + if err := placementv1beta1.AddToScheme(scheme); err != nil { t.Fatalf("Failed to add placement v1beta1 scheme: %v", err) } if err := clusterv1beta1.AddToScheme(scheme); err != nil { t.Fatalf("Failed to add cluster v1beta1 scheme: %v", err) } - if err := fleetv1alpha1.AddToScheme(scheme); err != nil { + if err := placementv1alpha1.AddToScheme(scheme); err != nil { t.Fatalf("Failed to add v1alpha1 scheme: %v", err) } return scheme @@ -69,256 +69,356 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { tests := []struct { name string - master *fleetv1beta1.ClusterResourceSnapshot - snapshots []fleetv1beta1.ClusterResourceSnapshot - croList []fleetv1alpha1.ClusterResourceOverride - roList []fleetv1alpha1.ResourceOverride - wantCRO []*fleetv1alpha1.ClusterResourceOverride - wantRO []*fleetv1alpha1.ResourceOverride + master *placementv1beta1.ClusterResourceSnapshot + snapshots []placementv1beta1.ClusterResourceSnapshot + croList []placementv1alpha1.ClusterResourceOverrideSnapshot + roList []placementv1alpha1.ResourceOverrideSnapshot + wantCRO []*placementv1alpha1.ClusterResourceOverrideSnapshot + wantRO []*placementv1alpha1.ResourceOverrideSnapshot }{ { name: "single resource snapshot selecting empty resources", - master: &fleetv1beta1.ClusterResourceSnapshot{ + master: &placementv1beta1.ClusterResourceSnapshot{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameFmt, crpName, 0), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, crpName, 0), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.ResourceGroupHashAnnotation: "abc", - fleetv1beta1.NumberOfResourceSnapshotsAnnotation: "1", + placementv1beta1.ResourceGroupHashAnnotation: "abc", + placementv1beta1.NumberOfResourceSnapshotsAnnotation: "1", }, }, }, - croList: []fleetv1alpha1.ClusterResourceOverride{ + croList: []placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{}, + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{}, }, }, - wantCRO: []*fleetv1alpha1.ClusterResourceOverride{}, - wantRO: []*fleetv1alpha1.ResourceOverride{}, + wantCRO: []*placementv1alpha1.ClusterResourceOverrideSnapshot{}, + wantRO: []*placementv1alpha1.ResourceOverrideSnapshot{}, }, { name: "single resource snapshot with no matched overrides", - master: &fleetv1beta1.ClusterResourceSnapshot{ + master: &placementv1beta1.ClusterResourceSnapshot{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameFmt, crpName, 0), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, crpName, 0), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.ResourceGroupHashAnnotation: "abc", - fleetv1beta1.NumberOfResourceSnapshotsAnnotation: "1", + placementv1beta1.ResourceGroupHashAnnotation: "abc", + placementv1beta1.NumberOfResourceSnapshotsAnnotation: "1", }, }, - Spec: fleetv1beta1.ResourceSnapshotSpec{ - SelectedResources: []fleetv1beta1.ResourceContent{ + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ *resource.ServiceResourceContentForTest(t), }, }, }, - croList: []fleetv1alpha1.ClusterResourceOverride{ + croList: []placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "rbac.authorization.k8s.io", - Version: "v1", - Kind: "ClusterRole", - Name: "test-cluster-role", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + Name: "test-cluster-role", + }, }, }, }, }, }, - roList: []fleetv1alpha1.ResourceOverride{ + roList: []placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "rbac.authorization.k8s.io", - Version: "v1", - Kind: "Role", - Name: "test-role", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "Role", + Name: "test-role", + }, }, }, }, }, }, - wantCRO: []*fleetv1alpha1.ClusterResourceOverride{}, - wantRO: []*fleetv1alpha1.ResourceOverride{}, + wantCRO: []*placementv1alpha1.ClusterResourceOverrideSnapshot{}, + wantRO: []*placementv1alpha1.ResourceOverrideSnapshot{}, }, { name: "single resource snapshot with matched cro and ro", - master: &fleetv1beta1.ClusterResourceSnapshot{ + master: &placementv1beta1.ClusterResourceSnapshot{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameFmt, crpName, 0), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, crpName, 0), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.ResourceGroupHashAnnotation: "abc", - fleetv1beta1.NumberOfResourceSnapshotsAnnotation: "1", + placementv1beta1.ResourceGroupHashAnnotation: "abc", + placementv1beta1.NumberOfResourceSnapshotsAnnotation: "1", }, }, - Spec: fleetv1beta1.ResourceSnapshotSpec{ - SelectedResources: []fleetv1beta1.ResourceContent{ + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ *resource.ServiceResourceContentForTest(t), }, }, }, - croList: []fleetv1alpha1.ClusterResourceOverride{ + croList: []placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Namespace", - Name: "svc-namespace", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, }, }, }, }, }, - roList: []fleetv1alpha1.ResourceOverride{ + roList: []placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, }, }, - wantCRO: []*fleetv1alpha1.ClusterResourceOverride{ + wantCRO: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Namespace", - Name: "svc-namespace", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, }, }, }, }, }, - wantRO: []*fleetv1alpha1.ResourceOverride{ + wantRO: []*placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, }, }, }, + { + name: "single resource snapshot with matched stale cro and ro snapshot", + master: &placementv1beta1.ClusterResourceSnapshot{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, crpName, 0), + Labels: map[string]string{ + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, + }, + Annotations: map[string]string{ + placementv1beta1.ResourceGroupHashAnnotation: "abc", + placementv1beta1.NumberOfResourceSnapshotsAnnotation: "1", + }, + }, + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ + *resource.ServiceResourceContentForTest(t), + }, + }, + }, + croList: []placementv1alpha1.ClusterResourceOverrideSnapshot{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "cro-1", + }, + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, + }, + }, + }, + }, + }, + roList: []placementv1alpha1.ResourceOverrideSnapshot{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ro-1", + Namespace: "svc-namespace", + }, + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, + }, + }, + }, + }, + }, + wantCRO: []*placementv1alpha1.ClusterResourceOverrideSnapshot{}, + wantRO: []*placementv1alpha1.ResourceOverrideSnapshot{}, + }, { name: "multiple resource snapshots with matched cro and ro", - master: &fleetv1beta1.ClusterResourceSnapshot{ + master: &placementv1beta1.ClusterResourceSnapshot{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameFmt, crpName, 0), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, crpName, 0), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.ResourceGroupHashAnnotation: "abc", - fleetv1beta1.NumberOfResourceSnapshotsAnnotation: "3", + placementv1beta1.ResourceGroupHashAnnotation: "abc", + placementv1beta1.NumberOfResourceSnapshotsAnnotation: "3", }, }, - Spec: fleetv1beta1.ResourceSnapshotSpec{ - SelectedResources: []fleetv1beta1.ResourceContent{ + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ *resource.NamespaceResourceContentForTest(t), *resource.ServiceResourceContentForTest(t), }, }, }, - snapshots: []fleetv1beta1.ClusterResourceSnapshot{ + snapshots: []placementv1beta1.ClusterResourceSnapshot{ { ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameWithSubindexFmt, crpName, 0, 0), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameWithSubindexFmt, crpName, 0, 0), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.SubindexOfResourceSnapshotAnnotation: "0", + placementv1beta1.SubindexOfResourceSnapshotAnnotation: "0", }, }, - Spec: fleetv1beta1.ResourceSnapshotSpec{ - SelectedResources: []fleetv1beta1.ResourceContent{ + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ *resource.DeploymentResourceContentForTest(t), }, }, }, { ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameWithSubindexFmt, crpName, 0, 1), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameWithSubindexFmt, crpName, 0, 1), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.SubindexOfResourceSnapshotAnnotation: "1", + placementv1beta1.SubindexOfResourceSnapshotAnnotation: "1", }, }, - Spec: fleetv1beta1.ResourceSnapshotSpec{ - SelectedResources: []fleetv1beta1.ResourceContent{ + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ *resource.ClusterRoleResourceContentForTest(t), }, }, }, }, - croList: []fleetv1alpha1.ClusterResourceOverride{ + croList: []placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "rbac.authorization.k8s.io", - Version: "v1", - Kind: "ClusterRole", - Name: "not-exist", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + Name: "not-exist", + }, }, }, }, @@ -326,38 +426,48 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "rbac.authorization.k8s.io", - Version: "v1", - Kind: "ClusterRole", - Name: "clusterrole-name", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + Name: "clusterrole-name", + }, }, }, }, }, }, - roList: []fleetv1alpha1.ResourceOverride{ + roList: []placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Deployment", - Name: "not-exist", - }, - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Deployment", + Name: "not-exist", + }, + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, @@ -366,49 +476,64 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "deployment-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Deployment", - Name: "deployment-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Deployment", + Name: "deployment-name", + }, }, }, }, }, }, - wantCRO: []*fleetv1alpha1.ClusterResourceOverride{ + wantCRO: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "rbac.authorization.k8s.io", - Version: "v1", - Kind: "ClusterRole", - Name: "clusterrole-name", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + Name: "clusterrole-name", + }, }, }, }, }, }, - wantRO: []*fleetv1alpha1.ResourceOverride{ + wantRO: []*placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "deployment-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Deployment", - Name: "deployment-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Deployment", + Name: "deployment-name", + }, }, }, }, @@ -417,20 +542,25 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Deployment", - Name: "not-exist", - }, - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Deployment", + Name: "not-exist", + }, + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, @@ -440,36 +570,41 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { { // not supported in the first phase name: "single resource snapshot with multiple matched cro and ro", - master: &fleetv1beta1.ClusterResourceSnapshot{ + master: &placementv1beta1.ClusterResourceSnapshot{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf(fleetv1beta1.ResourceSnapshotNameFmt, crpName, 0), + Name: fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, crpName, 0), Labels: map[string]string{ - fleetv1beta1.ResourceIndexLabel: "0", - fleetv1beta1.CRPTrackingLabel: crpName, + placementv1beta1.ResourceIndexLabel: "0", + placementv1beta1.CRPTrackingLabel: crpName, }, Annotations: map[string]string{ - fleetv1beta1.ResourceGroupHashAnnotation: "abc", - fleetv1beta1.NumberOfResourceSnapshotsAnnotation: "1", + placementv1beta1.ResourceGroupHashAnnotation: "abc", + placementv1beta1.NumberOfResourceSnapshotsAnnotation: "1", }, }, - Spec: fleetv1beta1.ResourceSnapshotSpec{ - SelectedResources: []fleetv1beta1.ResourceContent{ + Spec: placementv1beta1.ResourceSnapshotSpec{ + SelectedResources: []placementv1beta1.ResourceContent{ *resource.ServiceResourceContentForTest(t), }, }, }, - croList: []fleetv1alpha1.ClusterResourceOverride{ + croList: []placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Namespace", - Name: "svc-namespace", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, }, }, }, @@ -477,32 +612,42 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Namespace", - Name: "svc-namespace", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, }, }, }, }, }, - roList: []fleetv1alpha1.ResourceOverride{ + roList: []placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, @@ -511,31 +656,41 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, }, }, - wantCRO: []*fleetv1alpha1.ClusterResourceOverride{ + wantCRO: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Namespace", - Name: "svc-namespace", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, }, }, }, @@ -543,32 +698,42 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - ClusterResourceSelectors: []fleetv1beta1.ClusterResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Namespace", - Name: "svc-namespace", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + ClusterResourceSelectors: []placementv1beta1.ClusterResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Namespace", + Name: "svc-namespace", + }, }, }, }, }, }, - wantRO: []*fleetv1alpha1.ResourceOverride{ + wantRO: []*placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, @@ -577,14 +742,19 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - ResourceSelectors: []fleetv1alpha1.ResourceSelector{ - { - Group: "", - Version: "v1", - Kind: "Service", - Name: "svc-name", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + ResourceSelectors: []placementv1alpha1.ResourceSelector{ + { + Group: "", + Version: "v1", + Kind: "Service", + Name: "svc-name", + }, }, }, }, @@ -620,10 +790,10 @@ func TestFetchAllMatchingOverridesForResourceSnapshot(t *testing.T) { } options := []cmp.Option{ cmpopts.IgnoreFields(metav1.ObjectMeta{}, "ResourceVersion"), - cmpopts.SortSlices(func(o1, o2 fleetv1alpha1.ClusterResourceOverride) bool { + cmpopts.SortSlices(func(o1, o2 placementv1alpha1.ClusterResourceOverride) bool { return o1.Name < o2.Name }), - cmpopts.SortSlices(func(o1, o2 fleetv1alpha1.ResourceOverride) bool { + cmpopts.SortSlices(func(o1, o2 placementv1alpha1.ResourceOverride) bool { if o1.Namespace == o2.Namespace { return o1.Name < o2.Name } @@ -645,10 +815,10 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { tests := []struct { name string cluster *clusterv1beta1.MemberCluster - croList []*fleetv1alpha1.ClusterResourceOverride - roList []*fleetv1alpha1.ResourceOverride + croList []*placementv1alpha1.ClusterResourceOverrideSnapshot + roList []*placementv1alpha1.ResourceOverrideSnapshot wantCRO []string - wantRO []fleetv1beta1.NamespacedName + wantRO []placementv1beta1.NamespacedName wantErr error }{ { @@ -661,17 +831,116 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { wantCRO: nil, wantRO: nil, }, + { + name: "non-latest override snapshots", + cluster: &clusterv1beta1.MemberCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-1", + }, + }, + croList: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "cro-1", + }, + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "cro-2", + }, + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, + }, + }, + }, + }, + }, + roList: []*placementv1alpha1.ResourceOverrideSnapshot{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ro-1", + Namespace: "svc-namespace", + }, + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ro-2", + Namespace: "deployment-namespace", + }, + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, + }, + }, + }, + }, + }, + wantCRO: []string{"cro-1", "cro-2"}, + wantRO: []placementv1beta1.NamespacedName{ + { + Namespace: "deployment-namespace", + Name: "ro-2", + }, + { + Namespace: "svc-namespace", + Name: "ro-1", + }, + }, + }, { name: "cluster not found", - croList: []*fleetv1alpha1.ClusterResourceOverride{ + croList: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - {}, // empty cluster label selects all clusters + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, }, }, }, @@ -691,22 +960,27 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { Name: "cluster-1", }, }, - croList: []*fleetv1alpha1.ClusterResourceOverride{ + croList: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - {}, // empty cluster label selects all clusters - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, @@ -720,26 +994,36 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - {}, // empty cluster label selects all clusters + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, }, }, }, }, }, - roList: []*fleetv1alpha1.ResourceOverride{ + roList: []*placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "svc-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - {}, // empty cluster label selects all clusters + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, }, }, }, @@ -748,18 +1032,23 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "deployment-namespace", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - {}, // empty cluster label selects all clusters + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + {}, // empty cluster label selects all clusters + }, }, }, }, }, }, wantCRO: []string{"cro-1", "cro-2"}, - wantRO: []fleetv1beta1.NamespacedName{ + wantRO: []placementv1beta1.NamespacedName{ { Namespace: "deployment-namespace", Name: "ro-2", @@ -781,21 +1070,26 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { }, }, }, - croList: []*fleetv1alpha1.ClusterResourceOverride{ + croList: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, @@ -809,17 +1103,22 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "cro-2", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value2", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value2", + }, }, }, }, @@ -831,22 +1130,27 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { }, }, }, - roList: []*fleetv1alpha1.ResourceOverride{ + roList: []*placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "test", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value1", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value1", + }, }, }, }, @@ -861,17 +1165,22 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ro-2", Namespace: "test", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key2": "value2", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key2": "value2", + }, }, }, }, @@ -884,7 +1193,7 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { }, }, wantCRO: []string{"cro-1"}, - wantRO: []fleetv1beta1.NamespacedName{ + wantRO: []placementv1beta1.NamespacedName{ { Namespace: "test", Name: "ro-1", @@ -906,21 +1215,26 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { }, }, }, - croList: []*fleetv1alpha1.ClusterResourceOverride{ + croList: []*placementv1alpha1.ClusterResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "cro-1", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ClusterResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key1": "value2", + Spec: placementv1alpha1.ClusterResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ClusterResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key1": "value2", + }, }, }, }, @@ -932,22 +1246,27 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { }, }, }, - roList: []*fleetv1alpha1.ResourceOverride{ + roList: []*placementv1alpha1.ResourceOverrideSnapshot{ { ObjectMeta: metav1.ObjectMeta{ Name: "ro-1", Namespace: "test", + Labels: map[string]string{ + placementv1beta1.IsLatestSnapshotLabel: "true", + }, }, - Spec: fleetv1alpha1.ResourceOverrideSpec{ - Policy: &fleetv1alpha1.OverridePolicy{ - OverrideRules: []fleetv1alpha1.OverrideRule{ - { - ClusterSelector: &fleetv1beta1.ClusterSelector{ - ClusterSelectorTerms: []fleetv1beta1.ClusterSelectorTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "key4": "value1", + Spec: placementv1alpha1.ResourceOverrideSnapshotSpec{ + OverrideSpec: placementv1alpha1.ResourceOverrideSpec{ + Policy: &placementv1alpha1.OverridePolicy{ + OverrideRules: []placementv1alpha1.OverrideRule{ + { + ClusterSelector: &placementv1beta1.ClusterSelector{ + ClusterSelectorTerms: []placementv1beta1.ClusterSelectorTerm{ + { + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "key4": "value1", + }, }, }, }, @@ -960,7 +1279,7 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { }, }, wantCRO: []string{}, - wantRO: []fleetv1beta1.NamespacedName{}, + wantRO: []placementv1beta1.NamespacedName{}, }, } for _, tc := range tests { @@ -974,11 +1293,11 @@ func TestPickFromResourceMatchedOverridesForTargetCluster(t *testing.T) { r := Reconciler{ Client: fakeClient, } - binding := &fleetv1beta1.ClusterResourceBinding{ + binding := &placementv1beta1.ClusterResourceBinding{ ObjectMeta: metav1.ObjectMeta{ Name: "binding-1", }, - Spec: fleetv1beta1.ResourceBindingSpec{ + Spec: placementv1beta1.ResourceBindingSpec{ TargetCluster: "cluster-1", }, }