diff --git a/pkg/webhook/handlers/validation.go b/pkg/webhook/handlers/validation.go index 9406605e4..dce77bcbd 100644 --- a/pkg/webhook/handlers/validation.go +++ b/pkg/webhook/handlers/validation.go @@ -74,17 +74,26 @@ func (r *registryBackedValidator) Validate(admissionSpec *admissionv1beta1.Admis } } - requestGVK := schema.GroupVersionKind{ - Group: admissionSpec.RequestKind.Group, - Version: admissionSpec.RequestKind.Version, - Kind: admissionSpec.RequestKind.Kind, + // RequestKind field is only present from Kubernetes 1.15 onwards, so + // use the regular 'kind' if RequestKind is not present + gvk := schema.GroupVersionKind{ + Group: admissionSpec.Kind.Group, + Version: admissionSpec.Kind.Version, + Kind: admissionSpec.Kind.Kind, + } + if admissionSpec.RequestKind != nil { + gvk = schema.GroupVersionKind{ + Group: admissionSpec.RequestKind.Group, + Version: admissionSpec.RequestKind.Version, + Kind: admissionSpec.RequestKind.Kind, + } } errs := field.ErrorList{} // perform validation on new version of resource - errs = append(errs, r.registry.Validate(obj, requestGVK)...) + errs = append(errs, r.registry.Validate(obj, gvk)...) if oldObj != nil { // perform update validation on resource - errs = append(errs, r.registry.ValidateUpdate(oldObj, obj, requestGVK)...) + errs = append(errs, r.registry.ValidateUpdate(oldObj, obj, gvk)...) } // return with allowed = false if any errors occurred if err := errs.ToAggregate(); err != nil { diff --git a/pkg/webhook/handlers/validation_test.go b/pkg/webhook/handlers/validation_test.go index 16d5a1d99..cf512a743 100644 --- a/pkg/webhook/handlers/validation_test.go +++ b/pkg/webhook/handlers/validation_test.go @@ -247,6 +247,34 @@ func TestRegistryBackedValidator(t *testing.T) { Allowed: true, }, }, + "should validate in the current APIVersion if RequestKind is not set (for Kubernetes <1.15 support)": { + inputRequest: admissionv1beta1.AdmissionRequest{ + UID: types.UID("abc"), + Kind: *testTypeGVKV2, + Object: runtime.RawExtension{ + Raw: []byte(fmt.Sprintf(` +{ + "apiVersion": "testgroup.testing.cert-manager.io/v2", + "kind": "TestType", + "metadata": { + "name": "testing", + "namespace": "abc", + "creationTimestamp": null + }, + "testField": "%s" +} +`, v2.DisallowedTestFieldValue)), + }, + }, + expectedResponse: admissionv1beta1.AdmissionResponse{ + UID: types.UID("abc"), + Allowed: false, + Result: &metav1.Status{ + Status: metav1.StatusFailure, Code: http.StatusNotAcceptable, Reason: metav1.StatusReasonNotAcceptable, + Message: "testField: Invalid value: \"not-allowed-in-v2\": value not allowed", + }, + }, + }, } for n, test := range tests {