init
This commit is contained in:
		
							
								
								
									
										312
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/codec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/codec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,312 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/url" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/conversion/queryparams" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| ) | ||||
|  | ||||
| // codec binds an encoder and decoder. | ||||
| type codec struct { | ||||
| 	Encoder | ||||
| 	Decoder | ||||
| } | ||||
|  | ||||
| // NewCodec creates a Codec from an Encoder and Decoder. | ||||
| func NewCodec(e Encoder, d Decoder) Codec { | ||||
| 	return codec{e, d} | ||||
| } | ||||
|  | ||||
| // Encode is a convenience wrapper for encoding to a []byte from an Encoder | ||||
| func Encode(e Encoder, obj Object) ([]byte, error) { | ||||
| 	// TODO: reuse buffer | ||||
| 	buf := &bytes.Buffer{} | ||||
| 	if err := e.Encode(obj, buf); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return buf.Bytes(), nil | ||||
| } | ||||
|  | ||||
| // Decode is a convenience wrapper for decoding data into an Object. | ||||
| func Decode(d Decoder, data []byte) (Object, error) { | ||||
| 	obj, _, err := d.Decode(data, nil, nil) | ||||
| 	return obj, err | ||||
| } | ||||
|  | ||||
| // DecodeInto performs a Decode into the provided object. | ||||
| func DecodeInto(d Decoder, data []byte, into Object) error { | ||||
| 	out, gvk, err := d.Decode(data, nil, into) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if out != into { | ||||
| 		return fmt.Errorf("unable to decode %s into %v", gvk, reflect.TypeOf(into)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests. | ||||
| func EncodeOrDie(e Encoder, obj Object) string { | ||||
| 	bytes, err := Encode(e, obj) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return string(bytes) | ||||
| } | ||||
|  | ||||
| // UseOrCreateObject returns obj if the canonical ObjectKind returned by the provided typer matches gvk, or | ||||
| // invokes the ObjectCreator to instantiate a new gvk. Returns an error if the typer cannot find the object. | ||||
| func UseOrCreateObject(t ObjectTyper, c ObjectCreater, gvk schema.GroupVersionKind, obj Object) (Object, error) { | ||||
| 	if obj != nil { | ||||
| 		kinds, _, err := t.ObjectKinds(obj) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		for _, kind := range kinds { | ||||
| 			if gvk == kind { | ||||
| 				return obj, nil | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return c.New(gvk) | ||||
| } | ||||
|  | ||||
| // NoopEncoder converts an Decoder to a Serializer or Codec for code that expects them but only uses decoding. | ||||
| type NoopEncoder struct { | ||||
| 	Decoder | ||||
| } | ||||
|  | ||||
| var _ Serializer = NoopEncoder{} | ||||
|  | ||||
| func (n NoopEncoder) Encode(obj Object, w io.Writer) error { | ||||
| 	return fmt.Errorf("encoding is not allowed for this codec: %v", reflect.TypeOf(n.Decoder)) | ||||
| } | ||||
|  | ||||
| // NoopDecoder converts an Encoder to a Serializer or Codec for code that expects them but only uses encoding. | ||||
| type NoopDecoder struct { | ||||
| 	Encoder | ||||
| } | ||||
|  | ||||
| var _ Serializer = NoopDecoder{} | ||||
|  | ||||
| func (n NoopDecoder) Decode(data []byte, gvk *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) { | ||||
| 	return nil, nil, fmt.Errorf("decoding is not allowed for this codec: %v", reflect.TypeOf(n.Encoder)) | ||||
| } | ||||
|  | ||||
| // NewParameterCodec creates a ParameterCodec capable of transforming url values into versioned objects and back. | ||||
| func NewParameterCodec(scheme *Scheme) ParameterCodec { | ||||
| 	return ¶meterCodec{ | ||||
| 		typer:     scheme, | ||||
| 		convertor: scheme, | ||||
| 		creator:   scheme, | ||||
| 		defaulter: scheme, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // parameterCodec implements conversion to and from query parameters and objects. | ||||
| type parameterCodec struct { | ||||
| 	typer     ObjectTyper | ||||
| 	convertor ObjectConvertor | ||||
| 	creator   ObjectCreater | ||||
| 	defaulter ObjectDefaulter | ||||
| } | ||||
|  | ||||
| var _ ParameterCodec = ¶meterCodec{} | ||||
|  | ||||
| // DecodeParameters converts the provided url.Values into an object of type From with the kind of into, and then | ||||
| // converts that object to into (if necessary). Returns an error if the operation cannot be completed. | ||||
| func (c *parameterCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into Object) error { | ||||
| 	if len(parameters) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	targetGVKs, _, err := c.typer.ObjectKinds(into) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for i := range targetGVKs { | ||||
| 		if targetGVKs[i].GroupVersion() == from { | ||||
| 			if err := c.convertor.Convert(¶meters, into, nil); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			// in the case where we going into the same object we're receiving, default on the outbound object | ||||
| 			if c.defaulter != nil { | ||||
| 				c.defaulter.Default(into) | ||||
| 			} | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	input, err := c.creator.New(from.WithKind(targetGVKs[0].Kind)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err := c.convertor.Convert(¶meters, input, nil); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// if we have defaulter, default the input before converting to output | ||||
| 	if c.defaulter != nil { | ||||
| 		c.defaulter.Default(input) | ||||
| 	} | ||||
| 	return c.convertor.Convert(input, into, nil) | ||||
| } | ||||
|  | ||||
| // EncodeParameters converts the provided object into the to version, then converts that object to url.Values. | ||||
| // Returns an error if conversion is not possible. | ||||
| func (c *parameterCodec) EncodeParameters(obj Object, to schema.GroupVersion) (url.Values, error) { | ||||
| 	gvks, _, err := c.typer.ObjectKinds(obj) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	gvk := gvks[0] | ||||
| 	if to != gvk.GroupVersion() { | ||||
| 		out, err := c.convertor.ConvertToVersion(obj, to) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		obj = out | ||||
| 	} | ||||
| 	return queryparams.Convert(obj) | ||||
| } | ||||
|  | ||||
| type base64Serializer struct { | ||||
| 	Encoder | ||||
| 	Decoder | ||||
| } | ||||
|  | ||||
| func NewBase64Serializer(e Encoder, d Decoder) Serializer { | ||||
| 	return &base64Serializer{e, d} | ||||
| } | ||||
|  | ||||
| func (s base64Serializer) Encode(obj Object, stream io.Writer) error { | ||||
| 	e := base64.NewEncoder(base64.StdEncoding, stream) | ||||
| 	err := s.Encoder.Encode(obj, e) | ||||
| 	e.Close() | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (s base64Serializer) Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) { | ||||
| 	out := make([]byte, base64.StdEncoding.DecodedLen(len(data))) | ||||
| 	n, err := base64.StdEncoding.Decode(out, data) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 	return s.Decoder.Decode(out[:n], defaults, into) | ||||
| } | ||||
|  | ||||
| // SerializerInfoForMediaType returns the first info in types that has a matching media type (which cannot | ||||
| // include media-type parameters), or the first info with an empty media type, or false if no type matches. | ||||
| func SerializerInfoForMediaType(types []SerializerInfo, mediaType string) (SerializerInfo, bool) { | ||||
| 	for _, info := range types { | ||||
| 		if info.MediaType == mediaType { | ||||
| 			return info, true | ||||
| 		} | ||||
| 	} | ||||
| 	for _, info := range types { | ||||
| 		if len(info.MediaType) == 0 { | ||||
| 			return info, true | ||||
| 		} | ||||
| 	} | ||||
| 	return SerializerInfo{}, false | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// InternalGroupVersioner will always prefer the internal version for a given group version kind. | ||||
| 	InternalGroupVersioner GroupVersioner = internalGroupVersioner{} | ||||
| 	// DisabledGroupVersioner will reject all kinds passed to it. | ||||
| 	DisabledGroupVersioner GroupVersioner = disabledGroupVersioner{} | ||||
| ) | ||||
|  | ||||
| type internalGroupVersioner struct{} | ||||
|  | ||||
| // KindForGroupVersionKinds returns an internal Kind if one is found, or converts the first provided kind to the internal version. | ||||
| func (internalGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) { | ||||
| 	for _, kind := range kinds { | ||||
| 		if kind.Version == APIVersionInternal { | ||||
| 			return kind, true | ||||
| 		} | ||||
| 	} | ||||
| 	for _, kind := range kinds { | ||||
| 		return schema.GroupVersionKind{Group: kind.Group, Version: APIVersionInternal, Kind: kind.Kind}, true | ||||
| 	} | ||||
| 	return schema.GroupVersionKind{}, false | ||||
| } | ||||
|  | ||||
| type disabledGroupVersioner struct{} | ||||
|  | ||||
| // KindForGroupVersionKinds returns false for any input. | ||||
| func (disabledGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) { | ||||
| 	return schema.GroupVersionKind{}, false | ||||
| } | ||||
|  | ||||
| // GroupVersioners implements GroupVersioner and resolves to the first exact match for any kind. | ||||
| type GroupVersioners []GroupVersioner | ||||
|  | ||||
| // KindForGroupVersionKinds returns the first match of any of the group versioners, or false if no match occurred. | ||||
| func (gvs GroupVersioners) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) { | ||||
| 	for _, gv := range gvs { | ||||
| 		target, ok := gv.KindForGroupVersionKinds(kinds) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 		return target, true | ||||
| 	} | ||||
| 	return schema.GroupVersionKind{}, false | ||||
| } | ||||
|  | ||||
| // Assert that schema.GroupVersion and GroupVersions implement GroupVersioner | ||||
| var _ GroupVersioner = schema.GroupVersion{} | ||||
| var _ GroupVersioner = schema.GroupVersions{} | ||||
| var _ GroupVersioner = multiGroupVersioner{} | ||||
|  | ||||
| type multiGroupVersioner struct { | ||||
| 	target             schema.GroupVersion | ||||
| 	acceptedGroupKinds []schema.GroupKind | ||||
| } | ||||
|  | ||||
| // NewMultiGroupVersioner returns the provided group version for any kind that matches one of the provided group kinds. | ||||
| // Kind may be empty in the provided group kind, in which case any kind will match. | ||||
| func NewMultiGroupVersioner(gv schema.GroupVersion, groupKinds ...schema.GroupKind) GroupVersioner { | ||||
| 	if len(groupKinds) == 0 || (len(groupKinds) == 1 && groupKinds[0].Group == gv.Group) { | ||||
| 		return gv | ||||
| 	} | ||||
| 	return multiGroupVersioner{target: gv, acceptedGroupKinds: groupKinds} | ||||
| } | ||||
|  | ||||
| // KindForGroupVersionKinds returns the target group version if any kind matches any of the original group kinds. It will | ||||
| // use the originating kind where possible. | ||||
| func (v multiGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) { | ||||
| 	for _, src := range kinds { | ||||
| 		for _, kind := range v.acceptedGroupKinds { | ||||
| 			if kind.Group != src.Group { | ||||
| 				continue | ||||
| 			} | ||||
| 			if len(kind.Kind) > 0 && kind.Kind != src.Kind { | ||||
| 				continue | ||||
| 			} | ||||
| 			return v.target.WithKind(src.Kind), true | ||||
| 		} | ||||
| 	} | ||||
| 	return schema.GroupVersionKind{}, false | ||||
| } | ||||
							
								
								
									
										48
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| ) | ||||
|  | ||||
| // CheckCodec makes sure that the codec can encode objects like internalType, | ||||
| // decode all of the external types listed, and also decode them into the given | ||||
| // object. (Will modify internalObject.) (Assumes JSON serialization.) | ||||
| // TODO: verify that the correct external version is chosen on encode... | ||||
| func CheckCodec(c Codec, internalType Object, externalTypes ...schema.GroupVersionKind) error { | ||||
| 	if _, err := Encode(c, internalType); err != nil { | ||||
| 		return fmt.Errorf("Internal type not encodable: %v", err) | ||||
| 	} | ||||
| 	for _, et := range externalTypes { | ||||
| 		exBytes := []byte(fmt.Sprintf(`{"kind":"%v","apiVersion":"%v"}`, et.Kind, et.GroupVersion().String())) | ||||
| 		obj, err := Decode(c, exBytes) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("external type %s not interpretable: %v", et, err) | ||||
| 		} | ||||
| 		if reflect.TypeOf(obj) != reflect.TypeOf(internalType) { | ||||
| 			return fmt.Errorf("decode of external type %s produced: %#v", et, obj) | ||||
| 		} | ||||
| 		if err = DecodeInto(c, exBytes, internalType); err != nil { | ||||
| 			return fmt.Errorf("external type %s not convertible to internal type: %v", et, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										113
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/conversion.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/conversion.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| /* | ||||
| 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 runtime defines conversions between generic types and structs to map query strings | ||||
| // to struct objects. | ||||
| package runtime | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/conversion" | ||||
| ) | ||||
|  | ||||
| // DefaultMetaV1FieldSelectorConversion auto-accepts metav1 values for name and namespace. | ||||
| // A cluster scoped resource specifying namespace empty works fine and specifying a particular | ||||
| // namespace will return no results, as expected. | ||||
| func DefaultMetaV1FieldSelectorConversion(label, value string) (string, string, error) { | ||||
| 	switch label { | ||||
| 	case "metadata.name": | ||||
| 		return label, value, nil | ||||
| 	case "metadata.namespace": | ||||
| 		return label, value, nil | ||||
| 	default: | ||||
| 		return "", "", fmt.Errorf("%q is not a known field selector: only %q, %q", label, "metadata.name", "metadata.namespace") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // JSONKeyMapper uses the struct tags on a conversion to determine the key value for | ||||
| // the other side. Use when mapping from a map[string]* to a struct or vice versa. | ||||
| func JSONKeyMapper(key string, sourceTag, destTag reflect.StructTag) (string, string) { | ||||
| 	if s := destTag.Get("json"); len(s) > 0 { | ||||
| 		return strings.SplitN(s, ",", 2)[0], key | ||||
| 	} | ||||
| 	if s := sourceTag.Get("json"); len(s) > 0 { | ||||
| 		return key, strings.SplitN(s, ",", 2)[0] | ||||
| 	} | ||||
| 	return key, key | ||||
| } | ||||
|  | ||||
| // DefaultStringConversions are helpers for converting []string and string to real values. | ||||
| var DefaultStringConversions = []interface{}{ | ||||
| 	Convert_Slice_string_To_string, | ||||
| 	Convert_Slice_string_To_int, | ||||
| 	Convert_Slice_string_To_bool, | ||||
| 	Convert_Slice_string_To_int64, | ||||
| } | ||||
|  | ||||
| func Convert_Slice_string_To_string(input *[]string, out *string, s conversion.Scope) error { | ||||
| 	if len(*input) == 0 { | ||||
| 		*out = "" | ||||
| 	} | ||||
| 	*out = (*input)[0] | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func Convert_Slice_string_To_int(input *[]string, out *int, s conversion.Scope) error { | ||||
| 	if len(*input) == 0 { | ||||
| 		*out = 0 | ||||
| 	} | ||||
| 	str := (*input)[0] | ||||
| 	i, err := strconv.Atoi(str) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*out = i | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Convert_Slice_string_To_bool will convert a string parameter to boolean. | ||||
| // Only the absence of a value, a value of "false", or a value of "0" resolve to false. | ||||
| // Any other value (including empty string) resolves to true. | ||||
| func Convert_Slice_string_To_bool(input *[]string, out *bool, s conversion.Scope) error { | ||||
| 	if len(*input) == 0 { | ||||
| 		*out = false | ||||
| 		return nil | ||||
| 	} | ||||
| 	switch strings.ToLower((*input)[0]) { | ||||
| 	case "false", "0": | ||||
| 		*out = false | ||||
| 	default: | ||||
| 		*out = true | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func Convert_Slice_string_To_int64(input *[]string, out *int64, s conversion.Scope) error { | ||||
| 	if len(*input) == 0 { | ||||
| 		*out = 0 | ||||
| 	} | ||||
| 	str := (*input)[0] | ||||
| 	i, err := strconv.ParseInt(str, 10, 64) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*out = i | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										805
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/converter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										805
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/converter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,805 @@ | ||||
| /* | ||||
| Copyright 2017 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	encodingjson "encoding/json" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/conversion" | ||||
| 	"k8s.io/apimachinery/pkg/util/json" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
|  | ||||
| 	"k8s.io/klog" | ||||
| ) | ||||
|  | ||||
| // UnstructuredConverter is an interface for converting between interface{} | ||||
| // and map[string]interface representation. | ||||
| type UnstructuredConverter interface { | ||||
| 	ToUnstructured(obj interface{}) (map[string]interface{}, error) | ||||
| 	FromUnstructured(u map[string]interface{}, obj interface{}) error | ||||
| } | ||||
|  | ||||
| type structField struct { | ||||
| 	structType reflect.Type | ||||
| 	field      int | ||||
| } | ||||
|  | ||||
| type fieldInfo struct { | ||||
| 	name      string | ||||
| 	nameValue reflect.Value | ||||
| 	omitempty bool | ||||
| } | ||||
|  | ||||
| type fieldsCacheMap map[structField]*fieldInfo | ||||
|  | ||||
| type fieldsCache struct { | ||||
| 	sync.Mutex | ||||
| 	value atomic.Value | ||||
| } | ||||
|  | ||||
| func newFieldsCache() *fieldsCache { | ||||
| 	cache := &fieldsCache{} | ||||
| 	cache.value.Store(make(fieldsCacheMap)) | ||||
| 	return cache | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	marshalerType          = reflect.TypeOf(new(encodingjson.Marshaler)).Elem() | ||||
| 	unmarshalerType        = reflect.TypeOf(new(encodingjson.Unmarshaler)).Elem() | ||||
| 	mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{}) | ||||
| 	stringType             = reflect.TypeOf(string("")) | ||||
| 	int64Type              = reflect.TypeOf(int64(0)) | ||||
| 	float64Type            = reflect.TypeOf(float64(0)) | ||||
| 	boolType               = reflect.TypeOf(bool(false)) | ||||
| 	fieldCache             = newFieldsCache() | ||||
|  | ||||
| 	// DefaultUnstructuredConverter performs unstructured to Go typed object conversions. | ||||
| 	DefaultUnstructuredConverter = &unstructuredConverter{ | ||||
| 		mismatchDetection: parseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR")), | ||||
| 		comparison: conversion.EqualitiesOrDie( | ||||
| 			func(a, b time.Time) bool { | ||||
| 				return a.UTC() == b.UTC() | ||||
| 			}, | ||||
| 		), | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func parseBool(key string) bool { | ||||
| 	if len(key) == 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 	value, err := strconv.ParseBool(key) | ||||
| 	if err != nil { | ||||
| 		utilruntime.HandleError(fmt.Errorf("Couldn't parse '%s' as bool for unstructured mismatch detection", key)) | ||||
| 	} | ||||
| 	return value | ||||
| } | ||||
|  | ||||
| // unstructuredConverter knows how to convert between interface{} and | ||||
| // Unstructured in both ways. | ||||
| type unstructuredConverter struct { | ||||
| 	// If true, we will be additionally running conversion via json | ||||
| 	// to ensure that the result is true. | ||||
| 	// This is supposed to be set only in tests. | ||||
| 	mismatchDetection bool | ||||
| 	// comparison is the default test logic used to compare | ||||
| 	comparison conversion.Equalities | ||||
| } | ||||
|  | ||||
| // NewTestUnstructuredConverter creates an UnstructuredConverter that accepts JSON typed maps and translates them | ||||
| // to Go types via reflection. It performs mismatch detection automatically and is intended for use by external | ||||
| // test tools. Use DefaultUnstructuredConverter if you do not explicitly need mismatch detection. | ||||
| func NewTestUnstructuredConverter(comparison conversion.Equalities) UnstructuredConverter { | ||||
| 	return &unstructuredConverter{ | ||||
| 		mismatchDetection: true, | ||||
| 		comparison:        comparison, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // FromUnstructured converts an object from map[string]interface{} representation into a concrete type. | ||||
| // It uses encoding/json/Unmarshaler if object implements it or reflection if not. | ||||
| func (c *unstructuredConverter) FromUnstructured(u map[string]interface{}, obj interface{}) error { | ||||
| 	t := reflect.TypeOf(obj) | ||||
| 	value := reflect.ValueOf(obj) | ||||
| 	if t.Kind() != reflect.Ptr || value.IsNil() { | ||||
| 		return fmt.Errorf("FromUnstructured requires a non-nil pointer to an object, got %v", t) | ||||
| 	} | ||||
| 	err := fromUnstructured(reflect.ValueOf(u), value.Elem()) | ||||
| 	if c.mismatchDetection { | ||||
| 		newObj := reflect.New(t.Elem()).Interface() | ||||
| 		newErr := fromUnstructuredViaJSON(u, newObj) | ||||
| 		if (err != nil) != (newErr != nil) { | ||||
| 			klog.Fatalf("FromUnstructured unexpected error for %v: error: %v", u, err) | ||||
| 		} | ||||
| 		if err == nil && !c.comparison.DeepEqual(obj, newObj) { | ||||
| 			klog.Fatalf("FromUnstructured mismatch\nobj1: %#v\nobj2: %#v", obj, newObj) | ||||
| 		} | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func fromUnstructuredViaJSON(u map[string]interface{}, obj interface{}) error { | ||||
| 	data, err := json.Marshal(u) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return json.Unmarshal(data, obj) | ||||
| } | ||||
|  | ||||
| func fromUnstructured(sv, dv reflect.Value) error { | ||||
| 	sv = unwrapInterface(sv) | ||||
| 	if !sv.IsValid() { | ||||
| 		dv.Set(reflect.Zero(dv.Type())) | ||||
| 		return nil | ||||
| 	} | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
|  | ||||
| 	switch dt.Kind() { | ||||
| 	case reflect.Map, reflect.Slice, reflect.Ptr, reflect.Struct, reflect.Interface: | ||||
| 		// Those require non-trivial conversion. | ||||
| 	default: | ||||
| 		// This should handle all simple types. | ||||
| 		if st.AssignableTo(dt) { | ||||
| 			dv.Set(sv) | ||||
| 			return nil | ||||
| 		} | ||||
| 		// We cannot simply use "ConvertibleTo", as JSON doesn't support conversions | ||||
| 		// between those four groups: bools, integers, floats and string. We need to | ||||
| 		// do the same. | ||||
| 		if st.ConvertibleTo(dt) { | ||||
| 			switch st.Kind() { | ||||
| 			case reflect.String: | ||||
| 				switch dt.Kind() { | ||||
| 				case reflect.String: | ||||
| 					dv.Set(sv.Convert(dt)) | ||||
| 					return nil | ||||
| 				} | ||||
| 			case reflect.Bool: | ||||
| 				switch dt.Kind() { | ||||
| 				case reflect.Bool: | ||||
| 					dv.Set(sv.Convert(dt)) | ||||
| 					return nil | ||||
| 				} | ||||
| 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | ||||
| 				reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 				switch dt.Kind() { | ||||
| 				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | ||||
| 					reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 					dv.Set(sv.Convert(dt)) | ||||
| 					return nil | ||||
| 				} | ||||
| 			case reflect.Float32, reflect.Float64: | ||||
| 				switch dt.Kind() { | ||||
| 				case reflect.Float32, reflect.Float64: | ||||
| 					dv.Set(sv.Convert(dt)) | ||||
| 					return nil | ||||
| 				} | ||||
| 				if sv.Float() == math.Trunc(sv.Float()) { | ||||
| 					dv.Set(sv.Convert(dt)) | ||||
| 					return nil | ||||
| 				} | ||||
| 			} | ||||
| 			return fmt.Errorf("cannot convert %s to %s", st.String(), dt.String()) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Check if the object has a custom JSON marshaller/unmarshaller. | ||||
| 	if reflect.PtrTo(dt).Implements(unmarshalerType) { | ||||
| 		data, err := json.Marshal(sv.Interface()) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("error encoding %s to json: %v", st.String(), err) | ||||
| 		} | ||||
| 		unmarshaler := dv.Addr().Interface().(encodingjson.Unmarshaler) | ||||
| 		return unmarshaler.UnmarshalJSON(data) | ||||
| 	} | ||||
|  | ||||
| 	switch dt.Kind() { | ||||
| 	case reflect.Map: | ||||
| 		return mapFromUnstructured(sv, dv) | ||||
| 	case reflect.Slice: | ||||
| 		return sliceFromUnstructured(sv, dv) | ||||
| 	case reflect.Ptr: | ||||
| 		return pointerFromUnstructured(sv, dv) | ||||
| 	case reflect.Struct: | ||||
| 		return structFromUnstructured(sv, dv) | ||||
| 	case reflect.Interface: | ||||
| 		return interfaceFromUnstructured(sv, dv) | ||||
| 	default: | ||||
| 		return fmt.Errorf("unrecognized type: %v", dt.Kind()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func fieldInfoFromField(structType reflect.Type, field int) *fieldInfo { | ||||
| 	fieldCacheMap := fieldCache.value.Load().(fieldsCacheMap) | ||||
| 	if info, ok := fieldCacheMap[structField{structType, field}]; ok { | ||||
| 		return info | ||||
| 	} | ||||
|  | ||||
| 	// Cache miss - we need to compute the field name. | ||||
| 	info := &fieldInfo{} | ||||
| 	typeField := structType.Field(field) | ||||
| 	jsonTag := typeField.Tag.Get("json") | ||||
| 	if len(jsonTag) == 0 { | ||||
| 		// Make the first character lowercase. | ||||
| 		if typeField.Name == "" { | ||||
| 			info.name = typeField.Name | ||||
| 		} else { | ||||
| 			info.name = strings.ToLower(typeField.Name[:1]) + typeField.Name[1:] | ||||
| 		} | ||||
| 	} else { | ||||
| 		items := strings.Split(jsonTag, ",") | ||||
| 		info.name = items[0] | ||||
| 		for i := range items { | ||||
| 			if items[i] == "omitempty" { | ||||
| 				info.omitempty = true | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	info.nameValue = reflect.ValueOf(info.name) | ||||
|  | ||||
| 	fieldCache.Lock() | ||||
| 	defer fieldCache.Unlock() | ||||
| 	fieldCacheMap = fieldCache.value.Load().(fieldsCacheMap) | ||||
| 	newFieldCacheMap := make(fieldsCacheMap) | ||||
| 	for k, v := range fieldCacheMap { | ||||
| 		newFieldCacheMap[k] = v | ||||
| 	} | ||||
| 	newFieldCacheMap[structField{structType, field}] = info | ||||
| 	fieldCache.value.Store(newFieldCacheMap) | ||||
| 	return info | ||||
| } | ||||
|  | ||||
| func unwrapInterface(v reflect.Value) reflect.Value { | ||||
| 	for v.Kind() == reflect.Interface { | ||||
| 		v = v.Elem() | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func mapFromUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	if st.Kind() != reflect.Map { | ||||
| 		return fmt.Errorf("cannot restore map from %v", st.Kind()) | ||||
| 	} | ||||
|  | ||||
| 	if !st.Key().AssignableTo(dt.Key()) && !st.Key().ConvertibleTo(dt.Key()) { | ||||
| 		return fmt.Errorf("cannot copy map with non-assignable keys: %v %v", st.Key(), dt.Key()) | ||||
| 	} | ||||
|  | ||||
| 	if sv.IsNil() { | ||||
| 		dv.Set(reflect.Zero(dt)) | ||||
| 		return nil | ||||
| 	} | ||||
| 	dv.Set(reflect.MakeMap(dt)) | ||||
| 	for _, key := range sv.MapKeys() { | ||||
| 		value := reflect.New(dt.Elem()).Elem() | ||||
| 		if val := unwrapInterface(sv.MapIndex(key)); val.IsValid() { | ||||
| 			if err := fromUnstructured(val, value); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			value.Set(reflect.Zero(dt.Elem())) | ||||
| 		} | ||||
| 		if st.Key().AssignableTo(dt.Key()) { | ||||
| 			dv.SetMapIndex(key, value) | ||||
| 		} else { | ||||
| 			dv.SetMapIndex(key.Convert(dt.Key()), value) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func sliceFromUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	if st.Kind() == reflect.String && dt.Elem().Kind() == reflect.Uint8 { | ||||
| 		// We store original []byte representation as string. | ||||
| 		// This conversion is allowed, but we need to be careful about | ||||
| 		// marshaling data appropriately. | ||||
| 		if len(sv.Interface().(string)) > 0 { | ||||
| 			marshalled, err := json.Marshal(sv.Interface()) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("error encoding %s to json: %v", st, err) | ||||
| 			} | ||||
| 			// TODO: Is this Unmarshal needed? | ||||
| 			var data []byte | ||||
| 			err = json.Unmarshal(marshalled, &data) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("error decoding from json: %v", err) | ||||
| 			} | ||||
| 			dv.SetBytes(data) | ||||
| 		} else { | ||||
| 			dv.Set(reflect.Zero(dt)) | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
| 	if st.Kind() != reflect.Slice { | ||||
| 		return fmt.Errorf("cannot restore slice from %v", st.Kind()) | ||||
| 	} | ||||
|  | ||||
| 	if sv.IsNil() { | ||||
| 		dv.Set(reflect.Zero(dt)) | ||||
| 		return nil | ||||
| 	} | ||||
| 	dv.Set(reflect.MakeSlice(dt, sv.Len(), sv.Cap())) | ||||
| 	for i := 0; i < sv.Len(); i++ { | ||||
| 		if err := fromUnstructured(sv.Index(i), dv.Index(i)); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func pointerFromUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
|  | ||||
| 	if st.Kind() == reflect.Ptr && sv.IsNil() { | ||||
| 		dv.Set(reflect.Zero(dt)) | ||||
| 		return nil | ||||
| 	} | ||||
| 	dv.Set(reflect.New(dt.Elem())) | ||||
| 	switch st.Kind() { | ||||
| 	case reflect.Ptr, reflect.Interface: | ||||
| 		return fromUnstructured(sv.Elem(), dv.Elem()) | ||||
| 	default: | ||||
| 		return fromUnstructured(sv, dv.Elem()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func structFromUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	if st.Kind() != reflect.Map { | ||||
| 		return fmt.Errorf("cannot restore struct from: %v", st.Kind()) | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < dt.NumField(); i++ { | ||||
| 		fieldInfo := fieldInfoFromField(dt, i) | ||||
| 		fv := dv.Field(i) | ||||
|  | ||||
| 		if len(fieldInfo.name) == 0 { | ||||
| 			// This field is inlined. | ||||
| 			if err := fromUnstructured(sv, fv); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			value := unwrapInterface(sv.MapIndex(fieldInfo.nameValue)) | ||||
| 			if value.IsValid() { | ||||
| 				if err := fromUnstructured(value, fv); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} else { | ||||
| 				fv.Set(reflect.Zero(fv.Type())) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func interfaceFromUnstructured(sv, dv reflect.Value) error { | ||||
| 	// TODO: Is this conversion safe? | ||||
| 	dv.Set(sv) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // ToUnstructured converts an object into map[string]interface{} representation. | ||||
| // It uses encoding/json/Marshaler if object implements it or reflection if not. | ||||
| func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]interface{}, error) { | ||||
| 	var u map[string]interface{} | ||||
| 	var err error | ||||
| 	if unstr, ok := obj.(Unstructured); ok { | ||||
| 		u = unstr.UnstructuredContent() | ||||
| 	} else { | ||||
| 		t := reflect.TypeOf(obj) | ||||
| 		value := reflect.ValueOf(obj) | ||||
| 		if t.Kind() != reflect.Ptr || value.IsNil() { | ||||
| 			return nil, fmt.Errorf("ToUnstructured requires a non-nil pointer to an object, got %v", t) | ||||
| 		} | ||||
| 		u = map[string]interface{}{} | ||||
| 		err = toUnstructured(value.Elem(), reflect.ValueOf(&u).Elem()) | ||||
| 	} | ||||
| 	if c.mismatchDetection { | ||||
| 		newUnstr := map[string]interface{}{} | ||||
| 		newErr := toUnstructuredViaJSON(obj, &newUnstr) | ||||
| 		if (err != nil) != (newErr != nil) { | ||||
| 			klog.Fatalf("ToUnstructured unexpected error for %v: error: %v; newErr: %v", obj, err, newErr) | ||||
| 		} | ||||
| 		if err == nil && !c.comparison.DeepEqual(u, newUnstr) { | ||||
| 			klog.Fatalf("ToUnstructured mismatch\nobj1: %#v\nobj2: %#v", u, newUnstr) | ||||
| 		} | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return u, nil | ||||
| } | ||||
|  | ||||
| // DeepCopyJSON deep copies the passed value, assuming it is a valid JSON representation i.e. only contains | ||||
| // types produced by json.Unmarshal() and also int64. | ||||
| // bool, int64, float64, string, []interface{}, map[string]interface{}, json.Number and nil | ||||
| func DeepCopyJSON(x map[string]interface{}) map[string]interface{} { | ||||
| 	return DeepCopyJSONValue(x).(map[string]interface{}) | ||||
| } | ||||
|  | ||||
| // DeepCopyJSONValue deep copies the passed value, assuming it is a valid JSON representation i.e. only contains | ||||
| // types produced by json.Unmarshal() and also int64. | ||||
| // bool, int64, float64, string, []interface{}, map[string]interface{}, json.Number and nil | ||||
| func DeepCopyJSONValue(x interface{}) interface{} { | ||||
| 	switch x := x.(type) { | ||||
| 	case map[string]interface{}: | ||||
| 		if x == nil { | ||||
| 			// Typed nil - an interface{} that contains a type map[string]interface{} with a value of nil | ||||
| 			return x | ||||
| 		} | ||||
| 		clone := make(map[string]interface{}, len(x)) | ||||
| 		for k, v := range x { | ||||
| 			clone[k] = DeepCopyJSONValue(v) | ||||
| 		} | ||||
| 		return clone | ||||
| 	case []interface{}: | ||||
| 		if x == nil { | ||||
| 			// Typed nil - an interface{} that contains a type []interface{} with a value of nil | ||||
| 			return x | ||||
| 		} | ||||
| 		clone := make([]interface{}, len(x)) | ||||
| 		for i, v := range x { | ||||
| 			clone[i] = DeepCopyJSONValue(v) | ||||
| 		} | ||||
| 		return clone | ||||
| 	case string, int64, bool, float64, nil, encodingjson.Number: | ||||
| 		return x | ||||
| 	default: | ||||
| 		panic(fmt.Errorf("cannot deep copy %T", x)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func toUnstructuredViaJSON(obj interface{}, u *map[string]interface{}) error { | ||||
| 	data, err := json.Marshal(obj) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return json.Unmarshal(data, u) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	nullBytes  = []byte("null") | ||||
| 	trueBytes  = []byte("true") | ||||
| 	falseBytes = []byte("false") | ||||
| ) | ||||
|  | ||||
| func getMarshaler(v reflect.Value) (encodingjson.Marshaler, bool) { | ||||
| 	// Check value receivers if v is not a pointer and pointer receivers if v is a pointer | ||||
| 	if v.Type().Implements(marshalerType) { | ||||
| 		return v.Interface().(encodingjson.Marshaler), true | ||||
| 	} | ||||
| 	// Check pointer receivers if v is not a pointer | ||||
| 	if v.Kind() != reflect.Ptr && v.CanAddr() { | ||||
| 		v = v.Addr() | ||||
| 		if v.Type().Implements(marshalerType) { | ||||
| 			return v.Interface().(encodingjson.Marshaler), true | ||||
| 		} | ||||
| 	} | ||||
| 	return nil, false | ||||
| } | ||||
|  | ||||
| func toUnstructured(sv, dv reflect.Value) error { | ||||
| 	// Check if the object has a custom JSON marshaller/unmarshaller. | ||||
| 	if marshaler, ok := getMarshaler(sv); ok { | ||||
| 		if sv.Kind() == reflect.Ptr && sv.IsNil() { | ||||
| 			// We're done - we don't need to store anything. | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		data, err := marshaler.MarshalJSON() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		switch { | ||||
| 		case len(data) == 0: | ||||
| 			return fmt.Errorf("error decoding from json: empty value") | ||||
|  | ||||
| 		case bytes.Equal(data, nullBytes): | ||||
| 			// We're done - we don't need to store anything. | ||||
|  | ||||
| 		case bytes.Equal(data, trueBytes): | ||||
| 			dv.Set(reflect.ValueOf(true)) | ||||
|  | ||||
| 		case bytes.Equal(data, falseBytes): | ||||
| 			dv.Set(reflect.ValueOf(false)) | ||||
|  | ||||
| 		case data[0] == '"': | ||||
| 			var result string | ||||
| 			err := json.Unmarshal(data, &result) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("error decoding string from json: %v", err) | ||||
| 			} | ||||
| 			dv.Set(reflect.ValueOf(result)) | ||||
|  | ||||
| 		case data[0] == '{': | ||||
| 			result := make(map[string]interface{}) | ||||
| 			err := json.Unmarshal(data, &result) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("error decoding object from json: %v", err) | ||||
| 			} | ||||
| 			dv.Set(reflect.ValueOf(result)) | ||||
|  | ||||
| 		case data[0] == '[': | ||||
| 			result := make([]interface{}, 0) | ||||
| 			err := json.Unmarshal(data, &result) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("error decoding array from json: %v", err) | ||||
| 			} | ||||
| 			dv.Set(reflect.ValueOf(result)) | ||||
|  | ||||
| 		default: | ||||
| 			var ( | ||||
| 				resultInt   int64 | ||||
| 				resultFloat float64 | ||||
| 				err         error | ||||
| 			) | ||||
| 			if err = json.Unmarshal(data, &resultInt); err == nil { | ||||
| 				dv.Set(reflect.ValueOf(resultInt)) | ||||
| 			} else if err = json.Unmarshal(data, &resultFloat); err == nil { | ||||
| 				dv.Set(reflect.ValueOf(resultFloat)) | ||||
| 			} else { | ||||
| 				return fmt.Errorf("error decoding number from json: %v", err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	switch st.Kind() { | ||||
| 	case reflect.String: | ||||
| 		if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 			dv.Set(reflect.New(stringType)) | ||||
| 		} | ||||
| 		dv.Set(reflect.ValueOf(sv.String())) | ||||
| 		return nil | ||||
| 	case reflect.Bool: | ||||
| 		if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 			dv.Set(reflect.New(boolType)) | ||||
| 		} | ||||
| 		dv.Set(reflect.ValueOf(sv.Bool())) | ||||
| 		return nil | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 			dv.Set(reflect.New(int64Type)) | ||||
| 		} | ||||
| 		dv.Set(reflect.ValueOf(sv.Int())) | ||||
| 		return nil | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		uVal := sv.Uint() | ||||
| 		if uVal > math.MaxInt64 { | ||||
| 			return fmt.Errorf("unsigned value %d does not fit into int64 (overflow)", uVal) | ||||
| 		} | ||||
| 		if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 			dv.Set(reflect.New(int64Type)) | ||||
| 		} | ||||
| 		dv.Set(reflect.ValueOf(int64(uVal))) | ||||
| 		return nil | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 			dv.Set(reflect.New(float64Type)) | ||||
| 		} | ||||
| 		dv.Set(reflect.ValueOf(sv.Float())) | ||||
| 		return nil | ||||
| 	case reflect.Map: | ||||
| 		return mapToUnstructured(sv, dv) | ||||
| 	case reflect.Slice: | ||||
| 		return sliceToUnstructured(sv, dv) | ||||
| 	case reflect.Ptr: | ||||
| 		return pointerToUnstructured(sv, dv) | ||||
| 	case reflect.Struct: | ||||
| 		return structToUnstructured(sv, dv) | ||||
| 	case reflect.Interface: | ||||
| 		return interfaceToUnstructured(sv, dv) | ||||
| 	default: | ||||
| 		return fmt.Errorf("unrecognized type: %v", st.Kind()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func mapToUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	if sv.IsNil() { | ||||
| 		dv.Set(reflect.Zero(dt)) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 		if st.Key().Kind() == reflect.String { | ||||
| 			switch st.Elem().Kind() { | ||||
| 			// TODO It should be possible to reuse the slice for primitive types. | ||||
| 			// However, it is panicing in the following form. | ||||
| 			// case reflect.String, reflect.Bool, | ||||
| 			// 	reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | ||||
| 			// 	reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 			// 	sv.Set(sv) | ||||
| 			// 	return nil | ||||
| 			default: | ||||
| 				// We need to do a proper conversion. | ||||
| 			} | ||||
| 		} | ||||
| 		dv.Set(reflect.MakeMap(mapStringInterfaceType)) | ||||
| 		dv = dv.Elem() | ||||
| 		dt = dv.Type() | ||||
| 	} | ||||
| 	if dt.Kind() != reflect.Map { | ||||
| 		return fmt.Errorf("cannot convert struct to: %v", dt.Kind()) | ||||
| 	} | ||||
|  | ||||
| 	if !st.Key().AssignableTo(dt.Key()) && !st.Key().ConvertibleTo(dt.Key()) { | ||||
| 		return fmt.Errorf("cannot copy map with non-assignable keys: %v %v", st.Key(), dt.Key()) | ||||
| 	} | ||||
|  | ||||
| 	for _, key := range sv.MapKeys() { | ||||
| 		value := reflect.New(dt.Elem()).Elem() | ||||
| 		if err := toUnstructured(sv.MapIndex(key), value); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if st.Key().AssignableTo(dt.Key()) { | ||||
| 			dv.SetMapIndex(key, value) | ||||
| 		} else { | ||||
| 			dv.SetMapIndex(key.Convert(dt.Key()), value) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func sliceToUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	if sv.IsNil() { | ||||
| 		dv.Set(reflect.Zero(dt)) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if st.Elem().Kind() == reflect.Uint8 { | ||||
| 		dv.Set(reflect.New(stringType)) | ||||
| 		data, err := json.Marshal(sv.Bytes()) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		var result string | ||||
| 		if err = json.Unmarshal(data, &result); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		dv.Set(reflect.ValueOf(result)) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 		switch st.Elem().Kind() { | ||||
| 		// TODO It should be possible to reuse the slice for primitive types. | ||||
| 		// However, it is panicing in the following form. | ||||
| 		// case reflect.String, reflect.Bool, | ||||
| 		// 	reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | ||||
| 		// 	reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		// 	sv.Set(sv) | ||||
| 		// 	return nil | ||||
| 		default: | ||||
| 			// We need to do a proper conversion. | ||||
| 			dv.Set(reflect.MakeSlice(reflect.SliceOf(dt), sv.Len(), sv.Cap())) | ||||
| 			dv = dv.Elem() | ||||
| 			dt = dv.Type() | ||||
| 		} | ||||
| 	} | ||||
| 	if dt.Kind() != reflect.Slice { | ||||
| 		return fmt.Errorf("cannot convert slice to: %v", dt.Kind()) | ||||
| 	} | ||||
| 	for i := 0; i < sv.Len(); i++ { | ||||
| 		if err := toUnstructured(sv.Index(i), dv.Index(i)); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func pointerToUnstructured(sv, dv reflect.Value) error { | ||||
| 	if sv.IsNil() { | ||||
| 		// We're done - we don't need to store anything. | ||||
| 		return nil | ||||
| 	} | ||||
| 	return toUnstructured(sv.Elem(), dv) | ||||
| } | ||||
|  | ||||
| func isZero(v reflect.Value) bool { | ||||
| 	switch v.Kind() { | ||||
| 	case reflect.Array, reflect.String: | ||||
| 		return v.Len() == 0 | ||||
| 	case reflect.Bool: | ||||
| 		return !v.Bool() | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		return v.Int() == 0 | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		return v.Uint() == 0 | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		return v.Float() == 0 | ||||
| 	case reflect.Map, reflect.Slice: | ||||
| 		// TODO: It seems that 0-len maps are ignored in it. | ||||
| 		return v.IsNil() || v.Len() == 0 | ||||
| 	case reflect.Ptr, reflect.Interface: | ||||
| 		return v.IsNil() | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func structToUnstructured(sv, dv reflect.Value) error { | ||||
| 	st, dt := sv.Type(), dv.Type() | ||||
| 	if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 { | ||||
| 		dv.Set(reflect.MakeMap(mapStringInterfaceType)) | ||||
| 		dv = dv.Elem() | ||||
| 		dt = dv.Type() | ||||
| 	} | ||||
| 	if dt.Kind() != reflect.Map { | ||||
| 		return fmt.Errorf("cannot convert struct to: %v", dt.Kind()) | ||||
| 	} | ||||
| 	realMap := dv.Interface().(map[string]interface{}) | ||||
|  | ||||
| 	for i := 0; i < st.NumField(); i++ { | ||||
| 		fieldInfo := fieldInfoFromField(st, i) | ||||
| 		fv := sv.Field(i) | ||||
|  | ||||
| 		if fieldInfo.name == "-" { | ||||
| 			// This field should be skipped. | ||||
| 			continue | ||||
| 		} | ||||
| 		if fieldInfo.omitempty && isZero(fv) { | ||||
| 			// omitempty fields should be ignored. | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(fieldInfo.name) == 0 { | ||||
| 			// This field is inlined. | ||||
| 			if err := toUnstructured(fv, dv); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		switch fv.Type().Kind() { | ||||
| 		case reflect.String: | ||||
| 			realMap[fieldInfo.name] = fv.String() | ||||
| 		case reflect.Bool: | ||||
| 			realMap[fieldInfo.name] = fv.Bool() | ||||
| 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 			realMap[fieldInfo.name] = fv.Int() | ||||
| 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 			realMap[fieldInfo.name] = fv.Uint() | ||||
| 		case reflect.Float32, reflect.Float64: | ||||
| 			realMap[fieldInfo.name] = fv.Float() | ||||
| 		default: | ||||
| 			subv := reflect.New(dt.Elem()).Elem() | ||||
| 			if err := toUnstructured(fv, subv); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			dv.SetMapIndex(fieldInfo.nameValue, subv) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func interfaceToUnstructured(sv, dv reflect.Value) error { | ||||
| 	if !sv.IsValid() || sv.IsNil() { | ||||
| 		dv.Set(reflect.Zero(dv.Type())) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return toUnstructured(sv.Elem(), dv) | ||||
| } | ||||
							
								
								
									
										51
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
| 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 runtime includes helper functions for working with API objects | ||||
| // that follow the kubernetes API object conventions, which are: | ||||
| // | ||||
| // 0. Your API objects have a common metadata struct member, TypeMeta. | ||||
| // | ||||
| // 1. Your code refers to an internal set of API objects. | ||||
| // | ||||
| // 2. In a separate package, you have an external set of API objects. | ||||
| // | ||||
| // 3. The external set is considered to be versioned, and no breaking | ||||
| // changes are ever made to it (fields may be added but not changed | ||||
| // or removed). | ||||
| // | ||||
| // 4. As your api evolves, you'll make an additional versioned package | ||||
| // with every major change. | ||||
| // | ||||
| // 5. Versioned packages have conversion functions which convert to | ||||
| // and from the internal version. | ||||
| // | ||||
| // 6. You'll continue to support older versions according to your | ||||
| // deprecation policy, and you can easily provide a program/library | ||||
| // to update old versions into new versions because of 5. | ||||
| // | ||||
| // 7. All of your serializations and deserializations are handled in a | ||||
| // centralized place. | ||||
| // | ||||
| // Package runtime provides a conversion helper to make 5 easy, and the | ||||
| // Encode/Decode/DecodeInto trio to accomplish 7. You can also register | ||||
| // additional "codecs" which use a version of your choice. It's | ||||
| // recommended that you register your types with runtime in your | ||||
| // package's init function. | ||||
| // | ||||
| // As a bonus, a few common types useful from all api objects and versions | ||||
| // are provided in types.go. | ||||
| package runtime // import "k8s.io/apimachinery/pkg/runtime" | ||||
							
								
								
									
										142
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/embedded.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/embedded.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/conversion" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| ) | ||||
|  | ||||
| type encodable struct { | ||||
| 	E        Encoder `json:"-"` | ||||
| 	obj      Object | ||||
| 	versions []schema.GroupVersion | ||||
| } | ||||
|  | ||||
| func (e encodable) GetObjectKind() schema.ObjectKind { return e.obj.GetObjectKind() } | ||||
| func (e encodable) DeepCopyObject() Object { | ||||
| 	out := e | ||||
| 	out.obj = e.obj.DeepCopyObject() | ||||
| 	copy(out.versions, e.versions) | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| // NewEncodable creates an object that will be encoded with the provided codec on demand. | ||||
| // Provided as a convenience for test cases dealing with internal objects. | ||||
| func NewEncodable(e Encoder, obj Object, versions ...schema.GroupVersion) Object { | ||||
| 	if _, ok := obj.(*Unknown); ok { | ||||
| 		return obj | ||||
| 	} | ||||
| 	return encodable{e, obj, versions} | ||||
| } | ||||
|  | ||||
| func (e encodable) UnmarshalJSON(in []byte) error { | ||||
| 	return errors.New("runtime.encodable cannot be unmarshalled from JSON") | ||||
| } | ||||
|  | ||||
| // Marshal may get called on pointers or values, so implement MarshalJSON on value. | ||||
| // http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go | ||||
| func (e encodable) MarshalJSON() ([]byte, error) { | ||||
| 	return Encode(e.E, e.obj) | ||||
| } | ||||
|  | ||||
| // NewEncodableList creates an object that will be encoded with the provided codec on demand. | ||||
| // Provided as a convenience for test cases dealing with internal objects. | ||||
| func NewEncodableList(e Encoder, objects []Object, versions ...schema.GroupVersion) []Object { | ||||
| 	out := make([]Object, len(objects)) | ||||
| 	for i := range objects { | ||||
| 		if _, ok := objects[i].(*Unknown); ok { | ||||
| 			out[i] = objects[i] | ||||
| 			continue | ||||
| 		} | ||||
| 		out[i] = NewEncodable(e, objects[i], versions...) | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| func (e *Unknown) UnmarshalJSON(in []byte) error { | ||||
| 	if e == nil { | ||||
| 		return errors.New("runtime.Unknown: UnmarshalJSON on nil pointer") | ||||
| 	} | ||||
| 	e.TypeMeta = TypeMeta{} | ||||
| 	e.Raw = append(e.Raw[0:0], in...) | ||||
| 	e.ContentEncoding = "" | ||||
| 	e.ContentType = ContentTypeJSON | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Marshal may get called on pointers or values, so implement MarshalJSON on value. | ||||
| // http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go | ||||
| func (e Unknown) MarshalJSON() ([]byte, error) { | ||||
| 	// If ContentType is unset, we assume this is JSON. | ||||
| 	if e.ContentType != "" && e.ContentType != ContentTypeJSON { | ||||
| 		return nil, errors.New("runtime.Unknown: MarshalJSON on non-json data") | ||||
| 	} | ||||
| 	if e.Raw == nil { | ||||
| 		return []byte("null"), nil | ||||
| 	} | ||||
| 	return e.Raw, nil | ||||
| } | ||||
|  | ||||
| func Convert_runtime_Object_To_runtime_RawExtension(in *Object, out *RawExtension, s conversion.Scope) error { | ||||
| 	if in == nil { | ||||
| 		out.Raw = []byte("null") | ||||
| 		return nil | ||||
| 	} | ||||
| 	obj := *in | ||||
| 	if unk, ok := obj.(*Unknown); ok { | ||||
| 		if unk.Raw != nil { | ||||
| 			out.Raw = unk.Raw | ||||
| 			return nil | ||||
| 		} | ||||
| 		obj = out.Object | ||||
| 	} | ||||
| 	if obj == nil { | ||||
| 		out.Raw = nil | ||||
| 		return nil | ||||
| 	} | ||||
| 	out.Object = obj | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func Convert_runtime_RawExtension_To_runtime_Object(in *RawExtension, out *Object, s conversion.Scope) error { | ||||
| 	if in.Object != nil { | ||||
| 		*out = in.Object | ||||
| 		return nil | ||||
| 	} | ||||
| 	data := in.Raw | ||||
| 	if len(data) == 0 || (len(data) == 4 && string(data) == "null") { | ||||
| 		*out = nil | ||||
| 		return nil | ||||
| 	} | ||||
| 	*out = &Unknown{ | ||||
| 		Raw: data, | ||||
| 		// TODO: Set ContentEncoding and ContentType appropriately. | ||||
| 		// Currently we set ContentTypeJSON to make tests passing. | ||||
| 		ContentType: ContentTypeJSON, | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func DefaultEmbeddedConversions() []interface{} { | ||||
| 	return []interface{}{ | ||||
| 		Convert_runtime_Object_To_runtime_RawExtension, | ||||
| 		Convert_runtime_RawExtension_To_runtime_Object, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										122
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| ) | ||||
|  | ||||
| type notRegisteredErr struct { | ||||
| 	schemeName string | ||||
| 	gvk        schema.GroupVersionKind | ||||
| 	target     GroupVersioner | ||||
| 	t          reflect.Type | ||||
| } | ||||
|  | ||||
| func NewNotRegisteredErrForKind(schemeName string, gvk schema.GroupVersionKind) error { | ||||
| 	return ¬RegisteredErr{schemeName: schemeName, gvk: gvk} | ||||
| } | ||||
|  | ||||
| func NewNotRegisteredErrForType(schemeName string, t reflect.Type) error { | ||||
| 	return ¬RegisteredErr{schemeName: schemeName, t: t} | ||||
| } | ||||
|  | ||||
| func NewNotRegisteredErrForTarget(schemeName string, t reflect.Type, target GroupVersioner) error { | ||||
| 	return ¬RegisteredErr{schemeName: schemeName, t: t, target: target} | ||||
| } | ||||
|  | ||||
| func NewNotRegisteredGVKErrForTarget(schemeName string, gvk schema.GroupVersionKind, target GroupVersioner) error { | ||||
| 	return ¬RegisteredErr{schemeName: schemeName, gvk: gvk, target: target} | ||||
| } | ||||
|  | ||||
| func (k *notRegisteredErr) Error() string { | ||||
| 	if k.t != nil && k.target != nil { | ||||
| 		return fmt.Sprintf("%v is not suitable for converting to %q in scheme %q", k.t, k.target, k.schemeName) | ||||
| 	} | ||||
| 	nullGVK := schema.GroupVersionKind{} | ||||
| 	if k.gvk != nullGVK && k.target != nil { | ||||
| 		return fmt.Sprintf("%q is not suitable for converting to %q in scheme %q", k.gvk.GroupVersion(), k.target, k.schemeName) | ||||
| 	} | ||||
| 	if k.t != nil { | ||||
| 		return fmt.Sprintf("no kind is registered for the type %v in scheme %q", k.t, k.schemeName) | ||||
| 	} | ||||
| 	if len(k.gvk.Kind) == 0 { | ||||
| 		return fmt.Sprintf("no version %q has been registered in scheme %q", k.gvk.GroupVersion(), k.schemeName) | ||||
| 	} | ||||
| 	if k.gvk.Version == APIVersionInternal { | ||||
| 		return fmt.Sprintf("no kind %q is registered for the internal version of group %q in scheme %q", k.gvk.Kind, k.gvk.Group, k.schemeName) | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("no kind %q is registered for version %q in scheme %q", k.gvk.Kind, k.gvk.GroupVersion(), k.schemeName) | ||||
| } | ||||
|  | ||||
| // IsNotRegisteredError returns true if the error indicates the provided | ||||
| // object or input data is not registered. | ||||
| func IsNotRegisteredError(err error) bool { | ||||
| 	if err == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	_, ok := err.(*notRegisteredErr) | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| type missingKindErr struct { | ||||
| 	data string | ||||
| } | ||||
|  | ||||
| func NewMissingKindErr(data string) error { | ||||
| 	return &missingKindErr{data} | ||||
| } | ||||
|  | ||||
| func (k *missingKindErr) Error() string { | ||||
| 	return fmt.Sprintf("Object 'Kind' is missing in '%s'", k.data) | ||||
| } | ||||
|  | ||||
| // IsMissingKind returns true if the error indicates that the provided object | ||||
| // is missing a 'Kind' field. | ||||
| func IsMissingKind(err error) bool { | ||||
| 	if err == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	_, ok := err.(*missingKindErr) | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
| type missingVersionErr struct { | ||||
| 	data string | ||||
| } | ||||
|  | ||||
| func NewMissingVersionErr(data string) error { | ||||
| 	return &missingVersionErr{data} | ||||
| } | ||||
|  | ||||
| func (k *missingVersionErr) Error() string { | ||||
| 	return fmt.Sprintf("Object 'apiVersion' is missing in '%s'", k.data) | ||||
| } | ||||
|  | ||||
| // IsMissingVersion returns true if the error indicates that the provided object | ||||
| // is missing a 'Version' field. | ||||
| func IsMissingVersion(err error) bool { | ||||
| 	if err == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	_, ok := err.(*missingVersionErr) | ||||
| 	return ok | ||||
| } | ||||
							
								
								
									
										51
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| ) | ||||
|  | ||||
| func (re *RawExtension) UnmarshalJSON(in []byte) error { | ||||
| 	if re == nil { | ||||
| 		return errors.New("runtime.RawExtension: UnmarshalJSON on nil pointer") | ||||
| 	} | ||||
| 	if !bytes.Equal(in, []byte("null")) { | ||||
| 		re.Raw = append(re.Raw[0:0], in...) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // MarshalJSON may get called on pointers or values, so implement MarshalJSON on value. | ||||
| // http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go | ||||
| func (re RawExtension) MarshalJSON() ([]byte, error) { | ||||
| 	if re.Raw == nil { | ||||
| 		// TODO: this is to support legacy behavior of JSONPrinter and YAMLPrinter, which | ||||
| 		// expect to call json.Marshal on arbitrary versioned objects (even those not in | ||||
| 		// the scheme). pkg/kubectl/resource#AsVersionedObjects and its interaction with | ||||
| 		// kubectl get on objects not in the scheme needs to be updated to ensure that the | ||||
| 		// objects that are not part of the scheme are correctly put into the right form. | ||||
| 		if re.Object != nil { | ||||
| 			return json.Marshal(re.Object) | ||||
| 		} | ||||
| 		return []byte("null"), nil | ||||
| 	} | ||||
| 	// TODO: Check whether ContentType is actually JSON before returning it. | ||||
| 	return re.Raw, nil | ||||
| } | ||||
							
								
								
									
										753
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										753
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,753 @@ | ||||
| /* | ||||
| Copyright 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. | ||||
| */ | ||||
|  | ||||
| // Code generated by protoc-gen-gogo. DO NOT EDIT. | ||||
| // source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto | ||||
|  | ||||
| /* | ||||
| 	Package runtime is a generated protocol buffer package. | ||||
|  | ||||
| 	It is generated from these files: | ||||
| 		k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto | ||||
|  | ||||
| 	It has these top-level messages: | ||||
| 		RawExtension | ||||
| 		TypeMeta | ||||
| 		Unknown | ||||
| */ | ||||
| package runtime | ||||
|  | ||||
| import proto "github.com/gogo/protobuf/proto" | ||||
| import fmt "fmt" | ||||
| import math "math" | ||||
|  | ||||
| import strings "strings" | ||||
| import reflect "reflect" | ||||
|  | ||||
| import io "io" | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ = proto.Marshal | ||||
| var _ = fmt.Errorf | ||||
| var _ = math.Inf | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the proto package it is being compiled against. | ||||
| // A compilation error at this line likely means your copy of the | ||||
| // proto package needs to be updated. | ||||
| const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package | ||||
|  | ||||
| func (m *RawExtension) Reset()                    { *m = RawExtension{} } | ||||
| func (*RawExtension) ProtoMessage()               {} | ||||
| func (*RawExtension) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} } | ||||
|  | ||||
| func (m *TypeMeta) Reset()                    { *m = TypeMeta{} } | ||||
| func (*TypeMeta) ProtoMessage()               {} | ||||
| func (*TypeMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} } | ||||
|  | ||||
| func (m *Unknown) Reset()                    { *m = Unknown{} } | ||||
| func (*Unknown) ProtoMessage()               {} | ||||
| func (*Unknown) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} } | ||||
|  | ||||
| func init() { | ||||
| 	proto.RegisterType((*RawExtension)(nil), "k8s.io.apimachinery.pkg.runtime.RawExtension") | ||||
| 	proto.RegisterType((*TypeMeta)(nil), "k8s.io.apimachinery.pkg.runtime.TypeMeta") | ||||
| 	proto.RegisterType((*Unknown)(nil), "k8s.io.apimachinery.pkg.runtime.Unknown") | ||||
| } | ||||
| func (m *RawExtension) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalTo(dAtA) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
|  | ||||
| func (m *RawExtension) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	var i int | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if m.Raw != nil { | ||||
| 		dAtA[i] = 0xa | ||||
| 		i++ | ||||
| 		i = encodeVarintGenerated(dAtA, i, uint64(len(m.Raw))) | ||||
| 		i += copy(dAtA[i:], m.Raw) | ||||
| 	} | ||||
| 	return i, nil | ||||
| } | ||||
|  | ||||
| func (m *TypeMeta) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalTo(dAtA) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
|  | ||||
| func (m *TypeMeta) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	var i int | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	dAtA[i] = 0xa | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) | ||||
| 	i += copy(dAtA[i:], m.APIVersion) | ||||
| 	dAtA[i] = 0x12 | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) | ||||
| 	i += copy(dAtA[i:], m.Kind) | ||||
| 	return i, nil | ||||
| } | ||||
|  | ||||
| func (m *Unknown) Marshal() (dAtA []byte, err error) { | ||||
| 	size := m.Size() | ||||
| 	dAtA = make([]byte, size) | ||||
| 	n, err := m.MarshalTo(dAtA) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return dAtA[:n], nil | ||||
| } | ||||
|  | ||||
| func (m *Unknown) MarshalTo(dAtA []byte) (int, error) { | ||||
| 	var i int | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	dAtA[i] = 0xa | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(dAtA, i, uint64(m.TypeMeta.Size())) | ||||
| 	n1, err := m.TypeMeta.MarshalTo(dAtA[i:]) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	i += n1 | ||||
| 	if m.Raw != nil { | ||||
| 		dAtA[i] = 0x12 | ||||
| 		i++ | ||||
| 		i = encodeVarintGenerated(dAtA, i, uint64(len(m.Raw))) | ||||
| 		i += copy(dAtA[i:], m.Raw) | ||||
| 	} | ||||
| 	dAtA[i] = 0x1a | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(dAtA, i, uint64(len(m.ContentEncoding))) | ||||
| 	i += copy(dAtA[i:], m.ContentEncoding) | ||||
| 	dAtA[i] = 0x22 | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(dAtA, i, uint64(len(m.ContentType))) | ||||
| 	i += copy(dAtA[i:], m.ContentType) | ||||
| 	return i, nil | ||||
| } | ||||
|  | ||||
| func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { | ||||
| 	for v >= 1<<7 { | ||||
| 		dAtA[offset] = uint8(v&0x7f | 0x80) | ||||
| 		v >>= 7 | ||||
| 		offset++ | ||||
| 	} | ||||
| 	dAtA[offset] = uint8(v) | ||||
| 	return offset + 1 | ||||
| } | ||||
| func (m *RawExtension) Size() (n int) { | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	if m.Raw != nil { | ||||
| 		l = len(m.Raw) | ||||
| 		n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
|  | ||||
| func (m *TypeMeta) Size() (n int) { | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	l = len(m.APIVersion) | ||||
| 	n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	l = len(m.Kind) | ||||
| 	n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	return n | ||||
| } | ||||
|  | ||||
| func (m *Unknown) Size() (n int) { | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	l = m.TypeMeta.Size() | ||||
| 	n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	if m.Raw != nil { | ||||
| 		l = len(m.Raw) | ||||
| 		n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	} | ||||
| 	l = len(m.ContentEncoding) | ||||
| 	n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	l = len(m.ContentType) | ||||
| 	n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	return n | ||||
| } | ||||
|  | ||||
| func sovGenerated(x uint64) (n int) { | ||||
| 	for { | ||||
| 		n++ | ||||
| 		x >>= 7 | ||||
| 		if x == 0 { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| func sozGenerated(x uint64) (n int) { | ||||
| 	return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) | ||||
| } | ||||
| func (this *RawExtension) String() string { | ||||
| 	if this == nil { | ||||
| 		return "nil" | ||||
| 	} | ||||
| 	s := strings.Join([]string{`&RawExtension{`, | ||||
| 		`Raw:` + valueToStringGenerated(this.Raw) + `,`, | ||||
| 		`}`, | ||||
| 	}, "") | ||||
| 	return s | ||||
| } | ||||
| func (this *TypeMeta) String() string { | ||||
| 	if this == nil { | ||||
| 		return "nil" | ||||
| 	} | ||||
| 	s := strings.Join([]string{`&TypeMeta{`, | ||||
| 		`APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, | ||||
| 		`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, | ||||
| 		`}`, | ||||
| 	}, "") | ||||
| 	return s | ||||
| } | ||||
| func (this *Unknown) String() string { | ||||
| 	if this == nil { | ||||
| 		return "nil" | ||||
| 	} | ||||
| 	s := strings.Join([]string{`&Unknown{`, | ||||
| 		`TypeMeta:` + strings.Replace(strings.Replace(this.TypeMeta.String(), "TypeMeta", "TypeMeta", 1), `&`, ``, 1) + `,`, | ||||
| 		`Raw:` + valueToStringGenerated(this.Raw) + `,`, | ||||
| 		`ContentEncoding:` + fmt.Sprintf("%v", this.ContentEncoding) + `,`, | ||||
| 		`ContentType:` + fmt.Sprintf("%v", this.ContentType) + `,`, | ||||
| 		`}`, | ||||
| 	}, "") | ||||
| 	return s | ||||
| } | ||||
| func valueToStringGenerated(v interface{}) string { | ||||
| 	rv := reflect.ValueOf(v) | ||||
| 	if rv.IsNil() { | ||||
| 		return "nil" | ||||
| 	} | ||||
| 	pv := reflect.Indirect(rv).Interface() | ||||
| 	return fmt.Sprintf("*%v", pv) | ||||
| } | ||||
| func (m *RawExtension) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowGenerated | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= (uint64(b) & 0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: RawExtension: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: RawExtension: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Raw", wireType) | ||||
| 			} | ||||
| 			var byteLen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				byteLen |= (int(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if byteLen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + byteLen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.Raw = append(m.Raw[:0], dAtA[iNdEx:postIndex]...) | ||||
| 			if m.Raw == nil { | ||||
| 				m.Raw = []byte{} | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipGenerated(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if skippy < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *TypeMeta) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowGenerated | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= (uint64(b) & 0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: TypeMeta: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: TypeMeta: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType) | ||||
| 			} | ||||
| 			var stringLen uint64 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				stringLen |= (uint64(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			intStringLen := int(stringLen) | ||||
| 			if intStringLen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + intStringLen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.APIVersion = string(dAtA[iNdEx:postIndex]) | ||||
| 			iNdEx = postIndex | ||||
| 		case 2: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) | ||||
| 			} | ||||
| 			var stringLen uint64 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				stringLen |= (uint64(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			intStringLen := int(stringLen) | ||||
| 			if intStringLen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + intStringLen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.Kind = string(dAtA[iNdEx:postIndex]) | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipGenerated(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if skippy < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (m *Unknown) Unmarshal(dAtA []byte) error { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		preIndex := iNdEx | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return ErrIntOverflowGenerated | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= (uint64(b) & 0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		fieldNum := int32(wire >> 3) | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		if wireType == 4 { | ||||
| 			return fmt.Errorf("proto: Unknown: wiretype end group for non-group") | ||||
| 		} | ||||
| 		if fieldNum <= 0 { | ||||
| 			return fmt.Errorf("proto: Unknown: illegal tag %d (wire type %d)", fieldNum, wire) | ||||
| 		} | ||||
| 		switch fieldNum { | ||||
| 		case 1: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field TypeMeta", wireType) | ||||
| 			} | ||||
| 			var msglen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				msglen |= (int(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if msglen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + msglen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			if err := m.TypeMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 2: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field Raw", wireType) | ||||
| 			} | ||||
| 			var byteLen int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				byteLen |= (int(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if byteLen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + byteLen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.Raw = append(m.Raw[:0], dAtA[iNdEx:postIndex]...) | ||||
| 			if m.Raw == nil { | ||||
| 				m.Raw = []byte{} | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 3: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field ContentEncoding", wireType) | ||||
| 			} | ||||
| 			var stringLen uint64 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				stringLen |= (uint64(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			intStringLen := int(stringLen) | ||||
| 			if intStringLen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + intStringLen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.ContentEncoding = string(dAtA[iNdEx:postIndex]) | ||||
| 			iNdEx = postIndex | ||||
| 		case 4: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field ContentType", wireType) | ||||
| 			} | ||||
| 			var stringLen uint64 | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				stringLen |= (uint64(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			intStringLen := int(stringLen) | ||||
| 			if intStringLen < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			postIndex := iNdEx + intStringLen | ||||
| 			if postIndex > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			m.ContentType = string(dAtA[iNdEx:postIndex]) | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipGenerated(dAtA[iNdEx:]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			if skippy < 0 { | ||||
| 				return ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			if (iNdEx + skippy) > l { | ||||
| 				return io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			iNdEx += skippy | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if iNdEx > l { | ||||
| 		return io.ErrUnexpectedEOF | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func skipGenerated(dAtA []byte) (n int, err error) { | ||||
| 	l := len(dAtA) | ||||
| 	iNdEx := 0 | ||||
| 	for iNdEx < l { | ||||
| 		var wire uint64 | ||||
| 		for shift := uint(0); ; shift += 7 { | ||||
| 			if shift >= 64 { | ||||
| 				return 0, ErrIntOverflowGenerated | ||||
| 			} | ||||
| 			if iNdEx >= l { | ||||
| 				return 0, io.ErrUnexpectedEOF | ||||
| 			} | ||||
| 			b := dAtA[iNdEx] | ||||
| 			iNdEx++ | ||||
| 			wire |= (uint64(b) & 0x7F) << shift | ||||
| 			if b < 0x80 { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		wireType := int(wire & 0x7) | ||||
| 		switch wireType { | ||||
| 		case 0: | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return 0, ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return 0, io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				iNdEx++ | ||||
| 				if dAtA[iNdEx-1] < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			return iNdEx, nil | ||||
| 		case 1: | ||||
| 			iNdEx += 8 | ||||
| 			return iNdEx, nil | ||||
| 		case 2: | ||||
| 			var length int | ||||
| 			for shift := uint(0); ; shift += 7 { | ||||
| 				if shift >= 64 { | ||||
| 					return 0, ErrIntOverflowGenerated | ||||
| 				} | ||||
| 				if iNdEx >= l { | ||||
| 					return 0, io.ErrUnexpectedEOF | ||||
| 				} | ||||
| 				b := dAtA[iNdEx] | ||||
| 				iNdEx++ | ||||
| 				length |= (int(b) & 0x7F) << shift | ||||
| 				if b < 0x80 { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			iNdEx += length | ||||
| 			if length < 0 { | ||||
| 				return 0, ErrInvalidLengthGenerated | ||||
| 			} | ||||
| 			return iNdEx, nil | ||||
| 		case 3: | ||||
| 			for { | ||||
| 				var innerWire uint64 | ||||
| 				var start int = iNdEx | ||||
| 				for shift := uint(0); ; shift += 7 { | ||||
| 					if shift >= 64 { | ||||
| 						return 0, ErrIntOverflowGenerated | ||||
| 					} | ||||
| 					if iNdEx >= l { | ||||
| 						return 0, io.ErrUnexpectedEOF | ||||
| 					} | ||||
| 					b := dAtA[iNdEx] | ||||
| 					iNdEx++ | ||||
| 					innerWire |= (uint64(b) & 0x7F) << shift | ||||
| 					if b < 0x80 { | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 				innerWireType := int(innerWire & 0x7) | ||||
| 				if innerWireType == 4 { | ||||
| 					break | ||||
| 				} | ||||
| 				next, err := skipGenerated(dAtA[start:]) | ||||
| 				if err != nil { | ||||
| 					return 0, err | ||||
| 				} | ||||
| 				iNdEx = start + next | ||||
| 			} | ||||
| 			return iNdEx, nil | ||||
| 		case 4: | ||||
| 			return iNdEx, nil | ||||
| 		case 5: | ||||
| 			iNdEx += 4 | ||||
| 			return iNdEx, nil | ||||
| 		default: | ||||
| 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType) | ||||
| 		} | ||||
| 	} | ||||
| 	panic("unreachable") | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") | ||||
| 	ErrIntOverflowGenerated   = fmt.Errorf("proto: integer overflow") | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto", fileDescriptorGenerated) | ||||
| } | ||||
|  | ||||
| var fileDescriptorGenerated = []byte{ | ||||
| 	// 378 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x4f, 0xab, 0x13, 0x31, | ||||
| 	0x14, 0xc5, 0x27, 0xaf, 0x85, 0x3e, 0xd3, 0xc2, 0x93, 0xb8, 0x70, 0x74, 0x91, 0x79, 0x74, 0xe5, | ||||
| 	0x5b, 0xbc, 0x04, 0x1e, 0x08, 0x6e, 0x3b, 0xa5, 0xa0, 0x88, 0x20, 0xc1, 0x3f, 0xe0, 0xca, 0x74, | ||||
| 	0x26, 0x4e, 0xc3, 0xd0, 0x9b, 0x21, 0xcd, 0x38, 0x76, 0xe7, 0x47, 0xf0, 0x63, 0x75, 0xd9, 0x65, | ||||
| 	0x57, 0xc5, 0x8e, 0x1f, 0xc2, 0xad, 0x34, 0x4d, 0x6b, 0xd5, 0x85, 0xbb, 0xe4, 0x9e, 0xf3, 0x3b, | ||||
| 	0xf7, 0x1e, 0xfc, 0xbc, 0x7c, 0xb6, 0x60, 0xda, 0xf0, 0xb2, 0x9e, 0x2a, 0x0b, 0xca, 0xa9, 0x05, | ||||
| 	0xff, 0xac, 0x20, 0x37, 0x96, 0x07, 0x41, 0x56, 0x7a, 0x2e, 0xb3, 0x99, 0x06, 0x65, 0x97, 0xbc, | ||||
| 	0x2a, 0x0b, 0x6e, 0x6b, 0x70, 0x7a, 0xae, 0x78, 0xa1, 0x40, 0x59, 0xe9, 0x54, 0xce, 0x2a, 0x6b, | ||||
| 	0x9c, 0x21, 0xc9, 0x01, 0x60, 0xe7, 0x00, 0xab, 0xca, 0x82, 0x05, 0xe0, 0xf1, 0x6d, 0xa1, 0xdd, | ||||
| 	0xac, 0x9e, 0xb2, 0xcc, 0xcc, 0x79, 0x61, 0x0a, 0xc3, 0x3d, 0x37, 0xad, 0x3f, 0xf9, 0x9f, 0xff, | ||||
| 	0xf8, 0xd7, 0x21, 0x6f, 0x78, 0x83, 0x07, 0x42, 0x36, 0x93, 0x2f, 0x4e, 0xc1, 0x42, 0x1b, 0x20, | ||||
| 	0x8f, 0x70, 0xc7, 0xca, 0x26, 0x46, 0xd7, 0xe8, 0xc9, 0x20, 0xed, 0xb5, 0xdb, 0xa4, 0x23, 0x64, | ||||
| 	0x23, 0xf6, 0xb3, 0xe1, 0x47, 0x7c, 0xf9, 0x66, 0x59, 0xa9, 0x57, 0xca, 0x49, 0x72, 0x87, 0xb1, | ||||
| 	0xac, 0xf4, 0x3b, 0x65, 0xf7, 0x90, 0x77, 0xdf, 0x4b, 0xc9, 0x6a, 0x9b, 0x44, 0xed, 0x36, 0xc1, | ||||
| 	0xa3, 0xd7, 0x2f, 0x82, 0x22, 0xce, 0x5c, 0xe4, 0x1a, 0x77, 0x4b, 0x0d, 0x79, 0x7c, 0xe1, 0xdd, | ||||
| 	0x83, 0xe0, 0xee, 0xbe, 0xd4, 0x90, 0x0b, 0xaf, 0x0c, 0x7f, 0x22, 0xdc, 0x7b, 0x0b, 0x25, 0x98, | ||||
| 	0x06, 0xc8, 0x7b, 0x7c, 0xe9, 0xc2, 0x36, 0x9f, 0xdf, 0xbf, 0xbb, 0x61, 0xff, 0xe9, 0xce, 0x8e, | ||||
| 	0xe7, 0xa5, 0xf7, 0x43, 0xf8, 0xe9, 0x60, 0x71, 0x0a, 0x3b, 0x36, 0xbc, 0xf8, 0xb7, 0x21, 0x19, | ||||
| 	0xe1, 0xab, 0xcc, 0x80, 0x53, 0xe0, 0x26, 0x90, 0x99, 0x5c, 0x43, 0x11, 0x77, 0xfc, 0xb1, 0x0f, | ||||
| 	0x43, 0xde, 0xd5, 0xf8, 0x4f, 0x59, 0xfc, 0xed, 0x27, 0x4f, 0x71, 0x3f, 0x8c, 0xf6, 0xab, 0xe3, | ||||
| 	0xae, 0xc7, 0x1f, 0x04, 0xbc, 0x3f, 0xfe, 0x2d, 0x89, 0x73, 0x5f, 0x7a, 0xbb, 0xda, 0xd1, 0x68, | ||||
| 	0xbd, 0xa3, 0xd1, 0x66, 0x47, 0xa3, 0xaf, 0x2d, 0x45, 0xab, 0x96, 0xa2, 0x75, 0x4b, 0xd1, 0xa6, | ||||
| 	0xa5, 0xe8, 0x7b, 0x4b, 0xd1, 0xb7, 0x1f, 0x34, 0xfa, 0xd0, 0x0b, 0x45, 0x7f, 0x05, 0x00, 0x00, | ||||
| 	0xff, 0xff, 0xe3, 0x33, 0x18, 0x0b, 0x50, 0x02, 0x00, 0x00, | ||||
| } | ||||
							
								
								
									
										127
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/generated.proto
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/generated.proto
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| /* | ||||
| Copyright 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. | ||||
| */ | ||||
|  | ||||
|  | ||||
| // This file was autogenerated by go-to-protobuf. Do not edit it manually! | ||||
|  | ||||
| syntax = 'proto2'; | ||||
|  | ||||
| package k8s.io.apimachinery.pkg.runtime; | ||||
|  | ||||
| // Package-wide variables from generator "generated". | ||||
| option go_package = "runtime"; | ||||
|  | ||||
| // RawExtension is used to hold extensions in external versions. | ||||
| // | ||||
| // To use this, make a field which has RawExtension as its type in your external, versioned | ||||
| // struct, and Object in your internal struct. You also need to register your | ||||
| // various plugin types. | ||||
| // | ||||
| // // Internal package: | ||||
| // type MyAPIObject struct { | ||||
| // 	runtime.TypeMeta `json:",inline"` | ||||
| // 	MyPlugin runtime.Object `json:"myPlugin"` | ||||
| // } | ||||
| // type PluginA struct { | ||||
| // 	AOption string `json:"aOption"` | ||||
| // } | ||||
| // | ||||
| // // External package: | ||||
| // type MyAPIObject struct { | ||||
| // 	runtime.TypeMeta `json:",inline"` | ||||
| // 	MyPlugin runtime.RawExtension `json:"myPlugin"` | ||||
| // } | ||||
| // type PluginA struct { | ||||
| // 	AOption string `json:"aOption"` | ||||
| // } | ||||
| // | ||||
| // // On the wire, the JSON will look something like this: | ||||
| // { | ||||
| // 	"kind":"MyAPIObject", | ||||
| // 	"apiVersion":"v1", | ||||
| // 	"myPlugin": { | ||||
| // 		"kind":"PluginA", | ||||
| // 		"aOption":"foo", | ||||
| // 	}, | ||||
| // } | ||||
| // | ||||
| // So what happens? Decode first uses json or yaml to unmarshal the serialized data into | ||||
| // your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. | ||||
| // The next step is to copy (using pkg/conversion) into the internal struct. The runtime | ||||
| // package's DefaultScheme has conversion functions installed which will unpack the | ||||
| // JSON stored in RawExtension, turning it into the correct object type, and storing it | ||||
| // in the Object. (TODO: In the case where the object is of an unknown type, a | ||||
| // runtime.Unknown object will be created and stored.) | ||||
| // | ||||
| // +k8s:deepcopy-gen=true | ||||
| // +protobuf=true | ||||
| // +k8s:openapi-gen=true | ||||
| message RawExtension { | ||||
|   // Raw is the underlying serialization of this object. | ||||
|   // | ||||
|   // TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data. | ||||
|   optional bytes raw = 1; | ||||
| } | ||||
|  | ||||
| // TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, | ||||
| // like this: | ||||
| // type MyAwesomeAPIObject struct { | ||||
| //      runtime.TypeMeta    `json:",inline"` | ||||
| //      ... // other fields | ||||
| // } | ||||
| // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind | ||||
| // | ||||
| // TypeMeta is provided here for convenience. You may use it directly from this package or define | ||||
| // your own with the same fields. | ||||
| // | ||||
| // +k8s:deepcopy-gen=false | ||||
| // +protobuf=true | ||||
| // +k8s:openapi-gen=true | ||||
| message TypeMeta { | ||||
|   // +optional | ||||
|   optional string apiVersion = 1; | ||||
|  | ||||
|   // +optional | ||||
|   optional string kind = 2; | ||||
| } | ||||
|  | ||||
| // Unknown allows api objects with unknown types to be passed-through. This can be used | ||||
| // to deal with the API objects from a plug-in. Unknown objects still have functioning | ||||
| // TypeMeta features-- kind, version, etc. | ||||
| // TODO: Make this object have easy access to field based accessors and settors for | ||||
| // metadata and field mutatation. | ||||
| // | ||||
| // +k8s:deepcopy-gen=true | ||||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||||
| // +protobuf=true | ||||
| // +k8s:openapi-gen=true | ||||
| message Unknown { | ||||
|   optional TypeMeta typeMeta = 1; | ||||
|  | ||||
|   // Raw will hold the complete serialized object which couldn't be matched | ||||
|   // with a registered type. Most likely, nothing should be done with this | ||||
|   // except for passing it through the system. | ||||
|   optional bytes raw = 2; | ||||
|  | ||||
|   // ContentEncoding is encoding used to encode 'Raw' data. | ||||
|   // Unspecified means no encoding. | ||||
|   optional string contentEncoding = 3; | ||||
|  | ||||
|   // ContentType  is serialization method used to serialize 'Raw'. | ||||
|   // Unspecified means ContentTypeJSON. | ||||
|   optional string contentType = 4; | ||||
| } | ||||
|  | ||||
							
								
								
									
										212
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/helper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/helper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,212 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/conversion" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| 	"k8s.io/apimachinery/pkg/util/errors" | ||||
| ) | ||||
|  | ||||
| // unsafeObjectConvertor implements ObjectConvertor using the unsafe conversion path. | ||||
| type unsafeObjectConvertor struct { | ||||
| 	*Scheme | ||||
| } | ||||
|  | ||||
| var _ ObjectConvertor = unsafeObjectConvertor{} | ||||
|  | ||||
| // ConvertToVersion converts in to the provided outVersion without copying the input first, which | ||||
| // is only safe if the output object is not mutated or reused. | ||||
| func (c unsafeObjectConvertor) ConvertToVersion(in Object, outVersion GroupVersioner) (Object, error) { | ||||
| 	return c.Scheme.UnsafeConvertToVersion(in, outVersion) | ||||
| } | ||||
|  | ||||
| // UnsafeObjectConvertor performs object conversion without copying the object structure, | ||||
| // for use when the converted object will not be reused or mutated. Primarily for use within | ||||
| // versioned codecs, which use the external object for serialization but do not return it. | ||||
| func UnsafeObjectConvertor(scheme *Scheme) ObjectConvertor { | ||||
| 	return unsafeObjectConvertor{scheme} | ||||
| } | ||||
|  | ||||
| // SetField puts the value of src, into fieldName, which must be a member of v. | ||||
| // The value of src must be assignable to the field. | ||||
| func SetField(src interface{}, v reflect.Value, fieldName string) error { | ||||
| 	field := v.FieldByName(fieldName) | ||||
| 	if !field.IsValid() { | ||||
| 		return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface()) | ||||
| 	} | ||||
| 	srcValue := reflect.ValueOf(src) | ||||
| 	if srcValue.Type().AssignableTo(field.Type()) { | ||||
| 		field.Set(srcValue) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if srcValue.Type().ConvertibleTo(field.Type()) { | ||||
| 		field.Set(srcValue.Convert(field.Type())) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return fmt.Errorf("couldn't assign/convert %v to %v", srcValue.Type(), field.Type()) | ||||
| } | ||||
|  | ||||
| // Field puts the value of fieldName, which must be a member of v, into dest, | ||||
| // which must be a variable to which this field's value can be assigned. | ||||
| func Field(v reflect.Value, fieldName string, dest interface{}) error { | ||||
| 	field := v.FieldByName(fieldName) | ||||
| 	if !field.IsValid() { | ||||
| 		return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface()) | ||||
| 	} | ||||
| 	destValue, err := conversion.EnforcePtr(dest) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if field.Type().AssignableTo(destValue.Type()) { | ||||
| 		destValue.Set(field) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if field.Type().ConvertibleTo(destValue.Type()) { | ||||
| 		destValue.Set(field.Convert(destValue.Type())) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return fmt.Errorf("couldn't assign/convert %v to %v", field.Type(), destValue.Type()) | ||||
| } | ||||
|  | ||||
| // FieldPtr puts the address of fieldName, which must be a member of v, | ||||
| // into dest, which must be an address of a variable to which this field's | ||||
| // address can be assigned. | ||||
| func FieldPtr(v reflect.Value, fieldName string, dest interface{}) error { | ||||
| 	field := v.FieldByName(fieldName) | ||||
| 	if !field.IsValid() { | ||||
| 		return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface()) | ||||
| 	} | ||||
| 	v, err := conversion.EnforcePtr(dest) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	field = field.Addr() | ||||
| 	if field.Type().AssignableTo(v.Type()) { | ||||
| 		v.Set(field) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if field.Type().ConvertibleTo(v.Type()) { | ||||
| 		v.Set(field.Convert(v.Type())) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return fmt.Errorf("couldn't assign/convert %v to %v", field.Type(), v.Type()) | ||||
| } | ||||
|  | ||||
| // EncodeList ensures that each object in an array is converted to a Unknown{} in serialized form. | ||||
| // TODO: accept a content type. | ||||
| func EncodeList(e Encoder, objects []Object) error { | ||||
| 	var errs []error | ||||
| 	for i := range objects { | ||||
| 		data, err := Encode(e, objects[i]) | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		// TODO: Set ContentEncoding and ContentType. | ||||
| 		objects[i] = &Unknown{Raw: data} | ||||
| 	} | ||||
| 	return errors.NewAggregate(errs) | ||||
| } | ||||
|  | ||||
| func decodeListItem(obj *Unknown, decoders []Decoder) (Object, error) { | ||||
| 	for _, decoder := range decoders { | ||||
| 		// TODO: Decode based on ContentType. | ||||
| 		obj, err := Decode(decoder, obj.Raw) | ||||
| 		if err != nil { | ||||
| 			if IsNotRegisteredError(err) { | ||||
| 				continue | ||||
| 			} | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		return obj, nil | ||||
| 	} | ||||
| 	// could not decode, so leave the object as Unknown, but give the decoders the | ||||
| 	// chance to set Unknown.TypeMeta if it is available. | ||||
| 	for _, decoder := range decoders { | ||||
| 		if err := DecodeInto(decoder, obj.Raw, obj); err == nil { | ||||
| 			return obj, nil | ||||
| 		} | ||||
| 	} | ||||
| 	return obj, nil | ||||
| } | ||||
|  | ||||
| // DecodeList alters the list in place, attempting to decode any objects found in | ||||
| // the list that have the Unknown type. Any errors that occur are returned | ||||
| // after the entire list is processed. Decoders are tried in order. | ||||
| func DecodeList(objects []Object, decoders ...Decoder) []error { | ||||
| 	errs := []error(nil) | ||||
| 	for i, obj := range objects { | ||||
| 		switch t := obj.(type) { | ||||
| 		case *Unknown: | ||||
| 			decoded, err := decodeListItem(t, decoders) | ||||
| 			if err != nil { | ||||
| 				errs = append(errs, err) | ||||
| 				break | ||||
| 			} | ||||
| 			objects[i] = decoded | ||||
| 		} | ||||
| 	} | ||||
| 	return errs | ||||
| } | ||||
|  | ||||
| // MultiObjectTyper returns the types of objects across multiple schemes in order. | ||||
| type MultiObjectTyper []ObjectTyper | ||||
|  | ||||
| var _ ObjectTyper = MultiObjectTyper{} | ||||
|  | ||||
| func (m MultiObjectTyper) ObjectKinds(obj Object) (gvks []schema.GroupVersionKind, unversionedType bool, err error) { | ||||
| 	for _, t := range m { | ||||
| 		gvks, unversionedType, err = t.ObjectKinds(obj) | ||||
| 		if err == nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (m MultiObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool { | ||||
| 	for _, t := range m { | ||||
| 		if t.Recognizes(gvk) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // SetZeroValue would set the object of objPtr to zero value of its type. | ||||
| func SetZeroValue(objPtr Object) error { | ||||
| 	v, err := conversion.EnforcePtr(objPtr) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	v.Set(reflect.Zero(v.Type())) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DefaultFramer is valid for any stream that can read objects serially without | ||||
| // any separation in the stream. | ||||
| var DefaultFramer = defaultFramer{} | ||||
|  | ||||
| type defaultFramer struct{} | ||||
|  | ||||
| func (defaultFramer) NewFrameReader(r io.ReadCloser) io.ReadCloser { return r } | ||||
| func (defaultFramer) NewFrameWriter(w io.Writer) io.Writer         { return w } | ||||
							
								
								
									
										252
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,252 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// APIVersionInternal may be used if you are registering a type that should not | ||||
| 	// be considered stable or serialized - it is a convention only and has no | ||||
| 	// special behavior in this package. | ||||
| 	APIVersionInternal = "__internal" | ||||
| ) | ||||
|  | ||||
| // GroupVersioner refines a set of possible conversion targets into a single option. | ||||
| type GroupVersioner interface { | ||||
| 	// KindForGroupVersionKinds returns a desired target group version kind for the given input, or returns ok false if no | ||||
| 	// target is known. In general, if the return target is not in the input list, the caller is expected to invoke | ||||
| 	// Scheme.New(target) and then perform a conversion between the current Go type and the destination Go type. | ||||
| 	// Sophisticated implementations may use additional information about the input kinds to pick a destination kind. | ||||
| 	KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (target schema.GroupVersionKind, ok bool) | ||||
| } | ||||
|  | ||||
| // Encoder writes objects to a serialized form | ||||
| type Encoder interface { | ||||
| 	// Encode writes an object to a stream. Implementations may return errors if the versions are | ||||
| 	// incompatible, or if no conversion is defined. | ||||
| 	Encode(obj Object, w io.Writer) error | ||||
| } | ||||
|  | ||||
| // Decoder attempts to load an object from data. | ||||
| type Decoder interface { | ||||
| 	// Decode attempts to deserialize the provided data using either the innate typing of the scheme or the | ||||
| 	// default kind, group, and version provided. It returns a decoded object as well as the kind, group, and | ||||
| 	// version from the serialized data, or an error. If into is non-nil, it will be used as the target type | ||||
| 	// and implementations may choose to use it rather than reallocating an object. However, the object is not | ||||
| 	// guaranteed to be populated. The returned object is not guaranteed to match into. If defaults are | ||||
| 	// provided, they are applied to the data by default. If no defaults or partial defaults are provided, the | ||||
| 	// type of the into may be used to guide conversion decisions. | ||||
| 	Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) | ||||
| } | ||||
|  | ||||
| // Serializer is the core interface for transforming objects into a serialized format and back. | ||||
| // Implementations may choose to perform conversion of the object, but no assumptions should be made. | ||||
| type Serializer interface { | ||||
| 	Encoder | ||||
| 	Decoder | ||||
| } | ||||
|  | ||||
| // Codec is a Serializer that deals with the details of versioning objects. It offers the same | ||||
| // interface as Serializer, so this is a marker to consumers that care about the version of the objects | ||||
| // they receive. | ||||
| type Codec Serializer | ||||
|  | ||||
| // ParameterCodec defines methods for serializing and deserializing API objects to url.Values and | ||||
| // performing any necessary conversion. Unlike the normal Codec, query parameters are not self describing | ||||
| // and the desired version must be specified. | ||||
| type ParameterCodec interface { | ||||
| 	// DecodeParameters takes the given url.Values in the specified group version and decodes them | ||||
| 	// into the provided object, or returns an error. | ||||
| 	DecodeParameters(parameters url.Values, from schema.GroupVersion, into Object) error | ||||
| 	// EncodeParameters encodes the provided object as query parameters or returns an error. | ||||
| 	EncodeParameters(obj Object, to schema.GroupVersion) (url.Values, error) | ||||
| } | ||||
|  | ||||
| // Framer is a factory for creating readers and writers that obey a particular framing pattern. | ||||
| type Framer interface { | ||||
| 	NewFrameReader(r io.ReadCloser) io.ReadCloser | ||||
| 	NewFrameWriter(w io.Writer) io.Writer | ||||
| } | ||||
|  | ||||
| // SerializerInfo contains information about a specific serialization format | ||||
| type SerializerInfo struct { | ||||
| 	// MediaType is the value that represents this serializer over the wire. | ||||
| 	MediaType string | ||||
| 	// EncodesAsText indicates this serializer can be encoded to UTF-8 safely. | ||||
| 	EncodesAsText bool | ||||
| 	// Serializer is the individual object serializer for this media type. | ||||
| 	Serializer Serializer | ||||
| 	// PrettySerializer, if set, can serialize this object in a form biased towards | ||||
| 	// readability. | ||||
| 	PrettySerializer Serializer | ||||
| 	// StreamSerializer, if set, describes the streaming serialization format | ||||
| 	// for this media type. | ||||
| 	StreamSerializer *StreamSerializerInfo | ||||
| } | ||||
|  | ||||
| // StreamSerializerInfo contains information about a specific stream serialization format | ||||
| type StreamSerializerInfo struct { | ||||
| 	// EncodesAsText indicates this serializer can be encoded to UTF-8 safely. | ||||
| 	EncodesAsText bool | ||||
| 	// Serializer is the top level object serializer for this type when streaming | ||||
| 	Serializer | ||||
| 	// Framer is the factory for retrieving streams that separate objects on the wire | ||||
| 	Framer | ||||
| } | ||||
|  | ||||
| // NegotiatedSerializer is an interface used for obtaining encoders, decoders, and serializers | ||||
| // for multiple supported media types. This would commonly be accepted by a server component | ||||
| // that performs HTTP content negotiation to accept multiple formats. | ||||
| type NegotiatedSerializer interface { | ||||
| 	// SupportedMediaTypes is the media types supported for reading and writing single objects. | ||||
| 	SupportedMediaTypes() []SerializerInfo | ||||
|  | ||||
| 	// EncoderForVersion returns an encoder that ensures objects being written to the provided | ||||
| 	// serializer are in the provided group version. | ||||
| 	EncoderForVersion(serializer Encoder, gv GroupVersioner) Encoder | ||||
| 	// DecoderForVersion returns a decoder that ensures objects being read by the provided | ||||
| 	// serializer are in the provided group version by default. | ||||
| 	DecoderToVersion(serializer Decoder, gv GroupVersioner) Decoder | ||||
| } | ||||
|  | ||||
| // StorageSerializer is an interface used for obtaining encoders, decoders, and serializers | ||||
| // that can read and write data at rest. This would commonly be used by client tools that must | ||||
| // read files, or server side storage interfaces that persist restful objects. | ||||
| type StorageSerializer interface { | ||||
| 	// SupportedMediaTypes are the media types supported for reading and writing objects. | ||||
| 	SupportedMediaTypes() []SerializerInfo | ||||
|  | ||||
| 	// UniversalDeserializer returns a Serializer that can read objects in multiple supported formats | ||||
| 	// by introspecting the data at rest. | ||||
| 	UniversalDeserializer() Decoder | ||||
|  | ||||
| 	// EncoderForVersion returns an encoder that ensures objects being written to the provided | ||||
| 	// serializer are in the provided group version. | ||||
| 	EncoderForVersion(serializer Encoder, gv GroupVersioner) Encoder | ||||
| 	// DecoderForVersion returns a decoder that ensures objects being read by the provided | ||||
| 	// serializer are in the provided group version by default. | ||||
| 	DecoderToVersion(serializer Decoder, gv GroupVersioner) Decoder | ||||
| } | ||||
|  | ||||
| // NestedObjectEncoder is an optional interface that objects may implement to be given | ||||
| // an opportunity to encode any nested Objects / RawExtensions during serialization. | ||||
| type NestedObjectEncoder interface { | ||||
| 	EncodeNestedObjects(e Encoder) error | ||||
| } | ||||
|  | ||||
| // NestedObjectDecoder is an optional interface that objects may implement to be given | ||||
| // an opportunity to decode any nested Objects / RawExtensions during serialization. | ||||
| type NestedObjectDecoder interface { | ||||
| 	DecodeNestedObjects(d Decoder) error | ||||
| } | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| // Non-codec interfaces | ||||
|  | ||||
| type ObjectDefaulter interface { | ||||
| 	// Default takes an object (must be a pointer) and applies any default values. | ||||
| 	// Defaulters may not error. | ||||
| 	Default(in Object) | ||||
| } | ||||
|  | ||||
| type ObjectVersioner interface { | ||||
| 	ConvertToVersion(in Object, gv GroupVersioner) (out Object, err error) | ||||
| } | ||||
|  | ||||
| // ObjectConvertor converts an object to a different version. | ||||
| type ObjectConvertor interface { | ||||
| 	// Convert attempts to convert one object into another, or returns an error. This | ||||
| 	// method does not mutate the in object, but the in and out object might share data structures, | ||||
| 	// i.e. the out object cannot be mutated without mutating the in object as well. | ||||
| 	// The context argument will be passed to all nested conversions. | ||||
| 	Convert(in, out, context interface{}) error | ||||
| 	// ConvertToVersion takes the provided object and converts it the provided version. This | ||||
| 	// method does not mutate the in object, but the in and out object might share data structures, | ||||
| 	// i.e. the out object cannot be mutated without mutating the in object as well. | ||||
| 	// This method is similar to Convert() but handles specific details of choosing the correct | ||||
| 	// output version. | ||||
| 	ConvertToVersion(in Object, gv GroupVersioner) (out Object, err error) | ||||
| 	ConvertFieldLabel(gvk schema.GroupVersionKind, label, value string) (string, string, error) | ||||
| } | ||||
|  | ||||
| // ObjectTyper contains methods for extracting the APIVersion and Kind | ||||
| // of objects. | ||||
| type ObjectTyper interface { | ||||
| 	// ObjectKinds returns the all possible group,version,kind of the provided object, true if | ||||
| 	// the object is unversioned, or an error if the object is not recognized | ||||
| 	// (IsNotRegisteredError will return true). | ||||
| 	ObjectKinds(Object) ([]schema.GroupVersionKind, bool, error) | ||||
| 	// Recognizes returns true if the scheme is able to handle the provided version and kind, | ||||
| 	// or more precisely that the provided version is a possible conversion or decoding | ||||
| 	// target. | ||||
| 	Recognizes(gvk schema.GroupVersionKind) bool | ||||
| } | ||||
|  | ||||
| // ObjectCreater contains methods for instantiating an object by kind and version. | ||||
| type ObjectCreater interface { | ||||
| 	New(kind schema.GroupVersionKind) (out Object, err error) | ||||
| } | ||||
|  | ||||
| // ResourceVersioner provides methods for setting and retrieving | ||||
| // the resource version from an API object. | ||||
| type ResourceVersioner interface { | ||||
| 	SetResourceVersion(obj Object, version string) error | ||||
| 	ResourceVersion(obj Object) (string, error) | ||||
| } | ||||
|  | ||||
| // SelfLinker provides methods for setting and retrieving the SelfLink field of an API object. | ||||
| type SelfLinker interface { | ||||
| 	SetSelfLink(obj Object, selfLink string) error | ||||
| 	SelfLink(obj Object) (string, error) | ||||
|  | ||||
| 	// Knowing Name is sometimes necessary to use a SelfLinker. | ||||
| 	Name(obj Object) (string, error) | ||||
| 	// Knowing Namespace is sometimes necessary to use a SelfLinker | ||||
| 	Namespace(obj Object) (string, error) | ||||
| } | ||||
|  | ||||
| // Object interface must be supported by all API types registered with Scheme. Since objects in a scheme are | ||||
| // expected to be serialized to the wire, the interface an Object must provide to the Scheme allows | ||||
| // serializers to set the kind, version, and group the object is represented as. An Object may choose | ||||
| // to return a no-op ObjectKindAccessor in cases where it is not expected to be serialized. | ||||
| type Object interface { | ||||
| 	GetObjectKind() schema.ObjectKind | ||||
| 	DeepCopyObject() Object | ||||
| } | ||||
|  | ||||
| // Unstructured objects store values as map[string]interface{}, with only values that can be serialized | ||||
| // to JSON allowed. | ||||
| type Unstructured interface { | ||||
| 	Object | ||||
| 	// UnstructuredContent returns a non-nil map with this object's contents. Values may be | ||||
| 	// []interface{}, map[string]interface{}, or any primitive type. Contents are typically serialized to | ||||
| 	// and from JSON. SetUnstructuredContent should be used to mutate the contents. | ||||
| 	UnstructuredContent() map[string]interface{} | ||||
| 	// SetUnstructuredContent updates the object content to match the provided map. | ||||
| 	SetUnstructuredContent(map[string]interface{}) | ||||
| 	// IsList returns true if this type is a list or matches the list convention - has an array called "items". | ||||
| 	IsList() bool | ||||
| 	// EachListItem should pass a single item out of the list as an Object to the provided function. Any | ||||
| 	// error should terminate the iteration. If IsList() returns false, this method should return an error | ||||
| 	// instead of calling the provided function. | ||||
| 	EachListItem(func(Object) error) error | ||||
| } | ||||
							
								
								
									
										61
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/register.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/register.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import "k8s.io/apimachinery/pkg/runtime/schema" | ||||
|  | ||||
| // SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta | ||||
| func (obj *TypeMeta) SetGroupVersionKind(gvk schema.GroupVersionKind) { | ||||
| 	obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() | ||||
| } | ||||
|  | ||||
| // GroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta | ||||
| func (obj *TypeMeta) GroupVersionKind() schema.GroupVersionKind { | ||||
| 	return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) | ||||
| } | ||||
|  | ||||
| func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj } | ||||
|  | ||||
| // GetObjectKind implements Object for VersionedObjects, returning an empty ObjectKind | ||||
| // interface if no objects are provided, or the ObjectKind interface of the object in the | ||||
| // highest array position. | ||||
| func (obj *VersionedObjects) GetObjectKind() schema.ObjectKind { | ||||
| 	last := obj.Last() | ||||
| 	if last == nil { | ||||
| 		return schema.EmptyObjectKind | ||||
| 	} | ||||
| 	return last.GetObjectKind() | ||||
| } | ||||
|  | ||||
| // First returns the leftmost object in the VersionedObjects array, which is usually the | ||||
| // object as serialized on the wire. | ||||
| func (obj *VersionedObjects) First() Object { | ||||
| 	if len(obj.Objects) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return obj.Objects[0] | ||||
| } | ||||
|  | ||||
| // Last is the rightmost object in the VersionedObjects array, which is the object after | ||||
| // all transformations have been applied. This is the same object that would be returned | ||||
| // by Decode in a normal invocation (without VersionedObjects in the into argument). | ||||
| func (obj *VersionedObjects) Last() Object { | ||||
| 	if len(obj.Objects) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return obj.Objects[len(obj.Objects)-1] | ||||
| } | ||||
							
								
								
									
										63
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| /* | ||||
| Copyright 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. | ||||
| */ | ||||
|  | ||||
| // Code generated by protoc-gen-gogo. DO NOT EDIT. | ||||
| // source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto | ||||
|  | ||||
| /* | ||||
| Package schema is a generated protocol buffer package. | ||||
|  | ||||
| It is generated from these files: | ||||
| 	k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto | ||||
|  | ||||
| It has these top-level messages: | ||||
| */ | ||||
| package schema | ||||
|  | ||||
| import proto "github.com/gogo/protobuf/proto" | ||||
| import fmt "fmt" | ||||
| import math "math" | ||||
|  | ||||
| // Reference imports to suppress errors if they are not otherwise used. | ||||
| var _ = proto.Marshal | ||||
| var _ = fmt.Errorf | ||||
| var _ = math.Inf | ||||
|  | ||||
| // This is a compile-time assertion to ensure that this generated file | ||||
| // is compatible with the proto package it is being compiled against. | ||||
| // A compilation error at this line likely means your copy of the | ||||
| // proto package needs to be updated. | ||||
| const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package | ||||
|  | ||||
| func init() { | ||||
| 	proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto", fileDescriptorGenerated) | ||||
| } | ||||
|  | ||||
| var fileDescriptorGenerated = []byte{ | ||||
| 	// 185 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0xcc, 0xaf, 0x6e, 0xc3, 0x30, | ||||
| 	0x10, 0xc7, 0x71, 0x9b, 0x0c, 0x0c, 0x0e, 0x0e, 0x1c, 0x1c, 0xda, 0x7c, 0x74, 0xb8, 0x2f, 0x50, | ||||
| 	0x5e, 0xe6, 0x24, 0x57, 0xc7, 0xb2, 0xfc, 0x47, 0x8e, 0x5d, 0xa9, 0xac, 0x8f, 0xd0, 0xc7, 0x0a, | ||||
| 	0x0c, 0x0c, 0x6c, 0xdc, 0x17, 0xa9, 0x64, 0x07, 0x94, 0xdd, 0x4f, 0xa7, 0xcf, 0xf7, 0xf3, 0x68, | ||||
| 	0xfe, 0x27, 0xa1, 0x3d, 0x9a, 0xdc, 0x51, 0x74, 0x94, 0x68, 0xc2, 0x0b, 0xb9, 0xc1, 0x47, 0xdc, | ||||
| 	0x1f, 0x32, 0x68, 0x2b, 0xfb, 0x51, 0x3b, 0x8a, 0x57, 0x0c, 0x46, 0x61, 0xcc, 0x2e, 0x69, 0x4b, | ||||
| 	0x38, 0xf5, 0x23, 0x59, 0x89, 0x8a, 0x1c, 0x45, 0x99, 0x68, 0x10, 0x21, 0xfa, 0xe4, 0xbf, 0x7e, | ||||
| 	0x9a, 0x13, 0xef, 0x4e, 0x04, 0xa3, 0xc4, 0xee, 0x44, 0x73, 0xdf, 0x7f, 0x4a, 0xa7, 0x31, 0x77, | ||||
| 	0xa2, 0xf7, 0x16, 0x95, 0x57, 0x1e, 0x2b, 0xef, 0xf2, 0xb9, 0xae, 0x3a, 0xea, 0xd5, 0xb2, 0x87, | ||||
| 	0xdf, 0x79, 0x03, 0xb6, 0x6c, 0xc0, 0xd6, 0x0d, 0xd8, 0xad, 0x00, 0x9f, 0x0b, 0xf0, 0xa5, 0x00, | ||||
| 	0x5f, 0x0b, 0xf0, 0x47, 0x01, 0x7e, 0x7f, 0x02, 0x3b, 0x7d, 0xb4, 0xf8, 0x2b, 0x00, 0x00, 0xff, | ||||
| 	0xff, 0xba, 0x7e, 0x65, 0xf4, 0xd6, 0x00, 0x00, 0x00, | ||||
| } | ||||
							
								
								
									
										26
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* | ||||
| Copyright 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. | ||||
| */ | ||||
|  | ||||
|  | ||||
| // This file was autogenerated by go-to-protobuf. Do not edit it manually! | ||||
|  | ||||
| syntax = 'proto2'; | ||||
|  | ||||
| package k8s.io.apimachinery.pkg.runtime.schema; | ||||
|  | ||||
| // Package-wide variables from generator "generated". | ||||
| option go_package = "schema"; | ||||
|  | ||||
							
								
								
									
										300
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,300 @@ | ||||
| /* | ||||
| 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 schema | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // ParseResourceArg takes the common style of string which may be either `resource.group.com` or `resource.version.group.com` | ||||
| // and parses it out into both possibilities.  This code takes no responsibility for knowing which representation was intended | ||||
| // but with a knowledge of all GroupVersions, calling code can take a very good guess.  If there are only two segments, then | ||||
| // `*GroupVersionResource` is nil. | ||||
| // `resource.group.com` -> `group=com, version=group, resource=resource` and `group=group.com, resource=resource` | ||||
| func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) { | ||||
| 	var gvr *GroupVersionResource | ||||
| 	if strings.Count(arg, ".") >= 2 { | ||||
| 		s := strings.SplitN(arg, ".", 3) | ||||
| 		gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]} | ||||
| 	} | ||||
|  | ||||
| 	return gvr, ParseGroupResource(arg) | ||||
| } | ||||
|  | ||||
| // ParseKindArg takes the common style of string which may be either `Kind.group.com` or `Kind.version.group.com` | ||||
| // and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended | ||||
| // but with a knowledge of all GroupKinds, calling code can take a very good guess. If there are only two segments, then | ||||
| // `*GroupVersionResource` is nil. | ||||
| // `Kind.group.com` -> `group=com, version=group, kind=Kind` and `group=group.com, kind=Kind` | ||||
| func ParseKindArg(arg string) (*GroupVersionKind, GroupKind) { | ||||
| 	var gvk *GroupVersionKind | ||||
| 	if strings.Count(arg, ".") >= 2 { | ||||
| 		s := strings.SplitN(arg, ".", 3) | ||||
| 		gvk = &GroupVersionKind{Group: s[2], Version: s[1], Kind: s[0]} | ||||
| 	} | ||||
|  | ||||
| 	return gvk, ParseGroupKind(arg) | ||||
| } | ||||
|  | ||||
| // GroupResource specifies a Group and a Resource, but does not force a version.  This is useful for identifying | ||||
| // concepts during lookup stages without having partially valid types | ||||
| type GroupResource struct { | ||||
| 	Group    string | ||||
| 	Resource string | ||||
| } | ||||
|  | ||||
| func (gr GroupResource) WithVersion(version string) GroupVersionResource { | ||||
| 	return GroupVersionResource{Group: gr.Group, Version: version, Resource: gr.Resource} | ||||
| } | ||||
|  | ||||
| func (gr GroupResource) Empty() bool { | ||||
| 	return len(gr.Group) == 0 && len(gr.Resource) == 0 | ||||
| } | ||||
|  | ||||
| func (gr GroupResource) String() string { | ||||
| 	if len(gr.Group) == 0 { | ||||
| 		return gr.Resource | ||||
| 	} | ||||
| 	return gr.Resource + "." + gr.Group | ||||
| } | ||||
|  | ||||
| func ParseGroupKind(gk string) GroupKind { | ||||
| 	i := strings.Index(gk, ".") | ||||
| 	if i == -1 { | ||||
| 		return GroupKind{Kind: gk} | ||||
| 	} | ||||
|  | ||||
| 	return GroupKind{Group: gk[i+1:], Kind: gk[:i]} | ||||
| } | ||||
|  | ||||
| // ParseGroupResource turns "resource.group" string into a GroupResource struct.  Empty strings are allowed | ||||
| // for each field. | ||||
| func ParseGroupResource(gr string) GroupResource { | ||||
| 	if i := strings.Index(gr, "."); i >= 0 { | ||||
| 		return GroupResource{Group: gr[i+1:], Resource: gr[:i]} | ||||
| 	} | ||||
| 	return GroupResource{Resource: gr} | ||||
| } | ||||
|  | ||||
| // GroupVersionResource unambiguously identifies a resource.  It doesn't anonymously include GroupVersion | ||||
| // to avoid automatic coercion.  It doesn't use a GroupVersion to avoid custom marshalling | ||||
| type GroupVersionResource struct { | ||||
| 	Group    string | ||||
| 	Version  string | ||||
| 	Resource string | ||||
| } | ||||
|  | ||||
| func (gvr GroupVersionResource) Empty() bool { | ||||
| 	return len(gvr.Group) == 0 && len(gvr.Version) == 0 && len(gvr.Resource) == 0 | ||||
| } | ||||
|  | ||||
| func (gvr GroupVersionResource) GroupResource() GroupResource { | ||||
| 	return GroupResource{Group: gvr.Group, Resource: gvr.Resource} | ||||
| } | ||||
|  | ||||
| func (gvr GroupVersionResource) GroupVersion() GroupVersion { | ||||
| 	return GroupVersion{Group: gvr.Group, Version: gvr.Version} | ||||
| } | ||||
|  | ||||
| func (gvr GroupVersionResource) String() string { | ||||
| 	return strings.Join([]string{gvr.Group, "/", gvr.Version, ", Resource=", gvr.Resource}, "") | ||||
| } | ||||
|  | ||||
| // GroupKind specifies a Group and a Kind, but does not force a version.  This is useful for identifying | ||||
| // concepts during lookup stages without having partially valid types | ||||
| type GroupKind struct { | ||||
| 	Group string | ||||
| 	Kind  string | ||||
| } | ||||
|  | ||||
| func (gk GroupKind) Empty() bool { | ||||
| 	return len(gk.Group) == 0 && len(gk.Kind) == 0 | ||||
| } | ||||
|  | ||||
| func (gk GroupKind) WithVersion(version string) GroupVersionKind { | ||||
| 	return GroupVersionKind{Group: gk.Group, Version: version, Kind: gk.Kind} | ||||
| } | ||||
|  | ||||
| func (gk GroupKind) String() string { | ||||
| 	if len(gk.Group) == 0 { | ||||
| 		return gk.Kind | ||||
| 	} | ||||
| 	return gk.Kind + "." + gk.Group | ||||
| } | ||||
|  | ||||
| // GroupVersionKind unambiguously identifies a kind.  It doesn't anonymously include GroupVersion | ||||
| // to avoid automatic coercion.  It doesn't use a GroupVersion to avoid custom marshalling | ||||
| type GroupVersionKind struct { | ||||
| 	Group   string | ||||
| 	Version string | ||||
| 	Kind    string | ||||
| } | ||||
|  | ||||
| // Empty returns true if group, version, and kind are empty | ||||
| func (gvk GroupVersionKind) Empty() bool { | ||||
| 	return len(gvk.Group) == 0 && len(gvk.Version) == 0 && len(gvk.Kind) == 0 | ||||
| } | ||||
|  | ||||
| func (gvk GroupVersionKind) GroupKind() GroupKind { | ||||
| 	return GroupKind{Group: gvk.Group, Kind: gvk.Kind} | ||||
| } | ||||
|  | ||||
| func (gvk GroupVersionKind) GroupVersion() GroupVersion { | ||||
| 	return GroupVersion{Group: gvk.Group, Version: gvk.Version} | ||||
| } | ||||
|  | ||||
| func (gvk GroupVersionKind) String() string { | ||||
| 	return gvk.Group + "/" + gvk.Version + ", Kind=" + gvk.Kind | ||||
| } | ||||
|  | ||||
| // GroupVersion contains the "group" and the "version", which uniquely identifies the API. | ||||
| type GroupVersion struct { | ||||
| 	Group   string | ||||
| 	Version string | ||||
| } | ||||
|  | ||||
| // Empty returns true if group and version are empty | ||||
| func (gv GroupVersion) Empty() bool { | ||||
| 	return len(gv.Group) == 0 && len(gv.Version) == 0 | ||||
| } | ||||
|  | ||||
| // String puts "group" and "version" into a single "group/version" string. For the legacy v1 | ||||
| // it returns "v1". | ||||
| func (gv GroupVersion) String() string { | ||||
| 	// special case the internal apiVersion for the legacy kube types | ||||
| 	if gv.Empty() { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	// special case of "v1" for backward compatibility | ||||
| 	if len(gv.Group) == 0 && gv.Version == "v1" { | ||||
| 		return gv.Version | ||||
| 	} | ||||
| 	if len(gv.Group) > 0 { | ||||
| 		return gv.Group + "/" + gv.Version | ||||
| 	} | ||||
| 	return gv.Version | ||||
| } | ||||
|  | ||||
| // KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false | ||||
| // if none of the options match the group. It prefers a match to group and version over just group. | ||||
| // TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme. | ||||
| // TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion) | ||||
| //   in fewer places. | ||||
| func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) { | ||||
| 	for _, gvk := range kinds { | ||||
| 		if gvk.Group == gv.Group && gvk.Version == gv.Version { | ||||
| 			return gvk, true | ||||
| 		} | ||||
| 	} | ||||
| 	for _, gvk := range kinds { | ||||
| 		if gvk.Group == gv.Group { | ||||
| 			return gv.WithKind(gvk.Kind), true | ||||
| 		} | ||||
| 	} | ||||
| 	return GroupVersionKind{}, false | ||||
| } | ||||
|  | ||||
| // ParseGroupVersion turns "group/version" string into a GroupVersion struct. It reports error | ||||
| // if it cannot parse the string. | ||||
| func ParseGroupVersion(gv string) (GroupVersion, error) { | ||||
| 	// this can be the internal version for the legacy kube types | ||||
| 	// TODO once we've cleared the last uses as strings, this special case should be removed. | ||||
| 	if (len(gv) == 0) || (gv == "/") { | ||||
| 		return GroupVersion{}, nil | ||||
| 	} | ||||
|  | ||||
| 	switch strings.Count(gv, "/") { | ||||
| 	case 0: | ||||
| 		return GroupVersion{"", gv}, nil | ||||
| 	case 1: | ||||
| 		i := strings.Index(gv, "/") | ||||
| 		return GroupVersion{gv[:i], gv[i+1:]}, nil | ||||
| 	default: | ||||
| 		return GroupVersion{}, fmt.Errorf("unexpected GroupVersion string: %v", gv) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WithKind creates a GroupVersionKind based on the method receiver's GroupVersion and the passed Kind. | ||||
| func (gv GroupVersion) WithKind(kind string) GroupVersionKind { | ||||
| 	return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind} | ||||
| } | ||||
|  | ||||
| // WithResource creates a GroupVersionResource based on the method receiver's GroupVersion and the passed Resource. | ||||
| func (gv GroupVersion) WithResource(resource string) GroupVersionResource { | ||||
| 	return GroupVersionResource{Group: gv.Group, Version: gv.Version, Resource: resource} | ||||
| } | ||||
|  | ||||
| // GroupVersions can be used to represent a set of desired group versions. | ||||
| // TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme. | ||||
| // TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion) | ||||
| //   in fewer places. | ||||
| type GroupVersions []GroupVersion | ||||
|  | ||||
| // KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false | ||||
| // if none of the options match the group. | ||||
| func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (GroupVersionKind, bool) { | ||||
| 	var targets []GroupVersionKind | ||||
| 	for _, gv := range gvs { | ||||
| 		target, ok := gv.KindForGroupVersionKinds(kinds) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 		targets = append(targets, target) | ||||
| 	} | ||||
| 	if len(targets) == 1 { | ||||
| 		return targets[0], true | ||||
| 	} | ||||
| 	if len(targets) > 1 { | ||||
| 		return bestMatch(kinds, targets), true | ||||
| 	} | ||||
| 	return GroupVersionKind{}, false | ||||
| } | ||||
|  | ||||
| // bestMatch tries to pick best matching GroupVersionKind and falls back to the first | ||||
| // found if no exact match exists. | ||||
| func bestMatch(kinds []GroupVersionKind, targets []GroupVersionKind) GroupVersionKind { | ||||
| 	for _, gvk := range targets { | ||||
| 		for _, k := range kinds { | ||||
| 			if k == gvk { | ||||
| 				return k | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return targets[0] | ||||
| } | ||||
|  | ||||
| // ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that | ||||
| // do not use TypeMeta. | ||||
| func (gvk GroupVersionKind) ToAPIVersionAndKind() (string, string) { | ||||
| 	if gvk.Empty() { | ||||
| 		return "", "" | ||||
| 	} | ||||
| 	return gvk.GroupVersion().String(), gvk.Kind | ||||
| } | ||||
|  | ||||
| // FromAPIVersionAndKind returns a GVK representing the provided fields for types that | ||||
| // do not use TypeMeta. This method exists to support test types and legacy serializations | ||||
| // that have a distinct group and kind. | ||||
| // TODO: further reduce usage of this method. | ||||
| func FromAPIVersionAndKind(apiVersion, kind string) GroupVersionKind { | ||||
| 	if gv, err := ParseGroupVersion(apiVersion); err == nil { | ||||
| 		return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind} | ||||
| 	} | ||||
| 	return GroupVersionKind{Kind: kind} | ||||
| } | ||||
							
								
								
									
										40
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/interfaces.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/schema/interfaces.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
| 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 schema | ||||
|  | ||||
| // All objects that are serialized from a Scheme encode their type information. This interface is used | ||||
| // by serialization to set type information from the Scheme onto the serialized version of an object. | ||||
| // For objects that cannot be serialized or have unique requirements, this interface may be a no-op. | ||||
| type ObjectKind interface { | ||||
| 	// SetGroupVersionKind sets or clears the intended serialized kind of an object. Passing kind nil | ||||
| 	// should clear the current setting. | ||||
| 	SetGroupVersionKind(kind GroupVersionKind) | ||||
| 	// GroupVersionKind returns the stored group, version, and kind of an object, or nil if the object does | ||||
| 	// not expose or provide these fields. | ||||
| 	GroupVersionKind() GroupVersionKind | ||||
| } | ||||
|  | ||||
| // EmptyObjectKind implements the ObjectKind interface as a noop | ||||
| var EmptyObjectKind = emptyObjectKind{} | ||||
|  | ||||
| type emptyObjectKind struct{} | ||||
|  | ||||
| // SetGroupVersionKind implements the ObjectKind interface | ||||
| func (emptyObjectKind) SetGroupVersionKind(gvk GroupVersionKind) {} | ||||
|  | ||||
| // GroupVersionKind implements the ObjectKind interface | ||||
| func (emptyObjectKind) GroupVersionKind() GroupVersionKind { return GroupVersionKind{} } | ||||
							
								
								
									
										754
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										754
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,754 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/conversion" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| 	"k8s.io/apimachinery/pkg/util/naming" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| ) | ||||
|  | ||||
| // Scheme defines methods for serializing and deserializing API objects, a type | ||||
| // registry for converting group, version, and kind information to and from Go | ||||
| // schemas, and mappings between Go schemas of different versions. A scheme is the | ||||
| // foundation for a versioned API and versioned configuration over time. | ||||
| // | ||||
| // In a Scheme, a Type is a particular Go struct, a Version is a point-in-time | ||||
| // identifier for a particular representation of that Type (typically backwards | ||||
| // compatible), a Kind is the unique name for that Type within the Version, and a | ||||
| // Group identifies a set of Versions, Kinds, and Types that evolve over time. An | ||||
| // Unversioned Type is one that is not yet formally bound to a type and is promised | ||||
| // to be backwards compatible (effectively a "v1" of a Type that does not expect | ||||
| // to break in the future). | ||||
| // | ||||
| // Schemes are not expected to change at runtime and are only threadsafe after | ||||
| // registration is complete. | ||||
| type Scheme struct { | ||||
| 	// versionMap allows one to figure out the go type of an object with | ||||
| 	// the given version and name. | ||||
| 	gvkToType map[schema.GroupVersionKind]reflect.Type | ||||
|  | ||||
| 	// typeToGroupVersion allows one to find metadata for a given go object. | ||||
| 	// The reflect.Type we index by should *not* be a pointer. | ||||
| 	typeToGVK map[reflect.Type][]schema.GroupVersionKind | ||||
|  | ||||
| 	// unversionedTypes are transformed without conversion in ConvertToVersion. | ||||
| 	unversionedTypes map[reflect.Type]schema.GroupVersionKind | ||||
|  | ||||
| 	// unversionedKinds are the names of kinds that can be created in the context of any group | ||||
| 	// or version | ||||
| 	// TODO: resolve the status of unversioned types. | ||||
| 	unversionedKinds map[string]reflect.Type | ||||
|  | ||||
| 	// Map from version and resource to the corresponding func to convert | ||||
| 	// resource field labels in that version to internal version. | ||||
| 	fieldLabelConversionFuncs map[schema.GroupVersionKind]FieldLabelConversionFunc | ||||
|  | ||||
| 	// defaulterFuncs is an array of interfaces to be called with an object to provide defaulting | ||||
| 	// the provided object must be a pointer. | ||||
| 	defaulterFuncs map[reflect.Type]func(interface{}) | ||||
|  | ||||
| 	// converter stores all registered conversion functions. It also has | ||||
| 	// default converting behavior. | ||||
| 	converter *conversion.Converter | ||||
|  | ||||
| 	// versionPriority is a map of groups to ordered lists of versions for those groups indicating the | ||||
| 	// default priorities of these versions as registered in the scheme | ||||
| 	versionPriority map[string][]string | ||||
|  | ||||
| 	// observedVersions keeps track of the order we've seen versions during type registration | ||||
| 	observedVersions []schema.GroupVersion | ||||
|  | ||||
| 	// schemeName is the name of this scheme.  If you don't specify a name, the stack of the NewScheme caller will be used. | ||||
| 	// This is useful for error reporting to indicate the origin of the scheme. | ||||
| 	schemeName string | ||||
| } | ||||
|  | ||||
| // FieldLabelConversionFunc converts a field selector to internal representation. | ||||
| type FieldLabelConversionFunc func(label, value string) (internalLabel, internalValue string, err error) | ||||
|  | ||||
| // NewScheme creates a new Scheme. This scheme is pluggable by default. | ||||
| func NewScheme() *Scheme { | ||||
| 	s := &Scheme{ | ||||
| 		gvkToType:                 map[schema.GroupVersionKind]reflect.Type{}, | ||||
| 		typeToGVK:                 map[reflect.Type][]schema.GroupVersionKind{}, | ||||
| 		unversionedTypes:          map[reflect.Type]schema.GroupVersionKind{}, | ||||
| 		unversionedKinds:          map[string]reflect.Type{}, | ||||
| 		fieldLabelConversionFuncs: map[schema.GroupVersionKind]FieldLabelConversionFunc{}, | ||||
| 		defaulterFuncs:            map[reflect.Type]func(interface{}){}, | ||||
| 		versionPriority:           map[string][]string{}, | ||||
| 		schemeName:                naming.GetNameFromCallsite(internalPackages...), | ||||
| 	} | ||||
| 	s.converter = conversion.NewConverter(s.nameFunc) | ||||
|  | ||||
| 	utilruntime.Must(s.AddConversionFuncs(DefaultEmbeddedConversions()...)) | ||||
|  | ||||
| 	// Enable map[string][]string conversions by default | ||||
| 	utilruntime.Must(s.AddConversionFuncs(DefaultStringConversions...)) | ||||
| 	utilruntime.Must(s.RegisterInputDefaults(&map[string][]string{}, JSONKeyMapper, conversion.AllowDifferentFieldTypeNames|conversion.IgnoreMissingFields)) | ||||
| 	utilruntime.Must(s.RegisterInputDefaults(&url.Values{}, JSONKeyMapper, conversion.AllowDifferentFieldTypeNames|conversion.IgnoreMissingFields)) | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // nameFunc returns the name of the type that we wish to use to determine when two types attempt | ||||
| // a conversion. Defaults to the go name of the type if the type is not registered. | ||||
| func (s *Scheme) nameFunc(t reflect.Type) string { | ||||
| 	// find the preferred names for this type | ||||
| 	gvks, ok := s.typeToGVK[t] | ||||
| 	if !ok { | ||||
| 		return t.Name() | ||||
| 	} | ||||
|  | ||||
| 	for _, gvk := range gvks { | ||||
| 		internalGV := gvk.GroupVersion() | ||||
| 		internalGV.Version = APIVersionInternal // this is hacky and maybe should be passed in | ||||
| 		internalGVK := internalGV.WithKind(gvk.Kind) | ||||
|  | ||||
| 		if internalType, exists := s.gvkToType[internalGVK]; exists { | ||||
| 			return s.typeToGVK[internalType][0].Kind | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return gvks[0].Kind | ||||
| } | ||||
|  | ||||
| // fromScope gets the input version, desired output version, and desired Scheme | ||||
| // from a conversion.Scope. | ||||
| func (s *Scheme) fromScope(scope conversion.Scope) *Scheme { | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // Converter allows access to the converter for the scheme | ||||
| func (s *Scheme) Converter() *conversion.Converter { | ||||
| 	return s.converter | ||||
| } | ||||
|  | ||||
| // AddUnversionedTypes registers the provided types as "unversioned", which means that they follow special rules. | ||||
| // Whenever an object of this type is serialized, it is serialized with the provided group version and is not | ||||
| // converted. Thus unversioned objects are expected to remain backwards compatible forever, as if they were in an | ||||
| // API group and version that would never be updated. | ||||
| // | ||||
| // TODO: there is discussion about removing unversioned and replacing it with objects that are manifest into | ||||
| //   every version with particular schemas. Resolve this method at that point. | ||||
| func (s *Scheme) AddUnversionedTypes(version schema.GroupVersion, types ...Object) { | ||||
| 	s.addObservedVersion(version) | ||||
| 	s.AddKnownTypes(version, types...) | ||||
| 	for _, obj := range types { | ||||
| 		t := reflect.TypeOf(obj).Elem() | ||||
| 		gvk := version.WithKind(t.Name()) | ||||
| 		s.unversionedTypes[t] = gvk | ||||
| 		if old, ok := s.unversionedKinds[gvk.Kind]; ok && t != old { | ||||
| 			panic(fmt.Sprintf("%v.%v has already been registered as unversioned kind %q - kind name must be unique in scheme %q", old.PkgPath(), old.Name(), gvk, s.schemeName)) | ||||
| 		} | ||||
| 		s.unversionedKinds[gvk.Kind] = t | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // AddKnownTypes registers all types passed in 'types' as being members of version 'version'. | ||||
| // All objects passed to types should be pointers to structs. The name that go reports for | ||||
| // the struct becomes the "kind" field when encoding. Version may not be empty - use the | ||||
| // APIVersionInternal constant if you have a type that does not have a formal version. | ||||
| func (s *Scheme) AddKnownTypes(gv schema.GroupVersion, types ...Object) { | ||||
| 	s.addObservedVersion(gv) | ||||
| 	for _, obj := range types { | ||||
| 		t := reflect.TypeOf(obj) | ||||
| 		if t.Kind() != reflect.Ptr { | ||||
| 			panic("All types must be pointers to structs.") | ||||
| 		} | ||||
| 		t = t.Elem() | ||||
| 		s.AddKnownTypeWithName(gv.WithKind(t.Name()), obj) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // AddKnownTypeWithName is like AddKnownTypes, but it lets you specify what this type should | ||||
| // be encoded as. Useful for testing when you don't want to make multiple packages to define | ||||
| // your structs. Version may not be empty - use the APIVersionInternal constant if you have a | ||||
| // type that does not have a formal version. | ||||
| func (s *Scheme) AddKnownTypeWithName(gvk schema.GroupVersionKind, obj Object) { | ||||
| 	s.addObservedVersion(gvk.GroupVersion()) | ||||
| 	t := reflect.TypeOf(obj) | ||||
| 	if len(gvk.Version) == 0 { | ||||
| 		panic(fmt.Sprintf("version is required on all types: %s %v", gvk, t)) | ||||
| 	} | ||||
| 	if t.Kind() != reflect.Ptr { | ||||
| 		panic("All types must be pointers to structs.") | ||||
| 	} | ||||
| 	t = t.Elem() | ||||
| 	if t.Kind() != reflect.Struct { | ||||
| 		panic("All types must be pointers to structs.") | ||||
| 	} | ||||
|  | ||||
| 	if oldT, found := s.gvkToType[gvk]; found && oldT != t { | ||||
| 		panic(fmt.Sprintf("Double registration of different types for %v: old=%v.%v, new=%v.%v in scheme %q", gvk, oldT.PkgPath(), oldT.Name(), t.PkgPath(), t.Name(), s.schemeName)) | ||||
| 	} | ||||
|  | ||||
| 	s.gvkToType[gvk] = t | ||||
|  | ||||
| 	for _, existingGvk := range s.typeToGVK[t] { | ||||
| 		if existingGvk == gvk { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	s.typeToGVK[t] = append(s.typeToGVK[t], gvk) | ||||
| } | ||||
|  | ||||
| // KnownTypes returns the types known for the given version. | ||||
| func (s *Scheme) KnownTypes(gv schema.GroupVersion) map[string]reflect.Type { | ||||
| 	types := make(map[string]reflect.Type) | ||||
| 	for gvk, t := range s.gvkToType { | ||||
| 		if gv != gvk.GroupVersion() { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		types[gvk.Kind] = t | ||||
| 	} | ||||
| 	return types | ||||
| } | ||||
|  | ||||
| // AllKnownTypes returns the all known types. | ||||
| func (s *Scheme) AllKnownTypes() map[schema.GroupVersionKind]reflect.Type { | ||||
| 	return s.gvkToType | ||||
| } | ||||
|  | ||||
| // ObjectKinds returns all possible group,version,kind of the go object, true if the | ||||
| // object is considered unversioned, or an error if it's not a pointer or is unregistered. | ||||
| func (s *Scheme) ObjectKinds(obj Object) ([]schema.GroupVersionKind, bool, error) { | ||||
| 	// Unstructured objects are always considered to have their declared GVK | ||||
| 	if _, ok := obj.(Unstructured); ok { | ||||
| 		// we require that the GVK be populated in order to recognize the object | ||||
| 		gvk := obj.GetObjectKind().GroupVersionKind() | ||||
| 		if len(gvk.Kind) == 0 { | ||||
| 			return nil, false, NewMissingKindErr("unstructured object has no kind") | ||||
| 		} | ||||
| 		if len(gvk.Version) == 0 { | ||||
| 			return nil, false, NewMissingVersionErr("unstructured object has no version") | ||||
| 		} | ||||
| 		return []schema.GroupVersionKind{gvk}, false, nil | ||||
| 	} | ||||
|  | ||||
| 	v, err := conversion.EnforcePtr(obj) | ||||
| 	if err != nil { | ||||
| 		return nil, false, err | ||||
| 	} | ||||
| 	t := v.Type() | ||||
|  | ||||
| 	gvks, ok := s.typeToGVK[t] | ||||
| 	if !ok { | ||||
| 		return nil, false, NewNotRegisteredErrForType(s.schemeName, t) | ||||
| 	} | ||||
| 	_, unversionedType := s.unversionedTypes[t] | ||||
|  | ||||
| 	return gvks, unversionedType, nil | ||||
| } | ||||
|  | ||||
| // Recognizes returns true if the scheme is able to handle the provided group,version,kind | ||||
| // of an object. | ||||
| func (s *Scheme) Recognizes(gvk schema.GroupVersionKind) bool { | ||||
| 	_, exists := s.gvkToType[gvk] | ||||
| 	return exists | ||||
| } | ||||
|  | ||||
| func (s *Scheme) IsUnversioned(obj Object) (bool, bool) { | ||||
| 	v, err := conversion.EnforcePtr(obj) | ||||
| 	if err != nil { | ||||
| 		return false, false | ||||
| 	} | ||||
| 	t := v.Type() | ||||
|  | ||||
| 	if _, ok := s.typeToGVK[t]; !ok { | ||||
| 		return false, false | ||||
| 	} | ||||
| 	_, ok := s.unversionedTypes[t] | ||||
| 	return ok, true | ||||
| } | ||||
|  | ||||
| // New returns a new API object of the given version and name, or an error if it hasn't | ||||
| // been registered. The version and kind fields must be specified. | ||||
| func (s *Scheme) New(kind schema.GroupVersionKind) (Object, error) { | ||||
| 	if t, exists := s.gvkToType[kind]; exists { | ||||
| 		return reflect.New(t).Interface().(Object), nil | ||||
| 	} | ||||
|  | ||||
| 	if t, exists := s.unversionedKinds[kind.Kind]; exists { | ||||
| 		return reflect.New(t).Interface().(Object), nil | ||||
| 	} | ||||
| 	return nil, NewNotRegisteredErrForKind(s.schemeName, kind) | ||||
| } | ||||
|  | ||||
| // Log sets a logger on the scheme. For test purposes only | ||||
| func (s *Scheme) Log(l conversion.DebugLogger) { | ||||
| 	s.converter.Debug = l | ||||
| } | ||||
|  | ||||
| // AddIgnoredConversionType identifies a pair of types that should be skipped by | ||||
| // conversion (because the data inside them is explicitly dropped during | ||||
| // conversion). | ||||
| func (s *Scheme) AddIgnoredConversionType(from, to interface{}) error { | ||||
| 	return s.converter.RegisterIgnoredConversion(from, to) | ||||
| } | ||||
|  | ||||
| // AddConversionFuncs adds functions to the list of conversion functions. The given | ||||
| // functions should know how to convert between two of your API objects, or their | ||||
| // sub-objects. We deduce how to call these functions from the types of their two | ||||
| // parameters; see the comment for Converter.Register. | ||||
| // | ||||
| // Note that, if you need to copy sub-objects that didn't change, you can use the | ||||
| // conversion.Scope object that will be passed to your conversion function. | ||||
| // Additionally, all conversions started by Scheme will set the SrcVersion and | ||||
| // DestVersion fields on the Meta object. Example: | ||||
| // | ||||
| // s.AddConversionFuncs( | ||||
| //	func(in *InternalObject, out *ExternalObject, scope conversion.Scope) error { | ||||
| //		// You can depend on Meta() being non-nil, and this being set to | ||||
| //		// the source version, e.g., "" | ||||
| //		s.Meta().SrcVersion | ||||
| //		// You can depend on this being set to the destination version, | ||||
| //		// e.g., "v1". | ||||
| //		s.Meta().DestVersion | ||||
| //		// Call scope.Convert to copy sub-fields. | ||||
| //		s.Convert(&in.SubFieldThatMoved, &out.NewLocation.NewName, 0) | ||||
| //		return nil | ||||
| //	}, | ||||
| // ) | ||||
| // | ||||
| // (For more detail about conversion functions, see Converter.Register's comment.) | ||||
| // | ||||
| // Also note that the default behavior, if you don't add a conversion function, is to | ||||
| // sanely copy fields that have the same names and same type names. It's OK if the | ||||
| // destination type has extra fields, but it must not remove any. So you only need to | ||||
| // add conversion functions for things with changed/removed fields. | ||||
| func (s *Scheme) AddConversionFuncs(conversionFuncs ...interface{}) error { | ||||
| 	for _, f := range conversionFuncs { | ||||
| 		if err := s.converter.RegisterConversionFunc(f); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // AddConversionFunc registers a function that converts between a and b by passing objects of those | ||||
| // types to the provided function. The function *must* accept objects of a and b - this machinery will not enforce | ||||
| // any other guarantee. | ||||
| func (s *Scheme) AddConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error { | ||||
| 	return s.converter.RegisterUntypedConversionFunc(a, b, fn) | ||||
| } | ||||
|  | ||||
| // AddGeneratedConversionFunc registers a function that converts between a and b by passing objects of those | ||||
| // types to the provided function. The function *must* accept objects of a and b - this machinery will not enforce | ||||
| // any other guarantee. | ||||
| func (s *Scheme) AddGeneratedConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error { | ||||
| 	return s.converter.RegisterGeneratedUntypedConversionFunc(a, b, fn) | ||||
| } | ||||
|  | ||||
| // AddFieldLabelConversionFunc adds a conversion function to convert field selectors | ||||
| // of the given kind from the given version to internal version representation. | ||||
| func (s *Scheme) AddFieldLabelConversionFunc(gvk schema.GroupVersionKind, conversionFunc FieldLabelConversionFunc) error { | ||||
| 	s.fieldLabelConversionFuncs[gvk] = conversionFunc | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // RegisterInputDefaults sets the provided field mapping function and field matching | ||||
| // as the defaults for the provided input type.  The fn may be nil, in which case no | ||||
| // mapping will happen by default. Use this method to register a mechanism for handling | ||||
| // a specific input type in conversion, such as a map[string]string to structs. | ||||
| func (s *Scheme) RegisterInputDefaults(in interface{}, fn conversion.FieldMappingFunc, defaultFlags conversion.FieldMatchingFlags) error { | ||||
| 	return s.converter.RegisterInputDefaults(in, fn, defaultFlags) | ||||
| } | ||||
|  | ||||
| // AddTypeDefaultingFunc registers a function that is passed a pointer to an | ||||
| // object and can default fields on the object. These functions will be invoked | ||||
| // when Default() is called. The function will never be called unless the | ||||
| // defaulted object matches srcType. If this function is invoked twice with the | ||||
| // same srcType, the fn passed to the later call will be used instead. | ||||
| func (s *Scheme) AddTypeDefaultingFunc(srcType Object, fn func(interface{})) { | ||||
| 	s.defaulterFuncs[reflect.TypeOf(srcType)] = fn | ||||
| } | ||||
|  | ||||
| // Default sets defaults on the provided Object. | ||||
| func (s *Scheme) Default(src Object) { | ||||
| 	if fn, ok := s.defaulterFuncs[reflect.TypeOf(src)]; ok { | ||||
| 		fn(src) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Convert will attempt to convert in into out. Both must be pointers. For easy | ||||
| // testing of conversion functions. Returns an error if the conversion isn't | ||||
| // possible. You can call this with types that haven't been registered (for example, | ||||
| // a to test conversion of types that are nested within registered types). The | ||||
| // context interface is passed to the convertor. Convert also supports Unstructured | ||||
| // types and will convert them intelligently. | ||||
| func (s *Scheme) Convert(in, out interface{}, context interface{}) error { | ||||
| 	unstructuredIn, okIn := in.(Unstructured) | ||||
| 	unstructuredOut, okOut := out.(Unstructured) | ||||
| 	switch { | ||||
| 	case okIn && okOut: | ||||
| 		// converting unstructured input to an unstructured output is a straight copy - unstructured | ||||
| 		// is a "smart holder" and the contents are passed by reference between the two objects | ||||
| 		unstructuredOut.SetUnstructuredContent(unstructuredIn.UnstructuredContent()) | ||||
| 		return nil | ||||
|  | ||||
| 	case okOut: | ||||
| 		// if the output is an unstructured object, use the standard Go type to unstructured | ||||
| 		// conversion. The object must not be internal. | ||||
| 		obj, ok := in.(Object) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("unable to convert object type %T to Unstructured, must be a runtime.Object", in) | ||||
| 		} | ||||
| 		gvks, unversioned, err := s.ObjectKinds(obj) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		gvk := gvks[0] | ||||
|  | ||||
| 		// if no conversion is necessary, convert immediately | ||||
| 		if unversioned || gvk.Version != APIVersionInternal { | ||||
| 			content, err := DefaultUnstructuredConverter.ToUnstructured(in) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			unstructuredOut.SetUnstructuredContent(content) | ||||
| 			unstructuredOut.GetObjectKind().SetGroupVersionKind(gvk) | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		// attempt to convert the object to an external version first. | ||||
| 		target, ok := context.(GroupVersioner) | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("unable to convert the internal object type %T to Unstructured without providing a preferred version to convert to", in) | ||||
| 		} | ||||
| 		// Convert is implicitly unsafe, so we don't need to perform a safe conversion | ||||
| 		versioned, err := s.UnsafeConvertToVersion(obj, target) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		content, err := DefaultUnstructuredConverter.ToUnstructured(versioned) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		unstructuredOut.SetUnstructuredContent(content) | ||||
| 		return nil | ||||
|  | ||||
| 	case okIn: | ||||
| 		// converting an unstructured object to any type is modeled by first converting | ||||
| 		// the input to a versioned type, then running standard conversions | ||||
| 		typed, err := s.unstructuredToTyped(unstructuredIn) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		in = typed | ||||
| 	} | ||||
|  | ||||
| 	flags, meta := s.generateConvertMeta(in) | ||||
| 	meta.Context = context | ||||
| 	if flags == 0 { | ||||
| 		flags = conversion.AllowDifferentFieldTypeNames | ||||
| 	} | ||||
| 	return s.converter.Convert(in, out, flags, meta) | ||||
| } | ||||
|  | ||||
| // ConvertFieldLabel alters the given field label and value for an kind field selector from | ||||
| // versioned representation to an unversioned one or returns an error. | ||||
| func (s *Scheme) ConvertFieldLabel(gvk schema.GroupVersionKind, label, value string) (string, string, error) { | ||||
| 	conversionFunc, ok := s.fieldLabelConversionFuncs[gvk] | ||||
| 	if !ok { | ||||
| 		return DefaultMetaV1FieldSelectorConversion(label, value) | ||||
| 	} | ||||
| 	return conversionFunc(label, value) | ||||
| } | ||||
|  | ||||
| // ConvertToVersion attempts to convert an input object to its matching Kind in another | ||||
| // version within this scheme. Will return an error if the provided version does not | ||||
| // contain the inKind (or a mapping by name defined with AddKnownTypeWithName). Will also | ||||
| // return an error if the conversion does not result in a valid Object being | ||||
| // returned. Passes target down to the conversion methods as the Context on the scope. | ||||
| func (s *Scheme) ConvertToVersion(in Object, target GroupVersioner) (Object, error) { | ||||
| 	return s.convertToVersion(true, in, target) | ||||
| } | ||||
|  | ||||
| // UnsafeConvertToVersion will convert in to the provided target if such a conversion is possible, | ||||
| // but does not guarantee the output object does not share fields with the input object. It attempts to be as | ||||
| // efficient as possible when doing conversion. | ||||
| func (s *Scheme) UnsafeConvertToVersion(in Object, target GroupVersioner) (Object, error) { | ||||
| 	return s.convertToVersion(false, in, target) | ||||
| } | ||||
|  | ||||
| // convertToVersion handles conversion with an optional copy. | ||||
| func (s *Scheme) convertToVersion(copy bool, in Object, target GroupVersioner) (Object, error) { | ||||
| 	var t reflect.Type | ||||
|  | ||||
| 	if u, ok := in.(Unstructured); ok { | ||||
| 		typed, err := s.unstructuredToTyped(u) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		in = typed | ||||
| 		// unstructuredToTyped returns an Object, which must be a pointer to a struct. | ||||
| 		t = reflect.TypeOf(in).Elem() | ||||
|  | ||||
| 	} else { | ||||
| 		// determine the incoming kinds with as few allocations as possible. | ||||
| 		t = reflect.TypeOf(in) | ||||
| 		if t.Kind() != reflect.Ptr { | ||||
| 			return nil, fmt.Errorf("only pointer types may be converted: %v", t) | ||||
| 		} | ||||
| 		t = t.Elem() | ||||
| 		if t.Kind() != reflect.Struct { | ||||
| 			return nil, fmt.Errorf("only pointers to struct types may be converted: %v", t) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	kinds, ok := s.typeToGVK[t] | ||||
| 	if !ok || len(kinds) == 0 { | ||||
| 		return nil, NewNotRegisteredErrForType(s.schemeName, t) | ||||
| 	} | ||||
|  | ||||
| 	gvk, ok := target.KindForGroupVersionKinds(kinds) | ||||
| 	if !ok { | ||||
| 		// try to see if this type is listed as unversioned (for legacy support) | ||||
| 		// TODO: when we move to server API versions, we should completely remove the unversioned concept | ||||
| 		if unversionedKind, ok := s.unversionedTypes[t]; ok { | ||||
| 			if gvk, ok := target.KindForGroupVersionKinds([]schema.GroupVersionKind{unversionedKind}); ok { | ||||
| 				return copyAndSetTargetKind(copy, in, gvk) | ||||
| 			} | ||||
| 			return copyAndSetTargetKind(copy, in, unversionedKind) | ||||
| 		} | ||||
| 		return nil, NewNotRegisteredErrForTarget(s.schemeName, t, target) | ||||
| 	} | ||||
|  | ||||
| 	// target wants to use the existing type, set kind and return (no conversion necessary) | ||||
| 	for _, kind := range kinds { | ||||
| 		if gvk == kind { | ||||
| 			return copyAndSetTargetKind(copy, in, gvk) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// type is unversioned, no conversion necessary | ||||
| 	if unversionedKind, ok := s.unversionedTypes[t]; ok { | ||||
| 		if gvk, ok := target.KindForGroupVersionKinds([]schema.GroupVersionKind{unversionedKind}); ok { | ||||
| 			return copyAndSetTargetKind(copy, in, gvk) | ||||
| 		} | ||||
| 		return copyAndSetTargetKind(copy, in, unversionedKind) | ||||
| 	} | ||||
|  | ||||
| 	out, err := s.New(gvk) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if copy { | ||||
| 		in = in.DeepCopyObject() | ||||
| 	} | ||||
|  | ||||
| 	flags, meta := s.generateConvertMeta(in) | ||||
| 	meta.Context = target | ||||
| 	if err := s.converter.Convert(in, out, flags, meta); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	setTargetKind(out, gvk) | ||||
| 	return out, nil | ||||
| } | ||||
|  | ||||
| // unstructuredToTyped attempts to transform an unstructured object to a typed | ||||
| // object if possible. It will return an error if conversion is not possible, or the versioned | ||||
| // Go form of the object. Note that this conversion will lose fields. | ||||
| func (s *Scheme) unstructuredToTyped(in Unstructured) (Object, error) { | ||||
| 	// the type must be something we recognize | ||||
| 	gvks, _, err := s.ObjectKinds(in) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	typed, err := s.New(gvks[0]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := DefaultUnstructuredConverter.FromUnstructured(in.UnstructuredContent(), typed); err != nil { | ||||
| 		return nil, fmt.Errorf("unable to convert unstructured object to %v: %v", gvks[0], err) | ||||
| 	} | ||||
| 	return typed, nil | ||||
| } | ||||
|  | ||||
| // generateConvertMeta constructs the meta value we pass to Convert. | ||||
| func (s *Scheme) generateConvertMeta(in interface{}) (conversion.FieldMatchingFlags, *conversion.Meta) { | ||||
| 	return s.converter.DefaultMeta(reflect.TypeOf(in)) | ||||
| } | ||||
|  | ||||
| // copyAndSetTargetKind performs a conditional copy before returning the object, or an error if copy was not successful. | ||||
| func copyAndSetTargetKind(copy bool, obj Object, kind schema.GroupVersionKind) (Object, error) { | ||||
| 	if copy { | ||||
| 		obj = obj.DeepCopyObject() | ||||
| 	} | ||||
| 	setTargetKind(obj, kind) | ||||
| 	return obj, nil | ||||
| } | ||||
|  | ||||
| // setTargetKind sets the kind on an object, taking into account whether the target kind is the internal version. | ||||
| func setTargetKind(obj Object, kind schema.GroupVersionKind) { | ||||
| 	if kind.Version == APIVersionInternal { | ||||
| 		// internal is a special case | ||||
| 		// TODO: look at removing the need to special case this | ||||
| 		obj.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) | ||||
| 		return | ||||
| 	} | ||||
| 	obj.GetObjectKind().SetGroupVersionKind(kind) | ||||
| } | ||||
|  | ||||
| // SetVersionPriority allows specifying a precise order of priority. All specified versions must be in the same group, | ||||
| // and the specified order overwrites any previously specified order for this group | ||||
| func (s *Scheme) SetVersionPriority(versions ...schema.GroupVersion) error { | ||||
| 	groups := sets.String{} | ||||
| 	order := []string{} | ||||
| 	for _, version := range versions { | ||||
| 		if len(version.Version) == 0 || version.Version == APIVersionInternal { | ||||
| 			return fmt.Errorf("internal versions cannot be prioritized: %v", version) | ||||
| 		} | ||||
|  | ||||
| 		groups.Insert(version.Group) | ||||
| 		order = append(order, version.Version) | ||||
| 	} | ||||
| 	if len(groups) != 1 { | ||||
| 		return fmt.Errorf("must register versions for exactly one group: %v", strings.Join(groups.List(), ", ")) | ||||
| 	} | ||||
|  | ||||
| 	s.versionPriority[groups.List()[0]] = order | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // PrioritizedVersionsForGroup returns versions for a single group in priority order | ||||
| func (s *Scheme) PrioritizedVersionsForGroup(group string) []schema.GroupVersion { | ||||
| 	ret := []schema.GroupVersion{} | ||||
| 	for _, version := range s.versionPriority[group] { | ||||
| 		ret = append(ret, schema.GroupVersion{Group: group, Version: version}) | ||||
| 	} | ||||
| 	for _, observedVersion := range s.observedVersions { | ||||
| 		if observedVersion.Group != group { | ||||
| 			continue | ||||
| 		} | ||||
| 		found := false | ||||
| 		for _, existing := range ret { | ||||
| 			if existing == observedVersion { | ||||
| 				found = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if !found { | ||||
| 			ret = append(ret, observedVersion) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| // PrioritizedVersionsAllGroups returns all known versions in their priority order.  Groups are random, but | ||||
| // versions for a single group are prioritized | ||||
| func (s *Scheme) PrioritizedVersionsAllGroups() []schema.GroupVersion { | ||||
| 	ret := []schema.GroupVersion{} | ||||
| 	for group, versions := range s.versionPriority { | ||||
| 		for _, version := range versions { | ||||
| 			ret = append(ret, schema.GroupVersion{Group: group, Version: version}) | ||||
| 		} | ||||
| 	} | ||||
| 	for _, observedVersion := range s.observedVersions { | ||||
| 		found := false | ||||
| 		for _, existing := range ret { | ||||
| 			if existing == observedVersion { | ||||
| 				found = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if !found { | ||||
| 			ret = append(ret, observedVersion) | ||||
| 		} | ||||
| 	} | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| // PreferredVersionAllGroups returns the most preferred version for every group. | ||||
| // group ordering is random. | ||||
| func (s *Scheme) PreferredVersionAllGroups() []schema.GroupVersion { | ||||
| 	ret := []schema.GroupVersion{} | ||||
| 	for group, versions := range s.versionPriority { | ||||
| 		for _, version := range versions { | ||||
| 			ret = append(ret, schema.GroupVersion{Group: group, Version: version}) | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	for _, observedVersion := range s.observedVersions { | ||||
| 		found := false | ||||
| 		for _, existing := range ret { | ||||
| 			if existing.Group == observedVersion.Group { | ||||
| 				found = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if !found { | ||||
| 			ret = append(ret, observedVersion) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| // IsGroupRegistered returns true if types for the group have been registered with the scheme | ||||
| func (s *Scheme) IsGroupRegistered(group string) bool { | ||||
| 	for _, observedVersion := range s.observedVersions { | ||||
| 		if observedVersion.Group == group { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // IsVersionRegistered returns true if types for the version have been registered with the scheme | ||||
| func (s *Scheme) IsVersionRegistered(version schema.GroupVersion) bool { | ||||
| 	for _, observedVersion := range s.observedVersions { | ||||
| 		if observedVersion == version { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (s *Scheme) addObservedVersion(version schema.GroupVersion) { | ||||
| 	if len(version.Version) == 0 || version.Version == APIVersionInternal { | ||||
| 		return | ||||
| 	} | ||||
| 	for _, observedVersion := range s.observedVersions { | ||||
| 		if observedVersion == version { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	s.observedVersions = append(s.observedVersions, version) | ||||
| } | ||||
|  | ||||
| func (s *Scheme) Name() string { | ||||
| 	return s.schemeName | ||||
| } | ||||
|  | ||||
| // internalPackages are packages that ignored when creating a default reflector name. These packages are in the common | ||||
| // call chains to NewReflector, so they'd be low entropy names for reflectors | ||||
| var internalPackages = []string{"k8s.io/apimachinery/pkg/runtime/scheme.go"} | ||||
							
								
								
									
										48
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/scheme_builder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/scheme_builder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| // SchemeBuilder collects functions that add things to a scheme. It's to allow | ||||
| // code to compile without explicitly referencing generated types. You should | ||||
| // declare one in each package that will have generated deep copy or conversion | ||||
| // functions. | ||||
| type SchemeBuilder []func(*Scheme) error | ||||
|  | ||||
| // AddToScheme applies all the stored functions to the scheme. A non-nil error | ||||
| // indicates that one function failed and the attempt was abandoned. | ||||
| func (sb *SchemeBuilder) AddToScheme(s *Scheme) error { | ||||
| 	for _, f := range *sb { | ||||
| 		if err := f(s); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Register adds a scheme setup function to the list. | ||||
| func (sb *SchemeBuilder) Register(funcs ...func(*Scheme) error) { | ||||
| 	for _, f := range funcs { | ||||
| 		*sb = append(*sb, f) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewSchemeBuilder calls Register for you. | ||||
| func NewSchemeBuilder(funcs ...func(*Scheme) error) SchemeBuilder { | ||||
| 	var sb SchemeBuilder | ||||
| 	sb.Register(funcs...) | ||||
| 	return sb | ||||
| } | ||||
							
								
								
									
										237
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										303
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,303 @@ | ||||
| /* | ||||
| 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" | ||||
| 	"strconv" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	jsoniter "github.com/json-iterator/go" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"sigs.k8s.io/yaml" | ||||
|  | ||||
| 	"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{} | ||||
|  | ||||
| type customNumberExtension struct { | ||||
| 	jsoniter.DummyExtension | ||||
| } | ||||
|  | ||||
| func (cne *customNumberExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder { | ||||
| 	if typ.String() == "interface {}" { | ||||
| 		return customNumberDecoder{} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type customNumberDecoder struct { | ||||
| } | ||||
|  | ||||
| func (customNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { | ||||
| 	switch iter.WhatIsNext() { | ||||
| 	case jsoniter.NumberValue: | ||||
| 		var number jsoniter.Number | ||||
| 		iter.ReadVal(&number) | ||||
| 		i64, err := strconv.ParseInt(string(number), 10, 64) | ||||
| 		if err == nil { | ||||
| 			*(*interface{})(ptr) = i64 | ||||
| 			return | ||||
| 		} | ||||
| 		f64, err := strconv.ParseFloat(string(number), 64) | ||||
| 		if err == nil { | ||||
| 			*(*interface{})(ptr) = f64 | ||||
| 			return | ||||
| 		} | ||||
| 		iter.ReportError("DecodeNumber", err.Error()) | ||||
| 	default: | ||||
| 		*(*interface{})(ptr) = iter.Read() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // CaseSensitiveJsonIterator returns a jsoniterator API that's configured to be | ||||
| // case-sensitive when unmarshalling, and otherwise compatible with | ||||
| // the encoding/json standard library. | ||||
| func CaseSensitiveJsonIterator() jsoniter.API { | ||||
| 	config := jsoniter.Config{ | ||||
| 		EscapeHTML:             true, | ||||
| 		SortMapKeys:            true, | ||||
| 		ValidateJsonRawMessage: true, | ||||
| 		CaseSensitive:          true, | ||||
| 	}.Froze() | ||||
| 	// Force jsoniter to decode number to interface{} via int64/float64, if possible. | ||||
| 	config.RegisterExtension(&customNumberExtension{}) | ||||
| 	return config | ||||
| } | ||||
|  | ||||
| // Private copy of jsoniter to try to shield against possible mutations | ||||
| // from outside. Still does not protect from package level jsoniter.Register*() functions - someone calling them | ||||
| // in some other library will mess with every usage of the jsoniter library in the whole program. | ||||
| // See https://github.com/json-iterator/go/issues/265 | ||||
| var caseSensitiveJsonIterator = CaseSensitiveJsonIterator() | ||||
|  | ||||
| // 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 | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| // If into is nil or data's gvk different from into's gvk, it will generate a new Object with ObjectCreater.New(gvk) | ||||
| // On success or most errors, the method will return the calculated schema kind. | ||||
| // The gvk calculate priority will be originalData > default gvk > into | ||||
| 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 { | ||||
| 		*actual = gvkWithDefaults(*actual, *gvk) | ||||
| 	} | ||||
|  | ||||
| 	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 { | ||||
| 		_, isUnstructured := into.(runtime.Unstructured) | ||||
| 		types, _, err := s.typer.ObjectKinds(into) | ||||
| 		switch { | ||||
| 		case runtime.IsNotRegisteredError(err), isUnstructured: | ||||
| 			if err := caseSensitiveJsonIterator.Unmarshal(data, into); err != nil { | ||||
| 				return nil, actual, err | ||||
| 			} | ||||
| 			return into, actual, nil | ||||
| 		case err != nil: | ||||
| 			return nil, actual, err | ||||
| 		default: | ||||
| 			*actual = gvkWithDefaults(*actual, types[0]) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	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 := caseSensitiveJsonIterator.Unmarshal(data, 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 := caseSensitiveJsonIterator.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 := caseSensitiveJsonIterator.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) | ||||
| } | ||||
|  | ||||
| // YAMLFramer 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) | ||||
| } | ||||
							
								
								
									
										63
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
							
								
								
									
										43
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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" | ||||
							
								
								
									
										459
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,459 @@ | ||||
| /* | ||||
| 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(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 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) | ||||
| } | ||||
							
								
								
									
										48
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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) | ||||
| } | ||||
							
								
								
									
										127
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
							
								
								
									
										137
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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: 16 * 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 | ||||
| } | ||||
							
								
								
									
										282
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,282 @@ | ||||
| /* | ||||
| 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" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| ) | ||||
|  | ||||
| // 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, encodeVersion, decodeVersion, scheme.Name()) | ||||
| } | ||||
|  | ||||
| // 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, | ||||
| 	typer runtime.ObjectTyper, | ||||
| 	defaulter runtime.ObjectDefaulter, | ||||
| 	encodeVersion runtime.GroupVersioner, | ||||
| 	decodeVersion runtime.GroupVersioner, | ||||
| 	originalSchemeName string, | ||||
| ) runtime.Codec { | ||||
| 	internal := &codec{ | ||||
| 		encoder:   encoder, | ||||
| 		decoder:   decoder, | ||||
| 		convertor: convertor, | ||||
| 		creater:   creater, | ||||
| 		typer:     typer, | ||||
| 		defaulter: defaulter, | ||||
|  | ||||
| 		encodeVersion: encodeVersion, | ||||
| 		decodeVersion: decodeVersion, | ||||
|  | ||||
| 		originalSchemeName: originalSchemeName, | ||||
| 	} | ||||
| 	return internal | ||||
| } | ||||
|  | ||||
| type codec struct { | ||||
| 	encoder   runtime.Encoder | ||||
| 	decoder   runtime.Decoder | ||||
| 	convertor runtime.ObjectConvertor | ||||
| 	creater   runtime.ObjectCreater | ||||
| 	typer     runtime.ObjectTyper | ||||
| 	defaulter runtime.ObjectDefaulter | ||||
|  | ||||
| 	encodeVersion runtime.GroupVersioner | ||||
| 	decodeVersion runtime.GroupVersioner | ||||
|  | ||||
| 	// originalSchemeName is optional, but when filled in it holds the name of the scheme from which this codec originates | ||||
| 	originalSchemeName string | ||||
| } | ||||
|  | ||||
| // 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() | ||||
| 	} | ||||
|  | ||||
| 	// If the into object is unstructured and expresses an opinion about its group/version, | ||||
| 	// create a new instance of the type so we always exercise the conversion path (skips short-circuiting on `into == obj`) | ||||
| 	decodeInto := into | ||||
| 	if into != nil { | ||||
| 		if _, ok := into.(runtime.Unstructured); ok && !into.GetObjectKind().GroupVersionKind().GroupVersion().Empty() { | ||||
| 			decodeInto = reflect.New(reflect.TypeOf(into).Elem()).Interface().(runtime.Object) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	obj, gvk, err := c.decoder.Decode(data, defaultGVK, decodeInto) | ||||
| 	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 { | ||||
| 				versioned.Objects = []runtime.Object{obj.DeepCopyObject()} | ||||
| 			} | ||||
| 			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 | ||||
| 		versioned.Objects = []runtime.Object{obj.DeepCopyObject()} | ||||
| 	} | ||||
|  | ||||
| 	// 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 := obj.(type) { | ||||
| 	case *runtime.Unknown: | ||||
| 		return c.encoder.Encode(obj, w) | ||||
| 	case runtime.Unstructured: | ||||
| 		// An unstructured list can contain objects of multiple group version kinds. don't short-circuit just | ||||
| 		// because the top-level type matches our desired destination type. actually send the object to the converter | ||||
| 		// to give it a chance to convert the list items if needed. | ||||
| 		if _, ok := obj.(*unstructured.UnstructuredList); !ok { | ||||
| 			// avoid conversion roundtrip if GVK is the right one already or is empty (yes, this is a hack, but the old behaviour we rely on in kubectl) | ||||
| 			objGVK := obj.GetObjectKind().GroupVersionKind() | ||||
| 			if len(objGVK.Version) == 0 { | ||||
| 				return c.encoder.Encode(obj, w) | ||||
| 			} | ||||
| 			targetGVK, ok := c.encodeVersion.KindForGroupVersionKinds([]schema.GroupVersionKind{objGVK}) | ||||
| 			if !ok { | ||||
| 				return runtime.NewNotRegisteredGVKErrForTarget(c.originalSchemeName, objGVK, c.encodeVersion) | ||||
| 			} | ||||
| 			if targetGVK == objGVK { | ||||
| 				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{Version: c.encodeVersion, 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 | ||||
| } | ||||
							
								
								
									
										262
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,262 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"go/ast" | ||||
| 	"go/doc" | ||||
| 	"go/parser" | ||||
| 	"go/token" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // Pair of strings. We keed the name of fields and the doc | ||||
| type Pair struct { | ||||
| 	Name, Doc string | ||||
| } | ||||
|  | ||||
| // KubeTypes is an array to represent all available types in a parsed file. [0] is for the type itself | ||||
| type KubeTypes []Pair | ||||
|  | ||||
| func astFrom(filePath string) *doc.Package { | ||||
| 	fset := token.NewFileSet() | ||||
| 	m := make(map[string]*ast.File) | ||||
|  | ||||
| 	f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	m[filePath] = f | ||||
| 	apkg, _ := ast.NewPackage(fset, m, nil, nil) | ||||
|  | ||||
| 	return doc.New(apkg, "", 0) | ||||
| } | ||||
|  | ||||
| func fmtRawDoc(rawDoc string) string { | ||||
| 	var buffer bytes.Buffer | ||||
| 	delPrevChar := func() { | ||||
| 		if buffer.Len() > 0 { | ||||
| 			buffer.Truncate(buffer.Len() - 1) // Delete the last " " or "\n" | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Ignore all lines after --- | ||||
| 	rawDoc = strings.Split(rawDoc, "---")[0] | ||||
|  | ||||
| 	for _, line := range strings.Split(rawDoc, "\n") { | ||||
| 		line = strings.TrimRight(line, " ") | ||||
| 		leading := strings.TrimLeft(line, " ") | ||||
| 		switch { | ||||
| 		case len(line) == 0: // Keep paragraphs | ||||
| 			delPrevChar() | ||||
| 			buffer.WriteString("\n\n") | ||||
| 		case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs | ||||
| 		case strings.HasPrefix(leading, "+"): // Ignore instructions to the generators | ||||
| 		default: | ||||
| 			if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") { | ||||
| 				delPrevChar() | ||||
| 				line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-someting..." | ||||
| 			} else { | ||||
| 				line += " " | ||||
| 			} | ||||
| 			buffer.WriteString(line) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	postDoc := strings.TrimRight(buffer.String(), "\n") | ||||
| 	postDoc = strings.Replace(postDoc, "\\\"", "\"", -1) // replace user's \" to " | ||||
| 	postDoc = strings.Replace(postDoc, "\"", "\\\"", -1) // Escape " | ||||
| 	postDoc = strings.Replace(postDoc, "\n", "\\n", -1) | ||||
| 	postDoc = strings.Replace(postDoc, "\t", "\\t", -1) | ||||
|  | ||||
| 	return postDoc | ||||
| } | ||||
|  | ||||
| // fieldName returns the name of the field as it should appear in JSON format | ||||
| // "-" indicates that this field is not part of the JSON representation | ||||
| func fieldName(field *ast.Field) string { | ||||
| 	jsonTag := "" | ||||
| 	if field.Tag != nil { | ||||
| 		jsonTag = reflect.StructTag(field.Tag.Value[1 : len(field.Tag.Value)-1]).Get("json") // Delete first and last quotation | ||||
| 		if strings.Contains(jsonTag, "inline") { | ||||
| 			return "-" | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	jsonTag = strings.Split(jsonTag, ",")[0] // This can return "-" | ||||
| 	if jsonTag == "" { | ||||
| 		if field.Names != nil { | ||||
| 			return field.Names[0].Name | ||||
| 		} | ||||
| 		return field.Type.(*ast.Ident).Name | ||||
| 	} | ||||
| 	return jsonTag | ||||
| } | ||||
|  | ||||
| // A buffer of lines that will be written. | ||||
| type bufferedLine struct { | ||||
| 	line        string | ||||
| 	indentation int | ||||
| } | ||||
|  | ||||
| type buffer struct { | ||||
| 	lines []bufferedLine | ||||
| } | ||||
|  | ||||
| func newBuffer() *buffer { | ||||
| 	return &buffer{ | ||||
| 		lines: make([]bufferedLine, 0), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (b *buffer) addLine(line string, indent int) { | ||||
| 	b.lines = append(b.lines, bufferedLine{line, indent}) | ||||
| } | ||||
|  | ||||
| func (b *buffer) flushLines(w io.Writer) error { | ||||
| 	for _, line := range b.lines { | ||||
| 		indentation := strings.Repeat("\t", line.indentation) | ||||
| 		fullLine := fmt.Sprintf("%s%s", indentation, line.line) | ||||
| 		if _, err := io.WriteString(w, fullLine); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func writeFuncHeader(b *buffer, structName string, indent int) { | ||||
| 	s := fmt.Sprintf("var map_%s = map[string]string {\n", structName) | ||||
| 	b.addLine(s, indent) | ||||
| } | ||||
|  | ||||
| func writeFuncFooter(b *buffer, structName string, indent int) { | ||||
| 	b.addLine("}\n", indent) // Closes the map definition | ||||
|  | ||||
| 	s := fmt.Sprintf("func (%s) SwaggerDoc() map[string]string {\n", structName) | ||||
| 	b.addLine(s, indent) | ||||
| 	s = fmt.Sprintf("return map_%s\n", structName) | ||||
| 	b.addLine(s, indent+1) | ||||
| 	b.addLine("}\n", indent) // Closes the function definition | ||||
| } | ||||
|  | ||||
| func writeMapBody(b *buffer, kubeType []Pair, indent int) { | ||||
| 	format := "\"%s\": \"%s\",\n" | ||||
| 	for _, pair := range kubeType { | ||||
| 		s := fmt.Sprintf(format, pair.Name, pair.Doc) | ||||
| 		b.addLine(s, indent+2) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ParseDocumentationFrom gets all types' documentation and returns them as an | ||||
| // array. Each type is again represented as an array (we have to use arrays as we | ||||
| // need to be sure for the order of the fields). This function returns fields and | ||||
| // struct definitions that have no documentation as {name, ""}. | ||||
| func ParseDocumentationFrom(src string) []KubeTypes { | ||||
| 	var docForTypes []KubeTypes | ||||
|  | ||||
| 	pkg := astFrom(src) | ||||
|  | ||||
| 	for _, kubType := range pkg.Types { | ||||
| 		if structType, ok := kubType.Decl.Specs[0].(*ast.TypeSpec).Type.(*ast.StructType); ok { | ||||
| 			var ks KubeTypes | ||||
| 			ks = append(ks, Pair{kubType.Name, fmtRawDoc(kubType.Doc)}) | ||||
|  | ||||
| 			for _, field := range structType.Fields.List { | ||||
| 				if n := fieldName(field); n != "-" { | ||||
| 					fieldDoc := fmtRawDoc(field.Doc.Text()) | ||||
| 					ks = append(ks, Pair{n, fieldDoc}) | ||||
| 				} | ||||
| 			} | ||||
| 			docForTypes = append(docForTypes, ks) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return docForTypes | ||||
| } | ||||
|  | ||||
| // WriteSwaggerDocFunc writes a declaration of a function as a string. This function is used in | ||||
| // Swagger as a documentation source for structs and theirs fields | ||||
| func WriteSwaggerDocFunc(kubeTypes []KubeTypes, w io.Writer) error { | ||||
| 	for _, kubeType := range kubeTypes { | ||||
| 		structName := kubeType[0].Name | ||||
| 		kubeType[0].Name = "" | ||||
|  | ||||
| 		// Ignore empty documentation | ||||
| 		docfulTypes := make(KubeTypes, 0, len(kubeType)) | ||||
| 		for _, pair := range kubeType { | ||||
| 			if pair.Doc != "" { | ||||
| 				docfulTypes = append(docfulTypes, pair) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if len(docfulTypes) == 0 { | ||||
| 			continue // If no fields and the struct have documentation, skip the function definition | ||||
| 		} | ||||
|  | ||||
| 		indent := 0 | ||||
| 		buffer := newBuffer() | ||||
|  | ||||
| 		writeFuncHeader(buffer, structName, indent) | ||||
| 		writeMapBody(buffer, docfulTypes, indent) | ||||
| 		writeFuncFooter(buffer, structName, indent) | ||||
| 		buffer.addLine("\n", 0) | ||||
|  | ||||
| 		if err := buffer.flushLines(w); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VerifySwaggerDocsExist writes in a io.Writer a list of structs and fields that | ||||
| // are missing of documentation. | ||||
| func VerifySwaggerDocsExist(kubeTypes []KubeTypes, w io.Writer) (int, error) { | ||||
| 	missingDocs := 0 | ||||
| 	buffer := newBuffer() | ||||
|  | ||||
| 	for _, kubeType := range kubeTypes { | ||||
| 		structName := kubeType[0].Name | ||||
| 		if kubeType[0].Doc == "" { | ||||
| 			format := "Missing documentation for the struct itself: %s\n" | ||||
| 			s := fmt.Sprintf(format, structName) | ||||
| 			buffer.addLine(s, 0) | ||||
| 			missingDocs++ | ||||
| 		} | ||||
| 		kubeType = kubeType[1:] // Skip struct definition | ||||
|  | ||||
| 		for _, pair := range kubeType { // Iterate only the fields | ||||
| 			if pair.Doc == "" { | ||||
| 				format := "In struct: %s, field documentation is missing: %s\n" | ||||
| 				s := fmt.Sprintf(format, structName, pair.Name) | ||||
| 				buffer.addLine(s, 0) | ||||
| 				missingDocs++ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := buffer.flushLines(w); err != nil { | ||||
| 		return -1, err | ||||
| 	} | ||||
| 	return missingDocs, nil | ||||
| } | ||||
							
								
								
									
										137
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/types.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/types.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| // Note that the types provided in this file are not versioned and are intended to be | ||||
| // safe to use from within all versions of every API object. | ||||
|  | ||||
| // TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, | ||||
| // like this: | ||||
| // type MyAwesomeAPIObject struct { | ||||
| //      runtime.TypeMeta    `json:",inline"` | ||||
| //      ... // other fields | ||||
| // } | ||||
| // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind | ||||
| // | ||||
| // TypeMeta is provided here for convenience. You may use it directly from this package or define | ||||
| // your own with the same fields. | ||||
| // | ||||
| // +k8s:deepcopy-gen=false | ||||
| // +protobuf=true | ||||
| // +k8s:openapi-gen=true | ||||
| type TypeMeta struct { | ||||
| 	// +optional | ||||
| 	APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty" protobuf:"bytes,1,opt,name=apiVersion"` | ||||
| 	// +optional | ||||
| 	Kind string `json:"kind,omitempty" yaml:"kind,omitempty" protobuf:"bytes,2,opt,name=kind"` | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	ContentTypeJSON string = "application/json" | ||||
| ) | ||||
|  | ||||
| // RawExtension is used to hold extensions in external versions. | ||||
| // | ||||
| // To use this, make a field which has RawExtension as its type in your external, versioned | ||||
| // struct, and Object in your internal struct. You also need to register your | ||||
| // various plugin types. | ||||
| // | ||||
| // // Internal package: | ||||
| // type MyAPIObject struct { | ||||
| // 	runtime.TypeMeta `json:",inline"` | ||||
| //	MyPlugin runtime.Object `json:"myPlugin"` | ||||
| // } | ||||
| // type PluginA struct { | ||||
| //	AOption string `json:"aOption"` | ||||
| // } | ||||
| // | ||||
| // // External package: | ||||
| // type MyAPIObject struct { | ||||
| // 	runtime.TypeMeta `json:",inline"` | ||||
| //	MyPlugin runtime.RawExtension `json:"myPlugin"` | ||||
| // } | ||||
| // type PluginA struct { | ||||
| //	AOption string `json:"aOption"` | ||||
| // } | ||||
| // | ||||
| // // On the wire, the JSON will look something like this: | ||||
| // { | ||||
| //	"kind":"MyAPIObject", | ||||
| //	"apiVersion":"v1", | ||||
| //	"myPlugin": { | ||||
| //		"kind":"PluginA", | ||||
| //		"aOption":"foo", | ||||
| //	}, | ||||
| // } | ||||
| // | ||||
| // So what happens? Decode first uses json or yaml to unmarshal the serialized data into | ||||
| // your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. | ||||
| // The next step is to copy (using pkg/conversion) into the internal struct. The runtime | ||||
| // package's DefaultScheme has conversion functions installed which will unpack the | ||||
| // JSON stored in RawExtension, turning it into the correct object type, and storing it | ||||
| // in the Object. (TODO: In the case where the object is of an unknown type, a | ||||
| // runtime.Unknown object will be created and stored.) | ||||
| // | ||||
| // +k8s:deepcopy-gen=true | ||||
| // +protobuf=true | ||||
| // +k8s:openapi-gen=true | ||||
| type RawExtension struct { | ||||
| 	// Raw is the underlying serialization of this object. | ||||
| 	// | ||||
| 	// TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data. | ||||
| 	Raw []byte `protobuf:"bytes,1,opt,name=raw"` | ||||
| 	// Object can hold a representation of this extension - useful for working with versioned | ||||
| 	// structs. | ||||
| 	Object Object `json:"-"` | ||||
| } | ||||
|  | ||||
| // Unknown allows api objects with unknown types to be passed-through. This can be used | ||||
| // to deal with the API objects from a plug-in. Unknown objects still have functioning | ||||
| // TypeMeta features-- kind, version, etc. | ||||
| // TODO: Make this object have easy access to field based accessors and settors for | ||||
| // metadata and field mutatation. | ||||
| // | ||||
| // +k8s:deepcopy-gen=true | ||||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||||
| // +protobuf=true | ||||
| // +k8s:openapi-gen=true | ||||
| type Unknown struct { | ||||
| 	TypeMeta `json:",inline" protobuf:"bytes,1,opt,name=typeMeta"` | ||||
| 	// Raw will hold the complete serialized object which couldn't be matched | ||||
| 	// with a registered type. Most likely, nothing should be done with this | ||||
| 	// except for passing it through the system. | ||||
| 	Raw []byte `protobuf:"bytes,2,opt,name=raw"` | ||||
| 	// ContentEncoding is encoding used to encode 'Raw' data. | ||||
| 	// Unspecified means no encoding. | ||||
| 	ContentEncoding string `protobuf:"bytes,3,opt,name=contentEncoding"` | ||||
| 	// ContentType  is serialization method used to serialize 'Raw'. | ||||
| 	// Unspecified means ContentTypeJSON. | ||||
| 	ContentType string `protobuf:"bytes,4,opt,name=contentType"` | ||||
| } | ||||
|  | ||||
| // VersionedObjects is used by Decoders to give callers a way to access all versions | ||||
| // of an object during the decoding process. | ||||
| // | ||||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||||
| // +k8s:deepcopy-gen=true | ||||
| type VersionedObjects struct { | ||||
| 	// Objects is the set of objects retrieved during decoding, in order of conversion. | ||||
| 	// The 0 index is the object as serialized on the wire. If conversion has occurred, | ||||
| 	// other objects may be present. The right most object is the same as would be returned | ||||
| 	// by a normal Decode call. | ||||
| 	Objects []Object | ||||
| } | ||||
							
								
								
									
										69
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/types_proto.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/types_proto.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| /* | ||||
| 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 runtime | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| type ProtobufMarshaller interface { | ||||
| 	MarshalTo(data []byte) (int, error) | ||||
| } | ||||
|  | ||||
| // NestedMarshalTo allows a caller to avoid extra allocations during serialization of an Unknown | ||||
| // that will contain an object that implements ProtobufMarshaller. | ||||
| func (m *Unknown) NestedMarshalTo(data []byte, b ProtobufMarshaller, size uint64) (int, error) { | ||||
| 	var i int | ||||
| 	_ = i | ||||
| 	var l int | ||||
| 	_ = l | ||||
| 	data[i] = 0xa | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(data, i, uint64(m.TypeMeta.Size())) | ||||
| 	n1, err := m.TypeMeta.MarshalTo(data[i:]) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	i += n1 | ||||
|  | ||||
| 	if b != nil { | ||||
| 		data[i] = 0x12 | ||||
| 		i++ | ||||
| 		i = encodeVarintGenerated(data, i, size) | ||||
| 		n2, err := b.MarshalTo(data[i:]) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		if uint64(n2) != size { | ||||
| 			// programmer error: the Size() method for protobuf does not match the results of MarshalTo, which means the proto | ||||
| 			// struct returned would be wrong. | ||||
| 			return 0, fmt.Errorf("the Size() value of %T was %d, but NestedMarshalTo wrote %d bytes to data", b, size, n2) | ||||
| 		} | ||||
| 		i += n2 | ||||
| 	} | ||||
|  | ||||
| 	data[i] = 0x1a | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(data, i, uint64(len(m.ContentEncoding))) | ||||
| 	i += copy(data[i:], m.ContentEncoding) | ||||
|  | ||||
| 	data[i] = 0x22 | ||||
| 	i++ | ||||
| 	i = encodeVarintGenerated(data, i, uint64(len(m.ContentType))) | ||||
| 	i += copy(data[i:], m.ContentType) | ||||
| 	return i, nil | ||||
| } | ||||
							
								
								
									
										108
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/zz_generated.deepcopy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								vendor/k8s.io/apimachinery/pkg/runtime/zz_generated.deepcopy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| // +build !ignore_autogenerated | ||||
|  | ||||
| /* | ||||
| Copyright 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. | ||||
| */ | ||||
|  | ||||
| // Code generated by deepcopy-gen. DO NOT EDIT. | ||||
|  | ||||
| package runtime | ||||
|  | ||||
| // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. | ||||
| func (in *RawExtension) DeepCopyInto(out *RawExtension) { | ||||
| 	*out = *in | ||||
| 	if in.Raw != nil { | ||||
| 		in, out := &in.Raw, &out.Raw | ||||
| 		*out = make([]byte, len(*in)) | ||||
| 		copy(*out, *in) | ||||
| 	} | ||||
| 	if in.Object != nil { | ||||
| 		out.Object = in.Object.DeepCopyObject() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RawExtension. | ||||
| func (in *RawExtension) DeepCopy() *RawExtension { | ||||
| 	if in == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	out := new(RawExtension) | ||||
| 	in.DeepCopyInto(out) | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. | ||||
| func (in *Unknown) DeepCopyInto(out *Unknown) { | ||||
| 	*out = *in | ||||
| 	out.TypeMeta = in.TypeMeta | ||||
| 	if in.Raw != nil { | ||||
| 		in, out := &in.Raw, &out.Raw | ||||
| 		*out = make([]byte, len(*in)) | ||||
| 		copy(*out, *in) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Unknown. | ||||
| func (in *Unknown) DeepCopy() *Unknown { | ||||
| 	if in == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	out := new(Unknown) | ||||
| 	in.DeepCopyInto(out) | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new Object. | ||||
| func (in *Unknown) DeepCopyObject() Object { | ||||
| 	if c := in.DeepCopy(); c != nil { | ||||
| 		return c | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. | ||||
| func (in *VersionedObjects) DeepCopyInto(out *VersionedObjects) { | ||||
| 	*out = *in | ||||
| 	if in.Objects != nil { | ||||
| 		in, out := &in.Objects, &out.Objects | ||||
| 		*out = make([]Object, len(*in)) | ||||
| 		for i := range *in { | ||||
| 			if (*in)[i] != nil { | ||||
| 				(*out)[i] = (*in)[i].DeepCopyObject() | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionedObjects. | ||||
| func (in *VersionedObjects) DeepCopy() *VersionedObjects { | ||||
| 	if in == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	out := new(VersionedObjects) | ||||
| 	in.DeepCopyInto(out) | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new Object. | ||||
| func (in *VersionedObjects) DeepCopyObject() Object { | ||||
| 	if c := in.DeepCopy(); c != nil { | ||||
| 		return c | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user