diff --git a/pkg/controllers/binding/binding_controller.go b/pkg/controllers/binding/binding_controller.go index 22d5161c2..0c988ac50 100644 --- a/pkg/controllers/binding/binding_controller.go +++ b/pkg/controllers/binding/binding_controller.go @@ -234,11 +234,13 @@ func (c *ResourceBindingController) SetupWithManager(mgr controllerruntime.Manag func (c *ResourceBindingController) newOverridePolicyFunc() handler.MapFunc { return func(a client.Object) []reconcile.Request { var overrideRS []policyv1alpha1.ResourceSelector + var namespace string switch t := a.(type) { case *policyv1alpha1.ClusterOverridePolicy: overrideRS = t.Spec.ResourceSelectors case *policyv1alpha1.OverridePolicy: overrideRS = t.Spec.ResourceSelectors + namespace = t.Namespace default: return nil } @@ -251,6 +253,18 @@ func (c *ResourceBindingController) newOverridePolicyFunc() handler.MapFunc { var requests []reconcile.Request for _, binding := range bindingList.Items { + // Skip resourceBinding with different namespace of current overridePolicy. + if len(namespace) != 0 && namespace != binding.Namespace { + continue + } + + // Nil resourceSelectors means matching all resources. + if len(overrideRS) == 0 { + klog.V(2).Infof("Enqueue ResourceBinding(%s/%s) as override policy(%s/%s) changes.", binding.Namespace, binding.Name, a.GetNamespace(), a.GetName()) + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{Namespace: binding.Namespace, Name: binding.Name}}) + continue + } + workload, err := helper.FetchWorkload(c.DynamicClient, c.InformerManager, c.RESTMapper, binding.Spec.Resource) if err != nil { klog.Errorf("Failed to fetch workload for resourceBinding(%s/%s). Error: %v.", binding.Namespace, binding.Name, err) diff --git a/pkg/controllers/binding/cluster_resource_binding_controller.go b/pkg/controllers/binding/cluster_resource_binding_controller.go index 6d5f49de0..23c1ecb91 100644 --- a/pkg/controllers/binding/cluster_resource_binding_controller.go +++ b/pkg/controllers/binding/cluster_resource_binding_controller.go @@ -243,6 +243,13 @@ func (c *ClusterResourceBindingController) newOverridePolicyFunc() handler.MapFu var requests []reconcile.Request for _, binding := range bindingList.Items { + // Nil resourceSelectors means matching all resources. + if len(overrideRS) == 0 { + klog.V(2).Infof("Enqueue ClusterResourceBinding(%s) as cluster override policy(%s) changes.", binding.Name, a.GetName()) + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{Name: binding.Name}}) + continue + } + workload, err := helper.FetchWorkload(c.DynamicClient, c.InformerManager, c.RESTMapper, binding.Spec.Resource) if err != nil { klog.Errorf("Failed to fetch workload for clusterResourceBinding(%s). Error: %v.", binding.Name, err) @@ -251,7 +258,7 @@ func (c *ClusterResourceBindingController) newOverridePolicyFunc() handler.MapFu for _, rs := range overrideRS { if util.ResourceMatches(workload, rs) { - klog.V(2).Infof("Enqueue ClusterResourceBinding(%s) as override policy(%s/%s) changes.", binding.Name, a.GetNamespace(), a.GetName()) + klog.V(2).Infof("Enqueue ClusterResourceBinding(%s) as cluster override policy(%s) changes.", binding.Name, a.GetName()) requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{Name: binding.Name}}) break } diff --git a/test/e2e/clusteroverridepolicy_test.go b/test/e2e/clusteroverridepolicy_test.go index 7a08c6ebb..f42e94f3c 100644 --- a/test/e2e/clusteroverridepolicy_test.go +++ b/test/e2e/clusteroverridepolicy_test.go @@ -6,6 +6,7 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -97,3 +98,84 @@ var _ = ginkgo.Describe("[BasicClusterOverridePolicy] basic cluster override pol }) }) }) + +var _ = ginkgo.Describe("Test clusterOverridePolicy with nil resourceSelectors", func() { + var deploymentNamespace, deploymentName string + var propagationPolicyNamespace, propagationPolicyName string + var clusterOverridePolicyName string + var deployment *appsv1.Deployment + var propagationPolicy *policyv1alpha1.PropagationPolicy + var clusterOverridePolicy *policyv1alpha1.ClusterOverridePolicy + + ginkgo.BeforeEach(func() { + deploymentNamespace = testNamespace + deploymentName = deploymentNamePrefix + rand.String(RandomStrLength) + propagationPolicyNamespace = testNamespace + propagationPolicyName = deploymentName + clusterOverridePolicyName = deploymentName + + deployment = testhelper.NewDeployment(deploymentNamespace, deploymentName) + propagationPolicy = testhelper.NewPropagationPolicy(propagationPolicyNamespace, propagationPolicyName, []policyv1alpha1.ResourceSelector{ + { + APIVersion: deployment.APIVersion, + Kind: deployment.Kind, + Name: deployment.Name, + }, + }, policyv1alpha1.Placement{ + ClusterAffinity: &policyv1alpha1.ClusterAffinity{ + ClusterNames: framework.ClusterNames(), + }, + }) + + clusterOverridePolicy = testhelper.NewClusterOverridePolicyByOverrideRules(clusterOverridePolicyName, nil, []policyv1alpha1.RuleWithCluster{ + { + TargetCluster: &policyv1alpha1.ClusterAffinity{ + ClusterNames: framework.ClusterNames(), + }, + Overriders: policyv1alpha1.Overriders{ + ImageOverrider: []policyv1alpha1.ImageOverrider{ + { + Predicate: &policyv1alpha1.ImagePredicate{ + Path: "/spec/template/spec/containers/0/image", + }, + Component: "Registry", + Operator: "replace", + Value: "fictional.registry.us", + }, + }, + }, + }, + }) + }) + + ginkgo.Context("Deployment override testing", func() { + ginkgo.BeforeEach(func() { + framework.CreatePropagationPolicy(karmadaClient, propagationPolicy) + framework.CreateDeployment(kubeClient, deployment) + ginkgo.DeferCleanup(func() { + framework.RemovePropagationPolicy(karmadaClient, propagationPolicy.Namespace, propagationPolicy.Name) + framework.RemoveDeployment(kubeClient, deployment.Namespace, deployment.Name) + }) + }) + + ginkgo.It("deployment imageOverride testing", func() { + ginkgo.By("Check if deployment have presented on member clusters", func() { + framework.WaitDeploymentPresentOnClustersFitWith(framework.ClusterNames(), deployment.Namespace, deployment.Name, + func(deployment *appsv1.Deployment) bool { + return true + }) + }) + + framework.CreateClusterOverridePolicy(karmadaClient, clusterOverridePolicy) + + ginkgo.By("Check if deployment presented on member clusters have correct image value", func() { + framework.WaitDeploymentPresentOnClustersFitWith(framework.ClusterNames(), deployment.Namespace, deployment.Name, + func(deployment *appsv1.Deployment) bool { + return deployment.Spec.Template.Spec.Containers[0].Image == "fictional.registry.us/nginx:1.19.0" + }) + }) + + framework.RemoveClusterOverridePolicy(karmadaClient, clusterOverridePolicy.Name) + }) + }) +}) diff --git a/test/e2e/overridepolicy_test.go b/test/e2e/overridepolicy_test.go index 3e38cff29..aa09b42bd 100644 --- a/test/e2e/overridepolicy_test.go +++ b/test/e2e/overridepolicy_test.go @@ -790,4 +790,35 @@ var _ = ginkgo.Describe("OverrideRules with nil resourceSelectors", func() { }) }) }) + + ginkgo.Context("Deployment override testing when creating overridePolicy after develop and propagationPolicy have been created", func() { + ginkgo.BeforeEach(func() { + framework.CreatePropagationPolicy(karmadaClient, propagationPolicy) + framework.CreateDeployment(kubeClient, deployment) + ginkgo.DeferCleanup(func() { + framework.RemovePropagationPolicy(karmadaClient, propagationPolicy.Namespace, propagationPolicy.Name) + framework.RemoveDeployment(kubeClient, deployment.Namespace, deployment.Name) + }) + }) + + ginkgo.It("deployment imageOverride testing", func() { + ginkgo.By("Check if deployment have presented on member clusters", func() { + framework.WaitDeploymentPresentOnClustersFitWith(framework.ClusterNames(), deployment.Namespace, deployment.Name, + func(deployment *appsv1.Deployment) bool { + return true + }) + }) + + framework.CreateOverridePolicy(karmadaClient, overridePolicy) + + ginkgo.By("Check if deployment presented on member clusters have correct image value", func() { + framework.WaitDeploymentPresentOnClustersFitWith(framework.ClusterNames(), deployment.Namespace, deployment.Name, + func(deployment *appsv1.Deployment) bool { + return deployment.Spec.Template.Spec.Containers[0].Image == "fictional.registry.us/nginx:1.19.0" + }) + }) + + framework.RemoveOverridePolicy(karmadaClient, overridePolicy.Namespace, overridePolicy.Name) + }) + }) })