aboutsummaryrefslogtreecommitdiff
path: root/vendor/k8s.io/apimachinery/pkg/conversion
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/apimachinery/pkg/conversion')
-rw-r--r--vendor/k8s.io/apimachinery/pkg/conversion/cloner.go249
-rw-r--r--vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go9
-rw-r--r--vendor/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go690
-rw-r--r--vendor/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go19
4 files changed, 8 insertions, 959 deletions
diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/cloner.go b/vendor/k8s.io/apimachinery/pkg/conversion/cloner.go
deleted file mode 100644
index c5dec1f31..000000000
--- a/vendor/k8s.io/apimachinery/pkg/conversion/cloner.go
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-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 conversion
-
-import (
- "fmt"
- "reflect"
-)
-
-// Cloner knows how to copy one type to another.
-type Cloner struct {
- // Map from the type to a function which can do the deep copy.
- deepCopyFuncs map[reflect.Type]reflect.Value
- generatedDeepCopyFuncs map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error
-}
-
-// NewCloner creates a new Cloner object.
-func NewCloner() *Cloner {
- c := &Cloner{
- deepCopyFuncs: map[reflect.Type]reflect.Value{},
- generatedDeepCopyFuncs: map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error{},
- }
- if err := c.RegisterDeepCopyFunc(byteSliceDeepCopy); err != nil {
- // If one of the deep-copy functions is malformed, detect it immediately.
- panic(err)
- }
- return c
-}
-
-// Prevent recursing into every byte...
-func byteSliceDeepCopy(in *[]byte, out *[]byte, c *Cloner) error {
- if *in != nil {
- *out = make([]byte, len(*in))
- copy(*out, *in)
- } else {
- *out = nil
- }
- return nil
-}
-
-// Verifies whether a deep-copy function has a correct signature.
-func verifyDeepCopyFunctionSignature(ft reflect.Type) error {
- if ft.Kind() != reflect.Func {
- return fmt.Errorf("expected func, got: %v", ft)
- }
- if ft.NumIn() != 3 {
- return fmt.Errorf("expected three 'in' params, got %v", ft)
- }
- if ft.NumOut() != 1 {
- return fmt.Errorf("expected one 'out' param, got %v", ft)
- }
- if ft.In(0).Kind() != reflect.Ptr {
- return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
- }
- if ft.In(1) != ft.In(0) {
- return fmt.Errorf("expected 'in' param 0 the same as param 1, got: %v", ft)
- }
- var forClonerType Cloner
- if expected := reflect.TypeOf(&forClonerType); ft.In(2) != expected {
- return fmt.Errorf("expected '%v' arg for 'in' param 2, got: '%v'", expected, ft.In(2))
- }
- var forErrorType error
- // This convolution is necessary, otherwise TypeOf picks up on the fact
- // that forErrorType is nil
- errorType := reflect.TypeOf(&forErrorType).Elem()
- if ft.Out(0) != errorType {
- return fmt.Errorf("expected error return, got: %v", ft)
- }
- return nil
-}
-
-// RegisterGeneratedDeepCopyFunc registers a copying func with the Cloner.
-// deepCopyFunc must take three parameters: a type input, a pointer to a
-// type output, and a pointer to Cloner. It should return an error.
-//
-// Example:
-// c.RegisterGeneratedDeepCopyFunc(
-// func(in Pod, out *Pod, c *Cloner) error {
-// // deep copy logic...
-// return nil
-// })
-func (c *Cloner) RegisterDeepCopyFunc(deepCopyFunc interface{}) error {
- fv := reflect.ValueOf(deepCopyFunc)
- ft := fv.Type()
- if err := verifyDeepCopyFunctionSignature(ft); err != nil {
- return err
- }
- c.deepCopyFuncs[ft.In(0)] = fv
- return nil
-}
-
-// GeneratedDeepCopyFunc bundles an untyped generated deep-copy function of a type
-// with a reflection type object used as a key to lookup the deep-copy function.
-type GeneratedDeepCopyFunc struct {
- Fn func(in interface{}, out interface{}, c *Cloner) error
- InType reflect.Type
-}
-
-// Similar to RegisterDeepCopyFunc, but registers deep copy function that were
-// automatically generated.
-func (c *Cloner) RegisterGeneratedDeepCopyFunc(fn GeneratedDeepCopyFunc) error {
- c.generatedDeepCopyFuncs[fn.InType] = fn.Fn
- return nil
-}
-
-// DeepCopy will perform a deep copy of a given object.
-func (c *Cloner) DeepCopy(in interface{}) (interface{}, error) {
- // Can be invalid if we run DeepCopy(X) where X is a nil interface type.
- // For example, we get an invalid value when someone tries to deep-copy
- // a nil labels.Selector.
- // This does not occur if X is nil and is a pointer to a concrete type.
- if in == nil {
- return nil, nil
- }
- inValue := reflect.ValueOf(in)
- outValue, err := c.deepCopy(inValue)
- if err != nil {
- return nil, err
- }
- return outValue.Interface(), nil
-}
-
-func (c *Cloner) deepCopy(src reflect.Value) (reflect.Value, error) {
- inType := src.Type()
-
- switch src.Kind() {
- case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
- if src.IsNil() {
- return src, nil
- }
- }
-
- if fv, ok := c.deepCopyFuncs[inType]; ok {
- return c.customDeepCopy(src, fv)
- }
- if fv, ok := c.generatedDeepCopyFuncs[inType]; ok {
- var outValue reflect.Value
- outValue = reflect.New(inType.Elem())
- err := fv(src.Interface(), outValue.Interface(), c)
- return outValue, err
- }
- return c.defaultDeepCopy(src)
-}
-
-func (c *Cloner) customDeepCopy(src, fv reflect.Value) (reflect.Value, error) {
- outValue := reflect.New(src.Type().Elem())
- args := []reflect.Value{src, outValue, reflect.ValueOf(c)}
- result := fv.Call(args)[0].Interface()
- // This convolution is necessary because nil interfaces won't convert
- // to error.
- if result == nil {
- return outValue, nil
- }
- return outValue, result.(error)
-}
-
-func (c *Cloner) defaultDeepCopy(src reflect.Value) (reflect.Value, error) {
- switch src.Kind() {
- case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
- return src, fmt.Errorf("cannot deep copy kind: %s", src.Kind())
- case reflect.Array:
- dst := reflect.New(src.Type())
- for i := 0; i < src.Len(); i++ {
- copyVal, err := c.deepCopy(src.Index(i))
- if err != nil {
- return src, err
- }
- dst.Elem().Index(i).Set(copyVal)
- }
- return dst.Elem(), nil
- case reflect.Interface:
- if src.IsNil() {
- return src, nil
- }
- return c.deepCopy(src.Elem())
- case reflect.Map:
- if src.IsNil() {
- return src, nil
- }
- dst := reflect.MakeMap(src.Type())
- for _, k := range src.MapKeys() {
- copyVal, err := c.deepCopy(src.MapIndex(k))
- if err != nil {
- return src, err
- }
- dst.SetMapIndex(k, copyVal)
- }
- return dst, nil
- case reflect.Ptr:
- if src.IsNil() {
- return src, nil
- }
- dst := reflect.New(src.Type().Elem())
- copyVal, err := c.deepCopy(src.Elem())
- if err != nil {
- return src, err
- }
- dst.Elem().Set(copyVal)
- return dst, nil
- case reflect.Slice:
- if src.IsNil() {
- return src, nil
- }
- dst := reflect.MakeSlice(src.Type(), 0, src.Len())
- for i := 0; i < src.Len(); i++ {
- copyVal, err := c.deepCopy(src.Index(i))
- if err != nil {
- return src, err
- }
- dst = reflect.Append(dst, copyVal)
- }
- return dst, nil
- case reflect.Struct:
- dst := reflect.New(src.Type())
- for i := 0; i < src.NumField(); i++ {
- if !dst.Elem().Field(i).CanSet() {
- // Can't set private fields. At this point, the
- // best we can do is a shallow copy. For
- // example, time.Time is a value type with
- // private members that can be shallow copied.
- return src, nil
- }
- copyVal, err := c.deepCopy(src.Field(i))
- if err != nil {
- return src, err
- }
- dst.Elem().Field(i).Set(copyVal)
- }
- return dst.Elem(), nil
-
- default:
- // Value types like numbers, booleans, and strings.
- return src, nil
- }
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go b/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go
index 30f717b2c..17b366617 100644
--- a/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go
+++ b/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go
@@ -90,7 +90,14 @@ func customMarshalValue(value reflect.Value) (reflect.Value, bool) {
marshaler, ok := value.Interface().(Marshaler)
if !ok {
- return reflect.Value{}, false
+ if !isPointerKind(value.Kind()) && value.CanAddr() {
+ marshaler, ok = value.Addr().Interface().(Marshaler)
+ if !ok {
+ return reflect.Value{}, false
+ }
+ } else {
+ return reflect.Value{}, false
+ }
}
// Don't invoke functions on nil pointers
diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go b/vendor/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go
deleted file mode 100644
index cf84a6198..000000000
--- a/vendor/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
-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 unstructured
-
-import (
- "bytes"
- encodingjson "encoding/json"
- "fmt"
- "math"
- "os"
- "reflect"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
-
- apiequality "k8s.io/apimachinery/pkg/api/equality"
- "k8s.io/apimachinery/pkg/util/diff"
- "k8s.io/apimachinery/pkg/util/json"
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-
- "github.com/golang/glog"
-)
-
-// Converter is an interface for converting between interface{}
-// and map[string]interface representation.
-type Converter interface {
- ToUnstructured(obj interface{}, u *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))
- uint64Type = reflect.TypeOf(uint64(0))
- float64Type = reflect.TypeOf(float64(0))
- boolType = reflect.TypeOf(bool(false))
- fieldCache = newFieldsCache()
- DefaultConverter = NewConverter(parseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR")))
-)
-
-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
-}
-
-// ConverterImpl knows how to convert between interface{} and
-// Unstructured in both ways.
-type converterImpl 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
-}
-
-func NewConverter(mismatchDetection bool) Converter {
- return &converterImpl{
- mismatchDetection: mismatchDetection,
- }
-}
-
-func (c *converterImpl) 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) {
- glog.Fatalf("FromUnstructured unexpected error for %v: error: %v", u, err)
- }
- if err == nil && !apiequality.Semantic.DeepEqual(obj, newObj) {
- glog.Fatalf("FromUnstructured mismatch for %#v, diff: %v", obj, diff.ObjectReflectDiff(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
-}
-
-func (c *converterImpl) ToUnstructured(obj interface{}, u *map[string]interface{}) error {
- t := reflect.TypeOf(obj)
- value := reflect.ValueOf(obj)
- if t.Kind() != reflect.Ptr || value.IsNil() {
- return fmt.Errorf("ToUnstructured requires a non-nil pointer to an object, got %v", t)
- }
- err := toUnstructured(value.Elem(), reflect.ValueOf(u).Elem())
- if c.mismatchDetection {
- newUnstr := &map[string]interface{}{}
- newErr := toUnstructuredViaJSON(obj, newUnstr)
- if (err != nil) != (newErr != nil) {
- glog.Fatalf("ToUnstructured unexpected error for %v: error: %v", obj, err)
- }
- if err == nil && !apiequality.Semantic.DeepEqual(u, newUnstr) {
- glog.Fatalf("ToUnstructured mismatch for %#v, diff: %v", u, diff.ObjectReflectDiff(u, newUnstr))
- }
- }
- return err
-}
-
-func toUnstructuredViaJSON(obj interface{}, u *map[string]interface{}) error {
- data, err := json.Marshal(obj)
- if err != nil {
- return err
- }
- return json.Unmarshal(data, u)
-}
-
-func toUnstructured(sv, dv reflect.Value) error {
- st, dt := sv.Type(), dv.Type()
-
- // Check if the object has a custom JSON marshaller/unmarshaller.
- if st.Implements(marshalerType) {
- if sv.Kind() == reflect.Ptr && sv.IsNil() {
- // We're done - we don't need to store anything.
- return nil
- }
-
- marshaler := sv.Interface().(encodingjson.Marshaler)
- data, err := marshaler.MarshalJSON()
- if err != nil {
- return err
- }
- if bytes.Equal(data, []byte("null")) {
- // We're done - we don't need to store anything.
- } else {
- switch {
- case len(data) > 0 && data[0] == '"':
- var result string
- err := json.Unmarshal(data, &result)
- if err != nil {
- return fmt.Errorf("error decoding from json: %v", err)
- }
- dv.Set(reflect.ValueOf(result))
- case len(data) > 0 && data[0] == '{':
- result := make(map[string]interface{})
- err := json.Unmarshal(data, &result)
- if err != nil {
- return fmt.Errorf("error decoding from json: %v", err)
- }
- dv.Set(reflect.ValueOf(result))
- default:
- var result int64
- err := json.Unmarshal(data, &result)
- if err != nil {
- return fmt.Errorf("error decoding from json: %v", err)
- }
- dv.Set(reflect.ValueOf(result))
- }
- }
- return nil
- }
-
- 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:
- if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
- dv.Set(reflect.New(uint64Type))
- }
- dv.Set(reflect.ValueOf(sv.Uint()))
- 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)
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go b/vendor/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go
deleted file mode 100644
index cd40e74be..000000000
--- a/vendor/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-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 unstructured provides conversion from runtime objects
-// to map[string]interface{} representation.
-package unstructured // import "k8s.io/apimachinery/pkg/conversion/unstructured"