Skip to content

Commit f469853

Browse files
committed
0. Introduce ClusterName field to ClusterResourceSetBinding
1. remove the Cluster owner reference from the ClusterResourceSetBinding. 2. update the clusterName field in the CRS controller to update existing CRSbindings with the new field. 3. adding a check in the validation webhook preventing the cluster name to be changed once it is set Signed-off-by: chaunceyjiang <[email protected]>
1 parent a8841fb commit f469853

16 files changed

+384
-64
lines changed

config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesetbindings.yaml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/webhook/manifests.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,28 @@ webhooks:
410410
resources:
411411
- clusterresourcesets
412412
sideEffects: None
413+
- admissionReviewVersions:
414+
- v1
415+
- v1beta1
416+
clientConfig:
417+
service:
418+
name: webhook-service
419+
namespace: system
420+
path: /validate-addons-cluster-x-k8s-io-v1beta1-clusterresourcesetbinding
421+
failurePolicy: Fail
422+
matchPolicy: Equivalent
423+
name: validation.clusterresourcesetbinding.addons.cluster.x-k8s.io
424+
rules:
425+
- apiGroups:
426+
- addons.cluster.x-k8s.io
427+
apiVersions:
428+
- v1beta1
429+
operations:
430+
- CREATE
431+
- UPDATE
432+
resources:
433+
- clusterresourcesetbindings
434+
sideEffects: None
413435
- admissionReviewVersions:
414436
- v1
415437
- v1beta1

exp/addons/api/v1alpha3/conversion.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ limitations under the License.
1717
package v1alpha3
1818

1919
import (
20+
apiconversion "k8s.io/apimachinery/pkg/conversion"
2021
"sigs.k8s.io/controller-runtime/pkg/conversion"
2122

2223
addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1"
24+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
2325
)
2426

