Skip to content

Commit d1ed8dc

Browse files
⚠️ Remove DefaulterRemoveUnknownOrOmitableFields mutating webhook option (again) (#12404)
* Remove DefaulterRemoveUnknownOrOmitableFields mutating webhook option (again) * Address feedback * Address feedback * More feedback
1 parent ffcfa7d commit d1ed8dc

30 files changed

+4145
-78
lines changed

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ linters:
354354
- linters:
355355
- revive
356356
# Ignoring stylistic checks for generated code
357-
path: .*(api|types)\/.*\/conversion.*\.go$
357+
path: .*(api|types|test)\/.*\/conversion.*\.go$
358358
# By convention, receiver names in a method should reflect their identity.
359359
text: 'receiver-naming: receiver name'
360360
- linters:

Makefile

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,14 @@ generate-manifests-core: $(CONTROLLER_GEN) $(KUSTOMIZE) ## Generate manifests e.
307307
paths=./util/test/builder/... \
308308
crd:crdVersions=v1 \
309309
output:crd:dir=./util/test/builder/crd
310+
$(CONTROLLER_GEN) \
311+
paths=./internal/topology/upgrade/test/t1/... \
312+
crd:crdVersions=v1 \
313+
output:crd:dir=./internal/topology/upgrade/test/t1/crd
314+
$(CONTROLLER_GEN) \
315+
paths=./internal/topology/upgrade/test/t2/... \
316+
crd:crdVersions=v1 \
317+
output:crd:dir=./internal/topology/upgrade/test/t2/crd
310318
$(CONTROLLER_GEN) \
311319
paths=./controllers/crdmigrator/test/t1/... \
312320
crd:crdVersions=v1 \
@@ -398,13 +406,14 @@ generate-go-deepcopy-core: $(CONTROLLER_GEN) ## Generate deepcopy go code for co
398406
paths=./api/ipam/... \
399407
paths=./api/runtime/... \
400408
paths=./api/runtime/hooks/... \
409+
paths=./cmd/clusterctl/... \
410+
paths=./controllers/crdmigrator/test/... \
401411
paths=./internal/api/addons/... \
402412
paths=./internal/api/core/... \
403413
paths=./internal/runtime/test/... \
404-
paths=./cmd/clusterctl/... \
414+
paths=./internal/topology/upgrade/test/... \
405415
paths=./util/test/builder/... \
406-
paths=./util/deprecated/v1beta1/test/builder/... \
407-
paths=./controllers/crdmigrator/test/...
416+
paths=./util/deprecated/v1beta1/test/builder/...
408417

409418
.PHONY: generate-go-deepcopy-kubeadm-bootstrap
410419
generate-go-deepcopy-kubeadm-bootstrap: $(CONTROLLER_GEN) ## Generate deepcopy go code for kubeadm bootstrap
@@ -454,13 +463,14 @@ generate-go-conversions-core: ## Run all generate-go-conversions-core-* targets
454463

455464
.PHONY: generate-go-conversions-core-api
456465
generate-go-conversions-core-api: $(CONVERSION_GEN) ## Generate conversions go code for core api
457-
$(MAKE) clean-generated-conversions SRC_DIRS="./api/core/v1beta1,./internal/api/core/v1alpha3,./internal/api/core/v1alpha4"
466+
$(MAKE) clean-generated-conversions SRC_DIRS="./api/core/v1beta1,./internal/api/core/v1alpha3,./internal/api/core/v1alpha4,./internal/topology/upgrade/test/t2/v1beta1"
458467
$(CONVERSION_GEN) \
459468
--output-file=zz_generated.conversion.go \
460469
--go-header-file=./hack/boilerplate/boilerplate.generatego.txt \
461470
./internal/api/core/v1alpha3 \
462471
./internal/api/core/v1alpha4 \
463-
./api/core/v1beta1
472+
./api/core/v1beta1 \
473+
./internal/topology/upgrade/test/t2/v1beta1
464474

465475
.PHONY: generate-go-conversions-addons-api
466476
generate-go-conversions-addons-api: $(CONVERSION_GEN) ## Generate conversions go code for addons api

bootstrap/kubeadm/internal/webhooks/kubeadmconfig.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
func (webhook *KubeadmConfig) SetupWebhookWithManager(mgr ctrl.Manager) error {
3434
return ctrl.NewWebhookManagedBy(mgr).
3535
For(&bootstrapv1.KubeadmConfig{}).
36-
WithDefaulter(webhook, admission.DefaulterRemoveUnknownOrOmitableFields).
36+
WithDefaulter(webhook).
3737
WithValidator(webhook).
3838
Complete()
3939
}

bootstrap/kubeadm/internal/webhooks/kubeadmconfigtemplate.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"fmt"
2222

2323
apierrors "k8s.io/apimachinery/pkg/api/errors"
24-
runtime "k8s.io/apimachinery/pkg/runtime"
24+
"k8s.io/apimachinery/pkg/runtime"
2525
"k8s.io/apimachinery/pkg/util/validation/field"
2626
ctrl "sigs.k8s.io/controller-runtime"
2727
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
@@ -32,7 +32,7 @@ import (
3232
func (webhook *KubeadmConfigTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
3333
return ctrl.NewWebhookManagedBy(mgr).
3434
For(&bootstrapv1.KubeadmConfigTemplate{}).
35-
WithDefaulter(webhook, admission.DefaulterRemoveUnknownOrOmitableFields).
35+
WithDefaulter(webhook).
3636
WithValidator(webhook).
3737
Complete()
3838
}

controllers/crdmigrator/crd_migrator_test.go

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package crdmigrator
1818

1919
import (
2020
"context"
21-
"fmt"
2221
"path"
2322
"path/filepath"
2423
goruntime "runtime"
@@ -29,7 +28,6 @@ import (
2928
. "github.com/onsi/gomega"
3029
corev1 "k8s.io/api/core/v1"
3130
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
32-
apierrors "k8s.io/apimachinery/pkg/api/errors"
3331
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3432
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3533
"k8s.io/apimachinery/pkg/labels"
@@ -38,14 +36,12 @@ import (
3836
"k8s.io/apimachinery/pkg/selection"
3937
"k8s.io/apimachinery/pkg/util/sets"
4038
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
41-
"k8s.io/client-go/util/retry"
4239
"k8s.io/utils/ptr"
4340
ctrl "sigs.k8s.io/controller-runtime"
4441
"sigs.k8s.io/controller-runtime/pkg/cache"
4542
"sigs.k8s.io/controller-runtime/pkg/client"
4643
"sigs.k8s.io/controller-runtime/pkg/config"
4744
"sigs.k8s.io/controller-runtime/pkg/controller"
48-
"sigs.k8s.io/controller-runtime/pkg/envtest"
4945
"sigs.k8s.io/controller-runtime/pkg/manager"
5046
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
5147
"sigs.k8s.io/controller-runtime/pkg/webhook"
@@ -59,6 +55,7 @@ import (
5955
)
6056

6157
func TestReconcile(t *testing.T) {
58+
_, filename, _, _ := goruntime.Caller(0) //nolint:dogsled
6259
crdName := "testclusters.test.cluster.x-k8s.io"
6360
crdObjectKey := client.ObjectKey{Name: crdName}
6461

@@ -170,7 +167,7 @@ func TestReconcile(t *testing.T) {
170167
}()
171168

172169
t.Logf("T1: Install CRDs")
173-
g.Expect(installCRDs(ctx, env.GetClient(), "test/t1/crd")).To(Succeed())
170+
g.Expect(env.ApplyCRDs(ctx, filepath.Join(path.Dir(filename), "test", "t1", "crd"))).To(Succeed())
174171
validateStoredVersions(t, g, crdObjectKey, "v1beta1")
175172

176173
t.Logf("T1: Start Manager")
@@ -211,7 +208,7 @@ func TestReconcile(t *testing.T) {
211208
stopManager(cancelManager, managerStopped)
212209

213210
t.Logf("T2: Install CRDs")
214-
g.Expect(installCRDs(ctx, env.GetClient(), "test/t2/crd")).To(Succeed())
211+
g.Expect(env.ApplyCRDs(ctx, filepath.Join(path.Dir(filename), "test", "t2", "crd"))).To(Succeed())
215212
validateStoredVersions(t, g, crdObjectKey, "v1beta1", "v1beta2")
216213

217214
t.Logf("T2: Start Manager")
@@ -245,7 +242,7 @@ func TestReconcile(t *testing.T) {
245242
stopManager(cancelManager, managerStopped)
246243

247244
t.Logf("T3: Install CRDs")
248-
g.Expect(installCRDs(ctx, env.GetClient(), "test/t3/crd")).To(Succeed())
245+
g.Expect(env.ApplyCRDs(ctx, filepath.Join(path.Dir(filename), "test", "t3", "crd"))).To(Succeed())
249246
// Stored versions didn't change.
250247
if skipCRDMigrationPhases.Has(StorageVersionMigrationPhase) {
251248
validateStoredVersions(t, g, crdObjectKey, "v1beta1", "v1beta2")
@@ -284,7 +281,7 @@ func TestReconcile(t *testing.T) {
284281
stopManager(cancelManager, managerStopped)
285282

286283
t.Logf("T4: Install CRDs")
287-
err = installCRDs(ctx, env.GetClient(), "test/t4/crd")
284+
err = env.ApplyCRDs(ctx, filepath.Join(path.Dir(filename), "test", "t4", "crd"))
288285
if skipCRDMigrationPhases.Has(StorageVersionMigrationPhase) {
289286
// If storage version migration was skipped before, we now cannot deploy CRDs that remove v1beta1.
290287
g.Expect(err).To(HaveOccurred())
@@ -489,65 +486,6 @@ func stopManager(cancelManager context.CancelFunc, managerStopped chan struct{})
489486
<-managerStopped
490487
}
491488

492-
func installCRDs(ctx context.Context, c client.Client, crdPath string) error {
493-
// Get the root of the current file to use in CRD paths.
494-
_, filename, _, _ := goruntime.Caller(0) //nolint:dogsled
495-
496-
installOpts := envtest.CRDInstallOptions{
497-
Scheme: env.GetScheme(),
498-
MaxTime: 10 * time.Second,
499-
PollInterval: 100 * time.Millisecond,
500-
Paths: []string{
501-
filepath.Join(path.Dir(filename), "..", "..", "controllers", "crdmigrator", crdPath),
502-
},
503-
ErrorIfPathMissing: true,
504-
}
505-
506-
// Read the CRD YAMLs into options.CRDs.
507-
if err := envtest.ReadCRDFiles(&installOpts); err != nil {
508-
return fmt.Errorf("unable to read CRD files: %w", err)
509-
}
510-
511-
// Apply the CRDs.
512-
if err := applyCRDs(ctx, c, installOpts.CRDs); err != nil {
513-
return fmt.Errorf("unable to create CRD instances: %w", err)
514-
}
515-
516-
// Wait for the CRDs to appear in discovery.
517-
if err := envtest.WaitForCRDs(env.GetConfig(), installOpts.CRDs, installOpts); err != nil {
518-
return fmt.Errorf("something went wrong waiting for CRDs to appear as API resources: %w", err)
519-
}
520-
521-
return nil
522-
}
523-
524-
func applyCRDs(ctx context.Context, c client.Client, crds []*apiextensionsv1.CustomResourceDefinition) error {
525-
for _, crd := range crds {
526-
existingCrd := crd.DeepCopy()
527-
err := c.Get(ctx, client.ObjectKey{Name: crd.GetName()}, existingCrd)
528-
switch {
529-
case apierrors.IsNotFound(err):
530-
if err := c.Create(ctx, crd); err != nil {
531-
return fmt.Errorf("unable to create CRD %s: %w", crd.GetName(), err)
532-
}
533-
case err != nil:
534-
return fmt.Errorf("unable to get CRD %s to check if it exists: %w", crd.GetName(), err)
535-
default:
536-
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
537-
if err := c.Get(ctx, client.ObjectKey{Name: crd.GetName()}, existingCrd); err != nil {
538-
return err
539-
}
540-
// Note: Intentionally only overwriting spec and thus preserving metadata labels, annotations, etc.
541-
existingCrd.Spec = crd.Spec
542-
return c.Update(ctx, existingCrd)
543-
}); err != nil {
544-
return fmt.Errorf("unable to update CRD %s: %w", crd.GetName(), err)
545-
}
546-
}
547-
}
548-
return nil
549-
}
550-
551489
type noopWebhookServer struct {
552490
webhook.Server
553491
}

controlplane/kubeadm/internal/webhooks/kubeadm_control_plane.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import (
4646
func (webhook *KubeadmControlPlane) SetupWebhookWithManager(mgr ctrl.Manager) error {
4747
return ctrl.NewWebhookManagedBy(mgr).
4848
For(&controlplanev1.KubeadmControlPlane{}).
49-
WithDefaulter(webhook, admission.DefaulterRemoveUnknownOrOmitableFields).
49+
WithDefaulter(webhook).
5050
WithValidator(webhook).
5151
Complete()
5252
}

controlplane/kubeadm/internal/webhooks/kubeadmcontrolplanetemplate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import (
3636
func (webhook *KubeadmControlPlaneTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
3737
return ctrl.NewWebhookManagedBy(mgr).
3838
For(&controlplanev1.KubeadmControlPlaneTemplate{}).
39-
WithDefaulter(webhook, admission.DefaulterRemoveUnknownOrOmitableFields).
39+
WithDefaulter(webhook).
4040
WithValidator(webhook).
4141
Complete()
4242
}

internal/test/envtest/environment.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"k8s.io/apimachinery/pkg/util/wait"
4545
"k8s.io/client-go/kubernetes/scheme"
4646
"k8s.io/client-go/rest"
47+
"k8s.io/client-go/util/retry"
4748
"k8s.io/component-base/logs"
4849
logsv1 "k8s.io/component-base/logs/api/v1"
4950
"k8s.io/klog/v2"
@@ -618,3 +619,60 @@ func verifyPanicMetrics() error {
618619

619620
return nil
620621
}
622+
623+
// ApplyCRDs allows you to add or replace CRDs after test env has been started.
624+
func (e *Environment) ApplyCRDs(ctx context.Context, crdPath string) error {
625+
installOpts := envtest.CRDInstallOptions{
626+
Scheme: e.GetScheme(),
627+
MaxTime: 10 * time.Second,
628+
PollInterval: 100 * time.Millisecond,
629+
Paths: []string{
630+
crdPath,
631+
},
632+
ErrorIfPathMissing: true,
633+
}
634+
635+
// Read the CRD YAMLs into options.CRDs.
636+
if err := envtest.ReadCRDFiles(&installOpts); err != nil {
637+
return fmt.Errorf("unable to read CRD files: %w", err)
638+
}
639+
640+
// Apply the CRDs.
641+
if err := applyCRDs(ctx, e.GetClient(), installOpts.CRDs); err != nil {
642+
return fmt.Errorf("unable to create CRD instances: %w", err)
643+
}
644+
645+
// Wait for the CRDs to appear in discovery.
646+
if err := envtest.WaitForCRDs(e.GetConfig(), installOpts.CRDs, installOpts); err != nil {
647+
return fmt.Errorf("something went wrong waiting for CRDs to appear as API resources: %w", err)
648+
}
649+
650+
return nil
651+
}
652+
653+
func applyCRDs(ctx context.Context, c client.Client, crds []*apiextensionsv1.CustomResourceDefinition) error {
654+
for _, crd := range crds {
655+
existingCrd := crd.DeepCopy()
656+
err := c.Get(ctx, client.ObjectKey{Name: crd.GetName()}, existingCrd)
657+
switch {
658+
case apierrors.IsNotFound(err):
659+
if err := c.Create(ctx, crd); err != nil {
660+
return fmt.Errorf("unable to create CRD %s: %w", crd.GetName(), err)
661+
}
662+
case err != nil:
663+
return fmt.Errorf("unable to get CRD %s to check if it exists: %w", crd.GetName(), err)
664+
default:
665+
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
666+
if err := c.Get(ctx, client.ObjectKey{Name: crd.GetName()}, existingCrd); err != nil {
667+
return err
668+
}
669+
// Note: Intentionally only overwriting spec and thus preserving metadata labels, annotations, etc.
670+
existingCrd.Spec = crd.Spec
671+
return c.Update(ctx, existingCrd)
672+
}); err != nil {
673+
return fmt.Errorf("unable to update CRD %s: %w", crd.GetName(), err)
674+
}
675+
}
676+
}
677+
return nil
678+
}

0 commit comments

Comments
 (0)