blob: db11eb8bcf648890687803d9dc6dff26f9f52527 [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001/*
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 out := 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 (e 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 (e encodable) MarshalJSON() ([]byte, error) {
56 return Encode(e.E, e.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 (e *Unknown) UnmarshalJSON(in []byte) error {
74 if e == nil {
75 return errors.New("runtime.Unknown: UnmarshalJSON on nil pointer")
76 }
77 e.TypeMeta = TypeMeta{}
78 e.Raw = append(e.Raw[0:0], in...)
79 e.ContentEncoding = ""
80 e.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 (e Unknown) MarshalJSON() ([]byte, error) {
87 // If ContentType is unset, we assume this is JSON.
88 if e.ContentType != "" && e.ContentType != ContentTypeJSON {
89 return nil, errors.New("runtime.Unknown: MarshalJSON on non-json data")
90 }
91 if e.Raw == nil {
92 return []byte("null"), nil
93 }
94 return e.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}