2527
func (src *ClusterResourceSet) ConvertTo(dstRaw conversion.Hub) error {
@@ -49,13 +51,31 @@ func (dst *ClusterResourceSetList) ConvertFrom(srcRaw conversion.Hub) error {
4951
func (src *ClusterResourceSetBinding) ConvertTo(dstRaw conversion.Hub) error {
5052
dst := dstRaw.(*addonsv1.ClusterResourceSetBinding)
5153

52-
return Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(src, dst, nil)
54+
if err := Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(src, dst, nil); err != nil {
55+
return err
56+
}
57+
// Manually restore data.
58+
restored := &addonsv1.ClusterResourceSetBinding{}
59+
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
60+
return err
61+
}
62+
dst.Spec.ClusterName = restored.Spec.ClusterName
63+
return nil
5364
}
5465

5566
func (dst *ClusterResourceSetBinding) ConvertFrom(srcRaw conversion.Hub) error {
5667
src := srcRaw.(*addonsv1.ClusterResourceSetBinding)
5768

58-
return Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(src, dst, nil)
69+
if err := Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(src, dst, nil); err != nil {
70+
return err
71+
}
72+
73+
// Preserve Hub data on down-conversion except for metadata
74+
if err := utilconversion.MarshalData(src, dst); err != nil {
75+
return err
76+
}
77+
78+
return nil
5979
}
6080

6181
func (src *ClusterResourceSetBindingList) ConvertTo(dstRaw conversion.Hub) error {
@@ -69,3 +89,9 @@ func (dst *ClusterResourceSetBindingList) ConvertFrom(srcRaw conversion.Hub) err
6989

7090
return Convert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList(src, dst, nil)
7191
}
92+
93+
// Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec is a conversion function.
94+
func Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(in *addonsv1.ClusterResourceSetBindingSpec, out *ClusterResourceSetBindingSpec, s apiconversion.Scope) error {
95+
// Spec.ClusterName does not exist in ClusterResourceSetBinding v1alpha3 API.
96+
return autoConvert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(in, out, s)
97+
}

exp/addons/api/v1alpha3/zz_generated.conversion.go

Lines changed: 28 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exp/addons/api/v1alpha4/conversion.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ limitations under the License.
1717
package v1alpha4
1818

1919
import (
20+
apiconversion "k8s.io/apimachinery/pkg/conversion"
2021
"sigs.k8s.io/controller-runtime/pkg/conversion"
2122

2223
addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1"
24+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
2325
)
2426

2527
func (src *ClusterResourceSet) ConvertTo(dstRaw conversion.Hub) error {
@@ -49,13 +51,31 @@ func (dst *ClusterResourceSetList) ConvertFrom(srcRaw conversion.Hub) error {
4951
func (src *ClusterResourceSetBinding) ConvertTo(dstRaw conversion.Hub) error {
5052
dst := dstRaw.(*addonsv1.ClusterResourceSetBinding)
5153

52-
return Convert_v1alpha4_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(src, dst, nil)
54+
if err := Convert_v1alpha4_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(src, dst, nil); err != nil {
55+
return err
56+
}
57+
// Manually restore data.
58+
restored := &addonsv1.ClusterResourceSetBinding{}
59+
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
60+
return err
61+
}
62+
dst.Spec.ClusterName = restored.Spec.ClusterName
63+
return nil
5364
}
5465

5566
func (dst *ClusterResourceSetBinding) ConvertFrom(srcRaw conversion.Hub) error {
5667
src := srcRaw.(*addonsv1.ClusterResourceSetBinding)
5768

58-
return Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha4_ClusterResourceSetBinding(src, dst, nil)
69+
if err := Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha4_ClusterResourceSetBinding(src, dst, nil); err != nil {
70+
return err
71+
}
72+
73+
// Preserve Hub data on down-conversion except for metadata
74+
if err := utilconversion.MarshalData(src, dst); err != nil {
75+
return err
76+
}
77+
78+
return nil
5979
}
6080

6181
func (src *ClusterResourceSetBindingList) ConvertTo(dstRaw conversion.Hub) error {
@@ -69,3 +89,9 @@ func (dst *ClusterResourceSetBindingList) ConvertFrom(srcRaw conversion.Hub) err
6989

7090
return Convert_v1beta1_ClusterResourceSetBindingList_To_v1alpha4_ClusterResourceSetBindingList(src, dst, nil)
7191
}
92+
93+
// Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha4_ClusterResourceSetBindingSpec is a conversion function.
94+
func Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha4_ClusterResourceSetBindingSpec(in *addonsv1.ClusterResourceSetBindingSpec, out *ClusterResourceSetBindingSpec, s apiconversion.Scope) error {
95+
// Spec.ClusterName does not exist in ClusterResourceSetBinding v1alpha4 API.
96+
return autoConvert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha4_ClusterResourceSetBindingSpec(in, out, s)
97+
}

exp/addons/api/v1alpha4/zz_generated.conversion.go

Lines changed: 28 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exp/addons/api/v1beta1/clusterresourcesetbinding_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ type ClusterResourceSetBindingSpec struct {
133133
// Bindings is a list of ClusterResourceSets and their resources.
134134
// +optional
135135
Bindings []*ResourceSetBinding `json:"bindings,omitempty"`
136+
137+
// ClusterName is the name of the Cluster this binding applies to.
138+
// Note: this field mandatory in v1beta2.
139+
// +optional
140+
ClusterName string `json:"clusterName,omitempty"`
136141
}
137142

138143
// ANCHOR_END: ClusterResourceSetBindingSpec
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1beta1
18+
19+
import (
20+
"fmt"
21+
22+
apierrors "k8s.io/apimachinery/pkg/api/errors"
23+
"k8s.io/apimachinery/pkg/runtime"
24+
"k8s.io/apimachinery/pkg/util/validation/field"
25+
ctrl "sigs.k8s.io/controller-runtime"
26+
"sigs.k8s.io/controller-runtime/pkg/webhook"
27+
28+
"sigs.k8s.io/cluster-api/feature"
29+
)
30+
31+
func (c *ClusterResourceSetBinding) SetupWebhookWithManager(mgr ctrl.Manager) error {
32+
return ctrl.NewWebhookManagedBy(mgr).
33+
For(c).
34+
Complete()
35+
}
36+
37+
// +kubebuilder:webhook:verbs=create;update,path=/validate-addons-cluster-x-k8s-io-v1beta1-clusterresourcesetbinding,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=addons.cluster.x-k8s.io,resources=clusterresourcesetbindings,versions=v1beta1,name=validation.clusterresourcesetbinding.addons.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
38+
39+
var _ webhook.Validator = &ClusterResourceSetBinding{}
40+
41+
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
42+
func (c *ClusterResourceSetBinding) ValidateCreate() error {
43+
return c.validate(nil)
44+
}
45+
46+
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
47+
func (c *ClusterResourceSetBinding) ValidateUpdate(old runtime.Object) error {
48+
oldBinding, ok := old.(*ClusterResourceSetBinding)
49+
if !ok {
50+
return apierrors.NewBadRequest(fmt.Sprintf("expected a ClusterResourceSetBinding but got a %T", old))
51+
}
52+
return c.validate(oldBinding)
53+
}
54+
55+
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
56+
func (c *ClusterResourceSetBinding) ValidateDelete() error {
57+
return nil
58+
}
59+
60+
func (c *ClusterResourceSetBinding) validate(old *ClusterResourceSetBinding) error {
61+
// NOTE: ClusterResourceSet is behind ClusterResourceSet feature gate flag; the web hook
62+
// must prevent creating new objects in case the feature flag is disabled.
63+
if !feature.Gates.Enabled(feature.ClusterResourceSet) {
64+
return field.Forbidden(
65+
field.NewPath("spec"),
66+
"can be set only if the ClusterResourceSet feature flag is enabled",
67+
)
68+
}
69+
var allErrs field.ErrorList
70+
if old != nil && old.Spec.ClusterName != "" && old.Spec.ClusterName != c.Spec.ClusterName {
71+
allErrs = append(allErrs,
72+
field.Invalid(field.NewPath("spec", "clusterName"), c.Spec.ClusterName, "field is immutable"))
73+
}
74+
if len(allErrs) == 0 {
75+
return nil
76+
}
77+
return apierrors.NewInvalid(GroupVersion.WithKind("ClusterResourceSetBinding").GroupKind(), c.Name, allErrs)
78+
}

0 commit comments

Comments
 (0)