Update code-generator to v0.26.0
This commit is contained in:
48
vendor/k8s.io/kube-openapi/pkg/common/common.go
generated
vendored
48
vendor/k8s.io/kube-openapi/pkg/common/common.go
generated
vendored
@@ -246,38 +246,42 @@ var schemaTypeFormatMap = map[string]typeInfo{
|
||||
// the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple
|
||||
// type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation.
|
||||
// Example:
|
||||
// type Sample struct {
|
||||
// ...
|
||||
// // port of the server
|
||||
// port IntOrString
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// type Sample struct {
|
||||
// ...
|
||||
// // port of the server
|
||||
// port IntOrString
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// // IntOrString documentation...
|
||||
// type IntOrString { ... }
|
||||
//
|
||||
// Adding IntOrString to this function:
|
||||
// "port" : {
|
||||
// format: "string",
|
||||
// type: "int-or-string",
|
||||
// Description: "port of the server"
|
||||
// }
|
||||
//
|
||||
// "port" : {
|
||||
// format: "string",
|
||||
// type: "int-or-string",
|
||||
// Description: "port of the server"
|
||||
// }
|
||||
//
|
||||
// Implement OpenAPIDefinitionGetter for IntOrString:
|
||||
//
|
||||
// "port" : {
|
||||
// $Ref: "#/definitions/IntOrString"
|
||||
// Description: "port of the server"
|
||||
// }
|
||||
// "port" : {
|
||||
// $Ref: "#/definitions/IntOrString"
|
||||
// Description: "port of the server"
|
||||
// }
|
||||
//
|
||||
// ...
|
||||
// definitions:
|
||||
// {
|
||||
// "IntOrString": {
|
||||
// format: "string",
|
||||
// type: "int-or-string",
|
||||
// Description: "IntOrString documentation..." // new
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "IntOrString": {
|
||||
// format: "string",
|
||||
// type: "int-or-string",
|
||||
// Description: "IntOrString documentation..." // new
|
||||
// }
|
||||
// }
|
||||
func OpenAPITypeFormat(typeName string) (string, string) {
|
||||
mapped, ok := schemaTypeFormatMap[typeName]
|
||||
if !ok {
|
||||
|
36
vendor/k8s.io/kube-openapi/pkg/handler3/handler.go
generated
vendored
36
vendor/k8s.io/kube-openapi/pkg/handler3/handler.go
generated
vendored
@@ -21,7 +21,6 @@ import (
|
||||
"crypto/sha512"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -41,15 +40,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
jsonExt = ".json"
|
||||
|
||||
mimeJson = "application/json"
|
||||
// TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags.
|
||||
mimePb = "application/com.github.googleapis.gnostic.OpenAPIv3@68f4ded+protobuf"
|
||||
mimePbGz = "application/x-gzip"
|
||||
|
||||
subTypeProtobuf = "com.github.proto-openapi.spec.v3@v1.0+protobuf"
|
||||
subTypeJSON = "json"
|
||||
subTypeProtobufDeprecated = "com.github.proto-openapi.spec.v3@v1.0+protobuf"
|
||||
subTypeProtobuf = "com.github.proto-openapi.spec.v3.v1.0+protobuf"
|
||||
subTypeJSON = "json"
|
||||
)
|
||||
|
||||
// OpenAPIV3Discovery is the format of the Discovery document for OpenAPI V3
|
||||
@@ -84,12 +77,6 @@ type OpenAPIV3Group struct {
|
||||
etagCache handler.HandlerCache
|
||||
}
|
||||
|
||||
func init() {
|
||||
mime.AddExtensionType(".json", mimeJson)
|
||||
mime.AddExtensionType(".pb-v1", mimePb)
|
||||
mime.AddExtensionType(".gz", mimePbGz)
|
||||
}
|
||||
|
||||
func computeETag(data []byte) string {
|
||||
if data == nil {
|
||||
return ""
|
||||
@@ -154,7 +141,7 @@ func (o *OpenAPIService) getSingleGroupBytes(getType string, group string) ([]by
|
||||
}
|
||||
etagBytes, err := v.etagCache.Get()
|
||||
return specBytes, string(etagBytes), v.lastModified, err
|
||||
} else if getType == subTypeProtobuf {
|
||||
} else if getType == subTypeProtobuf || getType == subTypeProtobufDeprecated {
|
||||
specPb, err := v.pbCache.Get()
|
||||
if err != nil {
|
||||
return nil, "", v.lastModified, err
|
||||
@@ -191,6 +178,8 @@ func ToV3ProtoBinary(json []byte) ([]byte, error) {
|
||||
|
||||
func (o *OpenAPIService) HandleDiscovery(w http.ResponseWriter, r *http.Request) {
|
||||
data, _ := o.getGroupBytes()
|
||||
w.Header().Set("Etag", strconv.Quote(computeETag(data)))
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
http.ServeContent(w, r, "/openapi/v3", time.Now(), bytes.NewReader(data))
|
||||
}
|
||||
|
||||
@@ -210,11 +199,13 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
accepted := []struct {
|
||||
Type string
|
||||
SubType string
|
||||
Type string
|
||||
SubType string
|
||||
ReturnedContentType string
|
||||
}{
|
||||
{"application", subTypeJSON},
|
||||
{"application", subTypeProtobuf},
|
||||
{"application", subTypeJSON, "application/" + subTypeJSON},
|
||||
{"application", subTypeProtobuf, "application/" + subTypeProtobuf},
|
||||
{"application", subTypeProtobufDeprecated, "application/" + subTypeProtobuf},
|
||||
}
|
||||
|
||||
for _, clause := range clauses {
|
||||
@@ -229,6 +220,9 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// Set Content-Type header in the reponse
|
||||
w.Header().Set("Content-Type", accepts.ReturnedContentType)
|
||||
|
||||
// ETag must be enclosed in double quotes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag
|
||||
w.Header().Set("Etag", strconv.Quote(etag))
|
||||
|
||||
|
4
vendor/k8s.io/kube-openapi/pkg/internal/flags.go
generated
vendored
4
vendor/k8s.io/kube-openapi/pkg/internal/flags.go
generated
vendored
@@ -18,3 +18,7 @@ package internal
|
||||
|
||||
// Used by tests to selectively disable experimental JSON unmarshaler
|
||||
var UseOptimizedJSONUnmarshaling bool = true
|
||||
var UseOptimizedJSONUnmarshalingV3 bool = false
|
||||
|
||||
// Used by tests to selectively disable experimental JSON marshaler
|
||||
var UseOptimizedJSONMarshaling bool = true
|
||||
|
65
vendor/k8s.io/kube-openapi/pkg/internal/serialization.go
generated
vendored
Normal file
65
vendor/k8s.io/kube-openapi/pkg/internal/serialization.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2023 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 internal
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/jsonreference"
|
||||
jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json"
|
||||
)
|
||||
|
||||
// DeterministicMarshal calls the jsonv2 library with the deterministic
|
||||
// flag in order to have stable marshaling.
|
||||
func DeterministicMarshal(in any) ([]byte, error) {
|
||||
return jsonv2.MarshalOptions{Deterministic: true}.Marshal(jsonv2.EncodeOptions{}, in)
|
||||
}
|
||||
|
||||
// JSONRefFromMap populates a json reference object if the map v contains a $ref key.
|
||||
func JSONRefFromMap(jsonRef *jsonreference.Ref, v map[string]interface{}) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
if vv, ok := v["$ref"]; ok {
|
||||
if str, ok := vv.(string); ok {
|
||||
ref, err := jsonreference.New(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*jsonRef = ref
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SanitizeExtensions sanitizes the input map such that non extension
|
||||
// keys (non x-*, X-*) keys are dropped from the map. Returns the new
|
||||
// modified map, or nil if the map is now empty.
|
||||
func SanitizeExtensions(e map[string]interface{}) map[string]interface{} {
|
||||
for k := range e {
|
||||
if !IsExtensionKey(k) {
|
||||
delete(e, k)
|
||||
}
|
||||
}
|
||||
if len(e) == 0 {
|
||||
e = nil
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// IsExtensionKey returns true if the input string is of format x-* or X-*
|
||||
func IsExtensionKey(k string) bool {
|
||||
return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-'
|
||||
}
|
@@ -34,6 +34,13 @@ type MarshalOptions struct {
|
||||
// unknown JSON object members.
|
||||
DiscardUnknownMembers bool
|
||||
|
||||
// Deterministic specifies that the same input value will be serialized
|
||||
// as the exact same output bytes. Different processes of
|
||||
// the same program will serialize equal values to the same bytes,
|
||||
// but different versions of the same program are not guaranteed
|
||||
// to produce the exact same sequence of bytes.
|
||||
Deterministic bool
|
||||
|
||||
// formatDepth is the depth at which we respect the format flag.
|
||||
formatDepth int
|
||||
// format is custom formatting for the value at the specified depth.
|
||||
|
@@ -62,7 +62,7 @@ func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) {
|
||||
}
|
||||
return dec.stringCache.make(val), nil
|
||||
case '0':
|
||||
fv, _ := parseFloat(val, 64) // ignore error since readValue gaurantees val is valid
|
||||
fv, _ := parseFloat(val, 64) // ignore error since readValue guarantees val is valid
|
||||
return fv, nil
|
||||
default:
|
||||
panic("BUG: invalid kind: " + k.String())
|
||||
@@ -99,13 +99,32 @@ func marshalObjectAny(mo MarshalOptions, enc *Encoder, obj map[string]any) error
|
||||
if !enc.options.AllowInvalidUTF8 {
|
||||
enc.tokens.last.disableNamespace()
|
||||
}
|
||||
for name, val := range obj {
|
||||
if err := enc.WriteToken(String(name)); err != nil {
|
||||
return err
|
||||
if !mo.Deterministic || len(obj) <= 1 {
|
||||
for name, val := range obj {
|
||||
if err := enc.WriteToken(String(name)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := marshalValueAny(mo, enc, val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := marshalValueAny(mo, enc, val); err != nil {
|
||||
return err
|
||||
} else {
|
||||
names := getStrings(len(obj))
|
||||
var i int
|
||||
for name := range obj {
|
||||
(*names)[i] = name
|
||||
i++
|
||||
}
|
||||
names.Sort()
|
||||
for _, name := range *names {
|
||||
if err := enc.WriteToken(String(name)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := marshalValueAny(mo, enc, obj[name]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
putStrings(names)
|
||||
}
|
||||
if err := enc.WriteToken(ObjectEnd); err != nil {
|
||||
return err
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
@@ -228,13 +230,7 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
|
||||
}
|
||||
}
|
||||
val := enc.UnusedBuffer()
|
||||
var b []byte
|
||||
if va.Kind() == reflect.Array {
|
||||
// TODO(https://go.dev/issue/47066): Avoid reflect.Value.Slice.
|
||||
b = va.Slice(0, va.Len()).Bytes()
|
||||
} else {
|
||||
b = va.Bytes()
|
||||
}
|
||||
b := va.Bytes()
|
||||
n := len(`"`) + encodedLen(len(b)) + len(`"`)
|
||||
if cap(val) < n {
|
||||
val = make([]byte, n)
|
||||
@@ -248,19 +244,19 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
|
||||
}
|
||||
unmarshalDefault := fncs.unmarshal
|
||||
fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
|
||||
decode, decodedLen := decodeBase64, decodedLenBase64
|
||||
decode, decodedLen, encodedLen := decodeBase64, decodedLenBase64, encodedLenBase64
|
||||
if uo.format != "" && uo.formatDepth == dec.tokens.depth() {
|
||||
switch uo.format {
|
||||
case "base64":
|
||||
decode, decodedLen = decodeBase64, decodedLenBase64
|
||||
decode, decodedLen, encodedLen = decodeBase64, decodedLenBase64, encodedLenBase64
|
||||
case "base64url":
|
||||
decode, decodedLen = decodeBase64URL, decodedLenBase64URL
|
||||
decode, decodedLen, encodedLen = decodeBase64URL, decodedLenBase64URL, encodedLenBase64URL
|
||||
case "base32":
|
||||
decode, decodedLen = decodeBase32, decodedLenBase32
|
||||
decode, decodedLen, encodedLen = decodeBase32, decodedLenBase32, encodedLenBase32
|
||||
case "base32hex":
|
||||
decode, decodedLen = decodeBase32Hex, decodedLenBase32Hex
|
||||
decode, decodedLen, encodedLen = decodeBase32Hex, decodedLenBase32Hex, encodedLenBase32Hex
|
||||
case "base16", "hex":
|
||||
decode, decodedLen = decodeBase16, decodedLenBase16
|
||||
decode, decodedLen, encodedLen = decodeBase16, decodedLenBase16, encodedLenBase16
|
||||
case "array":
|
||||
uo.format = ""
|
||||
return unmarshalDefault(uo, dec, va)
|
||||
@@ -290,23 +286,28 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
|
||||
n--
|
||||
}
|
||||
n = decodedLen(n)
|
||||
var b []byte
|
||||
b := va.Bytes()
|
||||
if va.Kind() == reflect.Array {
|
||||
// TODO(https://go.dev/issue/47066): Avoid reflect.Value.Slice.
|
||||
b = va.Slice(0, va.Len()).Bytes()
|
||||
if n != len(b) {
|
||||
err := fmt.Errorf("decoded base64 length of %d mismatches array length of %d", n, len(b))
|
||||
return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err}
|
||||
}
|
||||
} else {
|
||||
b = va.Bytes()
|
||||
if b == nil || cap(b) < n {
|
||||
b = make([]byte, n)
|
||||
} else {
|
||||
b = b[:n]
|
||||
}
|
||||
}
|
||||
if _, err := decode(b, val); err != nil {
|
||||
n2, err := decode(b, val)
|
||||
if err == nil && len(val) != encodedLen(n2) {
|
||||
// TODO(https://go.dev/issue/53845): RFC 4648, section 3.3,
|
||||
// specifies that non-alphabet characters must be rejected.
|
||||
// Unfortunately, the "base32" and "base64" packages allow
|
||||
// '\r' and '\n' characters by default.
|
||||
err = errors.New("illegal data at input byte " + strconv.Itoa(bytes.IndexAny(val, "\r\n")))
|
||||
}
|
||||
if err != nil {
|
||||
return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err}
|
||||
}
|
||||
if va.Kind() == reflect.Slice {
|
||||
@@ -412,7 +413,7 @@ func makeUintArshaler(t reflect.Type) *arshaler {
|
||||
return nil
|
||||
}
|
||||
|
||||
x := math.Float64frombits(uint64(va.Uint()))
|
||||
x := math.Float64frombits(va.Uint())
|
||||
return enc.writeNumber(x, rawUintNumber, mo.StringifyNumbers)
|
||||
}
|
||||
fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
|
||||
@@ -450,7 +451,7 @@ func makeUintArshaler(t reflect.Type) *arshaler {
|
||||
err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrRange)
|
||||
return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err}
|
||||
}
|
||||
va.SetUint(uint64(n))
|
||||
va.SetUint(n)
|
||||
return nil
|
||||
}
|
||||
return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t}
|
||||
@@ -549,23 +550,9 @@ func makeFloatArshaler(t reflect.Type) *arshaler {
|
||||
return &fncs
|
||||
}
|
||||
|
||||
var mapIterPool = sync.Pool{
|
||||
New: func() any { return new(reflect.MapIter) },
|
||||
}
|
||||
|
||||
func getMapIter(mv reflect.Value) *reflect.MapIter {
|
||||
iter := mapIterPool.Get().(*reflect.MapIter)
|
||||
iter.Reset(mv)
|
||||
return iter
|
||||
}
|
||||
func putMapIter(iter *reflect.MapIter) {
|
||||
iter.Reset(reflect.Value{}) // allow underlying map to be garbage collected
|
||||
mapIterPool.Put(iter)
|
||||
}
|
||||
|
||||
func makeMapArshaler(t reflect.Type) *arshaler {
|
||||
// NOTE: The logic below disables namespaces for tracking duplicate names
|
||||
// when handling map keys with a unique represention.
|
||||
// when handling map keys with a unique representation.
|
||||
|
||||
// NOTE: Values retrieved from a map are not addressable,
|
||||
// so we shallow copy the values to make them addressable and
|
||||
@@ -641,24 +628,76 @@ func makeMapArshaler(t reflect.Type) *arshaler {
|
||||
enc.tokens.last.disableNamespace()
|
||||
}
|
||||
|
||||
// NOTE: Map entries are serialized in a non-deterministic order.
|
||||
// Users that need stable output should call RawValue.Canonicalize.
|
||||
// TODO(go1.19): Remove use of a sync.Pool with reflect.MapIter.
|
||||
// Calling reflect.Value.MapRange no longer allocates.
|
||||
// See https://go.dev/cl/400675.
|
||||
iter := getMapIter(va.Value)
|
||||
defer putMapIter(iter)
|
||||
for iter.Next() {
|
||||
k.SetIterKey(iter)
|
||||
if err := marshalKey(mko, enc, k); err != nil {
|
||||
// TODO: If err is errMissingName, then wrap it as a
|
||||
// SemanticError since this key type cannot be serialized
|
||||
// as a JSON string.
|
||||
return err
|
||||
switch {
|
||||
case !mo.Deterministic || n <= 1:
|
||||
for iter := va.Value.MapRange(); iter.Next(); {
|
||||
k.SetIterKey(iter)
|
||||
if err := marshalKey(mko, enc, k); err != nil {
|
||||
// TODO: If err is errMissingName, then wrap it as a
|
||||
// SemanticError since this key type cannot be serialized
|
||||
// as a JSON string.
|
||||
return err
|
||||
}
|
||||
v.SetIterValue(iter)
|
||||
if err := marshalVal(mo, enc, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
v.SetIterValue(iter)
|
||||
if err := marshalVal(mo, enc, v); err != nil {
|
||||
return err
|
||||
case !nonDefaultKey && t.Key().Kind() == reflect.String:
|
||||
names := getStrings(n)
|
||||
for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ {
|
||||
k.SetIterKey(iter)
|
||||
(*names)[i] = k.String()
|
||||
}
|
||||
names.Sort()
|
||||
for _, name := range *names {
|
||||
if err := enc.WriteToken(String(name)); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf.
|
||||
k.SetString(name)
|
||||
v.Set(va.MapIndex(k.Value))
|
||||
if err := marshalVal(mo, enc, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
putStrings(names)
|
||||
default:
|
||||
type member struct {
|
||||
name string // unquoted name
|
||||
key addressableValue
|
||||
}
|
||||
members := make([]member, n)
|
||||
keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n)
|
||||
for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ {
|
||||
// Marshal the member name.
|
||||
k := addressableValue{keys.Index(i)} // indexed slice element is always addressable
|
||||
k.SetIterKey(iter)
|
||||
if err := marshalKey(mko, enc, k); err != nil {
|
||||
// TODO: If err is errMissingName, then wrap it as a
|
||||
// SemanticError since this key type cannot be serialized
|
||||
// as a JSON string.
|
||||
return err
|
||||
}
|
||||
name := enc.unwriteOnlyObjectMemberName()
|
||||
members[i] = member{name, k}
|
||||
}
|
||||
// TODO: If AllowDuplicateNames is enabled, then sort according
|
||||
// to reflect.Value as well if the names are equal.
|
||||
// See internal/fmtsort.
|
||||
// TODO(https://go.dev/issue/47619): Use slices.SortFunc instead.
|
||||
sort.Slice(members, func(i, j int) bool {
|
||||
return lessUTF16(members[i].name, members[j].name)
|
||||
})
|
||||
for _, member := range members {
|
||||
if err := enc.WriteToken(String(member.name)); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf.
|
||||
v.Set(va.MapIndex(member.key.Value))
|
||||
if err := marshalVal(mo, enc, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -856,7 +895,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
|
||||
// 2. The object namespace is guaranteed to be disabled.
|
||||
// 3. The object name is guaranteed to be valid and pre-escaped.
|
||||
// 4. There is no need to flush the buffer (for unwrite purposes).
|
||||
// 5. There is no possibility of an error occuring.
|
||||
// 5. There is no possibility of an error occurring.
|
||||
if optimizeCommon {
|
||||
// Append any delimiters or optional whitespace.
|
||||
if enc.tokens.last.length() > 0 {
|
||||
@@ -996,7 +1035,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
|
||||
|
||||
if fields.inlinedFallback == nil {
|
||||
// Skip unknown value since we have no place to store it.
|
||||
if err := dec.skipValue(); err != nil {
|
||||
if err := dec.SkipValue(); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
@@ -89,35 +90,61 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
if v.Len() == 0 {
|
||||
m := v // must be a map[string]V
|
||||
n := m.Len()
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
m := v
|
||||
mk := newAddressableValue(stringType)
|
||||
mv := newAddressableValue(m.Type().Elem())
|
||||
for iter := m.MapRange(); iter.Next(); {
|
||||
b, err := appendString(enc.UnusedBuffer(), iter.Key().String(), !enc.options.AllowInvalidUTF8, nil)
|
||||
marshalKey := func(mk addressableValue) error {
|
||||
b, err := appendString(enc.UnusedBuffer(), mk.String(), !enc.options.AllowInvalidUTF8, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if insertUnquotedName != nil {
|
||||
isVerbatim := consumeSimpleString(b) == len(b)
|
||||
isVerbatim := bytes.IndexByte(b, '\\') < 0
|
||||
name := unescapeStringMayCopy(b, isVerbatim)
|
||||
if !insertUnquotedName(name) {
|
||||
return &SyntacticError{str: "duplicate name " + string(b) + " in object"}
|
||||
}
|
||||
}
|
||||
if err := enc.WriteValue(b); err != nil {
|
||||
return err
|
||||
return enc.WriteValue(b)
|
||||
}
|
||||
marshalVal := f.fncs.marshal
|
||||
if mo.Marshalers != nil {
|
||||
marshalVal, _ = mo.Marshalers.lookup(marshalVal, mv.Type())
|
||||
}
|
||||
if !mo.Deterministic || n <= 1 {
|
||||
for iter := m.MapRange(); iter.Next(); {
|
||||
mk.SetIterKey(iter)
|
||||
if err := marshalKey(mk); err != nil {
|
||||
return err
|
||||
}
|
||||
mv.Set(iter.Value())
|
||||
if err := marshalVal(mo, enc, mv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
mv.Set(iter.Value())
|
||||
marshal := f.fncs.marshal
|
||||
if mo.Marshalers != nil {
|
||||
marshal, _ = mo.Marshalers.lookup(marshal, mv.Type())
|
||||
} else {
|
||||
names := getStrings(n)
|
||||
for i, iter := 0, m.Value.MapRange(); i < n && iter.Next(); i++ {
|
||||
mk.SetIterKey(iter)
|
||||
(*names)[i] = mk.String()
|
||||
}
|
||||
if err := marshal(mo, enc, mv); err != nil {
|
||||
return err
|
||||
names.Sort()
|
||||
for _, name := range *names {
|
||||
mk.SetString(name)
|
||||
if err := marshalKey(mk); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(https://go.dev/issue/57061): Use mv.SetMapIndexOf.
|
||||
mv.Set(m.MapIndex(mk.Value))
|
||||
if err := marshalVal(mo, enc, mv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
putStrings(names)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -162,7 +189,7 @@ func unmarshalInlinedFallbackNext(uo UnmarshalOptions, dec *Decoder, va addressa
|
||||
} else {
|
||||
name := string(unquotedName) // TODO: Intern this?
|
||||
|
||||
m := v
|
||||
m := v // must be a map[string]V
|
||||
if m.IsNil() {
|
||||
m.Set(reflect.MakeMap(m.Type()))
|
||||
}
|
||||
|
@@ -21,8 +21,8 @@ var (
|
||||
)
|
||||
|
||||
// MarshalerV1 is implemented by types that can marshal themselves.
|
||||
// It is recommended that types implement MarshalerV2 unless
|
||||
// the implementation is trying to avoid a hard dependency on this package.
|
||||
// It is recommended that types implement MarshalerV2 unless the implementation
|
||||
// is trying to avoid a hard dependency on the "jsontext" package.
|
||||
//
|
||||
// It is recommended that implementations return a buffer that is safe
|
||||
// for the caller to retain and potentially mutate.
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -85,25 +86,39 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
fncs.nonDefault = true
|
||||
fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
|
||||
format := time.RFC3339Nano
|
||||
isRFC3339 := true
|
||||
if mo.format != "" && mo.formatDepth == enc.tokens.depth() {
|
||||
var err error
|
||||
format, err = checkTimeFormat(mo.format)
|
||||
format, isRFC3339, err = checkTimeFormat(mo.format)
|
||||
if err != nil {
|
||||
return &SemanticError{action: "marshal", GoType: t, Err: err}
|
||||
}
|
||||
}
|
||||
|
||||
tt := va.Interface().(time.Time)
|
||||
if y := tt.Year(); y < 0 || y >= 10000 {
|
||||
// RFC 3339 is clear that years are 4 digits exactly.
|
||||
// See https://go.dev/issue/4556#c15 for more discussion.
|
||||
err := fmt.Errorf("year %d outside of range [0,9999]", y)
|
||||
return &SemanticError{action: "marshal", GoType: t, Err: err}
|
||||
}
|
||||
b := enc.UnusedBuffer()
|
||||
b = append(b, '"')
|
||||
b = tt.AppendFormat(b, format)
|
||||
b = append(b, '"')
|
||||
if isRFC3339 {
|
||||
// Not all Go timestamps can be represented as valid RFC 3339.
|
||||
// Explicitly check for these edge cases.
|
||||
// See https://go.dev/issue/4556 and https://go.dev/issue/54580.
|
||||
var err error
|
||||
switch b := b[len(`"`) : len(b)-len(`"`)]; {
|
||||
case b[len("9999")] != '-': // year must be exactly 4 digits wide
|
||||
err = errors.New("year outside of range [0,9999]")
|
||||
case b[len(b)-1] != 'Z':
|
||||
c := b[len(b)-len("Z07:00")]
|
||||
if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 {
|
||||
err = errors.New("timezone hour outside of range [0,23]")
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return &SemanticError{action: "marshal", GoType: t, Err: err}
|
||||
}
|
||||
return enc.WriteValue(b) // RFC 3339 never needs JSON escaping
|
||||
}
|
||||
// The format may contain special characters that need escaping.
|
||||
// Verify that the result is a valid JSON string (common case),
|
||||
// otherwise escape the string correctly (slower case).
|
||||
@@ -113,10 +128,11 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
return enc.WriteValue(b)
|
||||
}
|
||||
fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
|
||||
format := time.RFC3339Nano
|
||||
format := time.RFC3339
|
||||
isRFC3339 := true
|
||||
if uo.format != "" && uo.formatDepth == dec.tokens.depth() {
|
||||
var err error
|
||||
format, err = checkTimeFormat(uo.format)
|
||||
format, isRFC3339, err = checkTimeFormat(uo.format)
|
||||
if err != nil {
|
||||
return &SemanticError{action: "unmarshal", GoType: t, Err: err}
|
||||
}
|
||||
@@ -136,6 +152,29 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
case '"':
|
||||
val = unescapeStringMayCopy(val, flags.isVerbatim())
|
||||
tt2, err := time.Parse(format, string(val))
|
||||
if isRFC3339 && err == nil {
|
||||
// TODO(https://go.dev/issue/54580): RFC 3339 specifies
|
||||
// the exact grammar of a valid timestamp. However,
|
||||
// the parsing functionality in "time" is too loose and
|
||||
// incorrectly accepts invalid timestamps as valid.
|
||||
// Remove these manual checks when "time" checks it for us.
|
||||
newParseError := func(layout, value, layoutElem, valueElem, message string) error {
|
||||
return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message}
|
||||
}
|
||||
switch {
|
||||
case val[len("2006-01-02T")+1] == ':': // hour must be two digits
|
||||
err = newParseError(format, string(val), "15", string(val[len("2006-01-02T"):][:1]), "")
|
||||
case val[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period
|
||||
err = newParseError(format, string(val), ".", ",", "")
|
||||
case val[len(val)-1] != 'Z':
|
||||
switch {
|
||||
case parseDec2(val[len(val)-len("07:00"):]) >= 24: // timezone hour must be in range
|
||||
err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone hour out of range")
|
||||
case parseDec2(val[len(val)-len("00"):]) >= 60: // timezone minute must be in range
|
||||
err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone minute out of range")
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err}
|
||||
}
|
||||
@@ -149,48 +188,54 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
return fncs
|
||||
}
|
||||
|
||||
func checkTimeFormat(format string) (string, error) {
|
||||
func checkTimeFormat(format string) (string, bool, error) {
|
||||
// We assume that an exported constant in the time package will
|
||||
// always start with an uppercase ASCII letter.
|
||||
if len(format) > 0 && 'A' <= format[0] && format[0] <= 'Z' {
|
||||
switch format {
|
||||
case "ANSIC":
|
||||
return time.ANSIC, nil
|
||||
return time.ANSIC, false, nil
|
||||
case "UnixDate":
|
||||
return time.UnixDate, nil
|
||||
return time.UnixDate, false, nil
|
||||
case "RubyDate":
|
||||
return time.RubyDate, nil
|
||||
return time.RubyDate, false, nil
|
||||
case "RFC822":
|
||||
return time.RFC822, nil
|
||||
return time.RFC822, false, nil
|
||||
case "RFC822Z":
|
||||
return time.RFC822Z, nil
|
||||
return time.RFC822Z, false, nil
|
||||
case "RFC850":
|
||||
return time.RFC850, nil
|
||||
return time.RFC850, false, nil
|
||||
case "RFC1123":
|
||||
return time.RFC1123, nil
|
||||
return time.RFC1123, false, nil
|
||||
case "RFC1123Z":
|
||||
return time.RFC1123Z, nil
|
||||
return time.RFC1123Z, false, nil
|
||||
case "RFC3339":
|
||||
return time.RFC3339, nil
|
||||
return time.RFC3339, true, nil
|
||||
case "RFC3339Nano":
|
||||
return time.RFC3339Nano, nil
|
||||
return time.RFC3339Nano, true, nil
|
||||
case "Kitchen":
|
||||
return time.Kitchen, nil
|
||||
return time.Kitchen, false, nil
|
||||
case "Stamp":
|
||||
return time.Stamp, nil
|
||||
return time.Stamp, false, nil
|
||||
case "StampMilli":
|
||||
return time.StampMilli, nil
|
||||
return time.StampMilli, false, nil
|
||||
case "StampMicro":
|
||||
return time.StampMicro, nil
|
||||
return time.StampMicro, false, nil
|
||||
case "StampNano":
|
||||
return time.StampNano, nil
|
||||
return time.StampNano, false, nil
|
||||
default:
|
||||
// Reject any format that is an exported Go identifier in case
|
||||
// new format constants are added to the time package.
|
||||
if strings.TrimFunc(format, isLetterOrDigit) == "" {
|
||||
return "", fmt.Errorf("undefined format layout: %v", format)
|
||||
return "", false, fmt.Errorf("undefined format layout: %v", format)
|
||||
}
|
||||
}
|
||||
}
|
||||
return format, nil
|
||||
return format, false, nil
|
||||
}
|
||||
|
||||
// parseDec2 parses b as an unsigned, base-10, 2-digit number.
|
||||
// It panics if len(b) < 2. The result is undefined if digits are not base-10.
|
||||
func parseDec2(b []byte) byte {
|
||||
return 10*(b[0]-'0') + (b[1] - '0')
|
||||
}
|
||||
|
12
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go
generated
vendored
12
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go
generated
vendored
@@ -347,9 +347,9 @@ func (d *Decoder) PeekKind() Kind {
|
||||
return next
|
||||
}
|
||||
|
||||
// skipValue is semantically equivalent to calling ReadValue and discarding
|
||||
// SkipValue is semantically equivalent to calling ReadValue and discarding
|
||||
// the result except that memory is not wasted trying to hold the entire result.
|
||||
func (d *Decoder) skipValue() error {
|
||||
func (d *Decoder) SkipValue() error {
|
||||
switch d.PeekKind() {
|
||||
case '{', '[':
|
||||
// For JSON objects and arrays, keep skipping all tokens
|
||||
@@ -374,7 +374,7 @@ func (d *Decoder) skipValue() error {
|
||||
}
|
||||
|
||||
// ReadToken reads the next Token, advancing the read offset.
|
||||
// The returned token is only valid until the next Peek or Read call.
|
||||
// The returned token is only valid until the next Peek, Read, or Skip call.
|
||||
// It returns io.EOF if there are no more tokens.
|
||||
func (d *Decoder) ReadToken() (Token, error) {
|
||||
// Determine the next kind.
|
||||
@@ -585,7 +585,7 @@ func (f valueFlags) isCanonical() bool { return f&stringNonCanonical == 0 }
|
||||
|
||||
// ReadValue returns the next raw JSON value, advancing the read offset.
|
||||
// The value is stripped of any leading or trailing whitespace.
|
||||
// The returned value is only valid until the next Peek or Read call and
|
||||
// The returned value is only valid until the next Peek, Read, or Skip call and
|
||||
// may not be mutated while the Decoder remains in use.
|
||||
// If the decoder is currently at the end token for an object or array,
|
||||
// then it reports a SyntacticError and the internal state remains unchanged.
|
||||
@@ -1013,7 +1013,7 @@ func (d *Decoder) InputOffset() int64 {
|
||||
// UnreadBuffer returns the data remaining in the unread buffer,
|
||||
// which may contain zero or more bytes.
|
||||
// The returned buffer must not be mutated while Decoder continues to be used.
|
||||
// The buffer contents are valid until the next Peek or Read call.
|
||||
// The buffer contents are valid until the next Peek, Read, or Skip call.
|
||||
func (d *Decoder) UnreadBuffer() []byte {
|
||||
return d.unreadBuffer()
|
||||
}
|
||||
@@ -1213,7 +1213,7 @@ func consumeStringResumable(flags *valueFlags, b []byte, resumeOffset int, valid
|
||||
return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"}
|
||||
}
|
||||
// Only certain control characters can use the \uFFFF notation
|
||||
// for canonical formating (per RFC 8785, section 3.2.2.2.).
|
||||
// for canonical formatting (per RFC 8785, section 3.2.2.2.).
|
||||
switch v1 {
|
||||
// \uFFFF notation not permitted for these characters.
|
||||
case '\b', '\f', '\n', '\r', '\t':
|
||||
|
9
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go
generated
vendored
9
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go
generated
vendored
@@ -8,8 +8,7 @@
|
||||
// primitive data types such as booleans, strings, and numbers,
|
||||
// in addition to structured data types such as objects and arrays.
|
||||
//
|
||||
//
|
||||
// Terminology
|
||||
// # Terminology
|
||||
//
|
||||
// This package uses the terms "encode" and "decode" for syntactic functionality
|
||||
// that is concerned with processing JSON based on its grammar, and
|
||||
@@ -32,8 +31,7 @@
|
||||
//
|
||||
// See RFC 8259 for more information.
|
||||
//
|
||||
//
|
||||
// Specifications
|
||||
// # Specifications
|
||||
//
|
||||
// Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259,
|
||||
// and RFC 8785. Each RFC is generally a stricter subset of another RFC.
|
||||
@@ -60,8 +58,7 @@
|
||||
// In particular, it makes specific choices about behavior that RFC 8259
|
||||
// leaves as undefined in order to ensure greater interoperability.
|
||||
//
|
||||
//
|
||||
// JSON Representation of Go structs
|
||||
// # JSON Representation of Go structs
|
||||
//
|
||||
// A Go struct is naturally represented as a JSON object,
|
||||
// where each Go struct field corresponds with a JSON object member.
|
||||
|
24
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go
generated
vendored
24
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go
generated
vendored
@@ -347,6 +347,30 @@ func (e *Encoder) unwriteEmptyObjectMember(prevName *string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// unwriteOnlyObjectMemberName unwrites the only object member name
|
||||
// and returns the unquoted name.
|
||||
func (e *Encoder) unwriteOnlyObjectMemberName() string {
|
||||
if last := e.tokens.last; !last.isObject() || last.length() != 1 {
|
||||
panic("BUG: must be called on an object after writing first name")
|
||||
}
|
||||
|
||||
// Unwrite the name and whitespace.
|
||||
b := trimSuffixString(e.buf)
|
||||
isVerbatim := bytes.IndexByte(e.buf[len(b):], '\\') < 0
|
||||
name := string(unescapeStringMayCopy(e.buf[len(b):], isVerbatim))
|
||||
e.buf = trimSuffixWhitespace(b)
|
||||
|
||||
// Undo state changes.
|
||||
e.tokens.last.decrement()
|
||||
if !e.options.AllowDuplicateNames {
|
||||
if e.tokens.last.isActiveNamespace() {
|
||||
e.namespaces.last().removeLast()
|
||||
}
|
||||
e.names.clearLast()
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func trimSuffixWhitespace(b []byte) []byte {
|
||||
// NOTE: The arguments and logic are kept simple to keep this inlineable.
|
||||
n := len(b) - 1
|
||||
|
32
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go
generated
vendored
32
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go
generated
vendored
@@ -8,6 +8,7 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math/bits"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -148,3 +149,34 @@ func putStreamingDecoder(d *Decoder) {
|
||||
streamingDecoderPool.Put(d)
|
||||
}
|
||||
}
|
||||
|
||||
var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }}
|
||||
|
||||
type stringSlice []string
|
||||
|
||||
// getStrings returns a non-nil pointer to a slice with length n.
|
||||
func getStrings(n int) *stringSlice {
|
||||
s := stringsPools.Get().(*stringSlice)
|
||||
if cap(*s) < n {
|
||||
*s = make([]string, n)
|
||||
}
|
||||
*s = (*s)[:n]
|
||||
return s
|
||||
}
|
||||
|
||||
func putStrings(s *stringSlice) {
|
||||
if cap(*s) > 1<<10 {
|
||||
*s = nil // avoid pinning arbitrarily large amounts of memory
|
||||
}
|
||||
stringsPools.Put(s)
|
||||
}
|
||||
|
||||
// Sort sorts the string slice according to RFC 8785, section 3.2.3.
|
||||
func (ss *stringSlice) Sort() {
|
||||
// TODO(https://go.dev/issue/47619): Use slices.SortFunc instead.
|
||||
sort.Sort(ss)
|
||||
}
|
||||
|
||||
func (ss *stringSlice) Len() int { return len(*ss) }
|
||||
func (ss *stringSlice) Less(i, j int) bool { return lessUTF16((*ss)[i], (*ss)[j]) }
|
||||
func (ss *stringSlice) Swap(i, j int) { (*ss)[i], (*ss)[j] = (*ss)[j], (*ss)[i] }
|
||||
|
4
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go
generated
vendored
4
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go
generated
vendored
@@ -721,7 +721,7 @@ func (s *uintSet) has(i uint) bool {
|
||||
return s.lo.has(i)
|
||||
} else {
|
||||
i -= 64
|
||||
iHi, iLo := int(i/64), uint(i%64)
|
||||
iHi, iLo := int(i/64), i%64
|
||||
return iHi < len(s.hi) && s.hi[iHi].has(iLo)
|
||||
}
|
||||
}
|
||||
@@ -735,7 +735,7 @@ func (s *uintSet) insert(i uint) bool {
|
||||
return !has
|
||||
} else {
|
||||
i -= 64
|
||||
iHi, iLo := int(i/64), uint(i%64)
|
||||
iHi, iLo := int(i/64), i%64
|
||||
if iHi >= len(s.hi) {
|
||||
s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...)
|
||||
s.hi = s.hi[:cap(s.hi)]
|
||||
|
10
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go
generated
vendored
10
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go
generated
vendored
@@ -112,7 +112,7 @@ func Bool(b bool) Token {
|
||||
return False
|
||||
}
|
||||
|
||||
// String construct a Token representing a JSON string.
|
||||
// String constructs a Token representing a JSON string.
|
||||
// The provided string should contain valid UTF-8, otherwise invalid characters
|
||||
// may be mangled as the Unicode replacement character.
|
||||
func String(s string) Token {
|
||||
@@ -225,7 +225,7 @@ func (t Token) appendString(dst []byte, validateUTF8, preserveRaw bool, escapeRu
|
||||
}
|
||||
|
||||
// String returns the unescaped string value for a JSON string.
|
||||
// For other JSON kinds, this returns the raw JSON represention.
|
||||
// For other JSON kinds, this returns the raw JSON representation.
|
||||
func (t Token) String() string {
|
||||
// This is inlinable to take advantage of "function outlining".
|
||||
// This avoids an allocation for the string(b) conversion
|
||||
@@ -373,10 +373,10 @@ func (t Token) Int() int64 {
|
||||
case 'i':
|
||||
return int64(t.num)
|
||||
case 'u':
|
||||
if uint64(t.num) > maxInt64 {
|
||||
if t.num > maxInt64 {
|
||||
return maxInt64
|
||||
}
|
||||
return int64(uint64(t.num))
|
||||
return int64(t.num)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ func (t Token) Uint() uint64 {
|
||||
// Handle exact integer value.
|
||||
switch t.str[0] {
|
||||
case 'u':
|
||||
return uint64(t.num)
|
||||
return t.num
|
||||
case 'i':
|
||||
if int64(t.num) < minUint64 {
|
||||
return minUint64
|
||||
|
56
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go
generated
vendored
56
vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go
generated
vendored
@@ -263,7 +263,7 @@ func reorderObjects(d *Decoder, scratch *[]byte) {
|
||||
afterValue := d.InputOffset()
|
||||
|
||||
if isSorted && len(*members) > 0 {
|
||||
isSorted = lessUTF16(prevName, name)
|
||||
isSorted = lessUTF16(prevName, []byte(name))
|
||||
}
|
||||
*members = append(*members, memberName{name, beforeName, afterValue})
|
||||
prevName = name
|
||||
@@ -317,7 +317,7 @@ func reorderObjects(d *Decoder, scratch *[]byte) {
|
||||
// to the UTF-16 codepoints of the UTF-8 encoded input strings.
|
||||
// This implements the ordering specified in RFC 8785, section 3.2.3.
|
||||
// The inputs must be valid UTF-8, otherwise this may panic.
|
||||
func lessUTF16(x, y []byte) bool {
|
||||
func lessUTF16[Bytes []byte | string](x, y Bytes) bool {
|
||||
// NOTE: This is an optimized, allocation-free implementation
|
||||
// of lessUTF16Simple in fuzz_test.go. FuzzLessUTF16 verifies that the
|
||||
// two implementations agree on the result of comparing any two strings.
|
||||
@@ -326,8 +326,13 @@ func lessUTF16(x, y []byte) bool {
|
||||
return ('\u0000' <= r && r <= '\uD7FF') || ('\uE000' <= r && r <= '\uFFFF')
|
||||
}
|
||||
|
||||
var invalidUTF8 bool
|
||||
x0, y0 := x, y
|
||||
for {
|
||||
if len(x) == 0 || len(y) == 0 {
|
||||
if len(x) == len(y) && invalidUTF8 {
|
||||
return string(x0) < string(y0)
|
||||
}
|
||||
return len(x) < len(y)
|
||||
}
|
||||
|
||||
@@ -341,35 +346,36 @@ func lessUTF16(x, y []byte) bool {
|
||||
}
|
||||
|
||||
// Decode next pair of runes as UTF-8.
|
||||
rx, nx := utf8.DecodeRune(x)
|
||||
ry, ny := utf8.DecodeRune(y)
|
||||
// TODO(https://go.dev/issue/56948): Use a generic implementation
|
||||
// of utf8.DecodeRune, or rely on a compiler optimization to statically
|
||||
// hide the cost of a type switch (https://go.dev/issue/57072).
|
||||
var rx, ry rune
|
||||
var nx, ny int
|
||||
switch any(x).(type) {
|
||||
case string:
|
||||
rx, nx = utf8.DecodeRuneInString(string(x))
|
||||
ry, ny = utf8.DecodeRuneInString(string(y))
|
||||
case []byte:
|
||||
rx, nx = utf8.DecodeRune([]byte(x))
|
||||
ry, ny = utf8.DecodeRune([]byte(y))
|
||||
}
|
||||
|
||||
selfx := isUTF16Self(rx)
|
||||
selfy := isUTF16Self(ry)
|
||||
switch {
|
||||
|
||||
// Both runes encode as either a single or surrogate pair
|
||||
// of UTF-16 codepoints.
|
||||
case isUTF16Self(rx) == isUTF16Self(ry):
|
||||
if rx != ry {
|
||||
return rx < ry
|
||||
}
|
||||
|
||||
// The x rune is a single UTF-16 codepoint, while
|
||||
// the y rune is a surrogate pair of UTF-16 codepoints.
|
||||
case isUTF16Self(rx):
|
||||
ry, _ := utf16.EncodeRune(ry)
|
||||
if rx != ry {
|
||||
return rx < ry
|
||||
}
|
||||
panic("BUG: invalid UTF-8") // implies rx is an unpaired surrogate half
|
||||
|
||||
case selfx && !selfy:
|
||||
ry, _ = utf16.EncodeRune(ry)
|
||||
// The y rune is a single UTF-16 codepoint, while
|
||||
// the x rune is a surrogate pair of UTF-16 codepoints.
|
||||
case isUTF16Self(ry):
|
||||
rx, _ := utf16.EncodeRune(rx)
|
||||
if rx != ry {
|
||||
return rx < ry
|
||||
}
|
||||
panic("BUG: invalid UTF-8") // implies ry is an unpaired surrogate half
|
||||
case selfy && !selfx:
|
||||
rx, _ = utf16.EncodeRune(rx)
|
||||
}
|
||||
if rx != ry {
|
||||
return rx < ry
|
||||
}
|
||||
invalidUTF8 = invalidUTF8 || (rx == utf8.RuneError && nx == 1) || (ry == utf8.RuneError && ny == 1)
|
||||
x, y = x[nx:], y[ny:]
|
||||
}
|
||||
}
|
||||
|
260
vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go
generated
vendored
Normal file
260
vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
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 schemaconv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/schema"
|
||||
)
|
||||
|
||||
// ToSchemaFromOpenAPI converts a directory of OpenAPI schemas to an smd Schema.
|
||||
// - models: a map from definition name to OpenAPI V3 structural schema for each definition.
|
||||
// Key in map is used to resolve references in the schema.
|
||||
// - preserveUnknownFields: flag indicating whether unknown fields in all schemas should be preserved.
|
||||
// - returns: nil and an error if there is a parse error, or if schema does not satisfy a
|
||||
// required structural schema invariant for conversion. If no error, returns
|
||||
// a new smd schema.
|
||||
//
|
||||
// Schema should be validated as structural before using with this function, or
|
||||
// there may be information lost.
|
||||
func ToSchemaFromOpenAPI(models map[string]*spec.Schema, preserveUnknownFields bool) (*schema.Schema, error) {
|
||||
c := convert{
|
||||
preserveUnknownFields: preserveUnknownFields,
|
||||
output: &schema.Schema{},
|
||||
}
|
||||
|
||||
for name, spec := range models {
|
||||
// Skip/Ignore top-level references
|
||||
if len(spec.Ref.String()) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var a schema.Atom
|
||||
|
||||
// Hard-coded schemas for now as proto_models implementation functions.
|
||||
// https://github.com/kubernetes/kube-openapi/issues/364
|
||||
if name == quantityResource {
|
||||
a = schema.Atom{
|
||||
Scalar: untypedDef.Atom.Scalar,
|
||||
}
|
||||
} else if name == rawExtensionResource {
|
||||
a = untypedDef.Atom
|
||||
} else {
|
||||
c2 := c.push(name, &a)
|
||||
c2.visitSpec(spec)
|
||||
c.pop(c2)
|
||||
}
|
||||
|
||||
c.insertTypeDef(name, a)
|
||||
}
|
||||
|
||||
if len(c.errorMessages) > 0 {
|
||||
return nil, errors.New(strings.Join(c.errorMessages, "\n"))
|
||||
}
|
||||
|
||||
c.addCommonTypes()
|
||||
return c.output, nil
|
||||
}
|
||||
|
||||
func (c *convert) visitSpec(m *spec.Schema) {
|
||||
// Check if this schema opts its descendants into preserve-unknown-fields
|
||||
if p, ok := m.Extensions["x-kubernetes-preserve-unknown-fields"]; ok && p == true {
|
||||
c.preserveUnknownFields = true
|
||||
}
|
||||
a := c.top()
|
||||
*a = c.parseSchema(m)
|
||||
}
|
||||
|
||||
func (c *convert) parseSchema(m *spec.Schema) schema.Atom {
|
||||
// k8s-generated OpenAPI specs have historically used only one value for
|
||||
// type and starting with OpenAPIV3 it is only allowed to be
|
||||
// a single string.
|
||||
typ := ""
|
||||
if len(m.Type) > 0 {
|
||||
typ = m.Type[0]
|
||||
}
|
||||
|
||||
// Structural Schemas produced by kubernetes follow very specific rules which
|
||||
// we can use to infer the SMD type:
|
||||
switch typ {
|
||||
case "":
|
||||
// According to Swagger docs:
|
||||
// https://swagger.io/docs/specification/data-models/data-types/#any
|
||||
//
|
||||
// If no type is specified, it is equivalent to accepting any type.
|
||||
return schema.Atom{
|
||||
Scalar: ptr(schema.Scalar("untyped")),
|
||||
List: c.parseList(m),
|
||||
Map: c.parseObject(m),
|
||||
}
|
||||
|
||||
case "object":
|
||||
return schema.Atom{
|
||||
Map: c.parseObject(m),
|
||||
}
|
||||
case "array":
|
||||
return schema.Atom{
|
||||
List: c.parseList(m),
|
||||
}
|
||||
case "integer", "boolean", "number", "string":
|
||||
return convertPrimitive(typ, m.Format)
|
||||
default:
|
||||
c.reportError("unrecognized type: '%v'", typ)
|
||||
return schema.Atom{
|
||||
Scalar: ptr(schema.Scalar("untyped")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef {
|
||||
refString := specSchema.Ref.String()
|
||||
|
||||
// Special-case handling for $ref stored inside a single-element allOf
|
||||
if len(refString) == 0 && len(specSchema.AllOf) == 1 && len(specSchema.AllOf[0].Ref.String()) > 0 {
|
||||
refString = specSchema.AllOf[0].Ref.String()
|
||||
}
|
||||
|
||||
if _, n := path.Split(refString); len(n) > 0 {
|
||||
//!TODO: Refactor the field ElementRelationship override
|
||||
// we can generate the types with overrides ahead of time rather than
|
||||
// requiring the hacky runtime support
|
||||
// (could just create a normalized key struct containing all customizations
|
||||
// to deduplicate)
|
||||
mapRelationship, err := getMapElementRelationship(specSchema.Extensions)
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
|
||||
if len(mapRelationship) > 0 {
|
||||
return schema.TypeRef{
|
||||
NamedType: &n,
|
||||
ElementRelationship: &mapRelationship,
|
||||
}
|
||||
}
|
||||
|
||||
return schema.TypeRef{
|
||||
NamedType: &n,
|
||||
}
|
||||
|
||||
}
|
||||
var inlined schema.Atom
|
||||
|
||||
// compute the type inline
|
||||
c2 := c.push("inlined in "+c.currentName, &inlined)
|
||||
c2.preserveUnknownFields = c.preserveUnknownFields
|
||||
c2.visitSpec(specSchema)
|
||||
c.pop(c2)
|
||||
|
||||
return schema.TypeRef{
|
||||
Inlined: inlined,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) parseObject(s *spec.Schema) *schema.Map {
|
||||
var fields []schema.StructField
|
||||
for name, member := range s.Properties {
|
||||
fields = append(fields, schema.StructField{
|
||||
Name: name,
|
||||
Type: c.makeOpenAPIRef(&member),
|
||||
Default: member.Default,
|
||||
})
|
||||
}
|
||||
|
||||
// AdditionalProperties informs the schema of any "unknown" keys
|
||||
// Unknown keys are enforced by the ElementType field.
|
||||
elementType := func() schema.TypeRef {
|
||||
if s.AdditionalProperties == nil {
|
||||
// According to openAPI spec, an object without properties and without
|
||||
// additionalProperties is assumed to be a free-form object.
|
||||
if c.preserveUnknownFields || len(s.Properties) == 0 {
|
||||
return schema.TypeRef{
|
||||
NamedType: &deducedName,
|
||||
}
|
||||
}
|
||||
|
||||
// If properties are specified, do not implicitly allow unknown
|
||||
// fields
|
||||
return schema.TypeRef{}
|
||||
} else if s.AdditionalProperties.Schema != nil {
|
||||
// Unknown fields use the referred schema
|
||||
return c.makeOpenAPIRef(s.AdditionalProperties.Schema)
|
||||
|
||||
} else if s.AdditionalProperties.Allows {
|
||||
// A boolean instead of a schema was provided. Deduce the
|
||||
// type from the value provided at runtime.
|
||||
return schema.TypeRef{
|
||||
NamedType: &deducedName,
|
||||
}
|
||||
} else {
|
||||
// Additional Properties are explicitly disallowed by the user.
|
||||
// Ensure element type is empty.
|
||||
return schema.TypeRef{}
|
||||
}
|
||||
}()
|
||||
|
||||
relationship, err := getMapElementRelationship(s.Extensions)
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
|
||||
return &schema.Map{
|
||||
Fields: fields,
|
||||
ElementRelationship: relationship,
|
||||
ElementType: elementType,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) parseList(s *spec.Schema) *schema.List {
|
||||
relationship, mapKeys, err := getListElementRelationship(s.Extensions)
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
elementType := func() schema.TypeRef {
|
||||
if s.Items != nil {
|
||||
if s.Items.Schema == nil || s.Items.Len() != 1 {
|
||||
c.reportError("structural schema arrays must have exactly one member subtype")
|
||||
return schema.TypeRef{
|
||||
NamedType: &deducedName,
|
||||
}
|
||||
}
|
||||
|
||||
subSchema := s.Items.Schema
|
||||
if subSchema == nil {
|
||||
subSchema = &s.Items.Schemas[0]
|
||||
}
|
||||
return c.makeOpenAPIRef(subSchema)
|
||||
} else if len(s.Type) > 0 && len(s.Type[0]) > 0 {
|
||||
c.reportError("`items` must be specified on arrays")
|
||||
}
|
||||
|
||||
// A list with no items specified is treated as "untyped".
|
||||
return schema.TypeRef{
|
||||
NamedType: &untypedName,
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
return &schema.List{
|
||||
ElementRelationship: relationship,
|
||||
Keys: mapKeys,
|
||||
ElementType: elementType,
|
||||
}
|
||||
}
|
178
vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go
generated
vendored
Normal file
178
vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
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 schemaconv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/schema"
|
||||
)
|
||||
|
||||
// ToSchema converts openapi definitions into a schema suitable for structured
|
||||
// merge (i.e. kubectl apply v2).
|
||||
func ToSchema(models proto.Models) (*schema.Schema, error) {
|
||||
return ToSchemaWithPreserveUnknownFields(models, false)
|
||||
}
|
||||
|
||||
// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured
|
||||
// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified.
|
||||
func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) {
|
||||
c := convert{
|
||||
preserveUnknownFields: preserveUnknownFields,
|
||||
output: &schema.Schema{},
|
||||
}
|
||||
for _, name := range models.ListModels() {
|
||||
model := models.LookupModel(name)
|
||||
|
||||
var a schema.Atom
|
||||
c2 := c.push(name, &a)
|
||||
model.Accept(c2)
|
||||
c.pop(c2)
|
||||
|
||||
c.insertTypeDef(name, a)
|
||||
}
|
||||
|
||||
if len(c.errorMessages) > 0 {
|
||||
return nil, errors.New(strings.Join(c.errorMessages, "\n"))
|
||||
}
|
||||
|
||||
c.addCommonTypes()
|
||||
return c.output, nil
|
||||
}
|
||||
|
||||
func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef {
|
||||
var tr schema.TypeRef
|
||||
if r, ok := model.(*proto.Ref); ok {
|
||||
if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" {
|
||||
return schema.TypeRef{
|
||||
NamedType: &untypedName,
|
||||
}
|
||||
}
|
||||
// reference a named type
|
||||
_, n := path.Split(r.Reference())
|
||||
tr.NamedType = &n
|
||||
|
||||
mapRelationship, err := getMapElementRelationship(model.GetExtensions())
|
||||
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
|
||||
// empty string means unset.
|
||||
if len(mapRelationship) > 0 {
|
||||
tr.ElementRelationship = &mapRelationship
|
||||
}
|
||||
} else {
|
||||
// compute the type inline
|
||||
c2 := c.push("inlined in "+c.currentName, &tr.Inlined)
|
||||
c2.preserveUnknownFields = preserveUnknownFields
|
||||
model.Accept(c2)
|
||||
c.pop(c2)
|
||||
|
||||
if tr == (schema.TypeRef{}) {
|
||||
// emit warning?
|
||||
tr.NamedType = &untypedName
|
||||
}
|
||||
}
|
||||
return tr
|
||||
}
|
||||
|
||||
func (c *convert) VisitKind(k *proto.Kind) {
|
||||
preserveUnknownFields := c.preserveUnknownFields
|
||||
if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true {
|
||||
preserveUnknownFields = true
|
||||
}
|
||||
|
||||
a := c.top()
|
||||
a.Map = &schema.Map{}
|
||||
for _, name := range k.FieldOrder {
|
||||
member := k.Fields[name]
|
||||
tr := c.makeRef(member, preserveUnknownFields)
|
||||
a.Map.Fields = append(a.Map.Fields, schema.StructField{
|
||||
Name: name,
|
||||
Type: tr,
|
||||
Default: member.GetDefault(),
|
||||
})
|
||||
}
|
||||
|
||||
unions, err := makeUnions(k.GetExtensions())
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
return
|
||||
}
|
||||
// TODO: We should check that the fields and discriminator
|
||||
// specified in the union are actual fields in the struct.
|
||||
a.Map.Unions = unions
|
||||
|
||||
if preserveUnknownFields {
|
||||
a.Map.ElementType = schema.TypeRef{
|
||||
NamedType: &deducedName,
|
||||
}
|
||||
}
|
||||
|
||||
a.Map.ElementRelationship, err = getMapElementRelationship(k.GetExtensions())
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) VisitArray(a *proto.Array) {
|
||||
relationship, mapKeys, err := getListElementRelationship(a.GetExtensions())
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
|
||||
atom := c.top()
|
||||
atom.List = &schema.List{
|
||||
ElementType: c.makeRef(a.SubType, c.preserveUnknownFields),
|
||||
ElementRelationship: relationship,
|
||||
Keys: mapKeys,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) VisitMap(m *proto.Map) {
|
||||
relationship, err := getMapElementRelationship(m.GetExtensions())
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
}
|
||||
|
||||
a := c.top()
|
||||
a.Map = &schema.Map{
|
||||
ElementType: c.makeRef(m.SubType, c.preserveUnknownFields),
|
||||
ElementRelationship: relationship,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) VisitPrimitive(p *proto.Primitive) {
|
||||
a := c.top()
|
||||
if c.currentName == quantityResource {
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
} else {
|
||||
*a = convertPrimitive(p.Type, p.Format)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) VisitArbitrary(a *proto.Arbitrary) {
|
||||
*c.top() = deducedDef.Atom
|
||||
}
|
||||
|
||||
func (c *convert) VisitReference(proto.Reference) {
|
||||
// Do nothing, we handle references specially
|
||||
}
|
330
vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
generated
vendored
330
vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
generated
vendored
@@ -17,43 +17,18 @@ limitations under the License.
|
||||
package schemaconv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity"
|
||||
quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity"
|
||||
rawExtensionResource = "io.k8s.apimachinery.pkg.runtime.RawExtension"
|
||||
)
|
||||
|
||||
// ToSchema converts openapi definitions into a schema suitable for structured
|
||||
// merge (i.e. kubectl apply v2).
|
||||
func ToSchema(models proto.Models) (*schema.Schema, error) {
|
||||
return ToSchemaWithPreserveUnknownFields(models, false)
|
||||
}
|
||||
|
||||
// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured
|
||||
// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified.
|
||||
func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) {
|
||||
c := convert{
|
||||
input: models,
|
||||
preserveUnknownFields: preserveUnknownFields,
|
||||
output: &schema.Schema{},
|
||||
}
|
||||
if err := c.convertAll(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.addCommonTypes()
|
||||
return c.output, nil
|
||||
}
|
||||
|
||||
type convert struct {
|
||||
input proto.Models
|
||||
preserveUnknownFields bool
|
||||
output *schema.Schema
|
||||
|
||||
@@ -64,7 +39,6 @@ type convert struct {
|
||||
|
||||
func (c *convert) push(name string, a *schema.Atom) *convert {
|
||||
return &convert{
|
||||
input: c.input,
|
||||
preserveUnknownFields: c.preserveUnknownFields,
|
||||
output: c.output,
|
||||
currentName: name,
|
||||
@@ -78,30 +52,17 @@ func (c *convert) pop(c2 *convert) {
|
||||
c.errorMessages = append(c.errorMessages, c2.errorMessages...)
|
||||
}
|
||||
|
||||
func (c *convert) convertAll() error {
|
||||
for _, name := range c.input.ListModels() {
|
||||
model := c.input.LookupModel(name)
|
||||
c.insertTypeDef(name, model)
|
||||
}
|
||||
if len(c.errorMessages) > 0 {
|
||||
return errors.New(strings.Join(c.errorMessages, "\n"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *convert) reportError(format string, args ...interface{}) {
|
||||
c.errorMessages = append(c.errorMessages,
|
||||
c.currentName+": "+fmt.Sprintf(format, args...),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *convert) insertTypeDef(name string, model proto.Schema) {
|
||||
func (c *convert) insertTypeDef(name string, atom schema.Atom) {
|
||||
def := schema.TypeDef{
|
||||
Name: name,
|
||||
Atom: atom,
|
||||
}
|
||||
c2 := c.push(name, &def.Atom)
|
||||
model.Accept(c2)
|
||||
c.pop(c2)
|
||||
if def.Atom == (schema.Atom{}) {
|
||||
// This could happen if there were a top-level reference.
|
||||
return
|
||||
@@ -156,46 +117,6 @@ var deducedDef schema.TypeDef = schema.TypeDef{
|
||||
},
|
||||
}
|
||||
|
||||
func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef {
|
||||
var tr schema.TypeRef
|
||||
if r, ok := model.(*proto.Ref); ok {
|
||||
if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" {
|
||||
return schema.TypeRef{
|
||||
NamedType: &untypedName,
|
||||
}
|
||||
}
|
||||
// reference a named type
|
||||
_, n := path.Split(r.Reference())
|
||||
tr.NamedType = &n
|
||||
|
||||
ext := model.GetExtensions()
|
||||
if val, ok := ext["x-kubernetes-map-type"]; ok {
|
||||
switch val {
|
||||
case "atomic":
|
||||
relationship := schema.Atomic
|
||||
tr.ElementRelationship = &relationship
|
||||
case "granular":
|
||||
relationship := schema.Separable
|
||||
tr.ElementRelationship = &relationship
|
||||
default:
|
||||
c.reportError("unknown map type %v", val)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// compute the type inline
|
||||
c2 := c.push("inlined in "+c.currentName, &tr.Inlined)
|
||||
c2.preserveUnknownFields = preserveUnknownFields
|
||||
model.Accept(c2)
|
||||
c.pop(c2)
|
||||
|
||||
if tr == (schema.TypeRef{}) {
|
||||
// emit warning?
|
||||
tr.NamedType = &untypedName
|
||||
}
|
||||
}
|
||||
return tr
|
||||
}
|
||||
|
||||
func makeUnions(extensions map[string]interface{}) ([]schema.Union, error) {
|
||||
schemaUnions := []schema.Union{}
|
||||
if iunions, ok := extensions["x-kubernetes-unions"]; ok {
|
||||
@@ -299,52 +220,6 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) {
|
||||
return union, nil
|
||||
}
|
||||
|
||||
func (c *convert) VisitKind(k *proto.Kind) {
|
||||
preserveUnknownFields := c.preserveUnknownFields
|
||||
if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true {
|
||||
preserveUnknownFields = true
|
||||
}
|
||||
|
||||
a := c.top()
|
||||
a.Map = &schema.Map{}
|
||||
for _, name := range k.FieldOrder {
|
||||
member := k.Fields[name]
|
||||
tr := c.makeRef(member, preserveUnknownFields)
|
||||
a.Map.Fields = append(a.Map.Fields, schema.StructField{
|
||||
Name: name,
|
||||
Type: tr,
|
||||
Default: member.GetDefault(),
|
||||
})
|
||||
}
|
||||
|
||||
unions, err := makeUnions(k.GetExtensions())
|
||||
if err != nil {
|
||||
c.reportError(err.Error())
|
||||
return
|
||||
}
|
||||
// TODO: We should check that the fields and discriminator
|
||||
// specified in the union are actual fields in the struct.
|
||||
a.Map.Unions = unions
|
||||
|
||||
if preserveUnknownFields {
|
||||
a.Map.ElementType = schema.TypeRef{
|
||||
NamedType: &deducedName,
|
||||
}
|
||||
}
|
||||
|
||||
ext := k.GetExtensions()
|
||||
if val, ok := ext["x-kubernetes-map-type"]; ok {
|
||||
switch val {
|
||||
case "atomic":
|
||||
a.Map.ElementRelationship = schema.Atomic
|
||||
case "granular":
|
||||
a.Map.ElementRelationship = schema.Separable
|
||||
default:
|
||||
c.reportError("unknown map type %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toStringSlice(o interface{}) (out []string, ok bool) {
|
||||
switch t := o.(type) {
|
||||
case []interface{}:
|
||||
@@ -355,117 +230,108 @@ func toStringSlice(o interface{}) (out []string, ok bool) {
|
||||
}
|
||||
}
|
||||
return out, true
|
||||
case []string:
|
||||
return t, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (c *convert) VisitArray(a *proto.Array) {
|
||||
atom := c.top()
|
||||
atom.List = &schema.List{
|
||||
ElementRelationship: schema.Atomic,
|
||||
}
|
||||
l := atom.List
|
||||
l.ElementType = c.makeRef(a.SubType, c.preserveUnknownFields)
|
||||
|
||||
ext := a.GetExtensions()
|
||||
|
||||
if val, ok := ext["x-kubernetes-list-type"]; ok {
|
||||
if val == "atomic" {
|
||||
l.ElementRelationship = schema.Atomic
|
||||
} else if val == "set" {
|
||||
l.ElementRelationship = schema.Associative
|
||||
} else if val == "map" {
|
||||
l.ElementRelationship = schema.Associative
|
||||
if keys, ok := ext["x-kubernetes-list-map-keys"]; ok {
|
||||
if keyNames, ok := toStringSlice(keys); ok {
|
||||
l.Keys = keyNames
|
||||
} else {
|
||||
c.reportError("uninterpreted map keys: %#v", keys)
|
||||
}
|
||||
} else {
|
||||
c.reportError("missing map keys")
|
||||
}
|
||||
} else {
|
||||
c.reportError("unknown list type %v", val)
|
||||
l.ElementRelationship = schema.Atomic
|
||||
}
|
||||
} else if val, ok := ext["x-kubernetes-patch-strategy"]; ok {
|
||||
if val == "merge" || val == "merge,retainKeys" {
|
||||
l.ElementRelationship = schema.Associative
|
||||
if key, ok := ext["x-kubernetes-patch-merge-key"]; ok {
|
||||
if keyName, ok := key.(string); ok {
|
||||
l.Keys = []string{keyName}
|
||||
} else {
|
||||
c.reportError("uninterpreted merge key: %#v", key)
|
||||
}
|
||||
} else {
|
||||
// It's not an error for this to be absent, it
|
||||
// means it's a set.
|
||||
}
|
||||
} else if val == "retainKeys" {
|
||||
} else {
|
||||
c.reportError("unknown patch strategy %v", val)
|
||||
l.ElementRelationship = schema.Atomic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) VisitMap(m *proto.Map) {
|
||||
a := c.top()
|
||||
a.Map = &schema.Map{}
|
||||
a.Map.ElementType = c.makeRef(m.SubType, c.preserveUnknownFields)
|
||||
|
||||
ext := m.GetExtensions()
|
||||
if val, ok := ext["x-kubernetes-map-type"]; ok {
|
||||
switch val {
|
||||
case "atomic":
|
||||
a.Map.ElementRelationship = schema.Atomic
|
||||
case "granular":
|
||||
a.Map.ElementRelationship = schema.Separable
|
||||
default:
|
||||
c.reportError("unknown map type %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ptr(s schema.Scalar) *schema.Scalar { return &s }
|
||||
|
||||
func (c *convert) VisitPrimitive(p *proto.Primitive) {
|
||||
a := c.top()
|
||||
if c.currentName == quantityResource {
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
} else {
|
||||
switch p.Type {
|
||||
case proto.Integer:
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case proto.Number:
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case proto.String:
|
||||
switch p.Format {
|
||||
case "":
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "byte":
|
||||
// byte really means []byte and is encoded as a string.
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "int-or-string":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
case "date-time":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
default:
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
}
|
||||
case proto.Boolean:
|
||||
a.Scalar = ptr(schema.Boolean)
|
||||
// Basic conversion functions to convert OpenAPI schema definitions to
|
||||
// SMD Schema atoms
|
||||
func convertPrimitive(typ string, format string) (a schema.Atom) {
|
||||
switch typ {
|
||||
case "integer":
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case "number":
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case "string":
|
||||
switch format {
|
||||
case "":
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "byte":
|
||||
// byte really means []byte and is encoded as a string.
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "int-or-string":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
case "date-time":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
default:
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
}
|
||||
case "boolean":
|
||||
a.Scalar = ptr(schema.Boolean)
|
||||
default:
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func getListElementRelationship(ext map[string]any) (schema.ElementRelationship, []string, error) {
|
||||
if val, ok := ext["x-kubernetes-list-type"]; ok {
|
||||
switch val {
|
||||
case "atomic":
|
||||
return schema.Atomic, nil, nil
|
||||
case "set":
|
||||
return schema.Associative, nil, nil
|
||||
case "map":
|
||||
keys, ok := ext["x-kubernetes-list-map-keys"]
|
||||
|
||||
if !ok {
|
||||
return schema.Associative, nil, fmt.Errorf("missing map keys")
|
||||
}
|
||||
|
||||
keyNames, ok := toStringSlice(keys)
|
||||
if !ok {
|
||||
return schema.Associative, nil, fmt.Errorf("uninterpreted map keys: %#v", keys)
|
||||
}
|
||||
|
||||
return schema.Associative, keyNames, nil
|
||||
default:
|
||||
return schema.Atomic, nil, fmt.Errorf("unknown list type %v", val)
|
||||
}
|
||||
} else if val, ok := ext["x-kubernetes-patch-strategy"]; ok {
|
||||
switch val {
|
||||
case "merge", "merge,retainKeys":
|
||||
if key, ok := ext["x-kubernetes-patch-merge-key"]; ok {
|
||||
keyName, ok := key.(string)
|
||||
|
||||
if !ok {
|
||||
return schema.Associative, nil, fmt.Errorf("uninterpreted merge key: %#v", key)
|
||||
}
|
||||
|
||||
return schema.Associative, []string{keyName}, nil
|
||||
}
|
||||
// It's not an error for x-kubernetes-patch-merge-key to be absent,
|
||||
// it means it's a set
|
||||
return schema.Associative, nil, nil
|
||||
case "retainKeys":
|
||||
return schema.Atomic, nil, nil
|
||||
default:
|
||||
return schema.Atomic, nil, fmt.Errorf("unknown patch strategy %v", val)
|
||||
}
|
||||
}
|
||||
|
||||
// Treat as atomic by default
|
||||
return schema.Atomic, nil, nil
|
||||
}
|
||||
|
||||
// Returns map element relationship if specified, or empty string if unspecified
|
||||
func getMapElementRelationship(ext map[string]any) (schema.ElementRelationship, error) {
|
||||
val, ok := ext["x-kubernetes-map-type"]
|
||||
if !ok {
|
||||
// unset Map element relationship
|
||||
return "", nil
|
||||
}
|
||||
|
||||
switch val {
|
||||
case "atomic":
|
||||
return schema.Atomic, nil
|
||||
case "granular":
|
||||
return schema.Separable, nil
|
||||
default:
|
||||
return "", fmt.Errorf("unknown map type %v", val)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *convert) VisitArbitrary(a *proto.Arbitrary) {
|
||||
*c.top() = deducedDef.Atom
|
||||
}
|
||||
|
||||
func (c *convert) VisitReference(proto.Reference) {
|
||||
// Do nothing, we handle references specially
|
||||
}
|
||||
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go
generated
vendored
@@ -58,7 +58,7 @@ type EncodingProps struct {
|
||||
// Describes how a specific property value will be serialized depending on its type
|
||||
Style string `json:"style,omitempty"`
|
||||
// When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect
|
||||
Explode string `json:"explode,omitempty"`
|
||||
Explode bool `json:"explode,omitempty"`
|
||||
// AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986
|
||||
AllowReserved bool `json:"allowReserved,omitempty"`
|
||||
}
|
||||
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/example.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/example.go
generated
vendored
@@ -19,8 +19,8 @@ package spec3
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// Example https://swagger.io/specification/#example-object
|
||||
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go
generated
vendored
@@ -18,8 +18,8 @@ package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
type ExternalDocumentation struct {
|
||||
|
250
vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go
generated
vendored
Normal file
250
vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
package spec3
|
||||
|
||||
import (
|
||||
fuzz "github.com/google/gofuzz"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// refChance is the chance that a particular component will use a $ref
|
||||
// instead of fuzzed. Expressed as a fraction 1/n, currently there is
|
||||
// a 1/3 chance that a ref will be used.
|
||||
const refChance = 3
|
||||
|
||||
const alphaNumChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
func randAlphanumString() string {
|
||||
arr := make([]string, rand.Intn(10)+5)
|
||||
for i := 0; i < len(arr); i++ {
|
||||
arr[i] = string(alphaNumChars[rand.Intn(len(alphaNumChars))])
|
||||
}
|
||||
return strings.Join(arr, "")
|
||||
}
|
||||
|
||||
var OpenAPIV3FuzzFuncs []interface{} = []interface{}{
|
||||
func(s *string, c fuzz.Continue) {
|
||||
// All OpenAPI V3 map keys must follow the corresponding
|
||||
// regex. Note that this restricts the range for all other
|
||||
// string values as well.
|
||||
str := randAlphanumString()
|
||||
*s = str
|
||||
},
|
||||
func(o *OpenAPI, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(o)
|
||||
o.Version = "3.0.0"
|
||||
},
|
||||
func(r *interface{}, c fuzz.Continue) {
|
||||
switch c.Intn(3) {
|
||||
case 0:
|
||||
*r = nil
|
||||
case 1:
|
||||
n := c.RandString() + "x"
|
||||
*r = n
|
||||
case 2:
|
||||
n := c.Float64()
|
||||
*r = n
|
||||
}
|
||||
},
|
||||
func(v **spec.Info, c fuzz.Continue) {
|
||||
// Info is never nil
|
||||
*v = &spec.Info{}
|
||||
c.FuzzNoCustom(*v)
|
||||
(*v).Title = c.RandString() + "x"
|
||||
},
|
||||
func(v *Paths, c fuzz.Continue) {
|
||||
c.Fuzz(&v.VendorExtensible)
|
||||
num := c.Intn(5)
|
||||
if num > 0 {
|
||||
v.Paths = make(map[string]*Path)
|
||||
}
|
||||
for i := 0; i < num; i++ {
|
||||
val := Path{}
|
||||
c.Fuzz(&val)
|
||||
v.Paths["/"+c.RandString()] = &val
|
||||
}
|
||||
},
|
||||
func(v *SecurityScheme, c fuzz.Continue) {
|
||||
if c.Intn(refChance) == 0 {
|
||||
c.Fuzz(&v.Refable)
|
||||
return
|
||||
}
|
||||
switch c.Intn(4) {
|
||||
case 0:
|
||||
v.Type = "apiKey"
|
||||
v.Name = c.RandString() + "x"
|
||||
switch c.Intn(3) {
|
||||
case 0:
|
||||
v.In = "query"
|
||||
case 1:
|
||||
v.In = "header"
|
||||
case 2:
|
||||
v.In = "cookie"
|
||||
}
|
||||
case 1:
|
||||
v.Type = "http"
|
||||
case 2:
|
||||
v.Type = "oauth2"
|
||||
v.Flows = make(map[string]*OAuthFlow)
|
||||
flow := OAuthFlow{}
|
||||
flow.AuthorizationUrl = c.RandString() + "x"
|
||||
v.Flows["implicit"] = &flow
|
||||
flow.Scopes = make(map[string]string)
|
||||
flow.Scopes["foo"] = "bar"
|
||||
case 3:
|
||||
v.Type = "openIdConnect"
|
||||
v.OpenIdConnectUrl = "https://" + c.RandString()
|
||||
}
|
||||
v.Scheme = "basic"
|
||||
},
|
||||
func(v *spec.Ref, c fuzz.Continue) {
|
||||
switch c.Intn(7) {
|
||||
case 0:
|
||||
*v = spec.MustCreateRef("#/components/schemas/" + randAlphanumString())
|
||||
case 1:
|
||||
*v = spec.MustCreateRef("#/components/responses/" + randAlphanumString())
|
||||
case 2:
|
||||
*v = spec.MustCreateRef("#/components/headers/" + randAlphanumString())
|
||||
case 3:
|
||||
*v = spec.MustCreateRef("#/components/securitySchemes/" + randAlphanumString())
|
||||
case 5:
|
||||
*v = spec.MustCreateRef("#/components/parameters/" + randAlphanumString())
|
||||
case 6:
|
||||
*v = spec.MustCreateRef("#/components/requestBodies/" + randAlphanumString())
|
||||
}
|
||||
},
|
||||
func(v *Parameter, c fuzz.Continue) {
|
||||
if c.Intn(refChance) == 0 {
|
||||
c.Fuzz(&v.Refable)
|
||||
return
|
||||
}
|
||||
c.Fuzz(&v.ParameterProps)
|
||||
c.Fuzz(&v.VendorExtensible)
|
||||
|
||||
switch c.Intn(3) {
|
||||
case 0:
|
||||
// Header param
|
||||
v.In = "query"
|
||||
case 1:
|
||||
v.In = "header"
|
||||
case 2:
|
||||
v.In = "cookie"
|
||||
}
|
||||
},
|
||||
func(v *RequestBody, c fuzz.Continue) {
|
||||
if c.Intn(refChance) == 0 {
|
||||
c.Fuzz(&v.Refable)
|
||||
return
|
||||
}
|
||||
c.Fuzz(&v.RequestBodyProps)
|
||||
c.Fuzz(&v.VendorExtensible)
|
||||
},
|
||||
func(v *Header, c fuzz.Continue) {
|
||||
if c.Intn(refChance) == 0 {
|
||||
c.Fuzz(&v.Refable)
|
||||
return
|
||||
}
|
||||
c.Fuzz(&v.HeaderProps)
|
||||
c.Fuzz(&v.VendorExtensible)
|
||||
},
|
||||
func(v *ResponsesProps, c fuzz.Continue) {
|
||||
c.Fuzz(&v.Default)
|
||||
n := c.Intn(5)
|
||||
for i := 0; i < n; i++ {
|
||||
r2 := Response{}
|
||||
c.Fuzz(&r2)
|
||||
// HTTP Status code in 100-599 Range
|
||||
code := c.Intn(500) + 100
|
||||
v.StatusCodeResponses = make(map[int]*Response)
|
||||
v.StatusCodeResponses[code] = &r2
|
||||
}
|
||||
},
|
||||
func(v *Response, c fuzz.Continue) {
|
||||
if c.Intn(refChance) == 0 {
|
||||
c.Fuzz(&v.Refable)
|
||||
return
|
||||
}
|
||||
c.Fuzz(&v.ResponseProps)
|
||||
c.Fuzz(&v.VendorExtensible)
|
||||
},
|
||||
func(v *spec.Extensions, c fuzz.Continue) {
|
||||
*v = spec.Extensions{}
|
||||
numChildren := c.Intn(5)
|
||||
if numChildren == 0 {
|
||||
*v = nil
|
||||
}
|
||||
for i := 0; i < numChildren; i++ {
|
||||
v.Add("x-"+randAlphanumString(), c.RandString()+"x")
|
||||
}
|
||||
},
|
||||
func(v *spec.ExternalDocumentation, c fuzz.Continue) {
|
||||
c.Fuzz(&v.Description)
|
||||
v.URL = "https://" + randAlphanumString()
|
||||
},
|
||||
func(v *spec.Schema, c fuzz.Continue) {
|
||||
if c.Intn(refChance) == 0 {
|
||||
c.Fuzz(&v.Ref)
|
||||
return
|
||||
}
|
||||
c.Fuzz(&v.VendorExtensible)
|
||||
c.Fuzz(&v.Description)
|
||||
c.Fuzz(&v.Nullable)
|
||||
c.Fuzz(&v.Title)
|
||||
c.Fuzz(&v.Required)
|
||||
c.Fuzz(&v.ExternalDocs)
|
||||
n := c.Intn(8)
|
||||
switch n {
|
||||
case 0:
|
||||
// To prevent exponential growth from recursively generating properties, only allow the schema to be an object with low frequency
|
||||
if c.Intn(5) == 0 {
|
||||
c.Fuzz(&v.Properties)
|
||||
c.Fuzz(&v.MinProperties)
|
||||
c.Fuzz(&v.MaxProperties)
|
||||
} else {
|
||||
v.Type = spec.StringOrArray{"integer"}
|
||||
switch c.Intn(3) {
|
||||
case 0:
|
||||
v.Format = "int32"
|
||||
case 1:
|
||||
v.Format = "int64"
|
||||
}
|
||||
c.Fuzz(&v.MultipleOf)
|
||||
c.Fuzz(&v.Minimum)
|
||||
c.Fuzz(&v.Maximum)
|
||||
c.Fuzz(&v.ExclusiveMaximum)
|
||||
c.Fuzz(&v.ExclusiveMinimum)
|
||||
}
|
||||
case 1:
|
||||
v.Type = spec.StringOrArray{"number"}
|
||||
switch c.Intn(3) {
|
||||
case 0:
|
||||
v.Format = "float"
|
||||
case 1:
|
||||
v.Format = "double"
|
||||
}
|
||||
c.Fuzz(&v.MultipleOf)
|
||||
c.Fuzz(&v.ExclusiveMaximum)
|
||||
c.Fuzz(&v.ExclusiveMinimum)
|
||||
c.Fuzz(&v.Minimum)
|
||||
c.Fuzz(&v.Maximum)
|
||||
case 2:
|
||||
v.Type = spec.StringOrArray{"string"}
|
||||
c.Fuzz(&v.MinLength)
|
||||
c.Fuzz(&v.MaxLength)
|
||||
case 3:
|
||||
v.Type = spec.StringOrArray{"boolean"}
|
||||
case 4:
|
||||
v.Type = spec.StringOrArray{"array"}
|
||||
s := spec.Schema{}
|
||||
c.Fuzz(&s)
|
||||
v.Items = &spec.SchemaOrArray{Schema: &s}
|
||||
case 5:
|
||||
c.Fuzz(&v.AnyOf)
|
||||
case 6:
|
||||
c.Fuzz(&v.AllOf)
|
||||
case 7:
|
||||
c.Fuzz(&v.OneOf)
|
||||
}
|
||||
},
|
||||
}
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go
generated
vendored
@@ -56,7 +56,7 @@ func (m *MediaType) UnmarshalJSON(data []byte) error {
|
||||
// MediaTypeProps a struct that allows you to specify content format, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject
|
||||
type MediaTypeProps struct {
|
||||
// Schema holds the schema defining the type used for the media type
|
||||
Schema *spec.Schema `json:"schema,omitempty"`
|
||||
Schema *spec.Schema `json:"schema,omitempty"`
|
||||
// Example of the media type
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
// Examples of the media type. Each example object should match the media type and specific schema if present
|
||||
|
4
vendor/k8s.io/kube-openapi/pkg/spec3/operation.go
generated
vendored
4
vendor/k8s.io/kube-openapi/pkg/spec3/operation.go
generated
vendored
@@ -19,8 +19,8 @@ package spec3
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// Operation describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject
|
||||
@@ -73,7 +73,7 @@ type OperationProps struct {
|
||||
// Deprecated declares this operation to be deprecated
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
// SecurityRequirement holds a declaration of which security mechanisms can be used for this operation
|
||||
SecurityRequirement []*SecurityRequirement `json:"security,omitempty"`
|
||||
SecurityRequirement []map[string][]string `json:"security,omitempty"`
|
||||
// Servers contains an alternative server array to service this operation
|
||||
Servers []*Server `json:"servers,omitempty"`
|
||||
}
|
||||
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/path.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/path.go
generated
vendored
@@ -20,8 +20,8 @@ import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// Paths describes the available paths and operations for the API, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathsObject
|
||||
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go
generated
vendored
@@ -19,8 +19,8 @@ package spec3
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// RequestBody describes a single request body, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject
|
||||
|
20
vendor/k8s.io/kube-openapi/pkg/spec3/response.go
generated
vendored
20
vendor/k8s.io/kube-openapi/pkg/spec3/response.go
generated
vendored
@@ -20,8 +20,8 @@ import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// Responses holds the list of possible responses as they are returned from executing this operation
|
||||
@@ -78,20 +78,29 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) {
|
||||
|
||||
// UnmarshalJSON unmarshals responses from JSON
|
||||
func (r *ResponsesProps) UnmarshalJSON(data []byte) error {
|
||||
var res map[string]*Response
|
||||
var res map[string]json.RawMessage
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
if v, ok := res["default"]; ok {
|
||||
r.Default = v
|
||||
value := Response{}
|
||||
if err := json.Unmarshal(v, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Default = &value
|
||||
delete(res, "default")
|
||||
}
|
||||
for k, v := range res {
|
||||
// Take all integral keys
|
||||
if nk, err := strconv.Atoi(k); err == nil {
|
||||
if r.StatusCodeResponses == nil {
|
||||
r.StatusCodeResponses = map[int]*Response{}
|
||||
}
|
||||
r.StatusCodeResponses[nk] = v
|
||||
value := Response{}
|
||||
if err := json.Unmarshal(v, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
r.StatusCodeResponses[nk] = &value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -149,7 +158,6 @@ type ResponseProps struct {
|
||||
Links map[string]*Link `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
// Link represents a possible design-time link for a response, more at https://swagger.io/specification/#link-object
|
||||
type Link struct {
|
||||
spec.Refable
|
||||
|
56
vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go
generated
vendored
56
vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go
generated
vendored
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 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 spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around SecurityRequirementProps to make it referable and extensible
|
||||
type SecurityRequirement struct {
|
||||
SecurityRequirementProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode SecurityRequirement as JSON
|
||||
func (s *SecurityRequirement) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.SecurityRequirementProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (s *SecurityRequirement) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &s.SecurityRequirementProps); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, &s.VendorExtensible)
|
||||
}
|
||||
|
||||
// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object
|
||||
type SecurityRequirementProps map[string][]string
|
2
vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go
generated
vendored
@@ -19,8 +19,8 @@ package spec3
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// SecurityScheme defines reusable Security Scheme Object, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject
|
||||
|
3
vendor/k8s.io/kube-openapi/pkg/spec3/server.go
generated
vendored
3
vendor/k8s.io/kube-openapi/pkg/spec3/server.go
generated
vendored
@@ -18,9 +18,8 @@ package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
|
4
vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go
generated
vendored
4
vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go
generated
vendored
@@ -120,7 +120,7 @@ func (d *Definitions) ParseSchemaV3(s *openapi_v3.Schema, path *Path) (Schema, e
|
||||
switch s.GetType() {
|
||||
case object:
|
||||
for _, extension := range s.GetSpecificationExtension() {
|
||||
if extension.Name == "x-kuberentes-group-version-kind" {
|
||||
if extension.Name == "x-kubernetes-group-version-kind" {
|
||||
// Objects with x-kubernetes-group-version-kind are always top
|
||||
// level types.
|
||||
return d.parseV3Kind(s, path)
|
||||
@@ -285,7 +285,7 @@ func parseV3Interface(def *yaml.Node) (interface{}, error) {
|
||||
|
||||
func (d *Definitions) parseV3BaseSchema(s *openapi_v3.Schema, path *Path) (*BaseSchema, error) {
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("cannot initializae BaseSchema from nil")
|
||||
return nil, fmt.Errorf("cannot initialize BaseSchema from nil")
|
||||
}
|
||||
|
||||
def, err := parseV3Interface(s.GetDefault().ToRawInfo())
|
||||
|
23
vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go
generated
vendored
23
vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go
generated
vendored
@@ -43,6 +43,9 @@ type Header struct {
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (h Header) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(h)
|
||||
}
|
||||
b1, err := json.Marshal(h.CommonValidations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -62,6 +65,20 @@ func (h Header) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2, b3, b4), nil
|
||||
}
|
||||
|
||||
func (h Header) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
CommonValidations commonValidationsOmitZero `json:",inline"`
|
||||
SimpleSchema simpleSchemaOmitZero `json:",inline"`
|
||||
Extensions
|
||||
HeaderProps
|
||||
}
|
||||
x.CommonValidations = commonValidationsOmitZero(h.CommonValidations)
|
||||
x.SimpleSchema = simpleSchemaOmitZero(h.SimpleSchema)
|
||||
x.Extensions = internal.SanitizeExtensions(h.Extensions)
|
||||
x.HeaderProps = h.HeaderProps
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals this header from JSON
|
||||
func (h *Header) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
@@ -94,12 +111,8 @@ func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Dec
|
||||
|
||||
h.CommonValidations = x.CommonValidations
|
||||
h.SimpleSchema = x.SimpleSchema
|
||||
h.Extensions = x.Extensions
|
||||
h.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
h.HeaderProps = x.HeaderProps
|
||||
|
||||
h.Extensions.sanitize()
|
||||
if len(h.Extensions) == 0 {
|
||||
h.Extensions = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
33
vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go
generated
vendored
33
vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go
generated
vendored
@@ -89,17 +89,9 @@ func (e Extensions) GetObject(key string, out interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e Extensions) sanitize() {
|
||||
for k := range e {
|
||||
if !isExtensionKey(k) {
|
||||
delete(e, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e Extensions) sanitizeWithExtra() (extra map[string]any) {
|
||||
for k, v := range e {
|
||||
if !isExtensionKey(k) {
|
||||
if !internal.IsExtensionKey(k) {
|
||||
if extra == nil {
|
||||
extra = make(map[string]any)
|
||||
}
|
||||
@@ -110,10 +102,6 @@ func (e Extensions) sanitizeWithExtra() (extra map[string]any) {
|
||||
return extra
|
||||
}
|
||||
|
||||
func isExtensionKey(k string) bool {
|
||||
return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-'
|
||||
}
|
||||
|
||||
// VendorExtensible composition block.
|
||||
type VendorExtensible struct {
|
||||
Extensions Extensions
|
||||
@@ -181,6 +169,9 @@ type Info struct {
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (i Info) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(i)
|
||||
}
|
||||
b1, err := json.Marshal(i.InfoProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -192,6 +183,16 @@ func (i Info) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (i Info) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Extensions
|
||||
InfoProps
|
||||
}
|
||||
x.Extensions = i.Extensions
|
||||
x.InfoProps = i.InfoProps
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
func (i *Info) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
@@ -212,11 +213,7 @@ func (i *Info) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decod
|
||||
if err := opts.UnmarshalNext(dec, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
x.Extensions.sanitize()
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
i.VendorExtensible.Extensions = x.Extensions
|
||||
i.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
i.InfoProps = x.InfoProps
|
||||
return nil
|
||||
}
|
||||
|
53
vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go
generated
vendored
53
vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go
generated
vendored
@@ -37,6 +37,18 @@ type SimpleSchema struct {
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type simpleSchemaOmitZero struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Nullable bool `json:"nullable,omitzero"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Items *Items `json:"items,omitzero"`
|
||||
CollectionFormat string `json:"collectionFormat,omitempty"`
|
||||
Default interface{} `json:"default,omitempty"`
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
}
|
||||
|
||||
// CommonValidations describe common JSON-schema validations
|
||||
type CommonValidations struct {
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
@@ -53,6 +65,23 @@ type CommonValidations struct {
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type commonValidationsOmitZero struct {
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"`
|
||||
MaxLength *int64 `json:"maxLength,omitempty"`
|
||||
MinLength *int64 `json:"minLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
MaxItems *int64 `json:"maxItems,omitempty"`
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitzero"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
}
|
||||
|
||||
// Items a limited subset of JSON-Schema's items object.
|
||||
// It is used by parameter definitions that are not located in "body".
|
||||
//
|
||||
@@ -105,18 +134,18 @@ func (i *Items) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco
|
||||
if err := i.Refable.Ref.fromMap(x.Extensions); err != nil {
|
||||
return err
|
||||
}
|
||||
x.Extensions.sanitize()
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
|
||||
i.CommonValidations = x.CommonValidations
|
||||
i.SimpleSchema = x.SimpleSchema
|
||||
i.VendorExtensible.Extensions = x.Extensions
|
||||
i.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (i Items) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(i)
|
||||
}
|
||||
b1, err := json.Marshal(i.CommonValidations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -135,3 +164,17 @@ func (i Items) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
return swag.ConcatJSON(b4, b3, b1, b2), nil
|
||||
}
|
||||
|
||||
func (i Items) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
CommonValidations commonValidationsOmitZero `json:",inline"`
|
||||
SimpleSchema simpleSchemaOmitZero `json:",inline"`
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
Extensions
|
||||
}
|
||||
x.CommonValidations = commonValidationsOmitZero(i.CommonValidations)
|
||||
x.SimpleSchema = simpleSchemaOmitZero(i.SimpleSchema)
|
||||
x.Ref = i.Refable.Ref.String()
|
||||
x.Extensions = internal.SanitizeExtensions(i.Extensions)
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
36
vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go
generated
vendored
36
vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go
generated
vendored
@@ -42,6 +42,23 @@ type OperationProps struct {
|
||||
Responses *Responses `json:"responses,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type operationPropsOmitZero struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Consumes []string `json:"consumes,omitempty"`
|
||||
Produces []string `json:"produces,omitempty"`
|
||||
Schemes []string `json:"schemes,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"`
|
||||
ID string `json:"operationId,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty,omitzero"`
|
||||
Security []map[string][]string `json:"security,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
Responses *Responses `json:"responses,omitzero"`
|
||||
}
|
||||
|
||||
// MarshalJSON takes care of serializing operation properties to JSON
|
||||
//
|
||||
// We use a custom marhaller here to handle a special cases related to
|
||||
@@ -96,17 +113,16 @@ func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.
|
||||
if err := opts.UnmarshalNext(dec, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
x.Extensions.sanitize()
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
o.VendorExtensible.Extensions = x.Extensions
|
||||
o.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
o.OperationProps = OperationProps(x.OperationPropsNoMethods)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (o Operation) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(o)
|
||||
}
|
||||
b1, err := json.Marshal(o.OperationProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -118,3 +134,13 @@ func (o Operation) MarshalJSON() ([]byte, error) {
|
||||
concated := swag.ConcatJSON(b1, b2)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
func (o Operation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Extensions
|
||||
OperationProps operationPropsOmitZero `json:",inline"`
|
||||
}
|
||||
x.Extensions = internal.SanitizeExtensions(o.Extensions)
|
||||
x.OperationProps = operationPropsOmitZero(o.OperationProps)
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
36
vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go
generated
vendored
36
vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go
generated
vendored
@@ -36,6 +36,17 @@ type ParamProps struct {
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type paramPropsOmitZero struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
In string `json:"in,omitempty"`
|
||||
Required bool `json:"required,omitzero"`
|
||||
Schema *Schema `json:"schema,omitzero"`
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitzero"`
|
||||
}
|
||||
|
||||
// Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn).
|
||||
//
|
||||
// There are five possible parameter types.
|
||||
@@ -109,19 +120,18 @@ func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.
|
||||
if err := p.Refable.Ref.fromMap(x.Extensions); err != nil {
|
||||
return err
|
||||
}
|
||||
x.Extensions.sanitize()
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
p.CommonValidations = x.CommonValidations
|
||||
p.SimpleSchema = x.SimpleSchema
|
||||
p.VendorExtensible.Extensions = x.Extensions
|
||||
p.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
p.ParamProps = x.ParamProps
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (p Parameter) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(p)
|
||||
}
|
||||
b1, err := json.Marshal(p.CommonValidations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -144,3 +154,19 @@ func (p Parameter) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
return swag.ConcatJSON(b3, b1, b2, b4, b5), nil
|
||||
}
|
||||
|
||||
func (p Parameter) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
CommonValidations commonValidationsOmitZero `json:",inline"`
|
||||
SimpleSchema simpleSchemaOmitZero `json:",inline"`
|
||||
ParamProps paramPropsOmitZero `json:",inline"`
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
Extensions
|
||||
}
|
||||
x.CommonValidations = commonValidationsOmitZero(p.CommonValidations)
|
||||
x.SimpleSchema = simpleSchemaOmitZero(p.SimpleSchema)
|
||||
x.Extensions = internal.SanitizeExtensions(p.Extensions)
|
||||
x.ParamProps = paramPropsOmitZero(p.ParamProps)
|
||||
x.Ref = p.Refable.Ref.String()
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
28
vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go
generated
vendored
28
vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go
generated
vendored
@@ -70,24 +70,20 @@ func (p *PathItem) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.D
|
||||
if err := opts.UnmarshalNext(dec, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Extensions = x.Extensions
|
||||
p.PathItemProps = x.PathItemProps
|
||||
|
||||
if err := p.Refable.Ref.fromMap(p.Extensions); err != nil {
|
||||
if err := p.Refable.Ref.fromMap(x.Extensions); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Extensions.sanitize()
|
||||
if len(p.Extensions) == 0 {
|
||||
p.Extensions = nil
|
||||
}
|
||||
p.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
p.PathItemProps = x.PathItemProps
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (p PathItem) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(p)
|
||||
}
|
||||
b3, err := json.Marshal(p.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,3 +99,15 @@ func (p PathItem) MarshalJSON() ([]byte, error) {
|
||||
concated := swag.ConcatJSON(b3, b4, b5)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
func (p PathItem) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
Extensions
|
||||
PathItemProps
|
||||
}
|
||||
x.Ref = p.Refable.Ref.String()
|
||||
x.Extensions = internal.SanitizeExtensions(p.Extensions)
|
||||
x.PathItemProps = p.PathItemProps
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
24
vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go
generated
vendored
24
vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go
generated
vendored
@@ -92,7 +92,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco
|
||||
}
|
||||
|
||||
switch k := tok.String(); {
|
||||
case isExtensionKey(k):
|
||||
case internal.IsExtensionKey(k):
|
||||
ext = nil
|
||||
if err := opts.UnmarshalNext(dec, &ext); err != nil {
|
||||
return err
|
||||
@@ -114,7 +114,9 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco
|
||||
p.Paths[k] = pi
|
||||
default:
|
||||
_, err := dec.ReadValue() // skip value
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -124,6 +126,9 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (p Paths) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(p)
|
||||
}
|
||||
b1, err := json.Marshal(p.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -142,3 +147,18 @@ func (p Paths) MarshalJSON() ([]byte, error) {
|
||||
concated := swag.ConcatJSON(b1, b2)
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
func (p Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
m := make(map[string]any, len(p.Extensions)+len(p.Paths))
|
||||
for k, v := range p.Extensions {
|
||||
if internal.IsExtensionKey(k) {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range p.Paths {
|
||||
if strings.HasPrefix(k, "/") {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
return opts.MarshalNext(enc, m)
|
||||
}
|
||||
|
18
vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go
generated
vendored
18
vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go
generated
vendored
@@ -21,6 +21,8 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-openapi/jsonreference"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/internal"
|
||||
)
|
||||
|
||||
// Refable is a struct for things that accept a $ref property
|
||||
@@ -149,19 +151,5 @@ func (r *Ref) UnmarshalJSON(d []byte) error {
|
||||
}
|
||||
|
||||
func (r *Ref) fromMap(v map[string]interface{}) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if vv, ok := v["$ref"]; ok {
|
||||
if str, ok := vv.(string); ok {
|
||||
ref, err := jsonreference.New(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = Ref{Ref: ref}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return internal.JSONRefFromMap(&r.Ref, v)
|
||||
}
|
||||
|
36
vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go
generated
vendored
36
vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go
generated
vendored
@@ -30,6 +30,15 @@ type ResponseProps struct {
|
||||
Examples map[string]interface{} `json:"examples,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type responsePropsOmitZero struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Schema *Schema `json:"schema,omitzero"`
|
||||
Headers map[string]Header `json:"headers,omitempty"`
|
||||
Examples map[string]interface{} `json:"examples,omitempty"`
|
||||
}
|
||||
|
||||
// Response describes a single response from an API Operation.
|
||||
//
|
||||
// For more information: http://goo.gl/8us55a#responseObject
|
||||
@@ -68,23 +77,20 @@ func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.D
|
||||
return err
|
||||
}
|
||||
|
||||
r.Extensions = x.Extensions
|
||||
r.ResponseProps = x.ResponseProps
|
||||
|
||||
if err := r.Refable.Ref.fromMap(r.Extensions); err != nil {
|
||||
if err := r.Refable.Ref.fromMap(x.Extensions); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.Extensions.sanitize()
|
||||
if len(r.Extensions) == 0 {
|
||||
r.Extensions = nil
|
||||
}
|
||||
r.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
r.ResponseProps = x.ResponseProps
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (r Response) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(r)
|
||||
}
|
||||
b1, err := json.Marshal(r.ResponseProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -100,6 +106,18 @@ func (r Response) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (r Response) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
Extensions
|
||||
ResponseProps responsePropsOmitZero `json:",inline"`
|
||||
}
|
||||
x.Ref = r.Refable.Ref.String()
|
||||
x.Extensions = internal.SanitizeExtensions(r.Extensions)
|
||||
x.ResponseProps = responsePropsOmitZero(r.ResponseProps)
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// NewResponse creates a new response instance
|
||||
func NewResponse() *Response {
|
||||
return new(Response)
|
||||
|
24
vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go
generated
vendored
24
vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go
generated
vendored
@@ -63,6 +63,9 @@ func (r *Responses) UnmarshalJSON(data []byte) error {
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (r Responses) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(r)
|
||||
}
|
||||
b1, err := json.Marshal(r.ResponsesProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -75,6 +78,25 @@ func (r Responses) MarshalJSON() ([]byte, error) {
|
||||
return concated, nil
|
||||
}
|
||||
|
||||
func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
type ArbitraryKeys map[string]interface{}
|
||||
var x struct {
|
||||
ArbitraryKeys
|
||||
Default *Response `json:"default,omitempty"`
|
||||
}
|
||||
x.ArbitraryKeys = make(map[string]any, len(r.Extensions)+len(r.StatusCodeResponses))
|
||||
for k, v := range r.Extensions {
|
||||
if internal.IsExtensionKey(k) {
|
||||
x.ArbitraryKeys[k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range r.StatusCodeResponses {
|
||||
x.ArbitraryKeys[strconv.Itoa(k)] = v
|
||||
}
|
||||
x.Default = r.Default
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// ResponsesProps describes all responses for an operation.
|
||||
// It tells what is the default response and maps all responses with a
|
||||
// HTTP status code.
|
||||
@@ -148,7 +170,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.
|
||||
return nil
|
||||
}
|
||||
switch k := tok.String(); {
|
||||
case isExtensionKey(k):
|
||||
case internal.IsExtensionKey(k):
|
||||
ext = nil
|
||||
if err := opts.UnmarshalNext(dec, &ext); err != nil {
|
||||
return err
|
||||
|
75
vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go
generated
vendored
75
vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go
generated
vendored
@@ -196,6 +196,46 @@ type SchemaProps struct {
|
||||
Definitions Definitions `json:"definitions,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type schemaPropsOmitZero struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Ref Ref `json:"-"`
|
||||
Schema SchemaURL `json:"-"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Type StringOrArray `json:"type,omitzero"`
|
||||
Nullable bool `json:"nullable,omitzero"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Default interface{} `json:"default,omitzero"`
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"`
|
||||
MaxLength *int64 `json:"maxLength,omitempty"`
|
||||
MinLength *int64 `json:"minLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
MaxItems *int64 `json:"maxItems,omitempty"`
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitzero"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
MaxProperties *int64 `json:"maxProperties,omitempty"`
|
||||
MinProperties *int64 `json:"minProperties,omitempty"`
|
||||
Required []string `json:"required,omitempty"`
|
||||
Items *SchemaOrArray `json:"items,omitzero"`
|
||||
AllOf []Schema `json:"allOf,omitempty"`
|
||||
OneOf []Schema `json:"oneOf,omitempty"`
|
||||
AnyOf []Schema `json:"anyOf,omitempty"`
|
||||
Not *Schema `json:"not,omitzero"`
|
||||
Properties map[string]Schema `json:"properties,omitempty"`
|
||||
AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitzero"`
|
||||
PatternProperties map[string]Schema `json:"patternProperties,omitempty"`
|
||||
Dependencies Dependencies `json:"dependencies,omitempty"`
|
||||
AdditionalItems *SchemaOrBool `json:"additionalItems,omitzero"`
|
||||
Definitions Definitions `json:"definitions,omitempty"`
|
||||
}
|
||||
|
||||
// SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4)
|
||||
type SwaggerSchemaProps struct {
|
||||
Discriminator string `json:"discriminator,omitempty"`
|
||||
@@ -204,6 +244,15 @@ type SwaggerSchemaProps struct {
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
}
|
||||
|
||||
// Marshaling structure only, always edit along with corresponding
|
||||
// struct (or compilation will fail).
|
||||
type swaggerSchemaPropsOmitZero struct {
|
||||
Discriminator string `json:"discriminator,omitempty"`
|
||||
ReadOnly bool `json:"readOnly,omitzero"`
|
||||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"`
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
}
|
||||
|
||||
// Schema the schema object allows the definition of input and output data types.
|
||||
// These types can be objects, but also primitives and arrays.
|
||||
// This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/)
|
||||
@@ -434,6 +483,9 @@ func (s *Schema) WithExternalDocs(description, url string) *Schema {
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (s Schema) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(s)
|
||||
}
|
||||
b1, err := json.Marshal(s.SchemaProps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("schema props %v", err)
|
||||
@@ -465,6 +517,29 @@ func (s Schema) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil
|
||||
}
|
||||
|
||||
func (s Schema) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
type ArbitraryKeys map[string]interface{}
|
||||
var x struct {
|
||||
ArbitraryKeys
|
||||
SchemaProps schemaPropsOmitZero `json:",inline"`
|
||||
SwaggerSchemaProps swaggerSchemaPropsOmitZero `json:",inline"`
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
}
|
||||
x.ArbitraryKeys = make(map[string]any, len(s.Extensions)+len(s.ExtraProps))
|
||||
for k, v := range s.Extensions {
|
||||
if internal.IsExtensionKey(k) {
|
||||
x.ArbitraryKeys[k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range s.ExtraProps {
|
||||
x.ArbitraryKeys[k] = v
|
||||
}
|
||||
x.SchemaProps = schemaPropsOmitZero(s.SchemaProps)
|
||||
x.SwaggerSchemaProps = swaggerSchemaPropsOmitZero(s.SwaggerSchemaProps)
|
||||
x.Ref = s.Ref.String()
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
func (s *Schema) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
|
20
vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go
generated
vendored
20
vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go
generated
vendored
@@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/internal"
|
||||
jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json"
|
||||
)
|
||||
|
||||
@@ -45,6 +46,9 @@ type SecurityScheme struct {
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (s SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(s)
|
||||
}
|
||||
b1, err := json.Marshal(s.SecuritySchemeProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -56,6 +60,16 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (s SecurityScheme) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Extensions
|
||||
SecuritySchemeProps
|
||||
}
|
||||
x.Extensions = internal.SanitizeExtensions(s.Extensions)
|
||||
x.SecuritySchemeProps = s.SecuritySchemeProps
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
func (s *SecurityScheme) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil {
|
||||
@@ -72,11 +86,7 @@ func (s *SecurityScheme) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *js
|
||||
if err := opts.UnmarshalNext(dec, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
x.Extensions.sanitize()
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
s.VendorExtensible.Extensions = x.Extensions
|
||||
s.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
s.SecuritySchemeProps = x.SecuritySchemeProps
|
||||
return nil
|
||||
}
|
||||
|
64
vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go
generated
vendored
64
vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go
generated
vendored
@@ -35,6 +35,9 @@ type Swagger struct {
|
||||
|
||||
// MarshalJSON marshals this swagger structure to json
|
||||
func (s Swagger) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(s)
|
||||
}
|
||||
b1, err := json.Marshal(s.SwaggerProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -46,12 +49,22 @@ func (s Swagger) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// MarshalJSON marshals this swagger structure to json
|
||||
func (s Swagger) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Extensions
|
||||
SwaggerProps
|
||||
}
|
||||
x.Extensions = internal.SanitizeExtensions(s.Extensions)
|
||||
x.SwaggerProps = s.SwaggerProps
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a swagger spec from json
|
||||
func (s *Swagger) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
return jsonv2.Unmarshal(data, s)
|
||||
}
|
||||
|
||||
var sw Swagger
|
||||
if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil {
|
||||
return err
|
||||
@@ -75,15 +88,8 @@ func (s *Swagger) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.De
|
||||
if err := opts.UnmarshalNext(dec, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Extensions = x.Extensions
|
||||
s.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
s.SwaggerProps = x.SwaggerProps
|
||||
|
||||
s.Extensions.sanitize()
|
||||
if len(s.Extensions) == 0 {
|
||||
s.Extensions = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -126,6 +132,9 @@ var jsFalse = []byte("false")
|
||||
|
||||
// MarshalJSON convert this object to JSON
|
||||
func (s SchemaOrBool) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(s)
|
||||
}
|
||||
if s.Schema != nil {
|
||||
return json.Marshal(s.Schema)
|
||||
}
|
||||
@@ -136,6 +145,18 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) {
|
||||
return jsTrue, nil
|
||||
}
|
||||
|
||||
// MarshalJSON convert this object to JSON
|
||||
func (s SchemaOrBool) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
if s.Schema != nil {
|
||||
return opts.MarshalNext(enc, s.Schema)
|
||||
}
|
||||
|
||||
if s.Schema == nil && !s.Allows {
|
||||
return enc.WriteToken(jsonv2.False)
|
||||
}
|
||||
return enc.WriteToken(jsonv2.True)
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts this bool or schema object from a JSON structure
|
||||
func (s *SchemaOrBool) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
@@ -185,6 +206,9 @@ type SchemaOrStringArray struct {
|
||||
|
||||
// MarshalJSON converts this schema object or array into JSON structure
|
||||
func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(s)
|
||||
}
|
||||
if len(s.Property) > 0 {
|
||||
return json.Marshal(s.Property)
|
||||
}
|
||||
@@ -194,6 +218,17 @@ func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts this schema object or array into JSON structure
|
||||
func (s SchemaOrStringArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
if len(s.Property) > 0 {
|
||||
return opts.MarshalNext(enc, s.Property)
|
||||
}
|
||||
if s.Schema != nil {
|
||||
return opts.MarshalNext(enc, s.Schema)
|
||||
}
|
||||
return enc.WriteToken(jsonv2.Null)
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts this schema object or array from a JSON structure
|
||||
func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
@@ -347,12 +382,23 @@ func (s *SchemaOrArray) ContainsType(name string) bool {
|
||||
|
||||
// MarshalJSON converts this schema object or array into JSON structure
|
||||
func (s SchemaOrArray) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(s)
|
||||
}
|
||||
if len(s.Schemas) > 0 {
|
||||
return json.Marshal(s.Schemas)
|
||||
}
|
||||
return json.Marshal(s.Schema)
|
||||
}
|
||||
|
||||
// MarshalJSON converts this schema object or array into JSON structure
|
||||
func (s SchemaOrArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
if len(s.Schemas) > 0 {
|
||||
return opts.MarshalNext(enc, s.Schemas)
|
||||
}
|
||||
return opts.MarshalNext(enc, s.Schema)
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts this schema object or array from a JSON structure
|
||||
func (s *SchemaOrArray) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
|
19
vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go
generated
vendored
19
vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go
generated
vendored
@@ -41,6 +41,9 @@ type Tag struct {
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (t Tag) MarshalJSON() ([]byte, error) {
|
||||
if internal.UseOptimizedJSONMarshaling {
|
||||
return internal.DeterministicMarshal(t)
|
||||
}
|
||||
b1, err := json.Marshal(t.TagProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -52,6 +55,16 @@ func (t Tag) MarshalJSON() ([]byte, error) {
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (t Tag) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error {
|
||||
var x struct {
|
||||
Extensions
|
||||
TagProps
|
||||
}
|
||||
x.Extensions = internal.SanitizeExtensions(t.Extensions)
|
||||
x.TagProps = t.TagProps
|
||||
return opts.MarshalNext(enc, x)
|
||||
}
|
||||
|
||||
// UnmarshalJSON marshal this from JSON
|
||||
func (t *Tag) UnmarshalJSON(data []byte) error {
|
||||
if internal.UseOptimizedJSONUnmarshaling {
|
||||
@@ -72,11 +85,7 @@ func (t *Tag) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decode
|
||||
if err := opts.UnmarshalNext(dec, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
x.Extensions.sanitize()
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
t.VendorExtensible.Extensions = x.Extensions
|
||||
t.Extensions = internal.SanitizeExtensions(x.Extensions)
|
||||
t.TagProps = x.TagProps
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user