rebase: update kubernetes to v1.25.0

update kubernetes to latest v1.25.0
release.

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna
2022-08-24 07:54:25 +05:30
committed by mergify[bot]
parent f47839d73d
commit e3bf375035
645 changed files with 42507 additions and 9219 deletions

View File

@ -35,7 +35,7 @@ import (
type Tunnel interface {
// Dial connects to the address on the named network, similar to
// what net.Dial does. The only supported protocol is tcp.
DialContext(ctx context.Context, protocol, address string) (net.Conn, error)
DialContext(requestCtx context.Context, protocol, address string) (net.Conn, error)
}
type dialResult struct {
@ -73,15 +73,27 @@ var _ clientConn = &grpc.ClientConn{}
// gRPC based proxy service.
// Currently, a single tunnel supports a single connection, and the tunnel is closed when the connection is terminated
// The Dial() method of the returned tunnel should only be called once
func CreateSingleUseGrpcTunnel(ctx context.Context, address string, opts ...grpc.DialOption) (Tunnel, error) {
c, err := grpc.DialContext(ctx, address, opts...)
// Deprecated 2022-06-07: use CreateSingleUseGrpcTunnelWithContext
func CreateSingleUseGrpcTunnel(tunnelCtx context.Context, address string, opts ...grpc.DialOption) (Tunnel, error) {
return CreateSingleUseGrpcTunnelWithContext(context.TODO(), tunnelCtx, address, opts...)
}
// CreateSingleUseGrpcTunnelWithContext creates a Tunnel to dial to a remote server through a
// gRPC based proxy service.
// Currently, a single tunnel supports a single connection.
// The tunnel is normally closed when the connection is terminated.
// If createCtx is cancelled before tunnel creation, an error will be returned.
// If tunnelCtx is cancelled while the tunnel is still in use, the tunnel (and any in flight connections) will be closed.
// The Dial() method of the returned tunnel should only be called once
func CreateSingleUseGrpcTunnelWithContext(createCtx, tunnelCtx context.Context, address string, opts ...grpc.DialOption) (Tunnel, error) {
c, err := grpc.DialContext(createCtx, address, opts...)
if err != nil {
return nil, err
}
grpcClient := client.NewProxyServiceClient(c)
stream, err := grpcClient.Proxy(ctx)
stream, err := grpcClient.Proxy(tunnelCtx)
if err != nil {
c.Close()
return nil, err
@ -94,13 +106,24 @@ func CreateSingleUseGrpcTunnel(ctx context.Context, address string, opts ...grpc
readTimeoutSeconds: 10,
}
go tunnel.serve(c)
go tunnel.serve(tunnelCtx, c)
return tunnel, nil
}
func (t *grpcTunnel) serve(c clientConn) {
defer c.Close()
func (t *grpcTunnel) serve(tunnelCtx context.Context, c clientConn) {
defer func() {
c.Close()
// A connection in t.conns after serve() returns means
// we never received a CLOSE_RSP for it, so we need to
// close any channels remaining for these connections.
t.connsLock.Lock()
for _, conn := range t.conns {
close(conn.readCh)
}
t.connsLock.Unlock()
}()
for {
pkt, err := t.stream.Recv()
@ -141,6 +164,9 @@ func (t *grpcTunnel) serve(c clientConn) {
// In either scenario, we should return here as this tunnel is no longer needed.
klog.V(1).InfoS("Pending dial has been cancelled; dropped", "connectionID", resp.ConnectID, "dialID", resp.Random)
return
case <-tunnelCtx.Done():
klog.V(1).InfoS("Tunnel has been closed; dropped", "connectionID", resp.ConnectID, "dialID", resp.Random)
return
}
}
@ -164,6 +190,8 @@ func (t *grpcTunnel) serve(c clientConn) {
case <-timer.C:
klog.ErrorS(fmt.Errorf("timeout"), "readTimeout has been reached, the grpc connection to the proxy server will be closed", "connectionID", conn.connID, "readTimeoutSeconds", t.readTimeoutSeconds)
return
case <-tunnelCtx.Done():
klog.V(1).InfoS("Tunnel has been closed, the grpc connection to the proxy server will be closed", "connectionID", conn.connID)
}
} else {
klog.V(1).InfoS("connection not recognized", "connectionID", resp.ConnectID)
@ -190,7 +218,7 @@ func (t *grpcTunnel) serve(c clientConn) {
// Dial connects to the address on the named network, similar to
// what net.Dial does. The only supported protocol is tcp.
func (t *grpcTunnel) DialContext(ctx context.Context, protocol, address string) (net.Conn, error) {
func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address string) (net.Conn, error) {
if protocol != "tcp" {
return nil, errors.New("protocol not supported")
}
@ -248,8 +276,8 @@ func (t *grpcTunnel) DialContext(ctx context.Context, protocol, address string)
case <-time.After(30 * time.Second):
klog.V(5).InfoS("Timed out waiting for DialResp", "dialID", random)
return nil, errors.New("dial timeout, backstop")
case <-ctx.Done():
klog.V(5).InfoS("Context canceled waiting for DialResp", "ctxErr", ctx.Err(), "dialID", random)
case <-requestCtx.Done():
klog.V(5).InfoS("Context canceled waiting for DialResp", "ctxErr", requestCtx.Err(), "dialID", random)
return nil, errors.New("dial timeout, context")
}

View File

@ -30,6 +30,8 @@ import (
// successful delivery of CLOSE_REQ.
const CloseTimeout = 10 * time.Second
var errConnCloseTimeout = errors.New("close timeout")
// conn is an implementation of net.Conn, where the data is transported
// over an established tunnel defined by a gRPC service ProxyService.
type conn struct {
@ -151,5 +153,5 @@ func (c *conn) Close() error {
case <-time.After(CloseTimeout):
}
return errors.New("close timeout")
return errConnCloseTimeout
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

@ -16,7 +16,9 @@ limitations under the License.
package schema
import "sync"
import (
"sync"
)
// Schema is a list of named types.
//
@ -27,6 +29,11 @@ type Schema struct {
once sync.Once
m map[string]TypeDef
lock sync.Mutex
// Cached results of resolving type references to atoms. Only stores
// type references which require fields of Atom to be overriden.
resolvedTypes map[TypeRef]Atom
}
// A TypeSpecifier references a particular type in a schema.
@ -48,6 +55,12 @@ type TypeRef struct {
// Either the name or one member of Atom should be set.
NamedType *string `yaml:"namedType,omitempty"`
Inlined Atom `yaml:",inline,omitempty"`
// If this reference refers to a map-type or list-type, this field overrides
// the `ElementRelationship` of the referred type when resolved.
// If this field is nil, then it has no effect.
// See `Map` and `List` for more information about `ElementRelationship`
ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"`
}
// Atom represents the smallest possible pieces of the type system.
@ -88,11 +101,11 @@ const (
// Map is a key-value pair. Its default semantics are the same as an
// associative list, but:
// * It is serialized differently:
// - It is serialized differently:
// map: {"k": {"value": "v"}}
// list: [{"key": "k", "value": "v"}]
// * Keys must be string typed.
// * Keys can't have multiple components.
// - Keys must be string typed.
// - Keys can't have multiple components.
//
// Optionally, maps may be atomic (for example, imagine representing an RGB
// color value--it doesn't make sense to have different actors own the R and G
@ -146,6 +159,31 @@ func (m *Map) FindField(name string) (StructField, bool) {
return sf, ok
}
// CopyInto this instance of Map into the other
// If other is nil this method does nothing.
// If other is already initialized, overwrites it with this instance
// Warning: Not thread safe
func (m *Map) CopyInto(dst *Map) {
if dst == nil {
return
}
// Map type is considered immutable so sharing references
dst.Fields = m.Fields
dst.ElementType = m.ElementType
dst.Unions = m.Unions
dst.ElementRelationship = m.ElementRelationship
if m.m != nil {
// If cache is non-nil then the once token had been consumed.
// Must reset token and use it again to ensure same semantics.
dst.once = sync.Once{}
dst.once.Do(func() {
dst.m = m.m
})
}
}
// UnionFields are mapping between the fields that are part of the union and
// their discriminated value. The discriminated value has to be set, and
// should not conflict with other discriminated value in the list.
@ -244,18 +282,93 @@ func (s *Schema) FindNamedType(name string) (TypeDef, bool) {
return t, ok
}
func (s *Schema) resolveNoOverrides(tr TypeRef) (Atom, bool) {
result := Atom{}
if tr.NamedType != nil {
t, ok := s.FindNamedType(*tr.NamedType)
if !ok {
return Atom{}, false
}
result = t.Atom
} else {
result = tr.Inlined
}
return result, true
}
// Resolve is a convenience function which returns the atom referenced, whether
// it is inline or named. Returns (Atom{}, false) if the type can't be resolved.
//
// This allows callers to not care about the difference between a (possibly
// inlined) reference and a definition.
func (s *Schema) Resolve(tr TypeRef) (Atom, bool) {
if tr.NamedType != nil {
t, ok := s.FindNamedType(*tr.NamedType)
if !ok {
// If this is a plain reference with no overrides, just return the type
if tr.ElementRelationship == nil {
return s.resolveNoOverrides(tr)
}
s.lock.Lock()
defer s.lock.Unlock()
if s.resolvedTypes == nil {
s.resolvedTypes = make(map[TypeRef]Atom)
}
var result Atom
var exists bool
// Return cached result if available
// If not, calculate result and cache it
if result, exists = s.resolvedTypes[tr]; !exists {
if result, exists = s.resolveNoOverrides(tr); exists {
// Allow field-level electives to override the referred type's modifiers
switch {
case result.Map != nil:
mapCopy := Map{}
result.Map.CopyInto(&mapCopy)
mapCopy.ElementRelationship = *tr.ElementRelationship
result.Map = &mapCopy
case result.List != nil:
listCopy := *result.List
listCopy.ElementRelationship = *tr.ElementRelationship
result.List = &listCopy
case result.Scalar != nil:
return Atom{}, false
default:
return Atom{}, false
}
} else {
return Atom{}, false
}
return t.Atom, true
// Save result. If it is nil, that is also recorded as not existing.
s.resolvedTypes[tr] = result
}
return result, true
}
// Clones this instance of Schema into the other
// If other is nil this method does nothing.
// If other is already initialized, overwrites it with this instance
// Warning: Not thread safe
func (s *Schema) CopyInto(dst *Schema) {
if dst == nil {
return
}
// Schema type is considered immutable so sharing references
dst.Types = s.Types
if s.m != nil {
// If cache is non-nil then the once token had been consumed.
// Must reset token and use it again to ensure same semantics.
dst.once = sync.Once{}
dst.once.Do(func() {
dst.m = s.m
})
}
return tr.Inlined, true
}

View File

@ -52,6 +52,9 @@ func (a *TypeRef) Equals(b *TypeRef) bool {
}
//return true
}
if a.ElementRelationship != b.ElementRelationship {
return false
}
return a.Inlined.Equals(&b.Inlined)
}

View File

@ -66,6 +66,9 @@ var SchemaSchemaYAML = `types:
- name: untyped
type:
namedType: untyped
- name: elementRelationship
type:
scalar: string
- name: scalar
scalar: string
- name: map

View File

@ -105,7 +105,11 @@ type atomHandler interface {
func resolveSchema(s *schema.Schema, tr schema.TypeRef, v value.Value, ah atomHandler) ValidationErrors {
a, ok := s.Resolve(tr)
if !ok {
return errorf("schema error: no type found matching: %v", *tr.NamedType)
typeName := "inlined type"
if tr.NamedType != nil {
typeName = *tr.NamedType
}
return errorf("schema error: no type found matching: %v", typeName)
}
a = deduceAtom(a, v)

View File

@ -80,7 +80,12 @@ func (w *mergingWalker) merge(prefixFn func() string) (errs ValidationErrors) {
alhs := deduceAtom(a, w.lhs)
arhs := deduceAtom(a, w.rhs)
if alhs.Equals(&arhs) {
// deduceAtom does not fix the type for nil values
// nil is a wildcard and will accept whatever form the other operand takes
if w.rhs == nil {
errs = append(errs, handleAtom(alhs, w.typeRef, w)...)
} else if w.lhs == nil || alhs.Equals(&arhs) {
errs = append(errs, handleAtom(arhs, w.typeRef, w)...)
} else {
w2 := *w

View File

@ -110,7 +110,7 @@ func (v *reconcileWithSchemaWalker) finishDescent(v2 *reconcileWithSchemaWalker)
}
// ReconcileFieldSetWithSchema reconciles the a field set with any changes to the
//// object's schema since the field set was written. Returns the reconciled field set, or nil of
// object's schema since the field set was written. Returns the reconciled field set, or nil of
// no changes were made to the field set.
//
// Supports:

View File

@ -99,12 +99,13 @@ func (tv TypedValue) ToFieldSet() (*fieldpath.Set, error) {
// Merge returns the result of merging tv and pso ("partially specified
// object") together. Of note:
// * No fields can be removed by this operation.
// * If both tv and pso specify a given leaf field, the result will keep pso's
// value.
// * Container typed elements will have their items ordered:
// * like tv, if pso doesn't change anything in the container
// * like pso, if pso does change something in the container.
// - No fields can be removed by this operation.
// - If both tv and pso specify a given leaf field, the result will keep pso's
// value.
// - Container typed elements will have their items ordered:
// 1. like tv, if pso doesn't change anything in the container
// 2. like pso, if pso does change something in the container.
//
// tv and pso must both be of the same type (their Schema and TypeRef must
// match), or an error will be returned. Validation errors will be returned if
// the objects don't conform to the schema.