Merge pull request #110178 from kevindelgado/validation-beta-1-25

Graduate server side validation to beta
This commit is contained in:
Kubernetes Prow Robot 2022-07-19 05:34:06 -07:00 committed by GitHub
commit eeb12bb3af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 885 additions and 350 deletions

4
go.mod
View File

@ -256,7 +256,7 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/warnings.v0 v0.1.1 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/kustomize/api v0.11.4 // indirect
sigs.k8s.io/kustomize/kustomize/v4 v4.5.4 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect
@ -605,7 +605,7 @@ replace (
modernc.org/xc => modernc.org/xc v1.0.0
rsc.io/pdf => rsc.io/pdf v0.1.1
sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32
sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.11.4
sigs.k8s.io/kustomize/cmd/config => sigs.k8s.io/kustomize/cmd/config v0.10.6
sigs.k8s.io/kustomize/kustomize/v4 => sigs.k8s.io/kustomize/kustomize/v4 v4.5.4

4
go.sum
View File

@ -557,8 +557,8 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo=
sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI=
sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco=

View File

@ -1046,7 +1046,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA},
genericfeatures.ServerSideFieldValidation: {Default: false, PreRelease: featuregate.Alpha},
genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta},
// features that enable backwards compatibility but are scheduled to be removed
// ...

View File

@ -29,7 +29,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -89,8 +89,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -30,7 +30,7 @@ require (
k8s.io/klog/v2 v2.70.1
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
sigs.k8s.io/structured-merge-diff/v4 v4.2.1
sigs.k8s.io/yaml v1.2.0
)

View File

