@@ -14,9 +14,10 @@ See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
16
17
- package v1beta1
17
+ package webhooks
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
21
22
"strings"
22
23
@@ -29,24 +30,35 @@ import (
29
30
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
30
31
31
32
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
33
+ expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
32
34
"sigs.k8s.io/cluster-api/feature"
33
35
"sigs.k8s.io/cluster-api/util/version"
34
36
)
35
37
36
- func (m * MachinePool ) SetupWebhookWithManager (mgr ctrl.Manager ) error {
38
+ func (webhook * MachinePool ) SetupWebhookWithManager (mgr ctrl.Manager ) error {
37
39
return ctrl .NewWebhookManagedBy (mgr ).
38
- For (m ).
40
+ For (& expv1.MachinePool {}).
41
+ WithDefaulter (webhook ).
42
+ WithValidator (webhook ).
39
43
Complete ()
40
44
}
41
45
42
46
// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1beta1-machinepool,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinepools,versions=v1beta1,name=validation.machinepool.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
43
47
// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1beta1-machinepool,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=cluster.x-k8s.io,resources=machinepools,versions=v1beta1,name=default.machinepool.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
44
48
45
- var _ webhook.Defaulter = & MachinePool {}
46
- var _ webhook.Validator = & MachinePool {}
49
+ // MachinePool implements a validation and defaulting webhook for MachinePool.
50
+ type MachinePool struct {}
51
+
52
+ var _ webhook.CustomValidator = & MachinePool {}
53
+ var _ webhook.CustomDefaulter = & MachinePool {}
47
54
48
55
// Default implements webhook.Defaulter so a webhook will be registered for the type.
49
- func (m * MachinePool ) Default () {
56
+ func (webhook * MachinePool ) Default (_ context.Context , obj runtime.Object ) error {
57
+ m , ok := obj .(* expv1.MachinePool )
58
+ if ! ok {
59
+ return apierrors .NewBadRequest (fmt .Sprintf ("expected a MachinePool but got a %T" , obj ))
60
+ }
61
+
50
62
if m .Labels == nil {
51
63
m .Labels = make (map [string ]string )
52
64
}
@@ -73,30 +85,45 @@ func (m *MachinePool) Default() {
73
85
normalizedVersion := "v" + * m .Spec .Template .Spec .Version
74
86
m .Spec .Template .Spec .Version = & normalizedVersion
75
87
}
88
+ return nil
76
89
}
77
90
78
91
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
79
- func (m * MachinePool ) ValidateCreate () (admission.Warnings , error ) {
80
- return nil , m .validate (nil )
92
+ func (webhook * MachinePool ) ValidateCreate (_ context.Context , obj runtime.Object ) (admission.Warnings , error ) {
93
+ mp , ok := obj .(* expv1.MachinePool )
94
+ if ! ok {
95
+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a MachinePool but got a %T" , obj ))
96
+ }
97
+
98
+ return nil , webhook .validate (nil , mp )
81
99
}
82
100
83
101
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
84
- func (m * MachinePool ) ValidateUpdate (old runtime.Object ) (admission.Warnings , error ) {
85
- oldMP , ok := old .(* MachinePool )
102
+ func (webhook * MachinePool ) ValidateUpdate (_ context.Context , oldObj , newObj runtime.Object ) (admission.Warnings , error ) {
103
+ oldMP , ok := oldObj .(* expv1.MachinePool )
104
+ if ! ok {
105
+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a MachinePool but got a %T" , oldObj ))
106
+ }
107
+ newMP , ok := newObj .(* expv1.MachinePool )
86
108
if ! ok {
87
- return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a MachinePool but got a %T" , old ))
109
+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a MachinePool but got a %T" , newObj ))
88
110
}
89
- return nil , m .validate (oldMP )
111
+ return nil , webhook .validate (oldMP , newMP )
90
112
}
91
113
92
114
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
93
- func (m * MachinePool ) ValidateDelete () (admission.Warnings , error ) {
94
- return nil , m .validate (nil )
115
+ func (webhook * MachinePool ) ValidateDelete (_ context.Context , obj runtime.Object ) (admission.Warnings , error ) {
116
+ mp , ok := obj .(* expv1.MachinePool )
117
+ if ! ok {
118
+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a MachinePool but got a %T" , obj ))
119
+ }
120
+
121
+ return nil , webhook .validate (nil , mp )
95
122
}
96
123
97
- func (m * MachinePool ) validate (old * MachinePool ) error {
124
+ func (webhook * MachinePool ) validate (oldObj , newObj * expv1. MachinePool ) error {
98
125
// NOTE: MachinePool is behind MachinePool feature gate flag; the web hook
99
- // must prevent creating new objects when the feature flag is disabled.
126
+ // must prevent creating newObj objects when the feature flag is disabled.
100
127
specPath := field .NewPath ("spec" )
101
128
if ! feature .Gates .Enabled (feature .MachinePool ) {
102
129
return field .Forbidden (
@@ -105,7 +132,7 @@ func (m *MachinePool) validate(old *MachinePool) error {
105
132
)
106
133
}
107
134
var allErrs field.ErrorList
108
- if m .Spec .Template .Spec .Bootstrap .ConfigRef == nil && m .Spec .Template .Spec .Bootstrap .DataSecretName == nil {
135
+ if newObj .Spec .Template .Spec .Bootstrap .ConfigRef == nil && newObj .Spec .Template .Spec .Bootstrap .DataSecretName == nil {
109
136
allErrs = append (
110
137
allErrs ,
111
138
field .Required (
@@ -115,29 +142,29 @@ func (m *MachinePool) validate(old *MachinePool) error {
115
142
)
116
143
}
117
144
118
- if m .Spec .Template .Spec .Bootstrap .ConfigRef != nil && m .Spec .Template .Spec .Bootstrap .ConfigRef .Namespace != m .Namespace {
145
+ if newObj .Spec .Template .Spec .Bootstrap .ConfigRef != nil && newObj .Spec .Template .Spec .Bootstrap .ConfigRef .Namespace != newObj .Namespace {
119
146
allErrs = append (
120
147
allErrs ,
121
148
field .Invalid (
122
149
specPath .Child ("template" , "spec" , "bootstrap" , "configRef" , "namespace" ),
123
- m .Spec .Template .Spec .Bootstrap .ConfigRef .Namespace ,
150
+ newObj .Spec .Template .Spec .Bootstrap .ConfigRef .Namespace ,
124
151
"must match metadata.namespace" ,
125
152
),
126
153
)
127
154
}
128
155
129
- if m .Spec .Template .Spec .InfrastructureRef .Namespace != m .Namespace {
156
+ if newObj .Spec .Template .Spec .InfrastructureRef .Namespace != newObj .Namespace {
130
157
allErrs = append (
131
158
allErrs ,
132
159
field .Invalid (
133
160
specPath .Child ("infrastructureRef" , "namespace" ),
134
- m .Spec .Template .Spec .InfrastructureRef .Namespace ,
161
+ newObj .Spec .Template .Spec .InfrastructureRef .Namespace ,
135
162
"must match metadata.namespace" ,
136
163
),
137
164
)
138
165
}
139
166
140
- if old != nil && old .Spec .ClusterName != m .Spec .ClusterName {
167
+ if oldObj != nil && oldObj .Spec .ClusterName != newObj .Spec .ClusterName {
141
168
allErrs = append (
142
169
allErrs ,
143
170
field .Forbidden (
@@ -146,17 +173,17 @@ func (m *MachinePool) validate(old *MachinePool) error {
146
173
)
147
174
}
148
175
149
- if m .Spec .Template .Spec .Version != nil {
150
- if ! version .KubeSemver .MatchString (* m .Spec .Template .Spec .Version ) {
151
- allErrs = append (allErrs , field .Invalid (specPath .Child ("template" , "spec" , "version" ), * m .Spec .Template .Spec .Version , "must be a valid semantic version" ))
176
+ if newObj .Spec .Template .Spec .Version != nil {
177
+ if ! version .KubeSemver .MatchString (* newObj .Spec .Template .Spec .Version ) {
178
+ allErrs = append (allErrs , field .Invalid (specPath .Child ("template" , "spec" , "version" ), * newObj .Spec .Template .Spec .Version , "must be a valid semantic version" ))
152
179
}
153
180
}
154
181
155
182
// Validate the metadata of the MachinePool template.
156
- allErrs = append (allErrs , m .Spec .Template .ObjectMeta .Validate (specPath .Child ("template" , "metadata" ))... )
183
+ allErrs = append (allErrs , newObj .Spec .Template .ObjectMeta .Validate (specPath .Child ("template" , "metadata" ))... )
157
184
158
185
if len (allErrs ) == 0 {
159
186
return nil
160
187
}
161
- return apierrors .NewInvalid (GroupVersion .WithKind ("MachinePool" ).GroupKind (), m .Name , allErrs )
188
+ return apierrors .NewInvalid (clusterv1 . GroupVersion .WithKind ("MachinePool" ).GroupKind (), newObj .Name , allErrs )
162
189
}
0 commit comments