Making resource selector required

Signed-off-by: RainbowMango <qdurenhongcai@gmail.com>
This commit is contained in:
RainbowMango 2021-06-10 15:59:50 +08:00
parent 17aead5d79
commit 89f3569147
6 changed files with 20 additions and 152 deletions

View File

@ -248,8 +248,7 @@ spec:
type: array
type: object
resourceSelectors:
description: ResourceSelectors used to select resources. nil represents
all resources.
description: ResourceSelectors used to select resources.
items:
description: ResourceSelector the resources will be selected.
properties:
@ -324,6 +323,8 @@ spec:
scheduler. If not specified, the policy will be dispatched by default
scheduler.
type: string
required:
- resourceSelectors
type: object
required:
- spec

View File

@ -244,8 +244,7 @@ spec:
type: array
type: object
resourceSelectors:
description: ResourceSelectors used to select resources. nil represents
all resources.
description: ResourceSelectors used to select resources.
items:
description: ResourceSelector the resources will be selected.
properties:
@ -320,6 +319,8 @@ spec:
scheduler. If not specified, the policy will be dispatched by default
scheduler.
type: string
required:
- resourceSelectors
type: object
required:
- spec

View File

@ -16,14 +16,15 @@ type PropagationPolicy struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec represents the desired behavior of PropagationPolicy.
// +required
Spec PropagationSpec `json:"spec"`
}
// PropagationSpec represents the desired behavior of PropagationPolicy.
type PropagationSpec struct {
// ResourceSelectors used to select resources.
// nil represents all resources.
ResourceSelectors []ResourceSelector `json:"resourceSelectors,omitempty"`
// +required
ResourceSelectors []ResourceSelector `json:"resourceSelectors"`
// Association tells if relevant resources should be selected automatically.
// e.g. a ConfigMap referred by a Deployment.
@ -32,6 +33,7 @@ type PropagationSpec struct {
Association bool `json:"association,omitempty"`
// Placement represents the rule for select clusters to propagate resources.
// +optional
Placement Placement `json:"placement,omitempty"`
// DependentOverrides represents the list of overrides(OverridePolicy)
@ -49,15 +51,18 @@ type PropagationSpec struct {
// SchedulerName represents which scheduler to proceed the scheduling.
// If specified, the policy will be dispatched by specified scheduler.
// If not specified, the policy will be dispatched by default scheduler.
// +optional
SchedulerName string `json:"schedulerName,omitempty"`
}
// ResourceSelector the resources will be selected.
type ResourceSelector struct {
// APIVersion represents the API version of the target resources.
// +required
APIVersion string `json:"apiVersion"`
// Kind represents the Kind of the target resources.
// +required
Kind string `json:"kind"`
// Namespace of the target resource.
@ -90,9 +95,11 @@ type Placement struct {
ClusterAffinity *ClusterAffinity `json:"clusterAffinity,omitempty"`
// ClusterTolerations represents the tolerations.
// +optional
ClusterTolerations []corev1.Toleration `json:"clusterTolerations,omitempty"`
// SpreadConstraints represents a list of the scheduling constraints.
// +optional
SpreadConstraints []SpreadConstraint `json:"spreadConstraints,omitempty"`
}
@ -140,16 +147,20 @@ type SpreadConstraint struct {
type ClusterAffinity struct {
// LabelSelector is a filter to select member clusters by labels.
// If non-nil and non-empty, only the clusters match this filter will be selected.
// +optional
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
// FieldSelector is a filter to select member clusters by fields.
// If non-nil and non-empty, only the clusters match this filter will be selected.
// +optional
FieldSelector *FieldSelector `json:"fieldSelector,omitempty"`
// ClusterNames is the list of clusters to be selected.
// +optional
ClusterNames []string `json:"clusterNames,omitempty"`
// ExcludedClusters is the list of clusters to be ignored.
// +optional
ExcludeClusters []string `json:"exclude,omitempty"`
}
@ -176,6 +187,7 @@ type ClusterPropagationPolicy struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec represents the desired behavior of ClusterPropagationPolicy.
// +required
Spec PropagationSpec `json:"spec"`
}

View File

@ -263,11 +263,6 @@ func (d *ResourceDetector) LookForMatchedPolicy(object *unstructured.Unstructure
matchedPolicies := make([]policyv1alpha1.PropagationPolicy, 0)
for _, policy := range policyList.Items {
if policy.Spec.ResourceSelectors == nil {
matchedPolicies = append(matchedPolicies, policy)
continue
}
if util.ResourceMatchSelectors(object, policy.Spec.ResourceSelectors...) {
matchedPolicies = append(matchedPolicies, policy)
}
@ -299,11 +294,6 @@ func (d *ResourceDetector) LookForMatchedClusterPolicy(object *unstructured.Unst
matchedClusterPolicies := make([]policyv1alpha1.ClusterPropagationPolicy, 0)
for _, policy := range policyList.Items {
if policy.Spec.ResourceSelectors == nil {
matchedClusterPolicies = append(matchedClusterPolicies, policy)
continue
}
if util.ResourceMatchSelectors(object, policy.Spec.ResourceSelectors...) {
matchedClusterPolicies = append(matchedClusterPolicies, policy)
}

View File

@ -119,77 +119,3 @@ var _ = ginkgo.Describe("[BasicClusterPropagation] basic cluster propagation tes
})
})
})
var _ = ginkgo.Describe("ClusterPropagationPolicy with nil resourceSelectors", func() {
ginkgo.Context("CustomResourceDefinition propagation testing", func() {
crdGroup := fmt.Sprintf("example-%s.karmada.io", rand.String(RandomStrLength))
randStr := rand.String(RandomStrLength)
crdSpecNames := apiextensionsv1.CustomResourceDefinitionNames{
Kind: fmt.Sprintf("Foo%s", randStr),
ListKind: fmt.Sprintf("Foo%sList", randStr),
Plural: fmt.Sprintf("foo%ss", randStr),
Singular: fmt.Sprintf("foo%s", randStr),
}
crd := helper.NewCustomResourceDefinition(crdGroup, crdSpecNames, apiextensionsv1.NamespaceScoped)
crdPolicy := helper.NewClusterPropagationPolicy(crd.Name, nil, policyv1alpha1.Placement{
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
ClusterNames: clusterNames,
},
})
crdGVR := schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"}
ginkgo.BeforeEach(func() {
ginkgo.By(fmt.Sprintf("creating crdPolicy(%s)", crdPolicy.Name), func() {
_, err := karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Create(context.TODO(), crdPolicy, metav1.CreateOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
})
ginkgo.AfterEach(func() {
ginkgo.By(fmt.Sprintf("removing crdPolicy(%s)", crdPolicy.Name), func() {
err := karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Delete(context.TODO(), crdPolicy.Name, metav1.DeleteOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
})
ginkgo.It("crd propagation testing", func() {
ginkgo.By(fmt.Sprintf("creating crd(%s)", crd.Name), func() {
unstructObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(crd)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
_, err = dynamicClient.Resource(crdGVR).Namespace(crd.Namespace).Create(context.TODO(), &unstructured.Unstructured{Object: unstructObj}, metav1.CreateOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
ginkgo.By(fmt.Sprintf("get crd(%s)", crd.Name), func() {
_, err := dynamicClient.Resource(crdGVR).Namespace(crd.Namespace).Get(context.TODO(), crd.Name, metav1.GetOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
ginkgo.By("check if crd present on member clusters", func() {
for _, cluster := range clusters {
clusterDynamicClient := getClusterDynamicClient(cluster.Name)
gomega.Expect(clusterDynamicClient).ShouldNot(gomega.BeNil())
klog.Infof("Waiting for crd(%s) present on cluster(%s)", crd.Name, cluster.Name)
err := wait.Poll(pollInterval, pollTimeout, func() (done bool, err error) {
_, err = clusterDynamicClient.Resource(crdGVR).Namespace(crd.Namespace).Get(context.TODO(), crd.Name, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return false, nil
}
return false, err
}
return true, nil
})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
}
})
ginkgo.By(fmt.Sprintf("removing crd(%s)", crd.Name), func() {
err := dynamicClient.Resource(crdGVR).Namespace(crd.Namespace).Delete(context.TODO(), crd.Name, metav1.DeleteOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
})
})
})

View File

@ -577,65 +577,3 @@ var _ = ginkgo.Describe("[BasicPropagation] basic propagation testing", func() {
})
})
})
var _ = ginkgo.Describe("PropagationPolicy with nil resourceSelectors", func() {
ginkgo.Context("Deployment propagation testing", func() {
policyNamespace := testNamespace
policyName := deploymentNamePrefix + rand.String(RandomStrLength)
deploymentNamespace := testNamespace
deploymentName := policyName
deployment := helper.NewDeployment(deploymentNamespace, deploymentName)
policy := helper.NewPropagationPolicy(policyNamespace, policyName, nil, policyv1alpha1.Placement{
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
ClusterNames: clusterNames,
},
})
ginkgo.BeforeEach(func() {
ginkgo.By(fmt.Sprintf("creating policy(%s/%s)", policyNamespace, policyName), func() {
_, err := karmadaClient.PolicyV1alpha1().PropagationPolicies(policyNamespace).Create(context.TODO(), policy, metav1.CreateOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
})
ginkgo.AfterEach(func() {
ginkgo.By(fmt.Sprintf("removing policy(%s/%s)", policyNamespace, policyName), func() {
err := karmadaClient.PolicyV1alpha1().PropagationPolicies(policyNamespace).Delete(context.TODO(), policyName, metav1.DeleteOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
})
ginkgo.It("deployment propagation", func() {
ginkgo.By(fmt.Sprintf("creating deployment(%s/%s)", deploymentNamespace, deploymentName), func() {
_, err := kubeClient.AppsV1().Deployments(testNamespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
ginkgo.By("check if deployment present on member clusters", func() {
for _, cluster := range clusters {
clusterClient := getClusterClient(cluster.Name)
gomega.Expect(clusterClient).ShouldNot(gomega.BeNil())
klog.Infof("Waiting for deployment(%s/%s) present on cluster(%s)", deploymentNamespace, deploymentName, cluster.Name)
err := wait.Poll(pollInterval, pollTimeout, func() (done bool, err error) {
_, err = clusterClient.AppsV1().Deployments(deploymentNamespace).Get(context.TODO(), deploymentName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return false, nil
}
return false, err
}
return true, nil
})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
}
})
ginkgo.By(fmt.Sprintf("removing deployment(%s/%s)", deploymentNamespace, deploymentName), func() {
err := kubeClient.AppsV1().Deployments(testNamespace).Delete(context.TODO(), deploymentName, metav1.DeleteOptions{})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
})
})
})