@ -853,8 +853,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -1331,10 +1331,14 @@ func (v *unstructuredSchemaCoercer) apply(u *unstructured.Unstructured) (unknown
if err != nil {
return nil, err
}
objectMeta, foundObjectMeta, err := schemaobjectmeta.GetObjectMeta(u.Object, v.dropInvalidMetadata)
objectMeta, foundObjectMeta, metaUnknownFields, err := schemaobjectmeta.GetObjectMetaWithOptions(u.Object, schemaobjectmeta.ObjectMetaOptions{
DropMalformedFields: v.dropInvalidMetadata,
ReturnUnknownFieldPaths: v.returnUnknownFieldPaths,
})
if err != nil {
return nil, err
}
unknownFieldPaths = append(unknownFieldPaths, metaUnknownFields...)
// compare group and kind because also other object like DeleteCollection options pass through here
gv, err := schema.ParseGroupVersion(apiVersion)
@ -1345,17 +1349,23 @@ func (v *unstructuredSchemaCoercer) apply(u *unstructured.Unstructured) (unknown
if gv.Group == v.structuralSchemaGK.Group && kind == v.structuralSchemaGK.Kind {
if !v.preserveUnknownFields {
// TODO: switch over pruning and coercing at the root to schemaobjectmeta.Coerce too
pruneOpts := structuralpruning.PruneOptions{}
pruneOpts := structuralschema.UnknownFieldPathOptions{}
if v.returnUnknownFieldPaths {
pruneOpts.ReturnPruned = true
pruneOpts.TrackUnknownFieldPaths = true
}
unknownFieldPaths = structuralpruning.PruneWithOptions(u.Object, v.structuralSchemas[gv.Version], true, pruneOpts)
unknownFieldPaths = append(unknownFieldPaths, structuralpruning.PruneWithOptions(u.Object, v.structuralSchemas[gv.Version], true, pruneOpts)...)
structuraldefaulting.PruneNonNullableNullsWithoutDefaults(u.Object, v.structuralSchemas[gv.Version])
}
if err := schemaobjectmeta.Coerce(nil, u.Object, v.structuralSchemas[gv.Version], false, v.dropInvalidMetadata); err != nil {
err, paths := schemaobjectmeta.CoerceWithOptions(nil, u.Object, v.structuralSchemas[gv.Version], false, schemaobjectmeta.CoerceOptions{
DropInvalidFields: v.dropInvalidMetadata,
ReturnUnknownFieldPaths: v.returnUnknownFieldPaths,
})
if err != nil {
return nil, err
}
unknownFieldPaths = append(unknownFieldPaths, paths...)
// fixup missing generation in very old CRs
if v.repairGeneration && objectMeta.Generation == 0 {
objectMeta.Generation = 1

View File

@ -17,15 +17,34 @@ limitations under the License.
package objectmeta
import (
"sort"
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// CoerceOptions gives the ability to ReturnUnknownFieldPaths for fields
// unrecognized by the schema or DropInvalidFields for fields that are a part
// of the schema, but are malformed.
type CoerceOptions struct {
// DropInvalidFields discards malformed serialized metadata fields that
// cannot be successfully decoded to the corresponding ObjectMeta field.
// This only applies to fields that are recognized as part of the schema,
// but of an invalid type (i.e. cause an error when unmarshaling, rather
// than being dropped or causing a strictErr).
DropInvalidFields bool
// ReturnUnknownFieldPaths will return the paths to fields that are not
// recognized as part of the schema.
ReturnUnknownFieldPaths bool
}
// Coerce checks types of embedded ObjectMeta and TypeMeta and prunes unknown fields inside the former.
// It does coerce ObjectMeta and TypeMeta at the root if isResourceRoot is true.
// If dropInvalidFields is true, fields of wrong type will be dropped.
func Coerce(pth *field.Path, obj interface{}, s *structuralschema.Structural, isResourceRoot, dropInvalidFields bool) *field.Error {
// If opts.ReturnUnknownFieldPaths is true, it will return the paths of any fields that are not a part of the
// schema that are dropped when unmarshaling.
// If opts.DropInvalidFields is true, fields of wrong type will be dropped.
func CoerceWithOptions(pth *field.Path, obj interface{}, s *structuralschema.Structural, isResourceRoot bool, opts CoerceOptions) (*field.Error, []string) {
if isResourceRoot {
if s == nil {
s = &structuralschema.Structural{}
@ -36,36 +55,57 @@ func Coerce(pth *field.Path, obj interface{}, s *structuralschema.Structural, is
s = &clone
}
}
c := coercer{dropInvalidFields: dropInvalidFields}
return c.coerce(pth, obj, s)
c := coercer{DropInvalidFields: opts.DropInvalidFields, ReturnUnknownFieldPaths: opts.ReturnUnknownFieldPaths}
schemaOpts := &structuralschema.UnknownFieldPathOptions{
TrackUnknownFieldPaths: opts.ReturnUnknownFieldPaths,
}
fieldErr := c.coerce(pth, obj, s, schemaOpts)
sort.Strings(schemaOpts.UnknownFieldPaths)
return fieldErr, schemaOpts.UnknownFieldPaths
}
// Coerce calls CoerceWithOptions without returning unknown field paths.
func Coerce(pth *field.Path, obj interface{}, s *structuralschema.Structural, isResourceRoot, dropInvalidFields bool) *field.Error {
fieldErr, _ := CoerceWithOptions(pth, obj, s, isResourceRoot, CoerceOptions{DropInvalidFields: dropInvalidFields})
return fieldErr
}
type coercer struct {
dropInvalidFields bool
DropInvalidFields bool
ReturnUnknownFieldPaths bool
}
func (c *coercer) coerce(pth *field.Path, x interface{}, s *structuralschema.Structural) *field.Error {
func (c *coercer) coerce(pth *field.Path, x interface{}, s *structuralschema.Structural, opts *structuralschema.UnknownFieldPathOptions) *field.Error {
if s == nil {
return nil
}
origPathLen := len(opts.ParentPath)
defer func() {
opts.ParentPath = opts.ParentPath[:origPathLen]
}()
switch x := x.(type) {
case map[string]interface{}:
for k, v := range x {
if s.XEmbeddedResource {
switch k {
case "apiVersion", "kind":
if _, ok := v.(string); !ok && c.dropInvalidFields {
if _, ok := v.(string); !ok && c.DropInvalidFields {
delete(x, k)
} else if !ok {
return field.Invalid(pth.Child(k), v, "must be a string")
}
case "metadata":
meta, found, err := GetObjectMeta(x, c.dropInvalidFields)
meta, found, unknownFields, err := GetObjectMetaWithOptions(x, ObjectMetaOptions{
DropMalformedFields: c.DropInvalidFields,
ReturnUnknownFieldPaths: c.ReturnUnknownFieldPaths,
ParentPath: pth,
})
opts.UnknownFieldPaths = append(opts.UnknownFieldPaths, unknownFields...)
if err != nil {
if !c.dropInvalidFields {
if !c.DropInvalidFields {
return field.Invalid(pth.Child("metadata"), v, err.Error())
}
// pass through on error if dropInvalidFields is true
// pass through on error if DropInvalidFields is true
} else if found {
if err := SetObjectMeta(x, meta); err != nil {
return field.Invalid(pth.Child("metadata"), v, err.Error())
@ -78,20 +118,26 @@ func (c *coercer) coerce(pth *field.Path, x interface{}, s *structuralschema.Str
}
prop, ok := s.Properties[k]
if ok {
if err := c.coerce(pth.Child(k), v, &prop); err != nil {
opts.AppendKey(k)
if err := c.coerce(pth.Child(k), v, &prop, opts); err != nil {
return err
}
opts.ParentPath = opts.ParentPath[:origPathLen]
} else if s.AdditionalProperties != nil {
if err := c.coerce(pth.Key(k), v, s.AdditionalProperties.Structural); err != nil {
opts.AppendKey(k)
if err := c.coerce(pth.Key(k), v, s.AdditionalProperties.Structural, opts); err != nil {
return err
}
opts.ParentPath = opts.ParentPath[:origPathLen]
}
}
case []interface{}:
for i, v := range x {
if err := c.coerce(pth.Index(i), v, s.Items); err != nil {
opts.AppendIndex(i)
if err := c.coerce(pth.Index(i), v, s.Items, opts); err != nil {
return err
}
opts.ParentPath = opts.ParentPath[:origPathLen]
}
default:
// scalars, do nothing

View File

@ -19,6 +19,7 @@ package objectmeta
import (
"bytes"
"reflect"
"strings"
"testing"
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
@ -28,13 +29,14 @@ import (
func TestCoerce(t *testing.T) {
tests := []struct {
name string
json string
includeRoot bool
dropInvalidFields bool
schema *structuralschema.Structural
expected string
expectedError bool
name string
json string
includeRoot bool
dropInvalidFields bool
schema *structuralschema.Structural
expected string
expectedError bool
expectedUnknownFields []string
}{
{name: "empty", json: "null", schema: nil, expected: "null"},
{name: "scalar", json: "4", schema: &structuralschema.Structural{}, expected: "4"},
@ -199,7 +201,12 @@ func TestCoerce(t *testing.T) {
}
}
}
`},
`, expectedUnknownFields: []string{
"nested.metadata.unspecified",
"nested.spec.embedded.metadata.unspecified",
"preserving.metadata.unspecified",
"pruned.metadata.unspecified",
}},
{name: "x-kubernetes-embedded-resource, with includeRoot=true", json: `
{
"apiVersion": "foo/v1",
@ -356,8 +363,13 @@ func TestCoerce(t *testing.T) {
}
}
}
}
`},
}`, expectedUnknownFields: []string{
"metadata.unspecified",
"nested.metadata.unspecified",
"nested.spec.embedded.metadata.unspecified",
"preserving.metadata.unspecified",
"pruned.metadata.unspecified",
}},
{name: "without name", json: `
{
"apiVersion": "foo/v1",
@ -495,7 +507,10 @@ func TestCoerce(t *testing.T) {
t.Fatal(err)
}
err := Coerce(nil, in, tt.schema, tt.includeRoot, tt.dropInvalidFields)
err, unknownFields := CoerceWithOptions(nil, in, tt.schema, tt.includeRoot, CoerceOptions{
DropInvalidFields: tt.dropInvalidFields,
ReturnUnknownFieldPaths: true,
})
if tt.expectedError && err == nil {
t.Error("expected error, but did not get any")
} else if !tt.expectedError && err != nil {
@ -510,6 +525,9 @@ func TestCoerce(t *testing.T) {
}
t.Errorf("expected: %s\ngot: %s\ndiff: %s", tt.expected, buf.String(), diff.ObjectDiff(expected, in))
}
if !reflect.DeepEqual(unknownFields, tt.expectedUnknownFields) {
t.Errorf("expected unknown fields:\n\t%v\ngot:\n\t%v\n", strings.Join(tt.expectedUnknownFields, "\n\t"), strings.Join(unknownFields, "\n\t"))
}
})
}
}

View File

@ -23,35 +23,83 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utiljson "k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/validation/field"
kjson "sigs.k8s.io/json"
)
// GetObjectMeta does conversion of JSON to ObjectMeta. It first tries json.Unmarshal into a metav1.ObjectMeta
// type. If that does not work and dropMalformedFields is true, it does field-by-field best-effort conversion
// throwing away fields which lead to errors.
// GetObjectMeta calls GetObjectMetaWithOptions without returning unknown field paths.
func GetObjectMeta(obj map[string]interface{}, dropMalformedFields bool) (*metav1.ObjectMeta, bool, error) {
meta, found, _, err := GetObjectMetaWithOptions(obj, ObjectMetaOptions{
DropMalformedFields: dropMalformedFields,
})
return meta, found, err
}
// ObjectMetaOptions provides the options for how GetObjectMeta should retrieve the object meta.
type ObjectMetaOptions struct {
// DropMalformedFields discards malformed serialized metadata fields that
// cannot be successfully decoded to the corresponding ObjectMeta field.
// This only applies to fields that are recognized as part of the schema,
// but of an invalid type (i.e. cause an error when unmarshaling, rather
// than being dropped or causing a strictErr).
DropMalformedFields bool
// ReturnUnknownFieldPaths will return the paths to fields that are not
// recognized as part of the schema.
ReturnUnknownFieldPaths bool
// ParentPath provides the current path up to the given ObjectMeta.
// If nil, the metadata is assumed to be at the root of the object.
ParentPath *field.Path
}
// GetObjectMetaWithOptions does conversion of JSON to ObjectMeta.
// It first tries json.Unmarshal into a metav1.ObjectMeta
// type. If that does not work and opts.DropMalformedFields is true, it does field-by-field best-effort conversion
// throwing away fields which lead to errors.
// If opts.ReturnedUnknownFields is true, it will UnmarshalStrict instead, returning the paths of any unknown fields
// it encounters (i.e. paths returned as strict errs from UnmarshalStrict)
func GetObjectMetaWithOptions(obj map[string]interface{}, opts ObjectMetaOptions) (*metav1.ObjectMeta, bool, []string, error) {
metadata, found := obj["metadata"]
if !found {
return nil, false, nil
return nil, false, nil, nil
}
// round-trip through JSON first, hoping that unmarshalling just works
objectMeta := &metav1.ObjectMeta{}
metadataBytes, err := utiljson.Marshal(metadata)
if err != nil {
return nil, false, err
return nil, false, nil, err
}
if err = utiljson.Unmarshal(metadataBytes, objectMeta); err == nil {
// if successful, return
return objectMeta, true, nil
var unmarshalErr error
if opts.ReturnUnknownFieldPaths {
var strictErrs []error
strictErrs, unmarshalErr = kjson.UnmarshalStrict(metadataBytes, objectMeta)
if unmarshalErr == nil {
if len(strictErrs) > 0 {
unknownPaths := []string{}
prefix := opts.ParentPath.Child("metadata").String()
for _, err := range strictErrs {
if fieldPathErr, ok := err.(kjson.FieldError); ok {
unknownPaths = append(unknownPaths, prefix+"."+fieldPathErr.FieldPath())
}
}
return objectMeta, true, unknownPaths, nil
}
return objectMeta, true, nil, nil
}
} else {
if unmarshalErr = utiljson.Unmarshal(metadataBytes, objectMeta); unmarshalErr == nil {
// if successful, return
return objectMeta, true, nil, nil
}
}
if !dropMalformedFields {
if !opts.DropMalformedFields {
// if we're not trying to drop malformed fields, return the error
return nil, true, err
return nil, true, nil, unmarshalErr
}
metadataMap, ok := metadata.(map[string]interface{})
if !ok {
return nil, false, fmt.Errorf("invalid metadata: expected object, got %T", metadata)
return nil, false, nil, fmt.Errorf("invalid metadata: expected object, got %T", metadata)
}
// Go field by field accumulating into the metadata object.
@ -59,18 +107,31 @@ func GetObjectMeta(obj map[string]interface{}, dropMalformedFields bool) (*metav
// each iteration preserving the old key-values.
accumulatedObjectMeta := &metav1.ObjectMeta{}
testObjectMeta := &metav1.ObjectMeta{}
var unknownFields []string
for k, v := range metadataMap {
// serialize a single field
if singleFieldBytes, err := utiljson.Marshal(map[string]interface{}{k: v}); err == nil {
// do a test unmarshal
if utiljson.Unmarshal(singleFieldBytes, testObjectMeta) == nil {
// if that succeeds, unmarshal for real
utiljson.Unmarshal(singleFieldBytes, accumulatedObjectMeta)
if opts.ReturnUnknownFieldPaths {
strictErrs, _ := kjson.UnmarshalStrict(singleFieldBytes, accumulatedObjectMeta)
if len(strictErrs) > 0 {
prefix := opts.ParentPath.Child("metadata").String()
for _, err := range strictErrs {
if fieldPathErr, ok := err.(kjson.FieldError); ok {
unknownFields = append(unknownFields, prefix+"."+fieldPathErr.FieldPath())
}
}
}
} else {
utiljson.Unmarshal(singleFieldBytes, accumulatedObjectMeta)
}
}
}
}
return accumulatedObjectMeta, true, nil
return accumulatedObjectMeta, true, unknownFields, nil
}
// SetObjectMeta writes back ObjectMeta into a JSON data structure.

View File

@ -161,6 +161,194 @@ func TestMalformedObjectMetaFields(t *testing.T) {
}
}
func TestGetObjectMetaWithOptions(t *testing.T) {
unknownAndMalformed := map[string]interface{}{
"kind": "Pod",
"apiVersion": "v1",
"metadata": map[string]interface{}{
"name": "my-meta",
"unknownField": "foo",
"generateName": nil,
"generation": nil,
"labels": map[string]string{
"foo": "bar",
},
"annotations": 11,
},
}
unknownOnly := map[string]interface{}{
"kind": "Pod",
"apiVersion": "v1",
"metadata": map[string]interface{}{
"name": "my-meta",
"unknownField": "foo",
"generateName": nil,
"generation": nil,
"labels": map[string]string{
"foo": "bar",
},
},
}
malformedOnly := map[string]interface{}{
"kind": "Pod",
"apiVersion": "v1",
"metadata": map[string]interface{}{
"name": "my-meta",
"generateName": nil,
"generation": nil,
"labels": map[string]string{
"foo": "bar",
},
"annotations": 11,
},
}
var testcases = []struct {
obj map[string]interface{}
dropMalformedFields bool
returnUnknownFieldPaths bool
expectedObject *metav1.ObjectMeta
expectedUnknownPaths []string
expectedErr string
}{
{
obj: unknownAndMalformed,
dropMalformedFields: false,
returnUnknownFieldPaths: false,
expectedErr: "json: cannot unmarshal number into Go struct field ObjectMeta.annotations of type map[string]string",
},
{
obj: unknownAndMalformed,
dropMalformedFields: true,
returnUnknownFieldPaths: false,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
},
{
obj: unknownAndMalformed,
dropMalformedFields: false,
returnUnknownFieldPaths: true,
expectedErr: "json: cannot unmarshal number into Go struct field ObjectMeta.annotations of type map[string]string",
},
{
obj: unknownAndMalformed,
dropMalformedFields: true,
returnUnknownFieldPaths: true,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
expectedUnknownPaths: []string{"metadata.unknownField"},
},
{
obj: unknownOnly,
dropMalformedFields: false,
returnUnknownFieldPaths: false,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
},
{
obj: unknownOnly,
dropMalformedFields: true,
returnUnknownFieldPaths: false,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
},
{
obj: unknownOnly,
dropMalformedFields: false,
returnUnknownFieldPaths: true,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
expectedUnknownPaths: []string{"metadata.unknownField"},
},
{
obj: unknownOnly,
dropMalformedFields: true,
returnUnknownFieldPaths: true,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
expectedUnknownPaths: []string{"metadata.unknownField"},
},
{
obj: malformedOnly,
dropMalformedFields: false,
returnUnknownFieldPaths: false,
expectedErr: "json: cannot unmarshal number into Go struct field ObjectMeta.annotations of type map[string]string",
},
{
obj: malformedOnly,
dropMalformedFields: true,
returnUnknownFieldPaths: false,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
},
{
obj: malformedOnly,
dropMalformedFields: false,
returnUnknownFieldPaths: true,
expectedErr: "json: cannot unmarshal number into Go struct field ObjectMeta.annotations of type map[string]string",
},
{
obj: malformedOnly,
dropMalformedFields: true,
returnUnknownFieldPaths: true,
expectedObject: &metav1.ObjectMeta{
Name: "my-meta",
Labels: map[string]string{
"foo": "bar",
},
},
},
}
for _, tc := range testcases {
opts := ObjectMetaOptions{
ReturnUnknownFieldPaths: tc.returnUnknownFieldPaths,
DropMalformedFields: tc.dropMalformedFields,
}
obj, _, unknownPaths, err := GetObjectMetaWithOptions(tc.obj, opts)
if !reflect.DeepEqual(tc.expectedObject, obj) {
t.Errorf("expected: %v, got: %v", tc.expectedObject, obj)
}
if (err == nil && tc.expectedErr != "") || err != nil && (err.Error() != tc.expectedErr) {
t.Errorf("expected: %v, got: %v", tc.expectedErr, err)
}
if !reflect.DeepEqual(tc.expectedUnknownPaths, unknownPaths) {
t.Errorf("expected: %v, got: %v", tc.expectedUnknownPaths, unknownPaths)
}
}
}
func TestGetObjectMetaNils(t *testing.T) {
u := &unstructured.Unstructured{
Object: map[string]interface{}{

View File

@ -0,0 +1,67 @@
/*
Copyright 2022 The Kubernetes 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 schema
import (
"strconv"
"strings"
)
// UnknownFieldPathOptions allow for tracking paths to unknown fields.
type UnknownFieldPathOptions struct {
// TrackUnknownFieldPaths determines whether or not unknown field
// paths should be stored or not.
TrackUnknownFieldPaths bool
// ParentPath builds the path to unknown fields as the object
// is recursively traversed.
ParentPath []string
// UnknownFieldPaths is the list of all unknown fields identified.
UnknownFieldPaths []string
}
// RecordUnknownFields adds a path to an unknown field to the
// record of UnknownFieldPaths, if TrackUnknownFieldPaths is true
func (o *UnknownFieldPathOptions) RecordUnknownField(field string) {
if !o.TrackUnknownFieldPaths {
return
}
l := len(o.ParentPath)
o.AppendKey(field)
o.UnknownFieldPaths = append(o.UnknownFieldPaths, strings.Join(o.ParentPath, ""))
o.ParentPath = o.ParentPath[:l]
}
// AppendKey adds a key (i.e. field) to the current parent
// path, if TrackUnknownFieldPaths is true.
func (o *UnknownFieldPathOptions) AppendKey(key string) {
if !o.TrackUnknownFieldPaths {
return
}
if len(o.ParentPath) > 0 {
o.ParentPath = append(o.ParentPath, ".")
}
o.ParentPath = append(o.ParentPath, key)
}
// AppendIndex adds an index to the most recent field of
// the current parent path, if TrackUnknownFieldPaths is true.
func (o *UnknownFieldPathOptions) AppendIndex(index int) {
if !o.TrackUnknownFieldPaths {
return
}
o.ParentPath = append(o.ParentPath, "[", strconv.Itoa(index), "]")
}

View File

@ -18,37 +18,15 @@ package pruning
import (
"sort"
"strconv"
"strings"
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
)
// PruneOptions sets options for pruning
// unknown fields
type PruneOptions struct {
// parentPath collects the path that the pruning
// takes as it traverses the object.
// It is used to report the full path to any unknown
// fields that the pruning encounters.
// It is only populated if ReturnPruned is true.
parentPath []string
// prunedPaths collects pruned field paths resulting from
// calls to recordPrunedKey.
// It is only populated if ReturnPruned is true.
prunedPaths []string
// ReturnPruned defines whether we want to track the
// fields that are pruned
ReturnPruned bool
}
// PruneWithOptions removes object fields in obj which are not specified in s. It skips TypeMeta
// and ObjectMeta fields if XEmbeddedResource is set to true, or for the root if isResourceRoot=true,
// i.e. it does not prune unknown metadata fields.
// It returns the set of fields that it prunes if opts.ReturnPruned is true
func PruneWithOptions(obj interface{}, s *structuralschema.Structural, isResourceRoot bool, opts PruneOptions) []string {
// It returns the set of fields that it prunes if opts.TrackUnknownFieldPaths is true
func PruneWithOptions(obj interface{}, s *structuralschema.Structural, isResourceRoot bool, opts structuralschema.UnknownFieldPathOptions) []string {
if isResourceRoot {
if s == nil {
s = &structuralschema.Structural{}
@ -60,14 +38,14 @@ func PruneWithOptions(obj interface{}, s *structuralschema.Structural, isResourc
}
}
prune(obj, s, &opts)
sort.Strings(opts.prunedPaths)
return opts.prunedPaths
sort.Strings(opts.UnknownFieldPaths)
return opts.UnknownFieldPaths
}
// Prune is equivalent to
// PruneWithOptions(obj, s, isResourceRoot, PruneOptions{})
// PruneWithOptions(obj, s, isResourceRoot, structuralschema.UnknownFieldPathOptions{})
func Prune(obj interface{}, s *structuralschema.Structural, isResourceRoot bool) {
PruneWithOptions(obj, s, isResourceRoot, PruneOptions{})
PruneWithOptions(obj, s, isResourceRoot, structuralschema.UnknownFieldPathOptions{})
}
var metaFields = map[string]bool{
@ -76,48 +54,21 @@ var metaFields = map[string]bool{
"metadata": true,
}
func (p *PruneOptions) recordPrunedKey(key string) {
if !p.ReturnPruned {
return
}
l := len(p.parentPath)
p.appendKey(key)
p.prunedPaths = append(p.prunedPaths, strings.Join(p.parentPath, ""))
p.parentPath = p.parentPath[:l]
}
func (p *PruneOptions) appendKey(key string) {
if !p.ReturnPruned {
return
}
if len(p.parentPath) > 0 {
p.parentPath = append(p.parentPath, ".")
}
p.parentPath = append(p.parentPath, key)
}
func (p *PruneOptions) appendIndex(index int) {
if !p.ReturnPruned {
return
}
p.parentPath = append(p.parentPath, "[", strconv.Itoa(index), "]")
}
func prune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) {
func prune(x interface{}, s *structuralschema.Structural, opts *structuralschema.UnknownFieldPathOptions) {
if s != nil && s.XPreserveUnknownFields {
skipPrune(x, s, opts)
return
}
origPathLen := len(opts.parentPath)
origPathLen := len(opts.ParentPath)
defer func() {
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
}()
switch x := x.(type) {
case map[string]interface{}:
if s == nil {
for k := range x {
opts.recordPrunedKey(k)
opts.RecordUnknownField(k)
delete(x, k)
}
return
@ -128,16 +79,16 @@ func prune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) {
}
prop, ok := s.Properties[k]
if ok {
opts.appendKey(k)
opts.AppendKey(k)
prune(v, &prop, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
} else if s.AdditionalProperties != nil {
opts.appendKey(k)
opts.AppendKey(k)
prune(v, s.AdditionalProperties.Structural, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
} else {
if !metaFields[k] || len(opts.parentPath) > 0 {
opts.recordPrunedKey(k)
if !metaFields[k] || len(opts.ParentPath) > 0 {
opts.RecordUnknownField(k)
}
delete(x, k)
}
@ -145,29 +96,29 @@ func prune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) {
case []interface{}:
if s == nil {
for i, v := range x {
opts.appendIndex(i)
opts.AppendIndex(i)
prune(v, nil, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
}
return
}
for i, v := range x {
opts.appendIndex(i)
opts.AppendIndex(i)
prune(v, s.Items, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
}
default:
// scalars, do nothing
}
}
func skipPrune(x interface{}, s *structuralschema.Structural, opts *PruneOptions) {
func skipPrune(x interface{}, s *structuralschema.Structural, opts *structuralschema.UnknownFieldPathOptions) {
if s == nil {
return
}
origPathLen := len(opts.parentPath)
origPathLen := len(opts.ParentPath)
defer func() {
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
}()
switch x := x.(type) {
@ -177,20 +128,20 @@ func skipPrune(x interface{}, s *structuralschema.Structural, opts *PruneOptions
continue
}
if prop, ok := s.Properties[k]; ok {
opts.appendKey(k)
opts.AppendKey(k)
prune(v, &prop, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
} else if s.AdditionalProperties != nil {
opts.appendKey(k)
opts.AppendKey(k)
prune(v, s.AdditionalProperties.Structural, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
}
}
case []interface{}:
for i, v := range x {
opts.appendIndex(i)
opts.AppendIndex(i)
skipPrune(v, s.Items, opts)
opts.parentPath = opts.parentPath[:origPathLen]
opts.ParentPath = opts.ParentPath[:origPathLen]
}
default:
// scalars, do nothing

View File

@ -575,8 +575,8 @@ func TestPrune(t *testing.T) {
t.Fatal(err)
}
pruned := PruneWithOptions(in, tt.schema, tt.isResourceRoot, PruneOptions{
ReturnPruned: true,
pruned := PruneWithOptions(in, tt.schema, tt.isResourceRoot, structuralschema.UnknownFieldPathOptions{
TrackUnknownFieldPaths: true,
})
if !reflect.DeepEqual(in, expectedObject) {
var buf bytes.Buffer
@ -592,8 +592,8 @@ func TestPrune(t *testing.T) {
t.Errorf("expected pruned:\n\t%v\ngot:\n\t%v\n", strings.Join(tt.expectedPruned, "\n\t"), strings.Join(pruned, "\n\t"))
}
// now check that pruned is empty when ReturnPruned is false
emptyPruned := PruneWithOptions(in, tt.schema, tt.isResourceRoot, PruneOptions{})
// now check that pruned is empty when TrackUnknownFieldPaths is false
emptyPruned := PruneWithOptions(in, tt.schema, tt.isResourceRoot, structuralschema.UnknownFieldPathOptions{})
if !reflect.DeepEqual(in, expectedObject) {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)

View File

@ -24,7 +24,7 @@ require (
k8s.io/klog/v2 v2.70.1
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
sigs.k8s.io/structured-merge-diff/v4 v4.2.1
sigs.k8s.io/yaml v1.2.0
)

View File

@ -180,8 +180,8 @@ k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 h1:yEQKdMCjzAOvGeiTwG4hO/
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8/go.mod h1:mbJ+NSUoAhuR14N0S63bPkh8MGVSo3VYSGZtH/mfMe0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -46,7 +46,7 @@ require (
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
sigs.k8s.io/structured-merge-diff/v4 v4.2.1
sigs.k8s.io/yaml v1.2.0
)

View File

@ -970,8 +970,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -150,6 +150,7 @@ const (
// owner: @kevindelgado
// kep: http://kep.k8s.io/2885
// alpha: v1.23
// beta: v1.24
//
// Enables server-side field validation.
ServerSideFieldValidation featuregate.Feature = "ServerSideFieldValidation"
@ -213,7 +214,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
ServerSideApply: {Default: true, PreRelease: featuregate.GA},
ServerSideFieldValidation: {Default: false, PreRelease: featuregate.Alpha},
ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta},
StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha},

View File

@ -65,7 +65,7 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -700,8 +700,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo=
sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI=
sigs.k8s.io/kustomize/kyaml v0.13.6 h1:eF+wsn4J7GOAXlvajv6OknSunxpcOBQQqsnPxObtkGs=

View File

@ -57,7 +57,7 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
)
replace (

View File

@ -489,8 +489,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -98,7 +98,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -709,8 +709,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -28,7 +28,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -83,8 +83,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -545,8 +545,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=

View File

@ -28,7 +28,7 @@ require (
k8s.io/client-go v0.0.0
k8s.io/klog/v2 v2.70.1
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
)
require (

View File

@ -653,8 +653,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -47,7 +47,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -471,8 +471,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -92,7 +92,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -695,8 +695,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -27,7 +27,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -81,8 +81,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -101,7 +101,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -708,8 +708,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -24,7 +24,7 @@ require (
k8s.io/component-base v0.0.0 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -76,8 +76,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -23,7 +23,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -77,8 +77,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -25,7 +25,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -77,8 +77,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -40,7 +40,7 @@ require (
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8
k8s.io/metrics v0.0.0
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
sigs.k8s.io/kustomize/kustomize/v4 v4.5.4
sigs.k8s.io/kustomize/kyaml v0.13.6
sigs.k8s.io/yaml v1.2.0

View File

@ -753,8 +753,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo=
sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI=
sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco=

View File

@ -32,7 +32,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -199,8 +199,8 @@ k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -96,7 +96,7 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -803,8 +803,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -54,7 +54,7 @@ require (
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -481,8 +481,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -96,7 +96,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)

View File

@ -701,8 +701,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -97,7 +97,7 @@ require (
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -706,8 +706,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -62,7 +62,7 @@ require (
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/kustomize/api v0.11.4 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect

View File

@ -699,8 +699,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo=
sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI=
sigs.k8s.io/kustomize/kyaml v0.13.6 h1:eF+wsn4J7GOAXlvajv6OknSunxpcOBQQqsnPxObtkGs=

View File

@ -54,7 +54,7 @@ require (
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

View File

@ -485,8 +485,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -1075,7 +1075,7 @@ metadata:
}
})
ginkgo.It("should create/apply a valid CR with arbitrary-extra properties for CRD with partially-specified validation schema", func() {
ginkgo.It("should create/apply an invalid/valid CR with arbitrary-extra properties for CRD with partially-specified validation schema", func() {
ginkgo.By("prepare CRD with partially-specified validation schema")
crd, err := crd.CreateTestCRD(f, func(crd *apiextensionsv1.CustomResourceDefinition) {
props := &apiextensionsv1.JSONSchemaProps{}
@ -1101,6 +1101,15 @@ metadata:
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
// XPreserveUnknownFields is defined on the root of the schema so unknown fields within the spec
// are still considered invalid
invalidArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}],"extraProperty":"arbitrary-value"}}`, meta)
err = createApplyCustomResource(invalidArbitraryCR, f.Namespace.Name, "test-cr", crd)
framework.ExpectError(err, "creating custom resource")
if !strings.Contains(err.Error(), `unknown field "spec.extraProperty"`) {
framework.Failf("incorrect error from createApplyCustomResource: %v", err)
}
// unknown fields on the root are considered valid
validArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]},"extraProperty":"arbitrary-value"}`, meta)
err = createApplyCustomResource(validArbitraryCR, f.Namespace.Name, "test-cr", crd)

View File

@ -38,6 +38,7 @@ import (
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/klog/v2"
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"k8s.io/kubernetes/test/integration/framework"
@ -49,8 +50,10 @@ var (
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "dupename",
"name": "%s",
"labels": {"app": "nginx"}
"labels": {"app": "nginx"},
"unknownMeta": "metaVal"
},
"spec": {
"unknown1": "val1",
@ -118,7 +121,9 @@ var (
invalidBodyYAML = `apiVersion: apps/v1
kind: Deployment
metadata:
name: dupename
name: %s
unknownMeta: metaVal
labels:
app: nginx
spec:
@ -236,7 +241,9 @@ spec:
"apiVersion": "%s",
"kind": "%s",
"metadata": {
"name": "dupename",
"name": "%s",
"unknownMeta": "metaVal",
"resourceVersion": "%s"
},
"spec": {
@ -252,7 +259,16 @@ spec:
"hostPort": 8081,
"hostPort": 8082,
"unknownNested": "val"
}]
}],
"embeddedObj": {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-cm",
"namespace": "my-ns",
"unknownEmbeddedMeta": "foo"
}
}
}
}`
@ -271,7 +287,14 @@ spec:
"containerPort": 8080,
"protocol": "TCP",
"hostPort": 8081
}]
}],
"embeddedObj": {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-cm"
}
}
}
}
`
@ -280,8 +303,10 @@ spec:
apiVersion: "%s"
kind: "%s"
metadata:
name: dupename
name: "%s"
resourceVersion: "%s"
unknownMeta: metaVal
spec:
unknown1: val1
unknownDupe: valDupe
@ -294,7 +319,14 @@ spec:
protocol: TCP
hostPort: 8081
hostPort: 8082
unknownNested: val`
unknownNested: val
embeddedObj:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-cm
namespace: my-ns
unknownEmbeddedMeta: foo`
crdValidBodyYAML = `
apiVersion: "%s"
@ -308,7 +340,13 @@ spec:
- name: portName
containerPort: 8080
protocol: TCP
hostPort: 8081`
hostPort: 8081
embeddedObj:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-cm
namespace: my-ns`
crdApplyInvalidBody = `
{
@ -326,7 +364,15 @@ spec:
"protocol": "TCP",
"hostPort": 8081,
"hostPort": 8082
}]
}],
"embeddedObj": {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-cm",
"namespace": "my-ns"
}
}
}
}`
@ -344,7 +390,15 @@ spec:
"containerPort": 8080,
"protocol": "TCP",
"hostPort": 8082
}]
}],
"embeddedObj": {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-cm",
"namespace": "my-ns"
}
}
}
}`
@ -362,7 +416,15 @@ spec:
"containerPort": 8080,
"protocol": "TCP",
"hostPort": 8083
}]
}],
"embeddedObj": {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "my-cm",
"namespace": "my-ns"
}
}
}
}`
@ -397,6 +459,21 @@ spec:
"knownField1": {
"type": "string"
},
"embeddedObj": {
"x-kubernetes-embedded-resource": true,
"type": "object",
"properties": {
"apiversion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
}
}
},
"ports": {
"type": "array",
"x-kubernetes-list-map-keys": [
@ -516,7 +593,7 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
FieldValidation: "Strict",
},
bodyBase: invalidBodyJSON,
strictDecodingError: `strict decoding error: unknown field "spec.unknown1", unknown field "spec.unknownDupe", duplicate field "spec.paused", unknown field "spec.template.spec.containers[0].unknownNested", duplicate field "spec.template.spec.containers[0].imagePullPolicy"`,
strictDecodingError: `strict decoding error: duplicate field "metadata.name", unknown field "metadata.unknownMeta", unknown field "spec.unknown1", unknown field "spec.unknownDupe", duplicate field "spec.paused", unknown field "spec.template.spec.containers[0].unknownNested", duplicate field "spec.template.spec.containers[0].imagePullPolicy"`,
},
{
name: "post-warn-validation",
@ -525,6 +602,8 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
},
bodyBase: invalidBodyJSON,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`duplicate field "spec.paused"`,
@ -546,6 +625,8 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
name: "post-no-validation",
bodyBase: invalidBodyJSON,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`duplicate field "spec.paused"`,
@ -564,9 +645,10 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
bodyBase: invalidBodyYAML,
contentType: "application/yaml",
strictDecodingError: `strict decoding error: yaml: unmarshal errors:
line 10: key "unknownDupe" already set in map
line 12: key "paused" already set in map
line 26: key "imagePullPolicy" already set in map, unknown field "spec.template.spec.containers[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
line 5: key "name" already set in map
line 12: key "unknownDupe" already set in map
line 14: key "paused" already set in map
line 28: key "imagePullPolicy" already set in map, unknown field "metadata.unknownMeta", unknown field "spec.template.spec.containers[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
},
{
name: "post-warn-validation-yaml",
@ -576,9 +658,11 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
bodyBase: invalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "paused" already set in map`,
`line 26: key "imagePullPolicy" already set in map`,
`line 5: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "paused" already set in map`,
`line 28: key "imagePullPolicy" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.template.spec.containers[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
@ -597,9 +681,11 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
bodyBase: invalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "paused" already set in map`,
`line 26: key "imagePullPolicy" already set in map`,
`line 5: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "paused" already set in map`,
`line 28: key "imagePullPolicy" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.template.spec.containers[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
@ -609,6 +695,7 @@ func testFieldValidationPost(t *testing.T, client clientset.Interface) {
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
klog.Warningf("running tc named: %s", tc.name)
body := []byte(fmt.Sprintf(tc.bodyBase, fmt.Sprintf("test-deployment-%s", tc.name)))
req := client.CoreV1().RESTClient().Post().
AbsPath("/apis/apps/v1").
@ -667,7 +754,7 @@ func testFieldValidationPut(t *testing.T, client clientset.Interface) {
FieldValidation: "Strict",
},
putBodyBase: invalidBodyJSON,
strictDecodingError: `strict decoding error: unknown field "spec.unknown1", unknown field "spec.unknownDupe", duplicate field "spec.paused", unknown field "spec.template.spec.containers[0].unknownNested", duplicate field "spec.template.spec.containers[0].imagePullPolicy"`,
strictDecodingError: `strict decoding error: duplicate field "metadata.name", unknown field "metadata.unknownMeta", unknown field "spec.unknown1", unknown field "spec.unknownDupe", duplicate field "spec.paused", unknown field "spec.template.spec.containers[0].unknownNested", duplicate field "spec.template.spec.containers[0].imagePullPolicy"`,
},
{
name: "put-warn-validation",
@ -676,6 +763,8 @@ func testFieldValidationPut(t *testing.T, client clientset.Interface) {
},
putBodyBase: invalidBodyJSON,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`duplicate field "spec.paused"`,
@ -687,16 +776,18 @@ func testFieldValidationPut(t *testing.T, client clientset.Interface) {
},
},
{
name: "put-default-ignore-validation",
name: "put-ignore-validation",
opts: metav1.UpdateOptions{
FieldValidation: "Ignore",
},
putBodyBase: invalidBodyJSON,
},
{
name: "put-ignore-validation",
name: "put-no-validation",
putBodyBase: invalidBodyJSON,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`duplicate field "spec.paused"`,
@ -715,9 +806,10 @@ func testFieldValidationPut(t *testing.T, client clientset.Interface) {
putBodyBase: invalidBodyYAML,
contentType: "application/yaml",
strictDecodingError: `strict decoding error: yaml: unmarshal errors:
line 10: key "unknownDupe" already set in map
line 12: key "paused" already set in map
line 26: key "imagePullPolicy" already set in map, unknown field "spec.template.spec.containers[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
line 5: key "name" already set in map
line 12: key "unknownDupe" already set in map
line 14: key "paused" already set in map
line 28: key "imagePullPolicy" already set in map, unknown field "metadata.unknownMeta", unknown field "spec.template.spec.containers[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
},
{
name: "put-warn-validation-yaml",
@ -727,9 +819,11 @@ func testFieldValidationPut(t *testing.T, client clientset.Interface) {
putBodyBase: invalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "paused" already set in map`,
`line 26: key "imagePullPolicy" already set in map`,
`line 5: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "paused" already set in map`,
`line 28: key "imagePullPolicy" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.template.spec.containers[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
@ -748,9 +842,11 @@ func testFieldValidationPut(t *testing.T, client clientset.Interface) {
putBodyBase: invalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "paused" already set in map`,
`line 26: key "imagePullPolicy" already set in map`,
`line 5: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "paused" already set in map`,
`line 28: key "imagePullPolicy" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.template.spec.containers[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
@ -1421,7 +1517,7 @@ func testFieldValidationPostCRD(t *testing.T, rest rest.Interface, gvk schema.Gr
FieldValidation: "Strict",
},
body: crdInvalidBody,
strictDecodingError: `strict decoding error: duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
strictDecodingError: `strict decoding error: duplicate field "metadata.name", duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "crd-post-warn-validation",
@ -1430,12 +1526,15 @@ func testFieldValidationPostCRD(t *testing.T, rest rest.Interface, gvk schema.Gr
},
body: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1449,12 +1548,15 @@ func testFieldValidationPostCRD(t *testing.T, rest rest.Interface, gvk schema.Gr
name: "crd-post-no-validation",
body: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1465,9 +1567,10 @@ func testFieldValidationPostCRD(t *testing.T, rest rest.Interface, gvk schema.Gr
body: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingError: `strict decoding error: yaml: unmarshal errors:
line 10: key "unknownDupe" already set in map
line 12: key "knownField1" already set in map
line 18: key "hostPort" already set in map, unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
line 6: key "name" already set in map
line 12: key "unknownDupe" already set in map
line 14: key "knownField1" already set in map
line 20: key "hostPort" already set in map, unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "crd-post-warn-validation-yaml",
@ -1477,12 +1580,15 @@ func testFieldValidationPostCRD(t *testing.T, rest rest.Interface, gvk schema.Gr
body: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1498,17 +1604,21 @@ func testFieldValidationPostCRD(t *testing.T, rest rest.Interface, gvk schema.Gr
body: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
klog.Warningf("running tc named: %s", tc.name)
kind := gvk.Kind
apiVersion := gvk.Group + "/" + gvk.Version
@ -1558,7 +1668,7 @@ func testFieldValidationPostCRDSchemaless(t *testing.T, rest rest.Interface, gvk
FieldValidation: "Strict",
},
body: crdInvalidBody,
strictDecodingError: `strict decoding error: duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "spec.ports[0].unknownNested"`,
strictDecodingError: `strict decoding error: duplicate field "metadata.name", duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "schemaless-crd-post-warn-validation",
@ -1567,10 +1677,13 @@ func testFieldValidationPostCRDSchemaless(t *testing.T, rest rest.Interface, gvk
},
body: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1584,10 +1697,13 @@ func testFieldValidationPostCRDSchemaless(t *testing.T, rest rest.Interface, gvk
name: "schemaless-crd-post-no-validation",
body: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1598,9 +1714,10 @@ func testFieldValidationPostCRDSchemaless(t *testing.T, rest rest.Interface, gvk
body: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingError: `strict decoding error: yaml: unmarshal errors:
line 10: key "unknownDupe" already set in map
line 12: key "knownField1" already set in map
line 18: key "hostPort" already set in map, unknown field "spec.ports[0].unknownNested"`,
line 6: key "name" already set in map
line 12: key "unknownDupe" already set in map
line 14: key "knownField1" already set in map
line 20: key "hostPort" already set in map, unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "schemaless-crd-post-warn-validation-yaml",
@ -1610,10 +1727,13 @@ func testFieldValidationPostCRDSchemaless(t *testing.T, rest rest.Interface, gvk
body: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1629,10 +1749,13 @@ func testFieldValidationPostCRDSchemaless(t *testing.T, rest rest.Interface, gvk
body: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
}
@ -1695,7 +1818,7 @@ func testFieldValidationPutCRD(t *testing.T, rest rest.Interface, gvk schema.Gro
FieldValidation: "Strict",
},
putBody: crdInvalidBody,
strictDecodingError: `strict decoding error: duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
strictDecodingError: `strict decoding error: duplicate field "metadata.name", duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "crd-put-warn-validation",
@ -1704,12 +1827,15 @@ func testFieldValidationPutCRD(t *testing.T, rest rest.Interface, gvk schema.Gro
},
putBody: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1723,12 +1849,15 @@ func testFieldValidationPutCRD(t *testing.T, rest rest.Interface, gvk schema.Gro
name: "crd-put-no-validation",
putBody: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1739,9 +1868,10 @@ func testFieldValidationPutCRD(t *testing.T, rest rest.Interface, gvk schema.Gro
putBody: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingError: `strict decoding error: yaml: unmarshal errors:
line 10: key "unknownDupe" already set in map
line 12: key "knownField1" already set in map
line 18: key "hostPort" already set in map, unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe"`,
line 6: key "name" already set in map
line 12: key "unknownDupe" already set in map
line 14: key "knownField1" already set in map
line 20: key "hostPort" already set in map, unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.unknown1", unknown field "spec.unknownDupe", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "crd-put-warn-validation-yaml",
@ -1751,12 +1881,15 @@ func testFieldValidationPutCRD(t *testing.T, rest rest.Interface, gvk schema.Gro
putBody: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1772,12 +1905,15 @@ func testFieldValidationPutCRD(t *testing.T, rest rest.Interface, gvk schema.Gro
putBody: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.unknown1"`,
`unknown field "spec.unknownDupe"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
}
@ -1847,7 +1983,7 @@ func testFieldValidationPutCRDSchemaless(t *testing.T, rest rest.Interface, gvk
FieldValidation: "Strict",
},
putBody: crdInvalidBody,
strictDecodingError: `strict decoding error: duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "spec.ports[0].unknownNested"`,
strictDecodingError: `strict decoding error: duplicate field "metadata.name", duplicate field "spec.unknownDupe", duplicate field "spec.knownField1", duplicate field "spec.ports[0].hostPort", unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "schemaless-crd-put-warn-validation",
@ -1856,10 +1992,13 @@ func testFieldValidationPutCRDSchemaless(t *testing.T, rest rest.Interface, gvk
},
putBody: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1873,10 +2012,13 @@ func testFieldValidationPutCRDSchemaless(t *testing.T, rest rest.Interface, gvk
name: "schemaless-crd-put-no-validation",
putBody: crdInvalidBody,
strictDecodingWarnings: []string{
`duplicate field "metadata.name"`,
`duplicate field "spec.unknownDupe"`,
`duplicate field "spec.knownField1"`,
`duplicate field "spec.ports[0].hostPort"`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1887,9 +2029,10 @@ func testFieldValidationPutCRDSchemaless(t *testing.T, rest rest.Interface, gvk
putBody: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingError: `strict decoding error: yaml: unmarshal errors:
line 10: key "unknownDupe" already set in map
line 12: key "knownField1" already set in map
line 18: key "hostPort" already set in map, unknown field "spec.ports[0].unknownNested"`,
line 6: key "name" already set in map
line 12: key "unknownDupe" already set in map
line 14: key "knownField1" already set in map
line 20: key "hostPort" already set in map, unknown field "metadata.unknownMeta", unknown field "spec.ports[0].unknownNested", unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
{
name: "schemaless-crd-put-warn-validation-yaml",
@ -1899,10 +2042,13 @@ func testFieldValidationPutCRDSchemaless(t *testing.T, rest rest.Interface, gvk
putBody: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
{
@ -1918,10 +2064,13 @@ func testFieldValidationPutCRDSchemaless(t *testing.T, rest rest.Interface, gvk
putBody: crdInvalidBodyYAML,
contentType: "application/yaml",
strictDecodingWarnings: []string{
`line 10: key "unknownDupe" already set in map`,
`line 12: key "knownField1" already set in map`,
`line 18: key "hostPort" already set in map`,
`line 6: key "name" already set in map`,
`line 12: key "unknownDupe" already set in map`,
`line 14: key "knownField1" already set in map`,
`line 20: key "hostPort" already set in map`,
`unknown field "metadata.unknownMeta"`,
`unknown field "spec.ports[0].unknownNested"`,
`unknown field "spec.embeddedObj.metadata.unknownEmbeddedMeta"`,
},
},
}

6
vendor/modules.txt vendored
View File

@ -2453,8 +2453,8 @@ k8s.io/utils/trace
## explicit; go 1.17
sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client
sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client
# sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 => sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
## explicit; go 1.17
# sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 => sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
## explicit; go 1.18
sigs.k8s.io/json
sigs.k8s.io/json/internal/golang/encoding/json
# sigs.k8s.io/kustomize/api v0.11.4 => sigs.k8s.io/kustomize/api v0.11.4
@ -2894,7 +2894,7 @@ sigs.k8s.io/yaml
# modernc.org/xc => modernc.org/xc v1.0.0
# rsc.io/pdf => rsc.io/pdf v0.1.1
# sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32
# sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
# sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
# sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.11.4
# sigs.k8s.io/kustomize/cmd/config => sigs.k8s.io/kustomize/cmd/config v0.10.6
# sigs.k8s.io/kustomize/kustomize/v4 => sigs.k8s.io/kustomize/kustomize/v4 v4.5.4

View File

@ -93,7 +93,7 @@ import (
// Instead, they are replaced by the Unicode replacement
// character U+FFFD.
//
func Unmarshal(data []byte, v interface{}, opts ...UnmarshalOpt) error {
func Unmarshal(data []byte, v any, opts ...UnmarshalOpt) error {
// Check for well-formedness.
// Avoids filling out half a data structure
// before discovering a JSON syntax error.
@ -167,16 +167,16 @@ func (e *InvalidUnmarshalError) Error() string {
return "json: Unmarshal(nil)"
}
if e.Type.Kind() != reflect.Ptr {
if e.Type.Kind() != reflect.Pointer {
return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
}
return "json: Unmarshal(nil " + e.Type.String() + ")"
}
*/
func (d *decodeState) unmarshal(v interface{}) error {
func (d *decodeState) unmarshal(v any) error {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr || rv.IsNil() {
if rv.Kind() != reflect.Pointer || rv.IsNil() {
return &InvalidUnmarshalError{reflect.TypeOf(v)}
}
@ -233,7 +233,7 @@ type decodeState struct {
disallowUnknownFields bool
savedStrictErrors []error
seenStrictErrors map[string]struct{}
seenStrictErrors map[strictError]struct{}
strictFieldStack []string
caseSensitive bool
@ -425,7 +425,7 @@ type unquotedValue struct{}
// quoted string literal or literal null into an interface value.
// If it finds anything other than a quoted string literal or null,
// valueQuoted returns unquotedValue{}.
func (d *decodeState) valueQuoted() interface{} {
func (d *decodeState) valueQuoted() any {
switch d.opcode {
default:
panic(phasePanicMsg)
@ -467,7 +467,7 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm
// If v is a named type and is addressable,
// start with its address, so that if the type has pointer methods,
// we find them.
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
haveAddr = true
v = v.Addr()
}
@ -476,14 +476,14 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm
// usefully addressable.
if v.Kind() == reflect.Interface && !v.IsNil() {
e := v.Elem()
if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) {
haveAddr = false
v = e
continue
}
}
if v.Kind() != reflect.Ptr {
if v.Kind() != reflect.Pointer {
break
}
@ -678,7 +678,7 @@ func (d *decodeState) object(v reflect.Value) error {
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
default:
if !reflect.PtrTo(t.Key()).Implements(textUnmarshalerType) {
if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) {
d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
d.skip()
return nil
@ -695,7 +695,7 @@ func (d *decodeState) object(v reflect.Value) error {
seenKeys = map[string]struct{}{}
}
if _, seen := seenKeys[fieldName]; seen {
d.saveStrictError(d.newFieldError("duplicate field", fieldName))
d.saveStrictError(d.newFieldError(duplicateStrictErrType, fieldName))
} else {
seenKeys[fieldName] = struct{}{}
}
@ -711,7 +711,7 @@ func (d *decodeState) object(v reflect.Value) error {
var seenKeys uint64
checkDuplicateField = func(fieldNameIndex int, fieldName string) {
if seenKeys&(1<<fieldNameIndex) != 0 {
d.saveStrictError(d.newFieldError("duplicate field", fieldName))
d.saveStrictError(d.newFieldError(duplicateStrictErrType, fieldName))
} else {
seenKeys = seenKeys | (1 << fieldNameIndex)
}
@ -724,7 +724,7 @@ func (d *decodeState) object(v reflect.Value) error {
seenIndexes = make([]bool, len(fields.list))
}
if seenIndexes[fieldNameIndex] {
d.saveStrictError(d.newFieldError("duplicate field", fieldName))
d.saveStrictError(d.newFieldError(duplicateStrictErrType, fieldName))
} else {
seenIndexes[fieldNameIndex] = true
}
@ -808,7 +808,7 @@ func (d *decodeState) object(v reflect.Value) error {
subv = v
destring = f.quoted
for _, i := range f.index {
if subv.Kind() == reflect.Ptr {
if subv.Kind() == reflect.Pointer {
if subv.IsNil() {
// If a struct embeds a pointer to an unexported type,
// it is not possible to set a newly allocated value
@ -836,7 +836,7 @@ func (d *decodeState) object(v reflect.Value) error {
d.errorContext.Struct = t
d.appendStrictFieldStackKey(f.name)
} else if d.disallowUnknownFields {
d.saveStrictError(d.newFieldError("unknown field", string(key)))
d.saveStrictError(d.newFieldError(unknownStrictErrType, string(key)))
}
}
@ -874,7 +874,7 @@ func (d *decodeState) object(v reflect.Value) error {
kt := t.Key()
var kv reflect.Value
switch {
case reflect.PtrTo(kt).Implements(textUnmarshalerType):
case reflect.PointerTo(kt).Implements(textUnmarshalerType):
kv = reflect.New(kt)
if err := d.literalStore(item, kv, true); err != nil {
return err
@ -934,7 +934,7 @@ func (d *decodeState) object(v reflect.Value) error {
// convertNumber converts the number literal s to a float64 or a Number
// depending on the setting of d.useNumber.
func (d *decodeState) convertNumber(s string) (interface{}, error) {
func (d *decodeState) convertNumber(s string) (any, error) {
if d.useNumber {
return Number(s), nil
}
@ -1010,7 +1010,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
break
}
switch v.Kind() {
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
v.Set(reflect.Zero(v.Type()))
// otherwise, ignore null for primitives/string
}
@ -1140,7 +1140,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
// but they avoid the weight of reflection in this common case.
// valueInterface is like value but returns interface{}
func (d *decodeState) valueInterface() (val interface{}) {
func (d *decodeState) valueInterface() (val any) {
switch d.opcode {
default:
panic(phasePanicMsg)
@ -1157,14 +1157,14 @@ func (d *decodeState) valueInterface() (val interface{}) {
}
// arrayInterface is like array but returns []interface{}.
func (d *decodeState) arrayInterface() []interface{} {
func (d *decodeState) arrayInterface() []any {
origStrictFieldStackLen := len(d.strictFieldStack)
defer func() {
// Reset to original length and reuse the allocated space for the strict FieldStack slice.
d.strictFieldStack = d.strictFieldStack[:origStrictFieldStackLen]
}()
var v = make([]interface{}, 0)
var v = make([]any, 0)
for {
// Look ahead for ] - can only happen on first iteration.
d.scanWhile(scanSkipSpace)
@ -1192,14 +1192,14 @@ func (d *decodeState) arrayInterface() []interface{} {
}
// objectInterface is like object but returns map[string]interface{}.
func (d *decodeState) objectInterface() map[string]interface{} {
func (d *decodeState) objectInterface() map[string]any {
origStrictFieldStackLen := len(d.strictFieldStack)
defer func() {
// Reset to original length and reuse the allocated space for the strict FieldStack slice.
d.strictFieldStack = d.strictFieldStack[:origStrictFieldStackLen]
}()
m := make(map[string]interface{})
m := make(map[string]any)
for {
// Read opening " of string key or closing }.
d.scanWhile(scanSkipSpace)
@ -1231,7 +1231,7 @@ func (d *decodeState) objectInterface() map[string]interface{} {
if d.disallowDuplicateFields {
if _, exists := m[key]; exists {
d.saveStrictError(d.newFieldError("duplicate field", key))
d.saveStrictError(d.newFieldError(duplicateStrictErrType, key))
}
}
@ -1258,7 +1258,7 @@ func (d *decodeState) objectInterface() map[string]interface{} {
// literalInterface consumes and returns a literal from d.data[d.off-1:] and
// it reads the following byte ahead. The first byte of the literal has been
// read already (that's how the caller knows it's a literal).
func (d *decodeState) literalInterface() interface{} {
func (d *decodeState) literalInterface() any {
// All bytes inside literal return scanContinue op code.
start := d.readIndex()
d.rescanLiteral()

View File

@ -155,7 +155,7 @@ import (
// handle them. Passing cyclic structures to Marshal will result in
// an error.
//
func Marshal(v interface{}) ([]byte, error) {
func Marshal(v any) ([]byte, error) {
e := newEncodeState()
err := e.marshal(v, encOpts{escapeHTML: true})
@ -172,7 +172,7 @@ func Marshal(v interface{}) ([]byte, error) {
// MarshalIndent is like Marshal but applies Indent to format the output.
// Each JSON element in the output will begin on a new line beginning with prefix
// followed by one or more copies of indent according to the indentation nesting.
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
b, err := Marshal(v)
if err != nil {
return nil, err
@ -294,7 +294,7 @@ type encodeState struct {
// startDetectingCyclesAfter, so that we skip the work if we're within a
// reasonable amount of nested pointers deep.
ptrLevel uint
ptrSeen map[interface{}]struct{}
ptrSeen map[any]struct{}
}
const startDetectingCyclesAfter = 1000
@ -311,7 +311,7 @@ func newEncodeState() *encodeState {
e.ptrLevel = 0
return e
}
return &encodeState{ptrSeen: make(map[interface{}]struct{})}
return &encodeState{ptrSeen: make(map[any]struct{})}
}
// jsonError is an error wrapper type for internal use only.
@ -319,7 +319,7 @@ func newEncodeState() *encodeState {
// can distinguish intentional panics from this package.
type jsonError struct{ error }
func (e *encodeState) marshal(v interface{}, opts encOpts) (err error) {
func (e *encodeState) marshal(v any, opts encOpts) (err error) {
defer func() {
if r := recover(); r != nil {
if je, ok := r.(jsonError); ok {
@ -350,7 +350,7 @@ func isEmptyValue(v reflect.Value) bool {
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
case reflect.Interface, reflect.Pointer:
return v.IsNil()
}
return false
@ -419,13 +419,13 @@ func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
// Marshaler with a value receiver, then we're better off taking
// the address of the value - otherwise we end up with an
// allocation as we cast the value to an interface.
if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(marshalerType) {
if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
}
if t.Implements(marshalerType) {
return marshalerEncoder
}
if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(textMarshalerType) {
if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
}
if t.Implements(textMarshalerType) {
@ -455,7 +455,7 @@ func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
return newSliceEncoder(t)
case reflect.Array:
return newArrayEncoder(t)
case reflect.Ptr:
case reflect.Pointer:
return newPtrEncoder(t)
default:
return unsupportedTypeEncoder
@ -467,7 +467,7 @@ func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
}
func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
if v.Kind() == reflect.Ptr && v.IsNil() {
if v.Kind() == reflect.Pointer && v.IsNil() {
e.WriteString("null")
return
}
@ -504,7 +504,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
}
func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
if v.Kind() == reflect.Ptr && v.IsNil() {
if v.Kind() == reflect.Pointer && v.IsNil() {
e.WriteString("null")
return
}
@ -738,7 +738,7 @@ FieldLoop:
// Find the nested struct field by following f.index.
fv := v
for _, i := range f.index {
if fv.Kind() == reflect.Ptr {
if fv.Kind() == reflect.Pointer {
if fv.IsNil() {
continue FieldLoop
}
@ -893,7 +893,7 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
func newSliceEncoder(t reflect.Type) encoderFunc {
// Byte slices get special treatment; arrays don't.
if t.Elem().Kind() == reflect.Uint8 {
p := reflect.PtrTo(t.Elem())
p := reflect.PointerTo(t.Elem())
if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
return encodeByteSlice
}
@ -989,7 +989,7 @@ func isValidTag(s string) bool {
func typeByIndex(t reflect.Type, index []int) reflect.Type {
for _, i := range index {
if t.Kind() == reflect.Ptr {
if t.Kind() == reflect.Pointer {
t = t.Elem()
}
t = t.Field(i).Type
@ -1009,7 +1009,7 @@ func (w *reflectWithString) resolve() error {
return nil
}
if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
if w.k.Kind() == reflect.Ptr && w.k.IsNil() {
if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
return nil
}
buf, err := tm.MarshalText()
@ -1243,7 +1243,7 @@ func typeFields(t reflect.Type) structFields {
sf := f.typ.Field(i)
if sf.Anonymous {
t := sf.Type
if t.Kind() == reflect.Ptr {
if t.Kind() == reflect.Pointer {
t = t.Elem()
}
if !sf.IsExported() && t.Kind() != reflect.Struct {
@ -1269,7 +1269,7 @@ func typeFields(t reflect.Type) structFields {
index[len(f.index)] = i
ft := sf.Type
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
if ft.Name() == "" && ft.Kind() == reflect.Pointer {
// Follow pointer.
ft = ft.Elem()
}

View File

@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build gofuzz
// +build gofuzz
package json
@ -12,10 +11,10 @@ import (
)
func Fuzz(data []byte) (score int) {
for _, ctor := range []func() interface{}{
func() interface{} { return new(interface{}) },
func() interface{} { return new(map[string]interface{}) },
func() interface{} { return new([]interface{}) },
for _, ctor := range []func() any{
func() any { return new(any) },
func() any { return new(map[string]any) },
func() any { return new([]any) },
} {
v := ctor()
err := Unmarshal(data, v)

View File

@ -18,7 +18,6 @@ package json
import (
gojson "encoding/json"
"fmt"
"strconv"
"strings"
)
@ -71,32 +70,37 @@ func (d *Decoder) DisallowDuplicateFields() {
d.d.disallowDuplicateFields = true
}
func (d *decodeState) newFieldError(msg, field string) error {
func (d *decodeState) newFieldError(errType strictErrType, field string) *strictError {
if len(d.strictFieldStack) > 0 {
return fmt.Errorf("%s %q", msg, strings.Join(d.strictFieldStack, "")+"."+field)
return &strictError{
ErrType: errType,
Path: strings.Join(d.strictFieldStack, "") + "." + field,
}
} else {
return fmt.Errorf("%s %q", msg, field)
return &strictError{
ErrType: errType,
Path: field,
}
}
}
// saveStrictError saves a strict decoding error,
// for reporting at the end of the unmarshal if no other errors occurred.
func (d *decodeState) saveStrictError(err error) {
func (d *decodeState) saveStrictError(err *strictError) {
// prevent excessive numbers of accumulated errors
if len(d.savedStrictErrors) >= 100 {
return
}
// dedupe accumulated strict errors
if d.seenStrictErrors == nil {
d.seenStrictErrors = map[string]struct{}{}
d.seenStrictErrors = map[strictError]struct{}{}
}
msg := err.Error()
if _, seen := d.seenStrictErrors[msg]; seen {
if _, seen := d.seenStrictErrors[*err]; seen {
return
}
// accumulate the error
d.seenStrictErrors[msg] = struct{}{}
d.seenStrictErrors[*err] = struct{}{}
d.savedStrictErrors = append(d.savedStrictErrors, err)
}
@ -118,6 +122,33 @@ func (d *decodeState) appendStrictFieldStackIndex(i int) {
d.strictFieldStack = append(d.strictFieldStack, "[", strconv.Itoa(i), "]")
}
type strictErrType string
const (
unknownStrictErrType strictErrType = "unknown field"
duplicateStrictErrType strictErrType = "duplicate field"
)
// strictError is a strict decoding error
// It has an ErrType (either unknown or duplicate)
// and a path to the erroneous field
type strictError struct {
ErrType strictErrType
Path string
}
func (e *strictError) Error() string {
return string(e.ErrType) + " " + strconv.Quote(e.Path)
}
func (e *strictError) FieldPath() string {
return e.Path
}
func (e *strictError) SetFieldPath(path string) {
e.Path = path
}
// UnmarshalStrictError holds errors resulting from use of strict disallow___ decoder directives.
// If this is returned from Unmarshal(), it means the decoding was successful in all other respects.
type UnmarshalStrictError struct {

View File

@ -83,7 +83,7 @@ type scanner struct {
}
var scannerPool = sync.Pool{
New: func() interface{} {
New: func() any {
return &scanner{}
},
}

View File

@ -45,7 +45,7 @@ func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true
//
// See the documentation for Unmarshal for details about
// the conversion of JSON into a Go value.
func (dec *Decoder) Decode(v interface{}) error {
func (dec *Decoder) Decode(v any) error {
if dec.err != nil {
return dec.err
}
@ -197,7 +197,7 @@ func NewEncoder(w io.Writer) *Encoder {
//
// See the documentation for Marshal for details about the
// conversion of Go values to JSON.
func (enc *Encoder) Encode(v interface{}) error {
func (enc *Encoder) Encode(v any) error {
if enc.err != nil {
return enc.err
}
@ -290,7 +290,7 @@ var _ Unmarshaler = (*RawMessage)(nil)
// string, for JSON string literals
// nil, for JSON null
//
type Token interface{}
type Token any
*/
const (
@ -457,7 +457,7 @@ func (dec *Decoder) Token() (Token, error) {
if !dec.tokenValueAllowed() {
return dec.tokenError(c)
}
var x interface{}
var x any
if err := dec.Decode(&x); err != nil {
return nil, err
}

View File

@ -15,10 +15,8 @@ type tagOptions string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
tag, opt, _ := strings.Cut(tag, ",")
return tag, tagOptions(opt)
}
// Contains reports whether a comma-separated list of options
@ -30,15 +28,11 @@ func (o tagOptions) Contains(optionName string) bool {
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
var name string
name, s, _ = strings.Cut(s, ",")
if name == optionName {
return true
}
s = next
}
return false
}

11
vendor/sigs.k8s.io/json/json.go generated vendored
View File

@ -84,6 +84,8 @@ const (
// and a list of the strict failures (if any) are returned. If no `strictOptions` are selected,
// all supported strict checks are performed.
//
// Strict errors returned will implement the FieldError interface for the specific erroneous fields.
//
// Currently supported strict checks are:
// - DisallowDuplicateFields: ensure the data contains no duplicate fields
// - DisallowUnknownFields: ensure the data contains no unknown fields (when decoding into typed structs)
@ -137,3 +139,12 @@ func SyntaxErrorOffset(err error) (isSyntaxError bool, offset int64) {
return false, 0
}
}
// FieldError is an error that provides access to the path of the erroneous field
type FieldError interface {
error
// FieldPath provides the full path of the erroneous field within the json object.
FieldPath() string
// SetFieldPath updates the path of the erroneous field output in the error message.
SetFieldPath(path string)
}