summaryrefslogtreecommitdiff
path: root/vendor/k8s.io/apimachinery/pkg/runtime/serializer
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-11-01 11:24:59 -0400
committerMatthew Heon <matthew.heon@gmail.com>2017-11-01 11:24:59 -0400
commita031b83a09a8628435317a03f199cdc18b78262f (patch)
treebc017a96769ce6de33745b8b0b1304ccf38e9df0 /vendor/k8s.io/apimachinery/pkg/runtime/serializer
parent2b74391cd5281f6fdf391ff8ad50fd1490f6bf89 (diff)
downloadpodman-a031b83a09a8628435317a03f199cdc18b78262f.tar.gz
podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.bz2
podman-a031b83a09a8628435317a03f199cdc18b78262f.zip
Initial checkin from CRI-O repo
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'vendor/k8s.io/apimachinery/pkg/runtime/serializer')
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go237
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go245
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go63
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go43
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go18
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go448
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go48
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go127
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go137
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go273
10 files changed, 1639 insertions, 0 deletions
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
new file mode 100644
index 000000000..65f451124
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
@@ -0,0 +1,237 @@
+/*
+Copyright 2014 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 serializer
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/runtime/serializer/json"
+ "k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
+ "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
+
+ AcceptStreamContentTypes []string
+ StreamContentType string
+
+ Framer runtime.Framer
+ StreamSerializer runtime.Serializer
+}
+
+func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory) []serializerType {
+ jsonSerializer := json.NewSerializer(mf, scheme, scheme, false)
+ jsonPrettySerializer := json.NewSerializer(mf, scheme, scheme, true)
+ yamlSerializer := json.NewYAMLSerializer(mf, scheme, scheme)
+
+ serializers := []serializerType{
+ {
+ AcceptContentTypes: []string{"application/json"},
+ ContentType: "application/json",
+ FileExtensions: []string{"json"},
+ EncodesAsText: true,
+ Serializer: jsonSerializer,
+ PrettySerializer: jsonPrettySerializer,
+
+ Framer: json.Framer,
+ StreamSerializer: jsonSerializer,
+ },
+ {
+ AcceptContentTypes: []string{"application/yaml"},
+ ContentType: "application/yaml",
+ FileExtensions: []string{"yaml"},
+ EncodesAsText: true,
+ Serializer: yamlSerializer,
+ },
+ }
+
+ for _, fn := range serializerExtensions {
+ if serializer, ok := fn(scheme); ok {
+ serializers = append(serializers, serializer)
+ }
+ }
+ return serializers
+}
+
+// CodecFactory provides methods for retrieving codecs and serializers for specific
+// versions and content types.
+type CodecFactory struct {
+ scheme *runtime.Scheme
+ serializers []serializerType
+ universal runtime.Decoder
+ accepts []runtime.SerializerInfo
+
+ legacySerializer runtime.Serializer
+}
+
+// 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
+// only convert objects which are shared internally (Status, common API machinery).
+// TODO: allow other codecs to be compiled in?
+// TODO: accept a scheme interface
+func NewCodecFactory(scheme *runtime.Scheme) CodecFactory {
+ serializers := newSerializersForScheme(scheme, json.DefaultMetaFactory)
+ return newCodecFactory(scheme, serializers)
+}
+
+// newCodecFactory is a helper for testing that allows a different metafactory to be specified.
+func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) CodecFactory {
+ decoders := make([]runtime.Decoder, 0, len(serializers))
+ var accepts []runtime.SerializerInfo
+ alreadyAccepted := make(map[string]struct{})
+
+ 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,
+ }
+ 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 legacySerializer == nil {
+ legacySerializer = serializers[0].Serializer
+ }
+
+ return CodecFactory{
+ scheme: scheme,
+ serializers: serializers,
+ universal: recognizer.NewDecoder(decoders...),
+
+ accepts: accepts,
+
+ legacySerializer: legacySerializer,
+ }
+}
+
+// SupportedMediaTypes returns the RFC2046 media types that this factory has serializers for.
+func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo {
+ return f.accepts
+}
+
+// LegacyCodec encodes output to a given API versions, and decodes output into the internal form from
+// any recognized source. The returned codec will always encode output to JSON. If a type is not
+// found in the list of versions an error will be returned.
+//
+// This method is deprecated - clients and servers should negotiate a serializer by mime-type and
+// invoke CodecForVersions. Callers that need only to read data should use UniversalDecoder().
+//
+// TODO: make this call exist only in pkg/api, and initialize it with the set of default versions.
+// All other callers will be forced to request a Codec directly.
+func (f CodecFactory) LegacyCodec(version ...schema.GroupVersion) runtime.Codec {
+ return versioning.NewDefaultingCodecForScheme(f.scheme, f.legacySerializer, f.universal, schema.GroupVersions(version), runtime.InternalGroupVersioner)
+}
+
+// UniversalDeserializer can convert any stored data recognized by this factory into a Go object that satisfies
+// runtime.Object. It does not perform conversion. It does not perform defaulting.
+func (f CodecFactory) UniversalDeserializer() runtime.Decoder {
+ return f.universal
+}
+
+// UniversalDecoder returns a runtime.Decoder capable of decoding all known API objects in all known formats. Used
+// by clients that do not need to encode objects but want to deserialize API objects stored on disk. Only decodes
+// objects in groups registered with the scheme. The GroupVersions passed may be used to select alternate
+// versions of objects to return - by default, runtime.APIVersionInternal is used. If any versions are specified,
+// unrecognized groups will be returned in the version they are encoded as (no conversion). This decoder performs
+// defaulting.
+//
+// TODO: the decoder will eventually be removed in favor of dealing with objects in their versioned form
+// TODO: only accept a group versioner
+func (f CodecFactory) UniversalDecoder(versions ...schema.GroupVersion) runtime.Decoder {
+ var versioner runtime.GroupVersioner
+ if len(versions) == 0 {
+ versioner = runtime.InternalGroupVersioner
+ } else {
+ versioner = schema.GroupVersions(versions)
+ }
+ return f.CodecForVersions(nil, f.universal, nil, versioner)
+}
+
+// CodecForVersions creates a codec with the provided serializer. If an object is decoded and its group is not in the list,
+// it will default to runtime.APIVersionInternal. If encode is not specified for an object's group, the object is not
+// converted. If encode or decode are nil, no conversion is performed.
+func (f CodecFactory) CodecForVersions(encoder runtime.Encoder, decoder runtime.Decoder, encode runtime.GroupVersioner, decode runtime.GroupVersioner) runtime.Codec {
+ // TODO: these are for backcompat, remove them in the future
+ if encode == nil {
+ encode = runtime.DisabledGroupVersioner
+ }
+ if decode == nil {
+ decode = runtime.InternalGroupVersioner
+ }
+ return versioning.NewDefaultingCodecForScheme(f.scheme, encoder, decoder, encode, decode)
+}
+
+// DecoderToVersion returns a decoder that targets the provided group version.
+func (f CodecFactory) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
+ return f.CodecForVersions(nil, decoder, nil, gv)
+}
+
+// EncoderForVersion returns an encoder that targets the provided group version.
+func (f CodecFactory) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
+ return f.CodecForVersions(encoder, nil, gv, nil)
+}
+
+// DirectCodecFactory provides methods for retrieving "DirectCodec"s, which do not do conversion.
+type DirectCodecFactory struct {
+ CodecFactory
+}
+
+// EncoderForVersion returns an encoder that does not do conversion.
+func (f DirectCodecFactory) EncoderForVersion(serializer runtime.Encoder, version runtime.GroupVersioner) runtime.Encoder {
+ return versioning.DirectEncoder{
+ Version: version,
+ Encoder: serializer,
+ ObjectTyper: f.CodecFactory.scheme,
+ }
+}
+
+// DecoderToVersion returns an decoder that does not do conversion. gv is ignored.
+func (f DirectCodecFactory) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
+ return versioning.DirectDecoder{
+ Decoder: serializer,
+ }
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
new file mode 100644
index 000000000..28bb91b53
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
@@ -0,0 +1,245 @@
+/*
+Copyright 2014 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 json
+
+import (
+ "encoding/json"
+ "io"
+
+ "github.com/ghodss/yaml"
+ "github.com/ugorji/go/codec"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
+ "k8s.io/apimachinery/pkg/util/framer"
+ utilyaml "k8s.io/apimachinery/pkg/util/yaml"
+)
+
+// NewSerializer creates a JSON serializer that handles encoding versioned objects into the proper JSON form. If typer
+// is not nil, the object has the group, version, and kind fields set.
+func NewSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, pretty bool) *Serializer {
+ return &Serializer{
+ meta: meta,
+ creater: creater,
+ typer: typer,
+ yaml: false,
+ pretty: pretty,
+ }
+}
+
+// NewYAMLSerializer creates a YAML serializer that handles encoding versioned objects into the proper YAML form. If typer
+// is not nil, the object has the group, version, and kind fields set. This serializer supports only the subset of YAML that
+// matches JSON, and will error if constructs are used that do not serialize to JSON.
+func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
+ return &Serializer{
+ meta: meta,
+ creater: creater,
+ typer: typer,
+ yaml: true,
+ }
+}
+
+type Serializer struct {
+ meta MetaFactory
+ creater runtime.ObjectCreater
+ typer runtime.ObjectTyper
+ yaml bool
+ pretty bool
+}
+
+// Serializer implements Serializer
+var _ runtime.Serializer = &Serializer{}
+var _ recognizer.RecognizingDecoder = &Serializer{}
+
+// Decode attempts to convert the provided data into YAML or JSON, 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 JSON/YAML unmarshalling. 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) {
+ if versioned, ok := into.(*runtime.VersionedObjects); ok {
+ into = versioned.Last()
+ obj, actual, err := s.Decode(originalData, gvk, into)
+ if err != nil {
+ return nil, actual, err
+ }
+ versioned.Objects = []runtime.Object{obj}
+ return versioned, actual, nil
+ }
+
+ data := originalData
+ if s.yaml {
+ altered, err := yaml.YAMLToJSON(data)
+ if err != nil {
+ return nil, nil, err
+ }
+ data = altered
+ }
+
+ actual, err := s.meta.Interpret(data)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if gvk != nil {
+ // apply kind and version defaulting from provided default
+ if len(actual.Kind) == 0 {
+ actual.Kind = gvk.Kind
+ }
+ if len(actual.Version) == 0 && len(actual.Group) == 0 {
+ actual.Group = gvk.Group
+ actual.Version = gvk.Version
+ }
+ if len(actual.Version) == 0 && actual.Group == gvk.Group {
+ actual.Version = gvk.Version
+ }
+ }
+
+ if unk, ok := into.(*runtime.Unknown); ok && unk != nil {
+ unk.Raw = originalData
+ unk.ContentType = runtime.ContentTypeJSON
+ unk.GetObjectKind().SetGroupVersionKind(*actual)
+ return unk, actual, nil
+ }
+
+ if into != nil {
+ types, _, err := s.typer.ObjectKinds(into)
+ switch {
+ case runtime.IsNotRegisteredError(err):
+ if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(into); err != nil {
+ return nil, actual, err
+ }
+ return into, actual, nil
+ case err != nil:
+ return nil, actual, err
+ default:
+ typed := types[0]
+ if len(actual.Kind) == 0 {
+ actual.Kind = typed.Kind
+ }
+ if len(actual.Version) == 0 && len(actual.Group) == 0 {
+ actual.Group = typed.Group
+ actual.Version = typed.Version
+ }
+ if len(actual.Version) == 0 && actual.Group == typed.Group {
+ actual.Version = typed.Version
+ }
+ }
+ }
+
+ if len(actual.Kind) == 0 {
+ return nil, actual, runtime.NewMissingKindErr(string(originalData))
+ }
+ if len(actual.Version) == 0 {
+ return nil, actual, runtime.NewMissingVersionErr(string(originalData))
+ }
+
+ // use the target if necessary
+ obj, err := runtime.UseOrCreateObject(s.typer, s.creater, *actual, into)
+ if err != nil {
+ return nil, actual, err
+ }
+
+ if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
+ return nil, actual, err
+ }
+ return obj, actual, nil
+}
+
+// Encode serializes the provided object to the given writer.
+func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
+ if s.yaml {
+ json, err := json.Marshal(obj)
+ if err != nil {
+ return err
+ }
+ data, err := yaml.JSONToYAML(json)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(data)
+ return err
+ }
+
+ if s.pretty {
+ data, err := json.MarshalIndent(obj, "", " ")
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(data)
+ return err
+ }
+ encoder := json.NewEncoder(w)
+ return encoder.Encode(obj)
+}
+
+// RecognizesData implements the RecognizingDecoder interface.
+func (s *Serializer) RecognizesData(peek io.Reader) (ok, unknown bool, err error) {
+ if s.yaml {
+ // we could potentially look for '---'
+ return false, true, nil
+ }
+ _, _, ok = utilyaml.GuessJSONStream(peek, 2048)
+ return ok, false, nil
+}
+
+// Framer is the default JSON framing behavior, with newlines delimiting individual objects.
+var Framer = jsonFramer{}
+
+type jsonFramer struct{}
+
+// NewFrameWriter implements stream framing for this serializer
+func (jsonFramer) NewFrameWriter(w io.Writer) io.Writer {
+ // we can write JSON objects directly to the writer, because they are self-framing
+ return w
+}
+
+// NewFrameReader implements stream framing for this serializer
+func (jsonFramer) NewFrameReader(r io.ReadCloser) io.ReadCloser {
+ // we need to extract the JSON chunks of data to pass to Decode()
+ return framer.NewJSONFramedReader(r)
+}
+
+// Framer is the default JSON framing behavior, with newlines delimiting individual objects.
+var YAMLFramer = yamlFramer{}
+
+type yamlFramer struct{}
+
+// NewFrameWriter implements stream framing for this serializer
+func (yamlFramer) NewFrameWriter(w io.Writer) io.Writer {
+ return yamlFrameWriter{w}
+}
+
+// NewFrameReader implements stream framing for this serializer
+func (yamlFramer) NewFrameReader(r io.ReadCloser) io.ReadCloser {
+ // extract the YAML document chunks directly
+ return utilyaml.NewDocumentDecoder(r)
+}
+
+type yamlFrameWriter struct {
+ w io.Writer
+}
+
+// Write separates each document with the YAML document separator (`---` followed by line
+// break). Writers must write well formed YAML documents (include a final line break).
+func (w yamlFrameWriter) Write(data []byte) (n int, err error) {
+ if _, err := w.w.Write([]byte("---\n")); err != nil {
+ return 0, err
+ }
+ return w.w.Write(data)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go
new file mode 100644
index 000000000..df3f5f989
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2014 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 json
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// MetaFactory is used to store and retrieve the version and kind
+// information for JSON objects in a serializer.
+type MetaFactory interface {
+ // Interpret should return the version and kind of the wire-format of
+ // the object.
+ Interpret(data []byte) (*schema.GroupVersionKind, error)
+}
+
+// DefaultMetaFactory is a default factory for versioning objects in JSON. The object
+// in memory and in the default JSON serialization will use the "kind" and "apiVersion"
+// fields.
+var DefaultMetaFactory = SimpleMetaFactory{}
+
+// SimpleMetaFactory provides default methods for retrieving the type and version of objects
+// that are identified with an "apiVersion" and "kind" fields in their JSON
+// serialization. It may be parameterized with the names of the fields in memory, or an
+// optional list of base structs to search for those fields in memory.
+type SimpleMetaFactory struct {
+}
+
+// Interpret will return the APIVersion and Kind of the JSON wire-format
+// encoding of an object, or an error.
+func (SimpleMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error) {
+ findKind := struct {
+ // +optional
+ APIVersion string `json:"apiVersion,omitempty"`
+ // +optional
+ Kind string `json:"kind,omitempty"`
+ }{}
+ if err := json.Unmarshal(data, &findKind); err != nil {
+ return nil, fmt.Errorf("couldn't get version/kind; json parse error: %v", err)
+ }
+ gv, err := schema.ParseGroupVersion(findKind.APIVersion)
+ if err != nil {
+ return nil, err
+ }
+ return &schema.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: findKind.Kind}, nil
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go
new file mode 100644
index 000000000..a42b4a41a
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go
@@ -0,0 +1,43 @@
+/*
+Copyright 2016 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 serializer
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+)
+
+// TODO: We should split negotiated serializers that we can change versions on from those we can change
+// serialization formats on
+type negotiatedSerializerWrapper struct {
+ info runtime.SerializerInfo
+}
+
+func NegotiatedSerializerWrapper(info runtime.SerializerInfo) runtime.NegotiatedSerializer {
+ return &negotiatedSerializerWrapper{info}
+}
+
+func (n *negotiatedSerializerWrapper) SupportedMediaTypes() []runtime.SerializerInfo {
+ return []runtime.SerializerInfo{n.info}
+}
+
+func (n *negotiatedSerializerWrapper) EncoderForVersion(e runtime.Encoder, _ runtime.GroupVersioner) runtime.Encoder {
+ return e
+}
+
+func (n *negotiatedSerializerWrapper) DecoderToVersion(d runtime.Decoder, _gv runtime.GroupVersioner) runtime.Decoder {
+ return d
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go
new file mode 100644
index 000000000..72d0ac79b
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go
@@ -0,0 +1,18 @@
+/*
+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 provides a Kubernetes serializer for the protobuf format.
+package protobuf // import "k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
new file mode 100644
index 000000000..8d4ea7118
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
@@ -0,0 +1,448 @@
+/*
+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"
+ "reflect"
+
+ "github.com/gogo/protobuf/proto"
+
+ "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 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).
+//
+// This encoding scheme is experimental, and is subject to change at any time.
+func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *Serializer {
+ return &Serializer{
+ prefix: protoEncodingPrefix,
+ creater: creater,
+ typer: typer,
+ contentType: defaultContentType,
+ }
+}
+
+type Serializer struct {
+ prefix []byte
+ creater runtime.ObjectCreater
+ typer runtime.ObjectTyper
+ contentType string
+}
+
+var _ runtime.Serializer = &Serializer{}
+var _ recognizer.RecognizingDecoder = &Serializer{}
+
+// 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) {
+ if versioned, ok := into.(*runtime.VersionedObjects); ok {
+ into = versioned.Last()
+ obj, actual, err := s.Decode(originalData, gvk, into)
+ if err != nil {
+ return nil, actual, err
+ }
+ // the last item in versioned becomes into, so if versioned was not originally empty we reset the object
+ // array so the first position is the decoded object and the second position is the outermost object.
+ // if there were no objects in the versioned list passed to us, only add ourselves.
+ if into != nil && into != obj {
+ versioned.Objects = []runtime.Object{obj, into}
+ } else {
+ versioned.Objects = []runtime.Object{obj}
+ }
+ return versioned, actual, err
+ }
+
+ 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 = s.contentType
+ }
+ 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 {
+ 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 MarshalTo 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)}
+ }
+}
+
+// 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
+}
+
+// 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, defaultContentType string) *RawSerializer {
+ return &RawSerializer{
+ creater: creater,
+ typer: typer,
+ contentType: defaultContentType,
+ }
+}
+
+// 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
+ contentType string
+}
+
+var _ runtime.Serializer = &RawSerializer{}
+
+// 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 versioned, ok := into.(*runtime.VersionedObjects); ok {
+ into = versioned.Last()
+ obj, actual, err := s.Decode(originalData, gvk, into)
+ if err != nil {
+ return nil, actual, err
+ }
+ if into != nil && into != obj {
+ versioned.Objects = []runtime.Object{obj, into}
+ } else {
+ versioned.Objects = []runtime.Object{obj}
+ }
+ return versioned, actual, err
+ }
+
+ 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 = s.contentType
+ 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
+ }
+ 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 {
+ 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 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)}
+ }
+}
+
+var LengthDelimitedFramer = lengthDelimitedFramer{}
+
+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)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go
new file mode 100644
index 000000000..545cf78df
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go
@@ -0,0 +1,48 @@
+/*
+Copyright 2014 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 serializer
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
+)
+
+const (
+ // contentTypeProtobuf is the protobuf type exposed for Kubernetes. It is private to prevent others from
+ // depending on it unintentionally.
+ // TODO: potentially move to pkg/api (since it's part of the Kube public API) and pass it in to the
+ // CodecFactory on initialization.
+ contentTypeProtobuf = "application/vnd.kubernetes.protobuf"
+)
+
+func protobufSerializer(scheme *runtime.Scheme) (serializerType, bool) {
+ serializer := protobuf.NewSerializer(scheme, scheme, contentTypeProtobuf)
+ raw := protobuf.NewRawSerializer(scheme, scheme, contentTypeProtobuf)
+ return serializerType{
+ AcceptContentTypes: []string{contentTypeProtobuf},
+ ContentType: contentTypeProtobuf,
+ FileExtensions: []string{"pb"},
+ Serializer: serializer,
+
+ Framer: protobuf.LengthDelimitedFramer,
+ StreamSerializer: raw,
+ }, true
+}
+
+func init() {
+ serializerExtensions = append(serializerExtensions, protobufSerializer)
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go
new file mode 100644
index 000000000..38497ab53
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go
@@ -0,0 +1,127 @@
+/*
+Copyright 2014 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 recognizer
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+type RecognizingDecoder interface {
+ runtime.Decoder
+ // RecognizesData should return true if the input provided in the provided reader
+ // belongs to this decoder, or an error if the data could not be read or is ambiguous.
+ // Unknown is true if the data could not be determined to match the decoder type.
+ // Decoders should assume that they can read as much of peek as they need (as the caller
+ // provides) and may return unknown if the data provided is not sufficient to make a
+ // a determination. When peek returns EOF that may mean the end of the input or the
+ // end of buffered input - recognizers should return the best guess at that time.
+ RecognizesData(peek io.Reader) (ok, unknown bool, err error)
+}
+
+// NewDecoder creates a decoder that will attempt multiple decoders in an order defined
+// by:
+//
+// 1. The decoder implements RecognizingDecoder and identifies the data
+// 2. All other decoders, and any decoder that returned true for unknown.
+//
+// The order passed to the constructor is preserved within those priorities.
+func NewDecoder(decoders ...runtime.Decoder) runtime.Decoder {
+ return &decoder{
+ decoders: decoders,
+ }
+}
+
+type decoder struct {
+ decoders []runtime.Decoder
+}
+
+var _ RecognizingDecoder = &decoder{}
+
+func (d *decoder) RecognizesData(peek io.Reader) (bool, bool, error) {
+ var (
+ lastErr error
+ anyUnknown bool
+ )
+ data, _ := bufio.NewReaderSize(peek, 1024).Peek(1024)
+ for _, r := range d.decoders {
+ switch t := r.(type) {
+ case RecognizingDecoder:
+ ok, unknown, err := t.RecognizesData(bytes.NewBuffer(data))
+ if err != nil {
+ lastErr = err
+ continue
+ }
+ anyUnknown = anyUnknown || unknown
+ if !ok {
+ continue
+ }
+ return true, false, nil
+ }
+ }
+ return false, anyUnknown, lastErr
+}
+
+func (d *decoder) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
+ var (
+ lastErr error
+ skipped []runtime.Decoder
+ )
+
+ // try recognizers, record any decoders we need to give a chance later
+ for _, r := range d.decoders {
+ switch t := r.(type) {
+ case RecognizingDecoder:
+ buf := bytes.NewBuffer(data)
+ ok, unknown, err := t.RecognizesData(buf)
+ if err != nil {
+ lastErr = err
+ continue
+ }
+ if unknown {
+ skipped = append(skipped, t)
+ continue
+ }
+ if !ok {
+ continue
+ }
+ return r.Decode(data, gvk, into)
+ default:
+ skipped = append(skipped, t)
+ }
+ }
+
+ // try recognizers that returned unknown or didn't recognize their data
+ for _, r := range skipped {
+ out, actual, err := r.Decode(data, gvk, into)
+ if err != nil {
+ lastErr = err
+ continue
+ }
+ return out, actual, nil
+ }
+
+ if lastErr == nil {
+ lastErr = fmt.Errorf("no serialization format matched the provided data")
+ }
+ return nil, nil, lastErr
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
new file mode 100644
index 000000000..91fd4ed4f
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
@@ -0,0 +1,137 @@
+/*
+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 streaming implements encoder and decoder for streams
+// of runtime.Objects over io.Writer/Readers.
+package streaming
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// Encoder is a runtime.Encoder on a stream.
+type Encoder interface {
+ // Encode will write the provided object to the stream or return an error. It obeys the same
+ // contract as runtime.VersionedEncoder.
+ Encode(obj runtime.Object) error
+}
+
+// Decoder is a runtime.Decoder from a stream.
+type Decoder interface {
+ // Decode will return io.EOF when no more objects are available.
+ Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error)
+ // Close closes the underlying stream.
+ Close() error
+}
+
+// Serializer is a factory for creating encoders and decoders that work over streams.
+type Serializer interface {
+ NewEncoder(w io.Writer) Encoder
+ NewDecoder(r io.ReadCloser) Decoder
+}
+
+type decoder struct {
+ reader io.ReadCloser
+ decoder runtime.Decoder
+ buf []byte
+ maxBytes int
+ resetRead bool
+}
+
+// NewDecoder creates a streaming decoder that reads object chunks from r and decodes them with d.
+// The reader is expected to return ErrShortRead if the provided buffer is not large enough to read
+// an entire object.
+func NewDecoder(r io.ReadCloser, d runtime.Decoder) Decoder {
+ return &decoder{
+ reader: r,
+ decoder: d,
+ buf: make([]byte, 1024),
+ maxBytes: 1024 * 1024,
+ }
+}
+
+var ErrObjectTooLarge = fmt.Errorf("object to decode was longer than maximum allowed size")
+
+// Decode reads the next object from the stream and decodes it.
+func (d *decoder) Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
+ base := 0
+ for {
+ n, err := d.reader.Read(d.buf[base:])
+ if err == io.ErrShortBuffer {
+ if n == 0 {
+ return nil, nil, fmt.Errorf("got short buffer with n=0, base=%d, cap=%d", base, cap(d.buf))
+ }
+ if d.resetRead {
+ continue
+ }
+ // double the buffer size up to maxBytes
+ if len(d.buf) < d.maxBytes {
+ base += n
+ d.buf = append(d.buf, make([]byte, len(d.buf))...)
+ continue
+ }
+ // must read the rest of the frame (until we stop getting ErrShortBuffer)
+ d.resetRead = true
+ base = 0
+ return nil, nil, ErrObjectTooLarge
+ }
+ if err != nil {
+ return nil, nil, err
+ }
+ if d.resetRead {
+ // now that we have drained the large read, continue
+ d.resetRead = false
+ continue
+ }
+ base += n
+ break
+ }
+ return d.decoder.Decode(d.buf[:base], defaults, into)
+}
+
+func (d *decoder) Close() error {
+ return d.reader.Close()
+}
+
+type encoder struct {
+ writer io.Writer
+ encoder runtime.Encoder
+ buf *bytes.Buffer
+}
+
+// NewEncoder returns a new streaming encoder.
+func NewEncoder(w io.Writer, e runtime.Encoder) Encoder {
+ return &encoder{
+ writer: w,
+ encoder: e,
+ buf: &bytes.Buffer{},
+ }
+}
+
+// Encode writes the provided object to the nested writer.
+func (e *encoder) Encode(obj runtime.Object) error {
+ if err := e.encoder.Encode(obj, e.buf); err != nil {
+ return err
+ }
+ _, err := e.writer.Write(e.buf.Bytes())
+ e.buf.Reset()
+ return err
+}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
new file mode 100644
index 000000000..829d4fa89
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
@@ -0,0 +1,273 @@
+/*
+Copyright 2014 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 versioning
+
+import (
+ "io"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+)
+
+// NewCodecForScheme is a convenience method for callers that are using a scheme.
+func NewCodecForScheme(
+ // TODO: I should be a scheme interface?
+ scheme *runtime.Scheme,
+ encoder runtime.Encoder,
+ decoder runtime.Decoder,
+ encodeVersion runtime.GroupVersioner,
+ decodeVersion runtime.GroupVersioner,
+) runtime.Codec {
+ return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, scheme, nil, encodeVersion, decodeVersion)
+}
+
+// NewDefaultingCodecForScheme is a convenience method for callers that are using a scheme.
+func NewDefaultingCodecForScheme(
+ // TODO: I should be a scheme interface?
+ scheme *runtime.Scheme,
+ encoder runtime.Encoder,
+ decoder runtime.Decoder,
+ encodeVersion runtime.GroupVersioner,
+ decodeVersion runtime.GroupVersioner,
+) runtime.Codec {
+ return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, scheme, scheme, encodeVersion, decodeVersion)
+}
+
+// NewCodec takes objects in their internal versions and converts them to external versions before
+// serializing them. It assumes the serializer provided to it only deals with external versions.
+// This class is also a serializer, but is generally used with a specific version.
+func NewCodec(
+ encoder runtime.Encoder,
+ decoder runtime.Decoder,
+ convertor runtime.ObjectConvertor,
+ creater runtime.ObjectCreater,
+ copier runtime.ObjectCopier,
+ typer runtime.ObjectTyper,
+ defaulter runtime.ObjectDefaulter,
+ encodeVersion runtime.GroupVersioner,
+ decodeVersion runtime.GroupVersioner,
+) runtime.Codec {
+ internal := &codec{
+ encoder: encoder,
+ decoder: decoder,
+ convertor: convertor,
+ creater: creater,
+ copier: copier,
+ typer: typer,
+ defaulter: defaulter,
+
+ encodeVersion: encodeVersion,
+ decodeVersion: decodeVersion,
+ }
+ return internal
+}
+
+type codec struct {
+ encoder runtime.Encoder
+ decoder runtime.Decoder
+ convertor runtime.ObjectConvertor
+ creater runtime.ObjectCreater
+ copier runtime.ObjectCopier
+ typer runtime.ObjectTyper
+ defaulter runtime.ObjectDefaulter
+
+ encodeVersion runtime.GroupVersioner
+ decodeVersion runtime.GroupVersioner
+}
+
+// Decode attempts a decode of the object, then tries to convert it to the internal version. If into is provided and the decoding is
+// successful, the returned runtime.Object will be the value passed as into. Note that this may bypass conversion if you pass an
+// into that matches the serialized version.
+func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
+ versioned, isVersioned := into.(*runtime.VersionedObjects)
+ if isVersioned {
+ into = versioned.Last()
+ }
+
+ obj, gvk, err := c.decoder.Decode(data, defaultGVK, into)
+ if err != nil {
+ return nil, gvk, err
+ }
+
+ if d, ok := obj.(runtime.NestedObjectDecoder); ok {
+ if err := d.DecodeNestedObjects(DirectDecoder{c.decoder}); err != nil {
+ return nil, gvk, err
+ }
+ }
+
+ // if we specify a target, use generic conversion.
+ if into != nil {
+ if into == obj {
+ if isVersioned {
+ return versioned, gvk, nil
+ }
+ return into, gvk, nil
+ }
+
+ // perform defaulting if requested
+ if c.defaulter != nil {
+ // create a copy to ensure defaulting is not applied to the original versioned objects
+ if isVersioned {
+ copied, err := c.copier.Copy(obj)
+ if err != nil {
+ utilruntime.HandleError(err)
+ copied = obj
+ }
+ versioned.Objects = []runtime.Object{copied}
+ }
+ c.defaulter.Default(obj)
+ } else {
+ if isVersioned {
+ versioned.Objects = []runtime.Object{obj}
+ }
+ }
+
+ if err := c.convertor.Convert(obj, into, c.decodeVersion); err != nil {
+ return nil, gvk, err
+ }
+
+ if isVersioned {
+ versioned.Objects = append(versioned.Objects, into)
+ return versioned, gvk, nil
+ }
+ return into, gvk, nil
+ }
+
+ // Convert if needed.
+ if isVersioned {
+ // create a copy, because ConvertToVersion does not guarantee non-mutation of objects
+ copied, err := c.copier.Copy(obj)
+ if err != nil {
+ utilruntime.HandleError(err)
+ copied = obj
+ }
+ versioned.Objects = []runtime.Object{copied}
+ }
+
+ // perform defaulting if requested
+ if c.defaulter != nil {
+ c.defaulter.Default(obj)
+ }
+
+ out, err := c.convertor.ConvertToVersion(obj, c.decodeVersion)
+ if err != nil {
+ return nil, gvk, err
+ }
+ if isVersioned {
+ if versioned.Last() != out {
+ versioned.Objects = append(versioned.Objects, out)
+ }
+ return versioned, gvk, nil
+ }
+ return out, gvk, nil
+}
+
+// Encode ensures the provided object is output in the appropriate group and version, invoking
+// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
+func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
+ switch obj.(type) {
+ case *runtime.Unknown, runtime.Unstructured:
+ return c.encoder.Encode(obj, w)
+ }
+
+ gvks, isUnversioned, err := c.typer.ObjectKinds(obj)
+ if err != nil {
+ return err
+ }
+
+ if c.encodeVersion == nil || isUnversioned {
+ if e, ok := obj.(runtime.NestedObjectEncoder); ok {
+ if err := e.EncodeNestedObjects(DirectEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
+ return err
+ }
+ }
+ objectKind := obj.GetObjectKind()
+ old := objectKind.GroupVersionKind()
+ objectKind.SetGroupVersionKind(gvks[0])
+ err = c.encoder.Encode(obj, w)
+ objectKind.SetGroupVersionKind(old)
+ return err
+ }
+
+ // Perform a conversion if necessary
+ objectKind := obj.GetObjectKind()
+ old := objectKind.GroupVersionKind()
+ out, err := c.convertor.ConvertToVersion(obj, c.encodeVersion)
+ if err != nil {
+ return err
+ }
+
+ if e, ok := out.(runtime.NestedObjectEncoder); ok {
+ if err := e.EncodeNestedObjects(DirectEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
+ return err
+ }
+ }
+
+ // Conversion is responsible for setting the proper group, version, and kind onto the outgoing object
+ err = c.encoder.Encode(out, w)
+ // restore the old GVK, in case conversion returned the same object
+ objectKind.SetGroupVersionKind(old)
+ return err
+}
+
+// DirectEncoder serializes an object and ensures the GVK is set.
+type DirectEncoder struct {
+ Version runtime.GroupVersioner
+ runtime.Encoder
+ runtime.ObjectTyper
+}
+
+// Encode does not do conversion. It sets the gvk during serialization.
+func (e DirectEncoder) Encode(obj runtime.Object, stream io.Writer) error {
+ gvks, _, err := e.ObjectTyper.ObjectKinds(obj)
+ if err != nil {
+ if runtime.IsNotRegisteredError(err) {
+ return e.Encoder.Encode(obj, stream)
+ }
+ return err
+ }
+ kind := obj.GetObjectKind()
+ oldGVK := kind.GroupVersionKind()
+ gvk := gvks[0]
+ if e.Version != nil {
+ preferredGVK, ok := e.Version.KindForGroupVersionKinds(gvks)
+ if ok {
+ gvk = preferredGVK
+ }
+ }
+ kind.SetGroupVersionKind(gvk)
+ err = e.Encoder.Encode(obj, stream)
+ kind.SetGroupVersionKind(oldGVK)
+ return err
+}
+
+// DirectDecoder clears the group version kind of a deserialized object.
+type DirectDecoder struct {
+ runtime.Decoder
+}
+
+// Decode does not do conversion. It removes the gvk during deserialization.
+func (d DirectDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
+ obj, gvk, err := d.Decoder.Decode(data, defaults, into)
+ if obj != nil {
+ kind := obj.GetObjectKind()
+ // clearing the gvk is just a convention of a codec
+ kind.SetGroupVersionKind(schema.GroupVersionKind{})
+ }
+ return obj, gvk, err
+}