1
16
17 package runtime
18
19 import (
20 "fmt"
21 "io"
22 "reflect"
23
24 "k8s.io/apimachinery/pkg/conversion"
25 "k8s.io/apimachinery/pkg/runtime/schema"
26 "k8s.io/apimachinery/pkg/util/errors"
27 )
28
29
30 type unsafeObjectConvertor struct {
31 *Scheme
32 }
33
34 var _ ObjectConvertor = unsafeObjectConvertor{}
35
36
37
38 func (c unsafeObjectConvertor) ConvertToVersion(in Object, outVersion GroupVersioner) (Object, error) {
39 return c.Scheme.UnsafeConvertToVersion(in, outVersion)
40 }
41
42
43
44
45 func UnsafeObjectConvertor(scheme *Scheme) ObjectConvertor {
46 return unsafeObjectConvertor{scheme}
47 }
48
49
50
51 func SetField(src interface{}, v reflect.Value, fieldName string) error {
52 field := v.FieldByName(fieldName)
53 if !field.IsValid() {
54 return fmt.Errorf("couldn't find %v field in %T", fieldName, v.Interface())
55 }
56 srcValue := reflect.ValueOf(src)
57 if srcValue.Type().AssignableTo(field.Type()) {
58 field.Set(srcValue)
59 return nil
60 }
61 if srcValue.Type().ConvertibleTo(field.Type()) {
62 field.Set(srcValue.Convert(field.Type()))
63 return nil
64 }
65 return fmt.Errorf("couldn't assign/convert %v to %v", srcValue.Type(), field.Type())
66 }
67
68
69
70 func Field(v reflect.Value, fieldName string, dest interface{}) error {
71 field := v.FieldByName(fieldName)
72 if !field.IsValid() {
73 return fmt.Errorf("couldn't find %v field in %T", fieldName, v.Interface())
74 }
75 destValue, err := conversion.EnforcePtr(dest)
76 if err != nil {
77 return err
78 }
79 if field.Type().AssignableTo(destValue.Type()) {
80 destValue.Set(field)
81 return nil
82 }
83 if field.Type().ConvertibleTo(destValue.Type()) {
84 destValue.Set(field.Convert(destValue.Type()))
85 return nil
86 }
87 return fmt.Errorf("couldn't assign/convert %v to %v", field.Type(), destValue.Type())
88 }
89
90
91
92
93 func FieldPtr(v reflect.Value, fieldName string, dest interface{}) error {
94 field := v.FieldByName(fieldName)
95 if !field.IsValid() {
96 return fmt.Errorf("couldn't find %v field in %T", fieldName, v.Interface())
97 }
98 v, err := conversion.EnforcePtr(dest)
99 if err != nil {
100 return err
101 }
102 field = field.Addr()
103 if field.Type().AssignableTo(v.Type()) {
104 v.Set(field)
105 return nil
106 }
107 if field.Type().ConvertibleTo(v.Type()) {
108 v.Set(field.Convert(v.Type()))
109 return nil
110 }
111 return fmt.Errorf("couldn't assign/convert %v to %v", field.Type(), v.Type())
112 }
113
114
115
116 func EncodeList(e Encoder, objects []Object) error {
117 var errs []error
118 for i := range objects {
119 data, err := Encode(e, objects[i])
120 if err != nil {
121 errs = append(errs, err)
122 continue
123 }
124
125 objects[i] = &Unknown{Raw: data}
126 }
127 return errors.NewAggregate(errs)
128 }
129
130 func decodeListItem(obj *Unknown, decoders []Decoder) (Object, error) {
131 for _, decoder := range decoders {
132
133 obj, err := Decode(decoder, obj.Raw)
134 if err != nil {
135 if IsNotRegisteredError(err) {
136 continue
137 }
138 return nil, err
139 }
140 return obj, nil
141 }
142
143
144 for _, decoder := range decoders {
145 if err := DecodeInto(decoder, obj.Raw, obj); err == nil {
146 return obj, nil
147 }
148 }
149 return obj, nil
150 }
151
152
153
154
155 func DecodeList(objects []Object, decoders ...Decoder) []error {
156 errs := []error(nil)
157 for i, obj := range objects {
158 switch t := obj.(type) {
159 case *Unknown:
160 decoded, err := decodeListItem(t, decoders)
161 if err != nil {
162 errs = append(errs, err)
163 break
164 }
165 objects[i] = decoded
166 }
167 }
168 return errs
169 }
170
171
172 type MultiObjectTyper []ObjectTyper
173
174 var _ ObjectTyper = MultiObjectTyper{}
175
176 func (m MultiObjectTyper) ObjectKinds(obj Object) (gvks []schema.GroupVersionKind, unversionedType bool, err error) {
177 for _, t := range m {
178 gvks, unversionedType, err = t.ObjectKinds(obj)
179 if err == nil {
180 return
181 }
182 }
183 return
184 }
185
186 func (m MultiObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
187 for _, t := range m {
188 if t.Recognizes(gvk) {
189 return true
190 }
191 }
192 return false
193 }
194
195
196 func SetZeroValue(objPtr Object) error {
197 v, err := conversion.EnforcePtr(objPtr)
198 if err != nil {
199 return err
200 }
201 v.Set(reflect.Zero(v.Type()))
202 return nil
203 }
204
205
206
207 var DefaultFramer = defaultFramer{}
208
209 type defaultFramer struct{}
210
211 func (defaultFramer) NewFrameReader(r io.ReadCloser) io.ReadCloser { return r }
212 func (defaultFramer) NewFrameWriter(w io.Writer) io.Writer { return w }
213
214
215 type WithVersionEncoder struct {
216 Version GroupVersioner
217 Encoder
218 ObjectTyper
219 }
220
221
222 func (e WithVersionEncoder) Encode(obj Object, stream io.Writer) error {
223 gvks, _, err := e.ObjectTyper.ObjectKinds(obj)
224 if err != nil {
225 if IsNotRegisteredError(err) {
226 return e.Encoder.Encode(obj, stream)
227 }
228 return err
229 }
230 kind := obj.GetObjectKind()
231 oldGVK := kind.GroupVersionKind()
232 gvk := gvks[0]
233 if e.Version != nil {
234 preferredGVK, ok := e.Version.KindForGroupVersionKinds(gvks)
235 if ok {
236 gvk = preferredGVK
237 }
238 }
239
240
241 if gvk != oldGVK {
242 kind.SetGroupVersionKind(gvk)
243 defer kind.SetGroupVersionKind(oldGVK)
244 }
245
246 return e.Encoder.Encode(obj, stream)
247 }
248
249
250 type WithoutVersionDecoder struct {
251 Decoder
252 }
253
254
255 func (d WithoutVersionDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) {
256 obj, gvk, err := d.Decoder.Decode(data, defaults, into)
257 if obj != nil {
258 kind := obj.GetObjectKind()
259
260 kind.SetGroupVersionKind(schema.GroupVersionKind{})
261 }
262 return obj, gvk, err
263 }
264
265 type encoderWithAllocator struct {
266 encoder EncoderWithAllocator
267 memAllocator MemoryAllocator
268 }
269
270
271 func NewEncoderWithAllocator(e EncoderWithAllocator, a MemoryAllocator) Encoder {
272 return &encoderWithAllocator{
273 encoder: e,
274 memAllocator: a,
275 }
276 }
277
278
279 func (e *encoderWithAllocator) Encode(obj Object, w io.Writer) error {
280 return e.encoder.EncodeWithAllocator(obj, w, e.memAllocator)
281 }
282
283
284 func (e *encoderWithAllocator) Identifier() Identifier {
285 return e.encoder.Identifier()
286 }
287
View as plain text