1/* 2Copyright 2014 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package runtime 18 19import ( 20 "errors" 21 22 "k8s.io/apimachinery/pkg/conversion" 23 "k8s.io/apimachinery/pkg/runtime/schema" 24) 25 26type encodable struct { 27 E Encoder `json:"-"` 28 obj Object 29 versions []schema.GroupVersion 30} 31 32func (e encodable) GetObjectKind() schema.ObjectKind { return e.obj.GetObjectKind() } 33func (e encodable) DeepCopyObject() Object { 34 var out encodable = e 35 out.obj = e.obj.DeepCopyObject() 36 copy(out.versions, e.versions) 37 return out 38} 39 40// NewEncodable creates an object that will be encoded with the provided codec on demand. 41// Provided as a convenience for test cases dealing with internal objects. 42func NewEncodable(e Encoder, obj Object, versions ...schema.GroupVersion) Object { 43 if _, ok := obj.(*Unknown); ok { 44 return obj 45 } 46 return encodable{e, obj, versions} 47} 48 49func (re encodable) UnmarshalJSON(in []byte) error { 50 return errors.New("runtime.encodable cannot be unmarshalled from JSON") 51} 52 53// Marshal may get called on pointers or values, so implement MarshalJSON on value. 54// http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go 55func (re encodable) MarshalJSON() ([]byte, error) { 56 return Encode(re.E, re.obj) 57} 58 59// NewEncodableList creates an object that will be encoded with the provided codec on demand. 60// Provided as a convenience for test cases dealing with internal objects. 61func NewEncodableList(e Encoder, objects []Object, versions ...schema.GroupVersion) []Object { 62 out := make([]Object, len(objects)) 63 for i := range objects { 64 if _, ok := objects[i].(*Unknown); ok { 65 out[i] = objects[i] 66 continue 67 } 68 out[i] = NewEncodable(e, objects[i], versions...) 69 } 70 return out 71} 72 73func (re *Unknown) UnmarshalJSON(in []byte) error { 74 if re == nil { 75 return errors.New("runtime.Unknown: UnmarshalJSON on nil pointer") 76 } 77 re.TypeMeta = TypeMeta{} 78 re.Raw = append(re.Raw[0:0], in...) 79 re.ContentEncoding = "" 80 re.ContentType = ContentTypeJSON 81 return nil 82} 83 84// Marshal may get called on pointers or values, so implement MarshalJSON on value. 85// http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go 86func (re Unknown) MarshalJSON() ([]byte, error) { 87 // If ContentType is unset, we assume this is JSON. 88 if re.ContentType != "" && re.ContentType != ContentTypeJSON { 89 return nil, errors.New("runtime.Unknown: MarshalJSON on non-json data") 90 } 91 if re.Raw == nil { 92 return []byte("null"), nil 93 } 94 return re.Raw, nil 95} 96 97func Convert_runtime_Object_To_runtime_RawExtension(in *Object, out *RawExtension, s conversion.Scope) error { 98 if in == nil { 99 out.Raw = []byte("null") 100 return nil 101 } 102 obj := *in 103 if unk, ok := obj.(*Unknown); ok { 104 if unk.Raw != nil { 105 out.Raw = unk.Raw 106 return nil 107 } 108 obj = out.Object 109 } 110 if obj == nil { 111 out.Raw = nil 112 return nil 113 } 114 out.Object = obj 115 return nil 116} 117 118func Convert_runtime_RawExtension_To_runtime_Object(in *RawExtension, out *Object, s conversion.Scope) error { 119 if in.Object != nil { 120 *out = in.Object 121 return nil 122 } 123 data := in.Raw 124 if len(data) == 0 || (len(data) == 4 && string(data) == "null") { 125 *out = nil 126 return nil 127 } 128 *out = &Unknown{ 129 Raw: data, 130 // TODO: Set ContentEncoding and ContentType appropriately. 131 // Currently we set ContentTypeJSON to make tests passing. 132 ContentType: ContentTypeJSON, 133 } 134 return nil 135} 136 137func DefaultEmbeddedConversions() []interface{} { 138 return []interface{}{ 139 Convert_runtime_Object_To_runtime_RawExtension, 140 Convert_runtime_RawExtension_To_runtime_Object, 141 } 142} 143