From bf0a33d1de4cff08f527c29ab235ea85def3e197 Mon Sep 17 00:00:00 2001 From: Lee Verberne Date: Thu, 10 Sep 2020 17:24:52 +0200 Subject: [PATCH] Use EphemeralContainers for storage validation When updating ephemeral containers, convert Pod to EphemeralContainers in storage validation. This resolves a bug where admission webhook validation fails for ephemeral container updates because the webhook client cannot perform the conversion. Also enable the EphemeralContainers feature gate for the admission control integration test, which would have caught this bug. --- pkg/registry/core/pod/storage/storage.go | 15 ++++++++++++++- .../apiserver/admissionwebhook/admission_test.go | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pkg/registry/core/pod/storage/storage.go b/pkg/registry/core/pod/storage/storage.go index 27b63120574..15ef375b458 100644 --- a/pkg/registry/core/pod/storage/storage.go +++ b/pkg/registry/core/pod/storage/storage.go @@ -346,13 +346,26 @@ func (r *EphemeralContainersREST) Update(ctx context.Context, name string, objIn return newPod, nil }) - obj, _, err = r.store.Update(ctx, name, updatedPodInfo, createValidation, updateValidation, false, options) + // Validation should be passed the API kind (EphemeralContainers) rather than the storage kind. + obj, _, err = r.store.Update(ctx, name, updatedPodInfo, toEphemeralContainersCreateValidation(createValidation), toEphemeralContainersUpdateValidation(updateValidation), false, options) if err != nil { return nil, false, err } return ephemeralContainersInPod(obj.(*api.Pod)), false, err } +func toEphemeralContainersCreateValidation(f rest.ValidateObjectFunc) rest.ValidateObjectFunc { + return func(ctx context.Context, obj runtime.Object) error { + return f(ctx, ephemeralContainersInPod(obj.(*api.Pod))) + } +} + +func toEphemeralContainersUpdateValidation(f rest.ValidateObjectUpdateFunc) rest.ValidateObjectUpdateFunc { + return func(ctx context.Context, obj, old runtime.Object) error { + return f(ctx, ephemeralContainersInPod(obj.(*api.Pod)), ephemeralContainersInPod(old.(*api.Pod))) + } +} + // Extract the list of Ephemeral Containers from a Pod func ephemeralContainersInPod(pod *api.Pod) *api.EphemeralContainers { ephemeralContainers := pod.Spec.EphemeralContainers diff --git a/test/integration/apiserver/admissionwebhook/admission_test.go b/test/integration/apiserver/admissionwebhook/admission_test.go index f73a9dc9984..7fa050f64cd 100644 --- a/test/integration/apiserver/admissionwebhook/admission_test.go +++ b/test/integration/apiserver/admissionwebhook/admission_test.go @@ -480,6 +480,8 @@ func testWebhookAdmission(t *testing.T, watchCache bool) { "--disable-admission-plugins=ServiceAccount,StorageObjectInUseProtection", // force enable all resources so we can check storage. "--runtime-config=api/all=true", + // enable feature-gates that protect resources to check their storage, too. + "--feature-gates=EphemeralContainers=true", }, etcdConfig) defer server.TearDownFn()