mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: update K8s packages to v0.32.1
Update K8s packages in go.mod to v0.32.1 Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
389
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/cbor.go
generated
vendored
Normal file
389
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/cbor.go
generated
vendored
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright 2024 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 cbor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
|
||||
util "k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
||||
type metaFactory interface {
|
||||
// Interpret should return the version and kind of the wire-format of the object.
|
||||
Interpret(data []byte) (*schema.GroupVersionKind, error)
|
||||
}
|
||||
|
||||
type defaultMetaFactory struct{}
|
||||
|
||||
func (mf *defaultMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error) {
|
||||
var tm metav1.TypeMeta
|
||||
// The input is expected to include additional map keys besides apiVersion and kind, so use
|
||||
// lax mode for decoding into TypeMeta.
|
||||
if err := modes.DecodeLax.Unmarshal(data, &tm); err != nil {
|
||||
return nil, fmt.Errorf("unable to determine group/version/kind: %w", err)
|
||||
}
|
||||
actual := tm.GetObjectKind().GroupVersionKind()
|
||||
return &actual, nil
|
||||
}
|
||||
|
||||
type Serializer interface {
|
||||
runtime.Serializer
|
||||
runtime.NondeterministicEncoder
|
||||
recognizer.RecognizingDecoder
|
||||
|
||||
// NewSerializer returns a value of this interface type rather than exporting the serializer
|
||||
// type and returning one of those because the zero value of serializer isn't ready to
|
||||
// use. Users aren't intended to implement cbor.Serializer themselves, and this unexported
|
||||
// interface method is here to prevent that (https://go.dev/blog/module-compatibility).
|
||||
private()
|
||||
}
|
||||
|
||||
var _ Serializer = &serializer{}
|
||||
|
||||
type options struct {
|
||||
strict bool
|
||||
transcode bool
|
||||
}
|
||||
|
||||
type Option func(*options)
|
||||
|
||||
// Strict configures a serializer to return a strict decoding error when it encounters map keys that
|
||||
// do not correspond to a field in the target object of a decode operation. This option is disabled
|
||||
// by default.
|
||||
func Strict(s bool) Option {
|
||||
return func(opts *options) {
|
||||
opts.strict = s
|
||||
}
|
||||
}
|
||||
|
||||
// Transcode configures a serializer to transcode the "raw" bytes of a decoded runtime.RawExtension
|
||||
// or metav1.FieldsV1 object to JSON. This is enabled by default to support existing programs that
|
||||
// depend on the assumption that objects of either type contain valid JSON.
|
||||
func Transcode(s bool) Option {
|
||||
return func(opts *options) {
|
||||
opts.transcode = s
|
||||
}
|
||||
}
|
||||
|
||||
type serializer struct {
|
||||
metaFactory metaFactory
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.ObjectTyper
|
||||
options options
|
||||
}
|
||||
|
||||
func (serializer) private() {}
|
||||
|
||||
// NewSerializer creates and returns a serializer configured with the provided options. The default
|
||||
// options are equivalent to explicitly passing Strict(false) and Transcode(true).
|
||||
func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, options ...Option) Serializer {
|
||||
return newSerializer(&defaultMetaFactory{}, creater, typer, options...)
|
||||
}
|
||||
|
||||
func newSerializer(metaFactory metaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, options ...Option) *serializer {
|
||||
s := &serializer{
|
||||
metaFactory: metaFactory,
|
||||
creater: creater,
|
||||
typer: typer,
|
||||
}
|
||||
s.options.transcode = true
|
||||
for _, o := range options {
|
||||
o(&s.options)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *serializer) Identifier() runtime.Identifier {
|
||||
return "cbor"
|
||||
}
|
||||
|
||||
// Encode writes a CBOR representation of the given object.
|
||||
//
|
||||
// Because the CBOR data item written by a call to Encode is always enclosed in the "self-described
|
||||
// CBOR" tag, its encoded form always has the prefix 0xd9d9f7. This prefix is suitable for use as a
|
||||
// "magic number" for distinguishing encoded CBOR from other protocols.
|
||||
//
|
||||
// The default serialization behavior for any given object replicates the behavior of the JSON
|
||||
// serializer as far as it is necessary to allow the CBOR serializer to be used as a drop-in
|
||||
// replacement for the JSON serializer, with limited exceptions. For example, the distinction
|
||||
// between integers and floating-point numbers is preserved in CBOR due to its distinct
|
||||
// representations for each type.
|
||||
//
|
||||
// Objects implementing runtime.Unstructured will have their unstructured content encoded rather
|
||||
// than following the default behavior for their dynamic type.
|
||||
func (s *serializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return s.encode(modes.Encode, obj, w)
|
||||
}
|
||||
|
||||
func (s *serializer) EncodeNondeterministic(obj runtime.Object, w io.Writer) error {
|
||||
return s.encode(modes.EncodeNondeterministic, obj, w)
|
||||
}
|
||||
|
||||
func (s *serializer) encode(mode modes.EncMode, obj runtime.Object, w io.Writer) error {
|
||||
var v interface{} = obj
|
||||
if u, ok := obj.(runtime.Unstructured); ok {
|
||||
v = u.UnstructuredContent()
|
||||
}
|
||||
|
||||
if err := modes.RejectCustomMarshalers(v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(selfDescribedCBOR); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mode.MarshalTo(v, w)
|
||||
}
|
||||
|
||||
// gvkWithDefaults returns group kind and version defaulting from provided default
|
||||
func gvkWithDefaults(actual, defaultGVK schema.GroupVersionKind) schema.GroupVersionKind {
|
||||
if len(actual.Kind) == 0 {
|
||||
actual.Kind = defaultGVK.Kind
|
||||
}
|
||||
if len(actual.Version) == 0 && len(actual.Group) == 0 {
|
||||
actual.Group = defaultGVK.Group
|
||||
actual.Version = defaultGVK.Version
|
||||
}
|
||||
if len(actual.Version) == 0 && actual.Group == defaultGVK.Group {
|
||||
actual.Version = defaultGVK.Version
|
||||
}
|
||||
return actual
|
||||
}
|
||||
|
||||
// diagnose returns the diagnostic encoding of a well-formed CBOR data item.
|
||||
func diagnose(data []byte) string {
|
||||
diag, err := modes.Diagnostic.Diagnose(data)
|
||||
if err != nil {
|
||||
// Since the input must already be well-formed CBOR, converting it to diagnostic
|
||||
// notation should not fail.
|
||||
util.HandleError(err)
|
||||
|
||||
return hex.EncodeToString(data)
|
||||
}
|
||||
return diag
|
||||
}
|
||||
|
||||
// unmarshal unmarshals CBOR data from the provided byte slice into a Go object. If the decoder is
|
||||
// configured to report strict errors, the first error return value may be a non-nil strict decoding
|
||||
// error. If the last error return value is non-nil, then the unmarshal failed entirely and the
|
||||
// state of the destination object should not be relied on.
|
||||
func (s *serializer) unmarshal(data []byte, into interface{}) (strict, lax error) {
|
||||
if u, ok := into.(runtime.Unstructured); ok {
|
||||
var content map[string]interface{}
|
||||
defer func() {
|
||||
switch u := u.(type) {
|
||||
case *unstructured.UnstructuredList:
|
||||
// UnstructuredList's implementation of SetUnstructuredContent
|
||||
// produces different objects than those produced by a decode using
|
||||
// UnstructuredJSONScheme:
|
||||
//
|
||||
// 1. SetUnstructuredContent retains the "items" key in the list's
|
||||
// Object field. It is omitted from Object when decoding with
|
||||
// UnstructuredJSONScheme.
|
||||
// 2. SetUnstructuredContent does not populate "apiVersion" and
|
||||
// "kind" on each entry of its Items
|
||||
// field. UnstructuredJSONScheme does, inferring the singular
|
||||
// Kind from the list Kind.
|
||||
// 3. SetUnstructuredContent ignores entries of "items" that are
|
||||
// not JSON objects or are objects without
|
||||
// "kind". UnstructuredJSONScheme returns an error in either
|
||||
// case.
|
||||
//
|
||||
// UnstructuredJSONScheme's behavior is replicated here.
|
||||
var items []interface{}
|
||||
if uncast, present := content["items"]; present {
|
||||
var cast bool
|
||||
items, cast = uncast.([]interface{})
|
||||
if !cast {
|
||||
strict, lax = nil, fmt.Errorf("items field of UnstructuredList must be encoded as an array or null if present")
|
||||
return
|
||||
}
|
||||
}
|
||||
apiVersion, _ := content["apiVersion"].(string)
|
||||
kind, _ := content["kind"].(string)
|
||||
kind = strings.TrimSuffix(kind, "List")
|
||||
var unstructureds []unstructured.Unstructured
|
||||
if len(items) > 0 {
|
||||
unstructureds = make([]unstructured.Unstructured, len(items))
|
||||
}
|
||||
for i := range items {
|
||||
object, cast := items[i].(map[string]interface{})
|
||||
if !cast {
|
||||
strict, lax = nil, fmt.Errorf("elements of the items field of UnstructuredList must be encoded as a map")
|
||||
return
|
||||
}
|
||||
|
||||
// As in UnstructuredJSONScheme, only set the heuristic
|
||||
// singular GVK when both "apiVersion" and "kind" are either
|
||||
// missing, non-string, or empty.
|
||||
object["apiVersion"], _ = object["apiVersion"].(string)
|
||||
object["kind"], _ = object["kind"].(string)
|
||||
if object["apiVersion"] == "" && object["kind"] == "" {
|
||||
object["apiVersion"] = apiVersion
|
||||
object["kind"] = kind
|
||||
}
|
||||
|
||||
if object["kind"] == "" {
|
||||
strict, lax = nil, runtime.NewMissingKindErr(diagnose(data))
|
||||
return
|
||||
}
|
||||
if object["apiVersion"] == "" {
|
||||
strict, lax = nil, runtime.NewMissingVersionErr(diagnose(data))
|
||||
return
|
||||
}
|
||||
|
||||
unstructureds[i].Object = object
|
||||
}
|
||||
delete(content, "items")
|
||||
u.Object = content
|
||||
u.Items = unstructureds
|
||||
default:
|
||||
u.SetUnstructuredContent(content)
|
||||
}
|
||||
}()
|
||||
into = &content
|
||||
} else if err := modes.RejectCustomMarshalers(into); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !s.options.strict {
|
||||
return nil, modes.DecodeLax.Unmarshal(data, into)
|
||||
}
|
||||
|
||||
err := modes.Decode.Unmarshal(data, into)
|
||||
// TODO: UnknownFieldError is ambiguous. It only provides the index of the first problematic
|
||||
// map entry encountered and does not indicate which map the index refers to.
|
||||
var unknownField *cbor.UnknownFieldError
|
||||
if errors.As(err, &unknownField) {
|
||||
// Unlike JSON, there are no strict errors in CBOR for duplicate map keys. CBOR maps
|
||||
// with duplicate keys are considered invalid according to the spec and are rejected
|
||||
// entirely.
|
||||
return runtime.NewStrictDecodingError([]error{unknownField}), modes.DecodeLax.Unmarshal(data, into)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (s *serializer) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
// A preliminary pass over the input to obtain the actual GVK is redundant on a successful
|
||||
// decode into Unstructured.
|
||||
if _, ok := into.(runtime.Unstructured); ok {
|
||||
if _, unmarshalErr := s.unmarshal(data, into); unmarshalErr != nil {
|
||||
actual, interpretErr := s.metaFactory.Interpret(data)
|
||||
if interpretErr != nil {
|
||||
return nil, nil, interpretErr
|
||||
}
|
||||
|
||||
if gvk != nil {
|
||||
*actual = gvkWithDefaults(*actual, *gvk)
|
||||
}
|
||||
|
||||
return nil, actual, unmarshalErr
|
||||
}
|
||||
|
||||
actual := into.GetObjectKind().GroupVersionKind()
|
||||
if len(actual.Kind) == 0 {
|
||||
return nil, &actual, runtime.NewMissingKindErr(diagnose(data))
|
||||
}
|
||||
if len(actual.Version) == 0 {
|
||||
return nil, &actual, runtime.NewMissingVersionErr(diagnose(data))
|
||||
}
|
||||
|
||||
return into, &actual, nil
|
||||
}
|
||||
|
||||
actual, err := s.metaFactory.Interpret(data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if gvk != nil {
|
||||
*actual = gvkWithDefaults(*actual, *gvk)
|
||||
}
|
||||
|
||||
if into != nil {
|
||||
types, _, err := s.typer.ObjectKinds(into)
|
||||
if err != nil {
|
||||
return nil, actual, err
|
||||
}
|
||||
*actual = gvkWithDefaults(*actual, types[0])
|
||||
}
|
||||
|
||||
if len(actual.Kind) == 0 {
|
||||
return nil, actual, runtime.NewMissingKindErr(diagnose(data))
|
||||
}
|
||||
if len(actual.Version) == 0 {
|
||||
return nil, actual, runtime.NewMissingVersionErr(diagnose(data))
|
||||
}
|
||||
|
||||
obj, err := runtime.UseOrCreateObject(s.typer, s.creater, *actual, into)
|
||||
if err != nil {
|
||||
return nil, actual, err
|
||||
}
|
||||
|
||||
strict, err := s.unmarshal(data, obj)
|
||||
if err != nil {
|
||||
return nil, actual, err
|
||||
}
|
||||
|
||||
if s.options.transcode {
|
||||
if err := transcodeRawTypes(obj); err != nil {
|
||||
return nil, actual, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, actual, strict
|
||||
}
|
||||
|
||||
// selfDescribedCBOR is the CBOR encoding of the head of tag number 55799. This tag, specified in
|
||||
// RFC 8949 Section 3.4.6 "Self-Described CBOR", encloses all output from the encoder, has no
|
||||
// special semantics, and is used as a magic number to recognize CBOR-encoded data items.
|
||||
//
|
||||
// See https://www.rfc-editor.org/rfc/rfc8949.html#name-self-described-cbor.
|
||||
var selfDescribedCBOR = []byte{0xd9, 0xd9, 0xf7}
|
||||
|
||||
func (s *serializer) RecognizesData(data []byte) (ok, unknown bool, err error) {
|
||||
return bytes.HasPrefix(data, selfDescribedCBOR), false, nil
|
||||
}
|
||||
|
||||
// NewSerializerInfo returns a default SerializerInfo for CBOR using the given creater and typer.
|
||||
func NewSerializerInfo(creater runtime.ObjectCreater, typer runtime.ObjectTyper) runtime.SerializerInfo {
|
||||
return runtime.SerializerInfo{
|
||||
MediaType: "application/cbor",
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "cbor",
|
||||
Serializer: NewSerializer(creater, typer),
|
||||
StrictSerializer: NewSerializer(creater, typer, Strict(true)),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
Framer: NewFramer(),
|
||||
Serializer: NewSerializer(creater, typer, Transcode(false)),
|
||||
},
|
||||
}
|
||||
}
|
25
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go
generated
vendored
25
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct/direct.go
generated
vendored
@ -23,14 +23,39 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
|
||||
)
|
||||
|
||||
// Marshal serializes a value to CBOR. If there is more than one way to encode the value, it will
|
||||
// make the same choice as the CBOR implementation of runtime.Serializer.
|
||||
//
|
||||
// Note: Support for CBOR is at an alpha stage. If the value (or, for composite types, any of its
|
||||
// nested values) implement any of the interfaces encoding.TextMarshaler, encoding.TextUnmarshaler,
|
||||
// encoding/json.Marshaler, or encoding/json.Unmarshaler, a non-nil error will be returned unless
|
||||
// the value also implements the corresponding CBOR interfaces. This limitation will ultimately be
|
||||
// removed in favor of automatic transcoding to CBOR.
|
||||
func Marshal(src interface{}) ([]byte, error) {
|
||||
if err := modes.RejectCustomMarshalers(src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return modes.Encode.Marshal(src)
|
||||
}
|
||||
|
||||
// Unmarshal deserializes from CBOR into an addressable value. If there is more than one way to
|
||||
// unmarshal a value, it will make the same choice as the CBOR implementation of runtime.Serializer.
|
||||
//
|
||||
// Note: Support for CBOR is at an alpha stage. If the value (or, for composite types, any of its
|
||||
// nested values) implement any of the interfaces encoding.TextMarshaler, encoding.TextUnmarshaler,
|
||||
// encoding/json.Marshaler, or encoding/json.Unmarshaler, a non-nil error will be returned unless
|
||||
// the value also implements the corresponding CBOR interfaces. This limitation will ultimately be
|
||||
// removed in favor of automatic transcoding to CBOR.
|
||||
func Unmarshal(src []byte, dst interface{}) error {
|
||||
if err := modes.RejectCustomMarshalers(dst); err != nil {
|
||||
return err
|
||||
}
|
||||
return modes.Decode.Unmarshal(src, dst)
|
||||
}
|
||||
|
||||
// Diagnose accepts well-formed CBOR bytes and returns a string representing the same data item in
|
||||
// human-readable diagnostic notation (RFC 8949 Section 8). The diagnostic notation is not meant to
|
||||
// be parsed.
|
||||
func Diagnose(src []byte) (string, error) {
|
||||
return modes.Diagnostic.Diagnose(src)
|
||||
}
|
||||
|
90
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/framer.go
generated
vendored
Normal file
90
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/framer.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2024 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 cbor
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
||||
// NewFramer returns a runtime.Framer based on RFC 8742 CBOR Sequences. Each frame contains exactly
|
||||
// one encoded CBOR data item.
|
||||
func NewFramer() runtime.Framer {
|
||||
return framer{}
|
||||
}
|
||||
|
||||
var _ runtime.Framer = framer{}
|
||||
|
||||
type framer struct{}
|
||||
|
||||
func (framer) NewFrameReader(rc io.ReadCloser) io.ReadCloser {
|
||||
return &frameReader{
|
||||
decoder: cbor.NewDecoder(rc),
|
||||
closer: rc,
|
||||
}
|
||||
}
|
||||
|
||||
func (framer) NewFrameWriter(w io.Writer) io.Writer {
|
||||
// Each data item in a CBOR sequence is self-delimiting (like JSON objects).
|
||||
return w
|
||||
}
|
||||
|
||||
type frameReader struct {
|
||||
decoder *cbor.Decoder
|
||||
closer io.Closer
|
||||
|
||||
overflow []byte
|
||||
}
|
||||
|
||||
func (fr *frameReader) Read(dst []byte) (int, error) {
|
||||
if len(fr.overflow) > 0 {
|
||||
// We read a frame that was too large for the destination slice in a previous call
|
||||
// to Read and have bytes left over.
|
||||
n := copy(dst, fr.overflow)
|
||||
if n < len(fr.overflow) {
|
||||
fr.overflow = fr.overflow[n:]
|
||||
return n, io.ErrShortBuffer
|
||||
}
|
||||
fr.overflow = nil
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// The Reader contract allows implementations to use all of dst[0:len(dst)] as scratch
|
||||
// space, even if n < len(dst), but it does not allow implementations to use
|
||||
// dst[len(dst):cap(dst)]. Slicing it up-front allows us to append to it without worrying
|
||||
// about overwriting dst[len(dst):cap(dst)].
|
||||
m := cbor.RawMessage(dst[0:0:len(dst)])
|
||||
if err := fr.decoder.Decode(&m); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(m) > len(dst) {
|
||||
// The frame was too big, m has a newly-allocated underlying array to accommodate
|
||||
// it.
|
||||
fr.overflow = m[len(dst):]
|
||||
return copy(dst, m), io.ErrShortBuffer
|
||||
}
|
||||
|
||||
return len(m), nil
|
||||
}
|
||||
|
||||
func (fr *frameReader) Close() error {
|
||||
return fr.closer.Close()
|
||||
}
|
2
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go
generated
vendored
2
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go
generated
vendored
@ -105,7 +105,7 @@ var Encode = EncMode{
|
||||
var EncodeNondeterministic = EncMode{
|
||||
delegate: func() cbor.UserBufferEncMode {
|
||||
opts := Encode.options()
|
||||
opts.Sort = cbor.SortNone // TODO: Use cbor.SortFastShuffle after bump to v2.7.0.
|
||||
opts.Sort = cbor.SortFastShuffle
|
||||
em, err := opts.UserBufferEncMode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
236
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/raw.go
generated
vendored
Normal file
236
vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/raw.go
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
Copyright 2024 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 cbor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
var sharedTranscoders transcoders
|
||||
|
||||
var rawTypeTranscodeFuncs = map[reflect.Type]func(reflect.Value) error{
|
||||
reflect.TypeFor[runtime.RawExtension](): func(rv reflect.Value) error {
|
||||
if !rv.CanAddr() {
|
||||
return nil
|
||||
}
|
||||
re := rv.Addr().Interface().(*runtime.RawExtension)
|
||||
if re.Raw == nil {
|
||||
// When Raw is nil it encodes to null. Don't change nil Raw values during
|
||||
// transcoding, they would have unmarshalled from JSON as nil too.
|
||||
return nil
|
||||
}
|
||||
j, err := re.MarshalJSON()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to transcode RawExtension to JSON: %w", err)
|
||||
}
|
||||
re.Raw = j
|
||||
return nil
|
||||
},
|
||||
reflect.TypeFor[metav1.FieldsV1](): func(rv reflect.Value) error {
|
||||
if !rv.CanAddr() {
|
||||
return nil
|
||||
}
|
||||
fields := rv.Addr().Interface().(*metav1.FieldsV1)
|
||||
if fields.Raw == nil {
|
||||
// When Raw is nil it encodes to null. Don't change nil Raw values during
|
||||
// transcoding, they would have unmarshalled from JSON as nil too.
|
||||
return nil
|
||||
}
|
||||
j, err := fields.MarshalJSON()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to transcode FieldsV1 to JSON: %w", err)
|
||||
}
|
||||
fields.Raw = j
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func transcodeRawTypes(v interface{}) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
return sharedTranscoders.getTranscoder(rv.Type()).fn(rv)
|
||||
}
|
||||
|
||||
type transcoder struct {
|
||||
fn func(rv reflect.Value) error
|
||||
}
|
||||
|
||||
var noop = transcoder{
|
||||
fn: func(reflect.Value) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
type transcoders struct {
|
||||
lock sync.RWMutex
|
||||
m map[reflect.Type]**transcoder
|
||||
}
|
||||
|
||||
func (ts *transcoders) getTranscoder(rt reflect.Type) transcoder {
|
||||
ts.lock.RLock()
|
||||
tpp, ok := ts.m[rt]
|
||||
ts.lock.RUnlock()
|
||||
if ok {
|
||||
return **tpp
|
||||
}
|
||||
|
||||
ts.lock.Lock()
|
||||
defer ts.lock.Unlock()
|
||||
tp := ts.getTranscoderLocked(rt)
|
||||
return *tp
|
||||
}
|
||||
|
||||
func (ts *transcoders) getTranscoderLocked(rt reflect.Type) *transcoder {
|
||||
if tpp, ok := ts.m[rt]; ok {
|
||||
// A transcoder for this type was cached while waiting to acquire the lock.
|
||||
return *tpp
|
||||
}
|
||||
|
||||
// Cache the transcoder now, before populating fn, so that circular references between types
|
||||
// don't overflow the call stack.
|
||||
t := new(transcoder)
|
||||
if ts.m == nil {
|
||||
ts.m = make(map[reflect.Type]**transcoder)
|
||||
}
|
||||
ts.m[rt] = &t
|
||||
|
||||
for rawType, fn := range rawTypeTranscodeFuncs {
|
||||
if rt == rawType {
|
||||
t = &transcoder{fn: fn}
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
switch rt.Kind() {
|
||||
case reflect.Array:
|
||||
te := ts.getTranscoderLocked(rt.Elem())
|
||||
rtlen := rt.Len()
|
||||
if rtlen == 0 || te == &noop {
|
||||
t = &noop
|
||||
break
|
||||
}
|
||||
t.fn = func(rv reflect.Value) error {
|
||||
for i := 0; i < rtlen; i++ {
|
||||
if err := te.fn(rv.Index(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
// Any interface value might have a dynamic type involving RawExtension. It needs to
|
||||
// be checked.
|
||||
t.fn = func(rv reflect.Value) error {
|
||||
if rv.IsNil() {
|
||||
return nil
|
||||
}
|
||||
rv = rv.Elem()
|
||||
// The interface element's type is dynamic so its transcoder can't be
|
||||
// determined statically.
|
||||
return ts.getTranscoder(rv.Type()).fn(rv)
|
||||
}
|
||||
case reflect.Map:
|
||||
rtk := rt.Key()
|
||||
tk := ts.getTranscoderLocked(rtk)
|
||||
rte := rt.Elem()
|
||||
te := ts.getTranscoderLocked(rte)
|
||||
if tk == &noop && te == &noop {
|
||||
t = &noop
|
||||
break
|
||||
}
|
||||
t.fn = func(rv reflect.Value) error {
|
||||
iter := rv.MapRange()
|
||||
rvk := reflect.New(rtk).Elem()
|
||||
rve := reflect.New(rte).Elem()
|
||||
for iter.Next() {
|
||||
rvk.SetIterKey(iter)
|
||||
if err := tk.fn(rvk); err != nil {
|
||||
return err
|
||||
}
|
||||
rve.SetIterValue(iter)
|
||||
if err := te.fn(rve); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case reflect.Pointer:
|
||||
te := ts.getTranscoderLocked(rt.Elem())
|
||||
if te == &noop {
|
||||
t = &noop
|
||||
break
|
||||
}
|
||||
t.fn = func(rv reflect.Value) error {
|
||||
if rv.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return te.fn(rv.Elem())
|
||||
}
|
||||
case reflect.Slice:
|
||||
te := ts.getTranscoderLocked(rt.Elem())
|
||||
if te == &noop {
|
||||
t = &noop
|
||||
break
|
||||
}
|
||||
t.fn = func(rv reflect.Value) error {
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if err := te.fn(rv.Index(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case reflect.Struct:
|
||||
type fieldTranscoder struct {
|
||||
Index int
|
||||
Transcoder *transcoder
|
||||
}
|
||||
var fieldTranscoders []fieldTranscoder
|
||||
for i := 0; i < rt.NumField(); i++ {
|
||||
f := rt.Field(i)
|
||||
tf := ts.getTranscoderLocked(f.Type)
|
||||
if tf == &noop {
|
||||
continue
|
||||
}
|
||||
fieldTranscoders = append(fieldTranscoders, fieldTranscoder{Index: i, Transcoder: tf})
|
||||
}
|
||||
if len(fieldTranscoders) == 0 {
|
||||
t = &noop
|
||||
break
|
||||
}
|
||||
t.fn = func(rv reflect.Value) error {
|
||||
for _, ft := range fieldTranscoders {
|
||||
if err := ft.Transcoder.fn(rv.Field(ft.Index)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
t = &noop
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
145
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
generated
vendored
145
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
generated
vendored
@ -17,9 +17,6 @@ limitations under the License.
|
||||
package serializer
|
||||
|
||||
import (
|
||||
"mime"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
@ -28,41 +25,26 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
|
||||
)
|
||||
|
||||
// serializerExtensions are for serializers that are conditionally compiled in
|
||||
var serializerExtensions = []func(*runtime.Scheme) (serializerType, bool){}
|
||||
|
||||
type serializerType struct {
|
||||
AcceptContentTypes []string
|
||||
ContentType string
|
||||
FileExtensions []string
|
||||
// EncodesAsText should be true if this content type can be represented safely in UTF-8
|
||||
EncodesAsText bool
|
||||
|
||||
Serializer runtime.Serializer
|
||||
PrettySerializer runtime.Serializer
|
||||
StrictSerializer runtime.Serializer
|
||||
|
||||
AcceptStreamContentTypes []string
|
||||
StreamContentType string
|
||||
|
||||
Framer runtime.Framer
|
||||
StreamSerializer runtime.Serializer
|
||||
}
|
||||
|
||||
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, options CodecFactoryOptions) []serializerType {
|
||||
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, options CodecFactoryOptions) []runtime.SerializerInfo {
|
||||
jsonSerializer := json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: false, Pretty: false, Strict: options.Strict},
|
||||
)
|
||||
jsonSerializerType := serializerType{
|
||||
AcceptContentTypes: []string{runtime.ContentTypeJSON},
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
FileExtensions: []string{"json"},
|
||||
EncodesAsText: true,
|
||||
Serializer: jsonSerializer,
|
||||
|
||||
Framer: json.Framer,
|
||||
StreamSerializer: jsonSerializer,
|
||||
jsonSerializerType := runtime.SerializerInfo{
|
||||
MediaType: runtime.ContentTypeJSON,
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "json",
|
||||
EncodesAsText: true,
|
||||
Serializer: jsonSerializer,
|
||||
StrictSerializer: json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: false, Pretty: false, Strict: true},
|
||||
),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
EncodesAsText: true,
|
||||
Serializer: jsonSerializer,
|
||||
Framer: json.Framer,
|
||||
},
|
||||
}
|
||||
if options.Pretty {
|
||||
jsonSerializerType.PrettySerializer = json.NewSerializerWithOptions(
|
||||
@ -71,12 +53,6 @@ func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, option
|
||||
)
|
||||
}
|
||||
|
||||
strictJSONSerializer := json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: false, Pretty: false, Strict: true},
|
||||
)
|
||||
jsonSerializerType.StrictSerializer = strictJSONSerializer
|
||||
|
||||
yamlSerializer := json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: true, Pretty: false, Strict: options.Strict},
|
||||
@ -88,35 +64,35 @@ func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, option
|
||||
protoSerializer := protobuf.NewSerializer(scheme, scheme)
|
||||
protoRawSerializer := protobuf.NewRawSerializer(scheme, scheme)
|
||||
|
||||
serializers := []serializerType{
|
||||
serializers := []runtime.SerializerInfo{
|
||||
jsonSerializerType,
|
||||
{
|
||||
AcceptContentTypes: []string{runtime.ContentTypeYAML},
|
||||
ContentType: runtime.ContentTypeYAML,
|
||||
FileExtensions: []string{"yaml"},
|
||||
EncodesAsText: true,
|
||||
Serializer: yamlSerializer,
|
||||
StrictSerializer: strictYAMLSerializer,
|
||||
MediaType: runtime.ContentTypeYAML,
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "yaml",
|
||||
EncodesAsText: true,
|
||||
Serializer: yamlSerializer,
|
||||
StrictSerializer: strictYAMLSerializer,
|
||||
},
|
||||
{
|
||||
AcceptContentTypes: []string{runtime.ContentTypeProtobuf},
|
||||
ContentType: runtime.ContentTypeProtobuf,
|
||||
FileExtensions: []string{"pb"},
|
||||
Serializer: protoSerializer,
|
||||
MediaType: runtime.ContentTypeProtobuf,
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "vnd.kubernetes.protobuf",
|
||||
Serializer: protoSerializer,
|
||||
// note, strict decoding is unsupported for protobuf,
|
||||
// fall back to regular serializing
|
||||
StrictSerializer: protoSerializer,
|
||||
|
||||
Framer: protobuf.LengthDelimitedFramer,
|
||||
StreamSerializer: protoRawSerializer,
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
Serializer: protoRawSerializer,
|
||||
Framer: protobuf.LengthDelimitedFramer,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, fn := range serializerExtensions {
|
||||
if serializer, ok := fn(scheme); ok {
|
||||
serializers = append(serializers, serializer)
|
||||
}
|
||||
for _, f := range options.serializers {
|
||||
serializers = append(serializers, f(scheme, scheme))
|
||||
}
|
||||
|
||||
return serializers
|
||||
}
|
||||
|
||||
@ -136,6 +112,8 @@ type CodecFactoryOptions struct {
|
||||
Strict bool
|
||||
// Pretty includes a pretty serializer along with the non-pretty one
|
||||
Pretty bool
|
||||
|
||||
serializers []func(runtime.ObjectCreater, runtime.ObjectTyper) runtime.SerializerInfo
|
||||
}
|
||||
|
||||
// CodecFactoryOptionsMutator takes a pointer to an options struct and then modifies it.
|
||||
@ -162,6 +140,13 @@ func DisableStrict(options *CodecFactoryOptions) {
|
||||
options.Strict = false
|
||||
}
|
||||
|
||||
// WithSerializer configures a serializer to be supported in addition to the default serializers.
|
||||
func WithSerializer(f func(runtime.ObjectCreater, runtime.ObjectTyper) runtime.SerializerInfo) CodecFactoryOptionsMutator {
|
||||
return func(options *CodecFactoryOptions) {
|
||||
options.serializers = append(options.serializers, f)
|
||||
}
|
||||
}
|
||||
|
||||
// NewCodecFactory provides methods for retrieving serializers for the supported wire formats
|
||||
// and conversion wrappers to define preferred internal and external versions. In the future,
|
||||
// as the internal version is used less, callers may instead use a defaulting serializer and
|
||||
@ -184,7 +169,7 @@ func NewCodecFactory(scheme *runtime.Scheme, mutators ...CodecFactoryOptionsMuta
|
||||
}
|
||||
|
||||
// newCodecFactory is a helper for testing that allows a different metafactory to be specified.
|
||||
func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) CodecFactory {
|
||||
func newCodecFactory(scheme *runtime.Scheme, serializers []runtime.SerializerInfo) CodecFactory {
|
||||
decoders := make([]runtime.Decoder, 0, len(serializers))
|
||||
var accepts []runtime.SerializerInfo
|
||||
alreadyAccepted := make(map[string]struct{})
|
||||
@ -192,38 +177,20 @@ func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) Codec
|
||||
var legacySerializer runtime.Serializer
|
||||
for _, d := range serializers {
|
||||
decoders = append(decoders, d.Serializer)
|
||||
for _, mediaType := range d.AcceptContentTypes {
|
||||
if _, ok := alreadyAccepted[mediaType]; ok {
|
||||
continue
|
||||
}
|
||||
alreadyAccepted[mediaType] = struct{}{}
|
||||
info := runtime.SerializerInfo{
|
||||
MediaType: d.ContentType,
|
||||
EncodesAsText: d.EncodesAsText,
|
||||
Serializer: d.Serializer,
|
||||
PrettySerializer: d.PrettySerializer,
|
||||
StrictSerializer: d.StrictSerializer,
|
||||
}
|
||||
if _, ok := alreadyAccepted[d.MediaType]; ok {
|
||||
continue
|
||||
}
|
||||
alreadyAccepted[d.MediaType] = struct{}{}
|
||||
|
||||
mediaType, _, err := mime.ParseMediaType(info.MediaType)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
parts := strings.SplitN(mediaType, "/", 2)
|
||||
info.MediaTypeType = parts[0]
|
||||
info.MediaTypeSubType = parts[1]
|
||||
acceptedSerializerShallowCopy := d
|
||||
if d.StreamSerializer != nil {
|
||||
cloned := *d.StreamSerializer
|
||||
acceptedSerializerShallowCopy.StreamSerializer = &cloned
|
||||
}
|
||||
accepts = append(accepts, acceptedSerializerShallowCopy)
|
||||
|
||||
if d.StreamSerializer != nil {
|
||||
info.StreamSerializer = &runtime.StreamSerializerInfo{
|
||||
Serializer: d.StreamSerializer,
|
||||
EncodesAsText: d.EncodesAsText,
|
||||
Framer: d.Framer,
|
||||
}
|
||||
}
|
||||
accepts = append(accepts, info)
|
||||
if mediaType == runtime.ContentTypeJSON {
|
||||
legacySerializer = d.Serializer
|
||||
}
|
||||
if d.MediaType == runtime.ContentTypeJSON {
|
||||
legacySerializer = d.Serializer
|
||||
}
|
||||
}
|
||||
if legacySerializer == nil {
|
||||
|
Reference in New Issue
Block a user