diff --git a/go.mod b/go.mod index d577de656..5cdb2e865 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,9 @@ require ( k8s.io/api v0.20.7 k8s.io/apimachinery v0.20.7 k8s.io/client-go v0.20.7 - knative.dev/eventing v0.24.0 + knative.dev/eventing v0.24.2 knative.dev/hack v0.0.0-20210622141627-e28525d8d260 - knative.dev/pkg v0.0.0-20210622173328-dd0db4b05c80 + knative.dev/pkg v0.0.0-20210902173607-953af0138c75 knative.dev/serving v0.24.0 ) diff --git a/go.sum b/go.sum index 563766c43..8265ff044 100644 --- a/go.sum +++ b/go.sum @@ -1541,15 +1541,16 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ= k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= knative.dev/caching v0.0.0-20210622183028-95f67e075071/go.mod h1:9gwZcCBtmo9pi1oTgchXcdMNAXAYWklwDmO9uhDsIJE= -knative.dev/eventing v0.24.0 h1:CoaQwZBizxZyOFJUvFcyb7vYSvpYBmfb4IYRNWUdTPE= -knative.dev/eventing v0.24.0/go.mod h1:9xo0SWkIfpXrx0lvGQO7MUlPF8cu+QCMd2gGxj6wxrU= +knative.dev/eventing v0.24.2 h1:yW3pOUKm/PixfH/lGsDVX9UdHahR2uzMoewV4PkRbK8= +knative.dev/eventing v0.24.2/go.mod h1:9xo0SWkIfpXrx0lvGQO7MUlPF8cu+QCMd2gGxj6wxrU= knative.dev/hack v0.0.0-20210622141627-e28525d8d260 h1:f2eMtOubAOc/Q7JlvFPDKXiPlJVK+VpX2Cot8hRzCgQ= knative.dev/hack v0.0.0-20210622141627-e28525d8d260/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/hack/schema v0.0.0-20210622141627-e28525d8d260/go.mod h1:ffjwmdcrH5vN3mPhO8RrF2KfNnbHeCE2C60A+2cv3U0= knative.dev/networking v0.0.0-20210622182128-53f45d6d2cfa h1:MprAGBX3eRaBZFRXC3ZjsnhnjttfprRVXdxmTeEzC2o= knative.dev/networking v0.0.0-20210622182128-53f45d6d2cfa/go.mod h1:vwPACNE712tyoEG4fjyUIgfL4xkbXFugx8bxW+QrKn4= -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/go.mod h1:4wqv2WyWUC5yhTesRUVwgjv/fHTHny1RYBfdB6tVDok= knative.dev/serving v0.24.0 h1:MZIXR0r2FCXlTuQQXwLuM9+tV6pl2K6YUtK6tEtDB58= knative.dev/serving v0.24.0/go.mod h1:l/dhsWs+Y8PAssBxaS/hN4HRQQGy4zxfVHD1xYjl3ns= diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1/ping_validation.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1/ping_validation.go index d86489747..c60f49a4f 100644 --- a/vendor/knative.dev/eventing/pkg/apis/sources/v1/ping_validation.go +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1/ping_validation.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "strings" @@ -37,8 +38,10 @@ func (c *PingSource) Validate(ctx context.Context) *apis.FieldError { func (cs *PingSourceSpec) Validate(ctx context.Context) *apis.FieldError { var errs *apis.FieldError - schedule := cs.Schedule + + errs = validateDescriptor(schedule) + if cs.Timezone != "" { schedule = "CRON_TZ=" + cs.Timezone + " " + schedule } @@ -98,3 +101,10 @@ func validateJSON(str string) error { var objmap map[string]interface{} return json.Unmarshal([]byte(str), &objmap) } + +func validateDescriptor(spec string) *apis.FieldError { + if strings.Contains(spec, "@every") { + return apis.ErrInvalidValue(errors.New("unsupported descriptor @every"), "schedule") + } + return nil +} diff --git a/vendor/knative.dev/eventing/pkg/apis/sources/v1beta2/ping_validation.go b/vendor/knative.dev/eventing/pkg/apis/sources/v1beta2/ping_validation.go index 5bbd2d7f0..c8fa47a60 100644 --- a/vendor/knative.dev/eventing/pkg/apis/sources/v1beta2/ping_validation.go +++ b/vendor/knative.dev/eventing/pkg/apis/sources/v1beta2/ping_validation.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "strings" @@ -37,8 +38,10 @@ func (c *PingSource) Validate(ctx context.Context) *apis.FieldError { func (cs *PingSourceSpec) Validate(ctx context.Context) *apis.FieldError { var errs *apis.FieldError - schedule := cs.Schedule + + errs = validateDescriptor(schedule) + if cs.Timezone != "" { schedule = "CRON_TZ=" + cs.Timezone + " " + schedule } @@ -98,3 +101,10 @@ func validateJSON(str string) error { var objmap map[string]interface{} return json.Unmarshal([]byte(str), &objmap) } + +func validateDescriptor(spec string) *apis.FieldError { + if strings.Contains(spec, "@every") { + return apis.ErrInvalidValue(errors.New("unsupported descriptor @every"), "schedule") + } + return nil +} 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 000000000..9e206a10b --- /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 ef16a9d83..9fa34d2c0 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 a5bcc4137..504dcaa06 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 f2d7ad9bf..0544d88a6 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 046e4495d..a4d34e32c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -925,7 +925,7 @@ k8s.io/utils/buffer k8s.io/utils/integer k8s.io/utils/pointer k8s.io/utils/trace -# knative.dev/eventing v0.24.0 +# knative.dev/eventing v0.24.2 ## explicit knative.dev/eventing/pkg/adapter/v2 knative.dev/eventing/pkg/adapter/v2/test @@ -998,7 +998,7 @@ knative.dev/hack knative.dev/networking/pkg knative.dev/networking/pkg/apis/networking knative.dev/networking/pkg/apis/networking/v1alpha1 -# knative.dev/pkg v0.0.0-20210622173328-dd0db4b05c80 +# knative.dev/pkg v0.0.0-20210902173607-953af0138c75 ## explicit knative.dev/pkg/apis knative.dev/pkg/apis/duck @@ -1074,6 +1074,7 @@ knative.dev/pkg/version knative.dev/pkg/webhook knative.dev/pkg/webhook/certificates knative.dev/pkg/webhook/certificates/resources +knative.dev/pkg/webhook/json knative.dev/pkg/webhook/psbinding knative.dev/pkg/webhook/resourcesemantics knative.dev/pkg/webhook/resourcesemantics/defaulting