@@ -19,17 +19,14 @@ package v1alpha4
19
19
import (
20
20
"encoding/json"
21
21
"fmt"
22
- "strings"
23
22
24
23
"github.com/blang/semver"
25
24
"github.com/coredns/corefile-migration/migration"
26
25
jsonpatch "github.com/evanphx/json-patch"
27
26
"github.com/pkg/errors"
28
27
apierrors "k8s.io/apimachinery/pkg/api/errors"
29
28
"k8s.io/apimachinery/pkg/runtime"
30
- "k8s.io/apimachinery/pkg/util/intstr"
31
29
"k8s.io/apimachinery/pkg/util/validation/field"
32
- "sigs.k8s.io/cluster-api/util/container"
33
30
"sigs.k8s.io/cluster-api/util/version"
34
31
ctrl "sigs.k8s.io/controller-runtime"
35
32
"sigs.k8s.io/controller-runtime/pkg/webhook"
@@ -49,47 +46,17 @@ var _ webhook.Validator = &KubeadmControlPlane{}
49
46
50
47
// Default implements webhook.Defaulter so a webhook will be registered for the type.
51
48
func (in * KubeadmControlPlane ) Default () {
52
- if in .Spec .Replicas == nil {
53
- replicas := int32 (1 )
54
- in .Spec .Replicas = & replicas
55
- }
56
-
57
- if in .Spec .MachineTemplate .InfrastructureRef .Namespace == "" {
58
- in .Spec .MachineTemplate .InfrastructureRef .Namespace = in .Namespace
59
- }
60
-
61
- if ! strings .HasPrefix (in .Spec .Version , "v" ) {
62
- in .Spec .Version = "v" + in .Spec .Version
63
- }
64
-
65
- ios1 := intstr .FromInt (1 )
66
-
67
- if in .Spec .RolloutStrategy == nil {
68
- in .Spec .RolloutStrategy = & RolloutStrategy {}
69
- }
70
-
71
- // Enforce RollingUpdate strategy and default MaxSurge if not set.
72
- if in .Spec .RolloutStrategy != nil {
73
- if len (in .Spec .RolloutStrategy .Type ) == 0 {
74
- in .Spec .RolloutStrategy .Type = RollingUpdateStrategyType
75
- }
76
- if in .Spec .RolloutStrategy .Type == RollingUpdateStrategyType {
77
- if in .Spec .RolloutStrategy .RollingUpdate == nil {
78
- in .Spec .RolloutStrategy .RollingUpdate = & RollingUpdate {}
79
- }
80
- in .Spec .RolloutStrategy .RollingUpdate .MaxSurge = intstr .ValueOrDefault (in .Spec .RolloutStrategy .RollingUpdate .MaxSurge , ios1 )
81
- }
82
- }
49
+ in .Spec .setDefaults (in .Namespace )
83
50
}
84
51
85
52
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
86
53
func (in * KubeadmControlPlane ) ValidateCreate () error {
87
- allErrs := in .validateCommon ()
88
- allErrs = append (allErrs , in .validateEtcd (nil )... )
54
+ spec := in .Spec
55
+ allErrs := spec .validate (in .Namespace )
56
+ allErrs = append (allErrs , spec .validateEtcd (nil )... )
89
57
if len (allErrs ) > 0 {
90
58
return apierrors .NewInvalid (GroupVersion .WithKind ("KubeadmControlPlane" ).GroupKind (), in .Name , allErrs )
91
59
}
92
-
93
60
return nil
94
61
}
95
62
@@ -141,7 +108,7 @@ func (in *KubeadmControlPlane) ValidateUpdate(old runtime.Object) error {
141
108
{spec , "rolloutStrategy" , "*" },
142
109
}
143
110
144
- allErrs := in .validateCommon ( )
111
+ allErrs := in .Spec . validate ( in . Namespace )
145
112
146
113
prev := old .(* KubeadmControlPlane )
147
114
@@ -180,7 +147,7 @@ func (in *KubeadmControlPlane) ValidateUpdate(old runtime.Object) error {
180
147
}
181
148
182
149
allErrs = append (allErrs , in .validateVersion (prev .Spec .Version )... )
183
- allErrs = append (allErrs , in .validateEtcd (prev )... )
150
+ allErrs = append (allErrs , in .Spec . validateEtcd (& prev . Spec )... )
184
151
allErrs = append (allErrs , in .validateCoreDNSVersion (prev )... )
185
152
186
153
if len (allErrs ) > 0 {
@@ -236,139 +203,6 @@ func paths(path []string, diff map[string]interface{}) [][]string {
236
203
return allPaths
237
204
}
238
205
239
- func (in * KubeadmControlPlane ) validateCommon () (allErrs field.ErrorList ) {
240
- if in .Spec .Replicas == nil {
241
- allErrs = append (
242
- allErrs ,
243
- field .Required (
244
- field .NewPath ("spec" , "replicas" ),
245
- "is required" ,
246
- ),
247
- )
248
- } else if * in .Spec .Replicas <= 0 {
249
- // The use of the scale subresource should provide a guarantee that negative values
250
- // should not be accepted for this field, but since we have to validate that Replicas != 0
251
- // it doesn't hurt to also additionally validate for negative numbers here as well.
252
- allErrs = append (
253
- allErrs ,
254
- field .Forbidden (
255
- field .NewPath ("spec" , "replicas" ),
256
- "cannot be less than or equal to 0" ,
257
- ),
258
- )
259
- }
260
-
261
- externalEtcd := false
262
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration != nil {
263
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .External != nil {
264
- externalEtcd = true
265
- }
266
- }
267
-
268
- if ! externalEtcd {
269
- if in .Spec .Replicas != nil && * in .Spec .Replicas % 2 == 0 {
270
- allErrs = append (
271
- allErrs ,
272
- field .Forbidden (
273
- field .NewPath ("spec" , "replicas" ),
274
- "cannot be an even number when using managed etcd" ,
275
- ),
276
- )
277
- }
278
- }
279
-
280
- if in .Spec .MachineTemplate .InfrastructureRef .APIVersion == "" {
281
- allErrs = append (
282
- allErrs ,
283
- field .Invalid (
284
- field .NewPath ("spec" , "machineTemplate" , "infrastructure" , "apiVersion" ),
285
- in .Spec .MachineTemplate .InfrastructureRef .APIVersion ,
286
- "cannot be empty" ,
287
- ),
288
- )
289
- }
290
- if in .Spec .MachineTemplate .InfrastructureRef .Kind == "" {
291
- allErrs = append (
292
- allErrs ,
293
- field .Invalid (
294
- field .NewPath ("spec" , "machineTemplate" , "infrastructure" , "kind" ),
295
- in .Spec .MachineTemplate .InfrastructureRef .Kind ,
296
- "cannot be empty" ,
297
- ),
298
- )
299
- }
300
- if in .Spec .MachineTemplate .InfrastructureRef .Namespace != in .Namespace {
301
- allErrs = append (
302
- allErrs ,
303
- field .Invalid (
304
- field .NewPath ("spec" , "machineTemplate" , "infrastructure" , "namespace" ),
305
- in .Spec .MachineTemplate .InfrastructureRef .Namespace ,
306
- "must match metadata.namespace" ,
307
- ),
308
- )
309
- }
310
-
311
- if ! version .KubeSemver .MatchString (in .Spec .Version ) {
312
- allErrs = append (allErrs , field .Invalid (field .NewPath ("spec" , "version" ), in .Spec .Version , "must be a valid semantic version" ))
313
- }
314
-
315
- if in .Spec .RolloutStrategy != nil {
316
- if in .Spec .RolloutStrategy .Type != RollingUpdateStrategyType {
317
- allErrs = append (
318
- allErrs ,
319
- field .Required (
320
- field .NewPath ("spec" , "rolloutStrategy" , "type" ),
321
- "only RollingUpdateStrategyType is supported" ,
322
- ),
323
- )
324
- }
325
-
326
- ios1 := intstr .FromInt (1 )
327
- ios0 := intstr .FromInt (0 )
328
-
329
- if * in .Spec .RolloutStrategy .RollingUpdate .MaxSurge == ios0 && * in .Spec .Replicas < int32 (3 ) {
330
- allErrs = append (
331
- allErrs ,
332
- field .Required (
333
- field .NewPath ("spec" , "rolloutStrategy" , "rollingUpdate" ),
334
- "when KubeadmControlPlane is configured to scale-in, replica count needs to be at least 3" ,
335
- ),
336
- )
337
- }
338
-
339
- if * in .Spec .RolloutStrategy .RollingUpdate .MaxSurge != ios1 && * in .Spec .RolloutStrategy .RollingUpdate .MaxSurge != ios0 {
340
- allErrs = append (
341
- allErrs ,
342
- field .Required (
343
- field .NewPath ("spec" , "rolloutStrategy" , "rollingUpdate" , "maxSurge" ),
344
- "value must be 1 or 0" ,
345
- ),
346
- )
347
- }
348
- }
349
-
350
- allErrs = append (allErrs , in .validateCoreDNSImage ()... )
351
-
352
- return allErrs
353
- }
354
-
355
- func (in * KubeadmControlPlane ) validateCoreDNSImage () (allErrs field.ErrorList ) {
356
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration == nil {
357
- return allErrs
358
- }
359
- // TODO: Remove when kubeadm types include OpenAPI validation
360
- if ! container .ImageTagIsValid (in .Spec .KubeadmConfigSpec .ClusterConfiguration .DNS .ImageTag ) {
361
- allErrs = append (
362
- allErrs ,
363
- field .Forbidden (
364
- field .NewPath ("spec" , "kubeadmConfigSpec" , "clusterConfiguration" , "dns" , "imageTag" ),
365
- fmt .Sprintf ("tag %s is invalid" , in .Spec .KubeadmConfigSpec .ClusterConfiguration .DNS .ImageTag ),
366
- ),
367
- )
368
- }
369
- return allErrs
370
- }
371
-
372
206
func (in * KubeadmControlPlane ) validateCoreDNSVersion (prev * KubeadmControlPlane ) (allErrs field.ErrorList ) {
373
207
if in .Spec .KubeadmConfigSpec .ClusterConfiguration == nil || prev .Spec .KubeadmConfigSpec .ClusterConfiguration == nil {
374
208
return allErrs
@@ -415,58 +249,6 @@ func (in *KubeadmControlPlane) validateCoreDNSVersion(prev *KubeadmControlPlane)
415
249
return allErrs
416
250
}
417
251
418
- func (in * KubeadmControlPlane ) validateEtcd (prev * KubeadmControlPlane ) (allErrs field.ErrorList ) {
419
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration == nil {
420
- return allErrs
421
- }
422
-
423
- // TODO: Remove when kubeadm types include OpenAPI validation
424
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .Local != nil && ! container .ImageTagIsValid (in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .Local .ImageTag ) {
425
- allErrs = append (
426
- allErrs ,
427
- field .Forbidden (
428
- field .NewPath ("spec" , "kubeadmConfigSpec" , "clusterConfiguration" , "etcd" , "local" , "imageTag" ),
429
- fmt .Sprintf ("tag %s is invalid" , in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .Local .ImageTag ),
430
- ),
431
- )
432
- }
433
-
434
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .Local != nil && in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .External != nil {
435
- allErrs = append (
436
- allErrs ,
437
- field .Forbidden (
438
- field .NewPath ("spec" , "kubeadmConfigSpec" , "clusterConfiguration" , "etcd" , "local" ),
439
- "cannot have both external and local etcd" ,
440
- ),
441
- )
442
- }
443
-
444
- // update validations
445
- if prev != nil && prev .Spec .KubeadmConfigSpec .ClusterConfiguration != nil {
446
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .External != nil && prev .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .Local != nil {
447
- allErrs = append (
448
- allErrs ,
449
- field .Forbidden (
450
- field .NewPath ("spec" , "kubeadmConfigSpec" , "clusterConfiguration" , "etcd" , "external" ),
451
- "cannot change between external and local etcd" ,
452
- ),
453
- )
454
- }
455
-
456
- if in .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .Local != nil && prev .Spec .KubeadmConfigSpec .ClusterConfiguration .Etcd .External != nil {
457
- allErrs = append (
458
- allErrs ,
459
- field .Forbidden (
460
- field .NewPath ("spec" , "kubeadmConfigSpec" , "clusterConfiguration" , "etcd" , "local" ),
461
- "cannot change between external and local etcd" ,
462
- ),
463
- )
464
- }
465
- }
466
-
467
- return allErrs
468
- }
469
-
470
252
func (in * KubeadmControlPlane ) validateVersion (previousVersion string ) (allErrs field.ErrorList ) {
471
253
fromVersion , err := version .ParseMajorMinorPatch (previousVersion )
472
254
if err != nil {
0 commit comments