From b2edcc11b54b870d09b6d4a44911eea9b3c38875 Mon Sep 17 00:00:00 2001 From: Matthias Wessendorf Date: Mon, 4 Oct 2021 11:23:02 +0200 Subject: [PATCH 1/2] Revert "[SRVKS-790] Patch subresource to unblock webhooks on 4.9 (#1361) (#1365)" This reverts commit cef96ebcd8a90bee5d346ab26efc7b7d431344e4. --- vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index 522336cba3b..d84878d7c25 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -1158,15 +1158,6 @@ type ManagedFieldsEntry struct { // FieldsV1 holds the first JSON version format as described in the "FieldsV1" type. // +optional FieldsV1 *FieldsV1 `json:"fieldsV1,omitempty" protobuf:"bytes,7,opt,name=fieldsV1"` - - // Subresource is the name of the subresource used to update that object, or - // empty string if the object was updated through the main resource. The - // value of this field is used to distinguish between managers, even if they - // share the same name. For example, a status update will be distinct from a - // regular update using the same manager name. - // Note that the APIVersion field is not related to the Subresource field and - // it always corresponds to the version of the main resource. - Subresource string `json:"subresource,omitempty" protobuf:"bytes,8,opt,name=subresource"` } // ManagedFieldsOperationType is the type of operation which lead to a ManagedFieldsEntry being created. From 4ed1398f9e00c062f5491b6e3b8627c00397bf69 Mon Sep 17 00:00:00 2001 From: knative-automation Date: Fri, 3 Sep 2021 15:35:41 -0400 Subject: [PATCH 2/2] upgrade to latest dependencies (#5707) bumping knative.dev/pkg dd0db4b...953af01: > 953af01 [release-0.24] allow unknown metadata fields (# 2255) > 03e7ca5 Drop redundant pointers and decoders (# 2260) Signed-off-by: Knative Automation --- go.mod | 2 +- go.sum | 3 +- .../pkg/webhook/configmaps/configmaps.go | 4 +- vendor/knative.dev/pkg/webhook/json/decode.go | 131 ++++++++++++++++++ .../pkg/webhook/psbinding/psbinding.go | 4 +- .../defaulting/defaulting.go | 17 +-- .../validation/validation_admit.go | 20 +-- vendor/modules.txt | 3 +- 8 files changed, 149 insertions(+), 35 deletions(-) create mode 100644 vendor/knative.dev/pkg/webhook/json/decode.go diff --git a/go.mod b/go.mod index 031c970e5f8..02da14866a9 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( k8s.io/utils v0.0.0-20201110183641-67b214c5f920 knative.dev/hack v0.0.0-20210622141627-e28525d8d260 knative.dev/hack/schema v0.0.0-20210622141627-e28525d8d260 - knative.dev/pkg v0.0.0-20210622173328-dd0db4b05c80 + knative.dev/pkg v0.0.0-20210902173607-953af0138c75 knative.dev/reconciler-test v0.0.0-20210623134345-88c84739abd9 sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 2f7214ea9d5..2e871020f4f 100644 --- a/go.sum +++ b/go.sum @@ -1090,8 +1090,9 @@ knative.dev/hack v0.0.0-20210622141627-e28525d8d260 h1:f2eMtOubAOc/Q7JlvFPDKXiPl knative.dev/hack v0.0.0-20210622141627-e28525d8d260/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/hack/schema v0.0.0-20210622141627-e28525d8d260 h1:YkMkZ7qdafyRHNIuKttYzEmM1ilKTGyEtPWeVLcLcDE= knative.dev/hack/schema v0.0.0-20210622141627-e28525d8d260/go.mod h1:ffjwmdcrH5vN3mPhO8RrF2KfNnbHeCE2C60A+2cv3U0= -knative.dev/pkg v0.0.0-20210622173328-dd0db4b05c80 h1:GHJ3lglE0/YHfBMMJqluqUNLOmsNXh7s7DBnfrkpRMM= knative.dev/pkg v0.0.0-20210622173328-dd0db4b05c80/go.mod h1:kGegTnbZ+ljFjAE3E1+8wgaH2LMv8qYi+72o3F3cbdc= +knative.dev/pkg v0.0.0-20210902173607-953af0138c75 h1:U9Im5Wp0oKV2ZWP+V9RZSDgRqv4IhfnzObMrgzWdDRQ= +knative.dev/pkg v0.0.0-20210902173607-953af0138c75/go.mod h1:kGegTnbZ+ljFjAE3E1+8wgaH2LMv8qYi+72o3F3cbdc= knative.dev/reconciler-test v0.0.0-20210623134345-88c84739abd9 h1:j+ZLX0o1vBxEpTc7J6QT6sSBblQHpZhJP4vxbFe+C5Y= knative.dev/reconciler-test v0.0.0-20210623134345-88c84739abd9/go.mod h1:4wqv2WyWUC5yhTesRUVwgjv/fHTHny1RYBfdB6tVDok= pgregory.net/rapid v0.3.3 h1:jCjBsY4ln4Atz78QoBWxUEvAHaFyNDQg9+WU62aCn1U= diff --git a/vendor/knative.dev/pkg/webhook/configmaps/configmaps.go b/vendor/knative.dev/pkg/webhook/configmaps/configmaps.go index 4d7ea5bfd35..5a4c4d88887 100644 --- a/vendor/knative.dev/pkg/webhook/configmaps/configmaps.go +++ b/vendor/knative.dev/pkg/webhook/configmaps/configmaps.go @@ -17,7 +17,6 @@ limitations under the License. package configmaps import ( - "bytes" "context" "encoding/json" "errors" @@ -192,8 +191,7 @@ func (ac *reconciler) validate(ctx context.Context, req *admissionv1.AdmissionRe var newObj corev1.ConfigMap if len(newBytes) != 0 { - newDecoder := json.NewDecoder(bytes.NewBuffer(newBytes)) - if err := newDecoder.Decode(&newObj); err != nil { + if err := json.Unmarshal(newBytes, &newObj); err != nil { return fmt.Errorf("cannot decode incoming new object: %w", err) } } diff --git a/vendor/knative.dev/pkg/webhook/json/decode.go b/vendor/knative.dev/pkg/webhook/json/decode.go new file mode 100644 index 00000000000..9e206a10ba3 --- /dev/null +++ b/vendor/knative.dev/pkg/webhook/json/decode.go @@ -0,0 +1,131 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package json + +import ( + "bytes" + "encoding/json" + "io" +) + +var ( + emptyMeta = []byte(`:{}`) + metaPrefix = []byte(`{"metadata"`) + metaSuffix = []byte(`}`) +) + +var ( + // Unmarshal is an alias for json.Unmarshal + Unmarshal = json.Unmarshal + + //Marshal is an alias for json.Marshal + Marshal = json.Marshal +) + +// Decode will parse the json byte array to the target object. When +// unknown fields are _not_ allowed we still accept unknown +// fields in the Object's metadata +// +// See https://github.com/knative/serving/issues/11448 for details +func Decode(bites []byte, target interface{}, disallowUnknownFields bool) error { + if !disallowUnknownFields { + return json.Unmarshal(bites, target) + } + + // If we don't allow unknown fields we skip validating fields in the metadata + // block since that is opaque to us and validated by the API server + start, end, err := findMetadataOffsets(bites) + if err != nil { + return err + } else if start == -1 || end == -1 { + // If for some reason the json does not have metadata continue with normal parsing + dec := json.NewDecoder(bytes.NewReader(bites)) + dec.DisallowUnknownFields() + return dec.Decode(target) + } + + before := bites[:start] + metadata := bites[start:end] + after := bites[end:] + + // Parse everything but skip metadata + dec := json.NewDecoder(io.MultiReader( + bytes.NewReader(before), + bytes.NewReader(emptyMeta), + bytes.NewReader(after), + )) + + dec.DisallowUnknownFields() + if err := dec.Decode(target); err != nil { + return err + } + + // Now we parse just the metadata + dec = json.NewDecoder(io.MultiReader( + bytes.NewReader(metaPrefix), + bytes.NewReader(metadata), + bytes.NewReader(metaSuffix), + )) + + if err := dec.Decode(target); err != nil { + return err + } + + return nil +} + +func findMetadataOffsets(bites []byte) (start, end int64, err error) { + start, end = -1, -1 + level := 0 + + var ( + dec = json.NewDecoder(bytes.NewReader(bites)) + t json.Token + ) + + for { + t, err = dec.Token() + if err == io.EOF { //nolint + break + } + if err != nil { + return + } + + switch v := t.(type) { + case json.Delim: + if v == '{' { + level++ + } else if v == '}' { + level-- + } + case string: + if v == "metadata" && level == 1 { + start = dec.InputOffset() + x := struct{}{} + if err = dec.Decode(&x); err != nil { + return -1, -1, err + } + end = dec.InputOffset() + + // we exit early to stop processing the rest of the object + return + } + } + } + return -1, -1, nil +} diff --git a/vendor/knative.dev/pkg/webhook/psbinding/psbinding.go b/vendor/knative.dev/pkg/webhook/psbinding/psbinding.go index ef16a9d83c2..9fa34d2c0c8 100644 --- a/vendor/knative.dev/pkg/webhook/psbinding/psbinding.go +++ b/vendor/knative.dev/pkg/webhook/psbinding/psbinding.go @@ -17,7 +17,6 @@ limitations under the License. package psbinding import ( - "bytes" "context" "encoding/json" "fmt" @@ -178,8 +177,7 @@ func (ac *Reconciler) Admit(ctx context.Context, request *admissionv1.AdmissionR } orig := &duckv1.WithPod{} - decoder := json.NewDecoder(bytes.NewBuffer(request.Object.Raw)) - if err := decoder.Decode(&orig); err != nil { + if err := json.Unmarshal(request.Object.Raw, orig); err != nil { return webhook.MakeErrorStatus("unable to decode object: %v", err) } diff --git a/vendor/knative.dev/pkg/webhook/resourcesemantics/defaulting/defaulting.go b/vendor/knative.dev/pkg/webhook/resourcesemantics/defaulting/defaulting.go index a5bcc4137d4..504dcaa0661 100644 --- a/vendor/knative.dev/pkg/webhook/resourcesemantics/defaulting/defaulting.go +++ b/vendor/knative.dev/pkg/webhook/resourcesemantics/defaulting/defaulting.go @@ -17,9 +17,7 @@ limitations under the License. package defaulting import ( - "bytes" "context" - "encoding/json" "errors" "fmt" "sort" @@ -47,6 +45,7 @@ import ( "knative.dev/pkg/system" "knative.dev/pkg/webhook" certresources "knative.dev/pkg/webhook/certificates/resources" + "knative.dev/pkg/webhook/json" "knative.dev/pkg/webhook/resourcesemantics" ) @@ -241,21 +240,15 @@ func (ac *reconciler) mutate(ctx context.Context, req *admissionv1.AdmissionRequ if len(newBytes) != 0 { newObj = handler.DeepCopyObject().(resourcesemantics.GenericCRD) - newDecoder := json.NewDecoder(bytes.NewBuffer(newBytes)) - if ac.disallowUnknownFields { - newDecoder.DisallowUnknownFields() - } - if err := newDecoder.Decode(&newObj); err != nil { + err := json.Decode(newBytes, newObj, ac.disallowUnknownFields) + if err != nil { return nil, fmt.Errorf("cannot decode incoming new object: %w", err) } } if len(oldBytes) != 0 { oldObj = handler.DeepCopyObject().(resourcesemantics.GenericCRD) - oldDecoder := json.NewDecoder(bytes.NewBuffer(oldBytes)) - if ac.disallowUnknownFields { - oldDecoder.DisallowUnknownFields() - } - if err := oldDecoder.Decode(&oldObj); err != nil { + err := json.Decode(oldBytes, oldObj, ac.disallowUnknownFields) + if err != nil { return nil, fmt.Errorf("cannot decode incoming old object: %w", err) } } diff --git a/vendor/knative.dev/pkg/webhook/resourcesemantics/validation/validation_admit.go b/vendor/knative.dev/pkg/webhook/resourcesemantics/validation/validation_admit.go index f2d7ad9bf5b..0544d88a6b1 100644 --- a/vendor/knative.dev/pkg/webhook/resourcesemantics/validation/validation_admit.go +++ b/vendor/knative.dev/pkg/webhook/resourcesemantics/validation/validation_admit.go @@ -17,9 +17,7 @@ limitations under the License. package validation import ( - "bytes" "context" - "encoding/json" "errors" "fmt" @@ -31,6 +29,7 @@ import ( kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/logging" "knative.dev/pkg/webhook" + "knative.dev/pkg/webhook/json" "knative.dev/pkg/webhook/resourcesemantics" ) @@ -110,11 +109,8 @@ func (ac *reconciler) decodeRequestAndPrepareContext( var newObj resourcesemantics.GenericCRD if len(newBytes) != 0 { newObj = handler.DeepCopyObject().(resourcesemantics.GenericCRD) - newDecoder := json.NewDecoder(bytes.NewBuffer(newBytes)) - if ac.disallowUnknownFields { - newDecoder.DisallowUnknownFields() - } - if err := newDecoder.Decode(&newObj); err != nil { + err := json.Decode(newBytes, newObj, ac.disallowUnknownFields) + if err != nil { return ctx, nil, fmt.Errorf("cannot decode incoming new object: %w", err) } } @@ -122,11 +118,8 @@ func (ac *reconciler) decodeRequestAndPrepareContext( var oldObj resourcesemantics.GenericCRD if len(oldBytes) != 0 { oldObj = handler.DeepCopyObject().(resourcesemantics.GenericCRD) - oldDecoder := json.NewDecoder(bytes.NewBuffer(oldBytes)) - if ac.disallowUnknownFields { - oldDecoder.DisallowUnknownFields() - } - if err := oldDecoder.Decode(&oldObj); err != nil { + err := json.Decode(oldBytes, oldObj, ac.disallowUnknownFields) + if err != nil { return ctx, nil, fmt.Errorf("cannot decode incoming old object: %w", err) } } @@ -201,8 +194,7 @@ func (ac *reconciler) callback(ctx context.Context, req *admissionv1.AdmissionRe if c, ok := ac.callbacks[gvk]; ok { if _, supported := c.supportedVerbs[req.Operation]; supported { unstruct := &unstructured.Unstructured{} - newDecoder := json.NewDecoder(bytes.NewBuffer(toDecode)) - if err := newDecoder.Decode(&unstruct); err != nil { + if err := json.Unmarshal(toDecode, unstruct); err != nil { return fmt.Errorf("cannot decode incoming new object: %w", err) } diff --git a/vendor/modules.txt b/vendor/modules.txt index ed4b5f5fb79..e11914a324e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1011,7 +1011,7 @@ knative.dev/hack/schema/commands knative.dev/hack/schema/docs knative.dev/hack/schema/registry knative.dev/hack/schema/schema -# knative.dev/pkg v0.0.0-20210622173328-dd0db4b05c80 +# knative.dev/pkg v0.0.0-20210902173607-953af0138c75 ## explicit knative.dev/pkg/apiextensions/storageversion knative.dev/pkg/apiextensions/storageversion/cmd/migrate @@ -1134,6 +1134,7 @@ knative.dev/pkg/webhook knative.dev/pkg/webhook/certificates knative.dev/pkg/webhook/certificates/resources knative.dev/pkg/webhook/configmaps +knative.dev/pkg/webhook/json knative.dev/pkg/webhook/psbinding knative.dev/pkg/webhook/resourcesemantics knative.dev/pkg/webhook/resourcesemantics/conversion