aboutsummaryrefslogtreecommitdiff
path: root/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go')
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go476
1 files changed, 0 insertions, 476 deletions
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
deleted file mode 100644
index 404fb1b7e..000000000
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
-Copyright 2015 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 protobuf
-
-import (
- "bytes"
- "fmt"
- "io"
- "net/http"
- "reflect"
-
- "github.com/gogo/protobuf/proto"
-
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
- "k8s.io/apimachinery/pkg/util/framer"
-)
-
-var (
- // protoEncodingPrefix serves as a magic number for an encoded protobuf message on this serializer. All
- // proto messages serialized by this schema will be preceded by the bytes 0x6b 0x38 0x73, with the fourth
- // byte being reserved for the encoding style. The only encoding style defined is 0x00, which means that
- // the rest of the byte stream is a message of type k8s.io.kubernetes.pkg.runtime.Unknown (proto2).
- //
- // See k8s.io/apimachinery/pkg/runtime/generated.proto for details of the runtime.Unknown message.
- //
- // This encoding scheme is experimental, and is subject to change at any time.
- protoEncodingPrefix = []byte{0x6b, 0x38, 0x73, 0x00}
-)
-
-type errNotMarshalable struct {
- t reflect.Type
-}
-
-func (e errNotMarshalable) Error() string {
- return fmt.Sprintf("object %v does not implement the protobuf marshalling interface and cannot be encoded to a protobuf message", e.t)
-}
-
-func (e errNotMarshalable) Status() metav1.Status {
- return metav1.Status{
- Status: metav1.StatusFailure,
- Code: http.StatusNotAcceptable,
- Reason: metav1.StatusReason("NotAcceptable"),
- Message: e.Error(),
- }
-}
-
-// IsNotMarshalable checks the type of error, returns a boolean true if error is not nil and not marshalable false otherwise
-func IsNotMarshalable(err error) bool {
- _, ok := err.(errNotMarshalable)
- return err != nil && ok
-}
-
-// NewSerializer creates a Protobuf serializer that handles encoding versioned objects into the proper wire form. If a typer
-// is passed, the encoded object will have group, version, and kind fields set. If typer is nil, the objects will be written
-// as-is (any type info passed with the object will be used).
-func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
- return &Serializer{
- prefix: protoEncodingPrefix,
- creater: creater,
- typer: typer,
- }
-}
-
-// Serializer handles encoding versioned objects into the proper wire form
-type Serializer struct {
- prefix []byte
- creater runtime.ObjectCreater
- typer runtime.ObjectTyper
-}
-
-var _ runtime.Serializer = &Serializer{}
-var _ recognizer.RecognizingDecoder = &Serializer{}
-
-const serializerIdentifier runtime.Identifier = "protobuf"
-
-// Decode attempts to convert the provided data into a protobuf message, extract the stored schema kind, apply the provided default
-// gvk, and then load that data into an object matching the desired schema kind or the provided into. If into is *runtime.Unknown,
-// the raw data will be extracted and no decoding will be performed. If into is not registered with the typer, then the object will
-// be straight decoded using normal protobuf unmarshalling (the MarshalTo interface). If into is provided and the original data is
-// not fully qualified with kind/version/group, the type of the into will be used to alter the returned gvk. On success or most
-// errors, the method will return the calculated schema kind.
-func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
- prefixLen := len(s.prefix)
- switch {
- case len(originalData) == 0:
- // TODO: treat like decoding {} from JSON with defaulting
- return nil, nil, fmt.Errorf("empty data")
- case len(originalData) < prefixLen || !bytes.Equal(s.prefix, originalData[:prefixLen]):
- return nil, nil, fmt.Errorf("provided data does not appear to be a protobuf message, expected prefix %v", s.prefix)
- case len(originalData) == prefixLen:
- // TODO: treat like decoding {} from JSON with defaulting
- return nil, nil, fmt.Errorf("empty body")
- }
-
- data := originalData[prefixLen:]
- unk := runtime.Unknown{}
- if err := unk.Unmarshal(data); err != nil {
- return nil, nil, err
- }
-
- actual := unk.GroupVersionKind()
- copyKindDefaults(&actual, gvk)
-
- if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
- *intoUnknown = unk
- if ok, _, _ := s.RecognizesData(bytes.NewBuffer(unk.Raw)); ok {
- intoUnknown.ContentType = runtime.ContentTypeProtobuf
- }
- return intoUnknown, &actual, nil
- }
-
- if into != nil {
- types, _, err := s.typer.ObjectKinds(into)
- switch {
- case runtime.IsNotRegisteredError(err):
- pb, ok := into.(proto.Message)
- if !ok {
- return nil, &actual, errNotMarshalable{reflect.TypeOf(into)}
- }
- if err := proto.Unmarshal(unk.Raw, pb); err != nil {
- return nil, &actual, err
- }
- return into, &actual, nil
- case err != nil:
- return nil, &actual, err
- default:
- copyKindDefaults(&actual, &types[0])
- // if the result of defaulting did not set a version or group, ensure that at least group is set
- // (copyKindDefaults will not assign Group if version is already set). This guarantees that the group
- // of into is set if there is no better information from the caller or object.
- if len(actual.Version) == 0 && len(actual.Group) == 0 {
- actual.Group = types[0].Group
- }
- }
- }
-
- if len(actual.Kind) == 0 {
- return nil, &actual, runtime.NewMissingKindErr(fmt.Sprintf("%#v", unk.TypeMeta))
- }
- if len(actual.Version) == 0 {
- return nil, &actual, runtime.NewMissingVersionErr(fmt.Sprintf("%#v", unk.TypeMeta))
- }
-
- return unmarshalToObject(s.typer, s.creater, &actual, into, unk.Raw)
-}
-
-// Encode serializes the provided object to the given writer.
-func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
- if co, ok := obj.(runtime.CacheableObject); ok {
- return co.CacheEncode(s.Identifier(), s.doEncode, w)
- }
- return s.doEncode(obj, w)
-}
-
-func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
- prefixSize := uint64(len(s.prefix))
-
- var unk runtime.Unknown
- switch t := obj.(type) {
- case *runtime.Unknown:
- estimatedSize := prefixSize + uint64(t.Size())
- data := make([]byte, estimatedSize)
- i, err := t.MarshalTo(data[prefixSize:])
- if err != nil {
- return err
- }
- copy(data, s.prefix)
- _, err = w.Write(data[:prefixSize+uint64(i)])
- return err
- default:
- kind := obj.GetObjectKind().GroupVersionKind()
- unk = runtime.Unknown{
- TypeMeta: runtime.TypeMeta{
- Kind: kind.Kind,
- APIVersion: kind.GroupVersion().String(),
- },
- }
- }
-
- switch t := obj.(type) {
- case bufferedMarshaller:
- // this path performs a single allocation during write but requires the caller to implement
- // the more efficient Size and MarshalToSizedBuffer methods
- encodedSize := uint64(t.Size())
- estimatedSize := prefixSize + estimateUnknownSize(&unk, encodedSize)
- data := make([]byte, estimatedSize)
-
- i, err := unk.NestedMarshalTo(data[prefixSize:], t, encodedSize)
- if err != nil {
- return err
- }
-
- copy(data, s.prefix)
-
- _, err = w.Write(data[:prefixSize+uint64(i)])
- return err
-
- case proto.Marshaler:
- // this path performs extra allocations
- data, err := t.Marshal()
- if err != nil {
- return err
- }
- unk.Raw = data
-
- estimatedSize := prefixSize + uint64(unk.Size())
- data = make([]byte, estimatedSize)
-
- i, err := unk.MarshalTo(data[prefixSize:])
- if err != nil {
- return err
- }
-
- copy(data, s.prefix)
-
- _, err = w.Write(data[:prefixSize+uint64(i)])
- return err
-
- default:
- // TODO: marshal with a different content type and serializer (JSON for third party objects)
- return errNotMarshalable{reflect.TypeOf(obj)}
- }
-}
-
-// Identifier implements runtime.Encoder interface.
-func (s *Serializer) Identifier() runtime.Identifier {
- return serializerIdentifier
-}
-
-// RecognizesData implements the RecognizingDecoder interface.
-func (s *Serializer) RecognizesData(peek io.Reader) (bool, bool, error) {
- prefix := make([]byte, 4)
- n, err := peek.Read(prefix)
- if err != nil {
- if err == io.EOF {
- return false, false, nil
- }
- return false, false, err
- }
- if n != 4 {
- return false, false, nil
- }
- return bytes.Equal(s.prefix, prefix), false, nil
-}
-
-// copyKindDefaults defaults dst to the value in src if dst does not have a value set.
-func copyKindDefaults(dst, src *schema.GroupVersionKind) {
- if src == nil {
- return
- }
- // apply kind and version defaulting from provided default
- if len(dst.Kind) == 0 {
- dst.Kind = src.Kind
- }
- if len(dst.Version) == 0 && len(src.Version) > 0 {
- dst.Group = src.Group
- dst.Version = src.Version
- }
-}
-
-// bufferedMarshaller describes a more efficient marshalling interface that can avoid allocating multiple
-// byte buffers by pre-calculating the size of the final buffer needed.
-type bufferedMarshaller interface {
- proto.Sizer
- runtime.ProtobufMarshaller
-}
-
-// Like bufferedMarshaller, but is able to marshal backwards, which is more efficient since it doesn't call Size() as frequently.
-type bufferedReverseMarshaller interface {
- proto.Sizer
- runtime.ProtobufReverseMarshaller
-}
-
-// estimateUnknownSize returns the expected bytes consumed by a given runtime.Unknown
-// object with a nil RawJSON struct and the expected size of the provided buffer. The
-// returned size will not be correct if RawJSOn is set on unk.
-func estimateUnknownSize(unk *runtime.Unknown, byteSize uint64) uint64 {
- size := uint64(unk.Size())
- // protobuf uses 1 byte for the tag, a varint for the length of the array (at most 8 bytes - uint64 - here),
- // and the size of the array.
- size += 1 + 8 + byteSize
- return size
-}
-
-// NewRawSerializer creates a Protobuf serializer that handles encoding versioned objects into the proper wire form. If typer
-// is not nil, the object has the group, version, and kind fields set. This serializer does not provide type information for the
-// encoded object, and thus is not self describing (callers must know what type is being described in order to decode).
-//
-// This encoding scheme is experimental, and is subject to change at any time.
-func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper) *RawSerializer {
- return &RawSerializer{
- creater: creater,
- typer: typer,
- }
-}
-
-// RawSerializer encodes and decodes objects without adding a runtime.Unknown wrapper (objects are encoded without identifying
-// type).
-type RawSerializer struct {
- creater runtime.ObjectCreater
- typer runtime.ObjectTyper
-}
-
-var _ runtime.Serializer = &RawSerializer{}
-
-const rawSerializerIdentifier runtime.Identifier = "raw-protobuf"
-
-// Decode attempts to convert the provided data into a protobuf message, extract the stored schema kind, apply the provided default
-// gvk, and then load that data into an object matching the desired schema kind or the provided into. If into is *runtime.Unknown,
-// the raw data will be extracted and no decoding will be performed. If into is not registered with the typer, then the object will
-// be straight decoded using normal protobuf unmarshalling (the MarshalTo interface). If into is provided and the original data is
-// not fully qualified with kind/version/group, the type of the into will be used to alter the returned gvk. On success or most
-// errors, the method will return the calculated schema kind.
-func (s *RawSerializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
- if into == nil {
- return nil, nil, fmt.Errorf("this serializer requires an object to decode into: %#v", s)
- }
-
- if len(originalData) == 0 {
- // TODO: treat like decoding {} from JSON with defaulting
- return nil, nil, fmt.Errorf("empty data")
- }
- data := originalData
-
- actual := &schema.GroupVersionKind{}
- copyKindDefaults(actual, gvk)
-
- if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
- intoUnknown.Raw = data
- intoUnknown.ContentEncoding = ""
- intoUnknown.ContentType = runtime.ContentTypeProtobuf
- intoUnknown.SetGroupVersionKind(*actual)
- return intoUnknown, actual, nil
- }
-
- types, _, err := s.typer.ObjectKinds(into)
- switch {
- case runtime.IsNotRegisteredError(err):
- pb, ok := into.(proto.Message)
- if !ok {
- return nil, actual, errNotMarshalable{reflect.TypeOf(into)}
- }
- if err := proto.Unmarshal(data, pb); err != nil {
- return nil, actual, err
- }
- return into, actual, nil
- case err != nil:
- return nil, actual, err
- default:
- copyKindDefaults(actual, &types[0])
- // if the result of defaulting did not set a version or group, ensure that at least group is set
- // (copyKindDefaults will not assign Group if version is already set). This guarantees that the group
- // of into is set if there is no better information from the caller or object.
- if len(actual.Version) == 0 && len(actual.Group) == 0 {
- actual.Group = types[0].Group
- }
- }
-
- if len(actual.Kind) == 0 {
- return nil, actual, runtime.NewMissingKindErr("<protobuf encoded body - must provide default type>")
- }
- if len(actual.Version) == 0 {
- return nil, actual, runtime.NewMissingVersionErr("<protobuf encoded body - must provide default type>")
- }
-
- return unmarshalToObject(s.typer, s.creater, actual, into, data)
-}
-
-// unmarshalToObject is the common code between decode in the raw and normal serializer.
-func unmarshalToObject(typer runtime.ObjectTyper, creater runtime.ObjectCreater, actual *schema.GroupVersionKind, into runtime.Object, data []byte) (runtime.Object, *schema.GroupVersionKind, error) {
- // use the target if necessary
- obj, err := runtime.UseOrCreateObject(typer, creater, *actual, into)
- if err != nil {
- return nil, actual, err
- }
-
- pb, ok := obj.(proto.Message)
- if !ok {
- return nil, actual, errNotMarshalable{reflect.TypeOf(obj)}
- }
- if err := proto.Unmarshal(data, pb); err != nil {
- return nil, actual, err
- }
- if actual != nil {
- obj.GetObjectKind().SetGroupVersionKind(*actual)
- }
- return obj, actual, nil
-}
-
-// Encode serializes the provided object to the given writer. Overrides is ignored.
-func (s *RawSerializer) Encode(obj runtime.Object, w io.Writer) error {
- if co, ok := obj.(runtime.CacheableObject); ok {
- return co.CacheEncode(s.Identifier(), s.doEncode, w)
- }
- return s.doEncode(obj, w)
-}
-
-func (s *RawSerializer) doEncode(obj runtime.Object, w io.Writer) error {
- switch t := obj.(type) {
- case bufferedReverseMarshaller:
- // this path performs a single allocation during write but requires the caller to implement
- // the more efficient Size and MarshalToSizedBuffer methods
- encodedSize := uint64(t.Size())
- data := make([]byte, encodedSize)
-
- n, err := t.MarshalToSizedBuffer(data)
- if err != nil {
- return err
- }
- _, err = w.Write(data[:n])
- return err
-
- case bufferedMarshaller:
- // this path performs a single allocation during write but requires the caller to implement
- // the more efficient Size and MarshalTo methods
- encodedSize := uint64(t.Size())
- data := make([]byte, encodedSize)
-
- n, err := t.MarshalTo(data)
- if err != nil {
- return err
- }
- _, err = w.Write(data[:n])
- return err
-
- case proto.Marshaler:
- // this path performs extra allocations
- data, err := t.Marshal()
- if err != nil {
- return err
- }
- _, err = w.Write(data)
- return err
-
- default:
- return errNotMarshalable{reflect.TypeOf(obj)}
- }
-}
-
-// Identifier implements runtime.Encoder interface.
-func (s *RawSerializer) Identifier() runtime.Identifier {
- return rawSerializerIdentifier
-}
-
-// LengthDelimitedFramer is exported variable of type lengthDelimitedFramer
-var LengthDelimitedFramer = lengthDelimitedFramer{}
-
-// Provides length delimited frame reader and writer methods
-type lengthDelimitedFramer struct{}
-
-// NewFrameWriter implements stream framing for this serializer
-func (lengthDelimitedFramer) NewFrameWriter(w io.Writer) io.Writer {
- return framer.NewLengthDelimitedFrameWriter(w)
-}
-
-// NewFrameReader implements stream framing for this serializer
-func (lengthDelimitedFramer) NewFrameReader(r io.ReadCloser) io.ReadCloser {
- return framer.NewLengthDelimitedFrameReader(r)
-}