Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
ce57455d
Unverified
Commit
ce57455d
authored
May 25, 2016
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow objects to serialize their nested objects
Introduce an optional interface for callers to encode themselves.
parent
12a5eeea
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
137 additions
and
58 deletions
+137
-58
interfaces.go
pkg/runtime/interfaces.go
+12
-0
codec_factory.go
pkg/runtime/serializer/codec_factory.go
+5
-39
versioning.go
pkg/runtime/serializer/versioning/versioning.go
+56
-15
versioning_test.go
pkg/runtime/serializer/versioning/versioning_test.go
+64
-4
No files found.
pkg/runtime/interfaces.go
View file @
ce57455d
...
@@ -154,6 +154,18 @@ type StorageSerializer interface {
...
@@ -154,6 +154,18 @@ type StorageSerializer interface {
DecoderToVersion
(
serializer
Decoder
,
gv
GroupVersioner
)
Decoder
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
// Non-codec interfaces
...
...
pkg/runtime/serializer/codec_factory.go
View file @
ce57455d
...
@@ -17,8 +17,6 @@ limitations under the License.
...
@@ -17,8 +17,6 @@ limitations under the License.
package
serializer
package
serializer
import
(
import
(
"io"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer/json"
"k8s.io/kubernetes/pkg/runtime/serializer/json"
...
@@ -336,47 +334,15 @@ type DirectCodecFactory struct {
...
@@ -336,47 +334,15 @@ type DirectCodecFactory struct {
// EncoderForVersion returns an encoder that does not do conversion. gv is ignored.
// EncoderForVersion returns an encoder that does not do conversion. gv is ignored.
func
(
f
DirectCodecFactory
)
EncoderForVersion
(
serializer
runtime
.
Encoder
,
_
runtime
.
GroupVersioner
)
runtime
.
Encoder
{
func
(
f
DirectCodecFactory
)
EncoderForVersion
(
serializer
runtime
.
Encoder
,
_
runtime
.
GroupVersioner
)
runtime
.
Encoder
{
return
DirectCodec
{
return
versioning
.
DirectEncoder
{
runtime
.
NewCodec
(
serializer
,
nil
)
,
Encoder
:
serializer
,
f
.
CodecFactory
.
scheme
,
ObjectTyper
:
f
.
CodecFactory
.
scheme
,
}
}
}
}
// DecoderToVersion returns an decoder that does not do conversion. gv is ignored.
// DecoderToVersion returns an decoder that does not do conversion. gv is ignored.
func
(
f
DirectCodecFactory
)
DecoderToVersion
(
serializer
runtime
.
Decoder
,
_
runtime
.
GroupVersioner
)
runtime
.
Decoder
{
func
(
f
DirectCodecFactory
)
DecoderToVersion
(
serializer
runtime
.
Decoder
,
_
runtime
.
GroupVersioner
)
runtime
.
Decoder
{
return
DirectCodec
{
return
versioning
.
DirectDecoder
{
runtime
.
NewCodec
(
nil
,
serializer
),
Decoder
:
serializer
,
nil
,
}
}
// DirectCodec is a codec that does not do conversion. It sets the gvk during serialization, and removes the gvk during deserialization.
type
DirectCodec
struct
{
runtime
.
Serializer
runtime
.
ObjectTyper
}
// EncodeToStream does not do conversion. It sets the gvk during serialization. overrides are ignored.
func
(
c
DirectCodec
)
Encode
(
obj
runtime
.
Object
,
stream
io
.
Writer
)
error
{
gvks
,
_
,
err
:=
c
.
ObjectTyper
.
ObjectKinds
(
obj
)
if
err
!=
nil
{
return
err
}
kind
:=
obj
.
GetObjectKind
()
oldGVK
:=
kind
.
GroupVersionKind
()
kind
.
SetGroupVersionKind
(
gvks
[
0
])
err
=
c
.
Serializer
.
Encode
(
obj
,
stream
)
kind
.
SetGroupVersionKind
(
oldGVK
)
return
err
}
// Decode does not do conversion. It removes the gvk during deserialization.
func
(
c
DirectCodec
)
Decode
(
data
[]
byte
,
defaults
*
unversioned
.
GroupVersionKind
,
into
runtime
.
Object
)
(
runtime
.
Object
,
*
unversioned
.
GroupVersionKind
,
error
)
{
obj
,
gvk
,
err
:=
c
.
Serializer
.
Decode
(
data
,
defaults
,
into
)
if
obj
!=
nil
{
kind
:=
obj
.
GetObjectKind
()
// clearing the gvk is just a convention of a codec
kind
.
SetGroupVersionKind
(
unversioned
.
GroupVersionKind
{})
}
}
return
obj
,
gvk
,
err
}
}
pkg/runtime/serializer/versioning/versioning.go
View file @
ce57455d
...
@@ -88,6 +88,12 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
...
@@ -88,6 +88,12 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
return
nil
,
gvk
,
err
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 we specify a target, use generic conversion.
if
into
!=
nil
{
if
into
!=
nil
{
if
into
==
obj
{
if
into
==
obj
{
...
@@ -131,21 +137,8 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
...
@@ -131,21 +137,8 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
// Encode ensures the provided object is output in the appropriate group and version, invoking
// 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.
// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
func
(
c
*
codec
)
Encode
(
obj
runtime
.
Object
,
w
io
.
Writer
)
error
{
func
(
c
*
codec
)
Encode
(
obj
runtime
.
Object
,
w
io
.
Writer
)
error
{
switch
t
:=
obj
.
(
type
)
{
switch
obj
.
(
type
)
{
case
*
runtime
.
Unknown
:
case
*
runtime
.
Unknown
,
*
runtime
.
Unstructured
,
*
runtime
.
UnstructuredList
:
if
gv
,
ok
:=
runtime
.
PreferredGroupVersion
(
c
.
encodeVersion
);
ok
{
t
.
APIVersion
=
gv
.
String
()
}
return
c
.
encoder
.
Encode
(
obj
,
w
)
case
*
runtime
.
Unstructured
:
if
gv
,
ok
:=
runtime
.
PreferredGroupVersion
(
c
.
encodeVersion
);
ok
{
t
.
SetAPIVersion
(
gv
.
String
())
}
return
c
.
encoder
.
Encode
(
obj
,
w
)
case
*
runtime
.
UnstructuredList
:
if
gv
,
ok
:=
runtime
.
PreferredGroupVersion
(
c
.
encodeVersion
);
ok
{
t
.
SetAPIVersion
(
gv
.
String
())
}
return
c
.
encoder
.
Encode
(
obj
,
w
)
return
c
.
encoder
.
Encode
(
obj
,
w
)
}
}
...
@@ -155,6 +148,11 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
...
@@ -155,6 +148,11 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
}
}
if
c
.
encodeVersion
==
nil
||
isUnversioned
{
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
()
objectKind
:=
obj
.
GetObjectKind
()
old
:=
objectKind
.
GroupVersionKind
()
old
:=
objectKind
.
GroupVersionKind
()
objectKind
.
SetGroupVersionKind
(
gvks
[
0
])
objectKind
.
SetGroupVersionKind
(
gvks
[
0
])
...
@@ -170,9 +168,52 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
...
@@ -170,9 +168,52 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
e
,
ok
:=
out
.
(
runtime
.
NestedObjectEncoder
);
ok
{
if
err
:=
e
.
EncodeNestedObjects
(
DirectEncoder
{
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
// Conversion is responsible for setting the proper group, version, and kind onto the outgoing object
err
=
c
.
encoder
.
Encode
(
out
,
w
)
err
=
c
.
encoder
.
Encode
(
out
,
w
)
// restore the old GVK, in case conversion returned the same object
// restore the old GVK, in case conversion returned the same object
objectKind
.
SetGroupVersionKind
(
old
)
objectKind
.
SetGroupVersionKind
(
old
)
return
err
return
err
}
}
// DirectEncoder serializes an object and ensures the GVK is set.
type
DirectEncoder
struct
{
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
{
return
err
}
kind
:=
obj
.
GetObjectKind
()
oldGVK
:=
kind
.
GroupVersionKind
()
kind
.
SetGroupVersionKind
(
gvks
[
0
])
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
*
unversioned
.
GroupVersionKind
,
into
runtime
.
Object
)
(
runtime
.
Object
,
*
unversioned
.
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
(
unversioned
.
GroupVersionKind
{})
}
return
obj
,
gvk
,
err
}
pkg/runtime/serializer/versioning/versioning_test.go
View file @
ce57455d
...
@@ -19,6 +19,7 @@ package versioning
...
@@ -19,6 +19,7 @@ package versioning
import
(
import
(
"fmt"
"fmt"
"io"
"io"
"io/ioutil"
"reflect"
"reflect"
"testing"
"testing"
...
@@ -37,6 +38,60 @@ func (d *testDecodable) GetObjectKind() unversioned.ObjectKind {
...
@@ -37,6 +38,60 @@ func (d *testDecodable) GetObjectKind() unversioned.ObjectKind {
func
(
d
*
testDecodable
)
SetGroupVersionKind
(
gvk
unversioned
.
GroupVersionKind
)
{
d
.
gvk
=
gvk
}
func
(
d
*
testDecodable
)
SetGroupVersionKind
(
gvk
unversioned
.
GroupVersionKind
)
{
d
.
gvk
=
gvk
}
func
(
d
*
testDecodable
)
GroupVersionKind
()
unversioned
.
GroupVersionKind
{
return
d
.
gvk
}
func
(
d
*
testDecodable
)
GroupVersionKind
()
unversioned
.
GroupVersionKind
{
return
d
.
gvk
}
type
testNestedDecodable
struct
{
Other
string
Value
int
`json:"value"`
gvk
unversioned
.
GroupVersionKind
nestedCalled
bool
nestedErr
error
}
func
(
d
*
testNestedDecodable
)
GetObjectKind
()
unversioned
.
ObjectKind
{
return
d
}
func
(
d
*
testNestedDecodable
)
SetGroupVersionKind
(
gvk
unversioned
.
GroupVersionKind
)
{
d
.
gvk
=
gvk
}
func
(
d
*
testNestedDecodable
)
GroupVersionKind
()
unversioned
.
GroupVersionKind
{
return
d
.
gvk
}
func
(
d
*
testNestedDecodable
)
EncodeNestedObjects
(
e
runtime
.
Encoder
)
error
{
d
.
nestedCalled
=
true
return
d
.
nestedErr
}
func
(
d
*
testNestedDecodable
)
DecodeNestedObjects
(
_
runtime
.
Decoder
)
error
{
d
.
nestedCalled
=
true
return
d
.
nestedErr
}
func
TestNestedDecode
(
t
*
testing
.
T
)
{
n
:=
&
testNestedDecodable
{
nestedErr
:
fmt
.
Errorf
(
"unable to decode"
)}
decoder
:=
&
mockSerializer
{
obj
:
n
}
codec
:=
NewCodec
(
nil
,
decoder
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
)
if
_
,
_
,
err
:=
codec
.
Decode
([]
byte
(
`{}`
),
nil
,
n
);
err
!=
n
.
nestedErr
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
!
n
.
nestedCalled
{
t
.
Errorf
(
"did not invoke nested decoder"
)
}
}
func
TestNestedEncode
(
t
*
testing
.
T
)
{
n
:=
&
testNestedDecodable
{
nestedErr
:
fmt
.
Errorf
(
"unable to decode"
)}
n2
:=
&
testNestedDecodable
{
nestedErr
:
fmt
.
Errorf
(
"unable to decode 2"
)}
encoder
:=
&
mockSerializer
{
obj
:
n
}
codec
:=
NewCodec
(
encoder
,
nil
,
&
checkConvertor
{
obj
:
n2
,
groupVersion
:
unversioned
.
GroupVersion
{
Group
:
"other"
}},
nil
,
nil
,
&
mockTyper
{
gvks
:
[]
unversioned
.
GroupVersionKind
{{
Kind
:
"test"
}}},
unversioned
.
GroupVersion
{
Group
:
"other"
},
nil
,
)
if
err
:=
codec
.
Encode
(
n
,
ioutil
.
Discard
);
err
!=
n2
.
nestedErr
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
n
.
nestedCalled
||
!
n2
.
nestedCalled
{
t
.
Errorf
(
"did not invoke correct nested decoder"
)
}
}
func
TestDecode
(
t
*
testing
.
T
)
{
func
TestDecode
(
t
*
testing
.
T
)
{
gvk1
:=
&
unversioned
.
GroupVersionKind
{
Kind
:
"Test"
,
Group
:
"other"
,
Version
:
"blah"
}
gvk1
:=
&
unversioned
.
GroupVersionKind
{
Kind
:
"Test"
,
Group
:
"other"
,
Version
:
"blah"
}
decodable1
:=
&
testDecodable
{}
decodable1
:=
&
testDecodable
{}
...
@@ -300,10 +355,15 @@ func (c *mockCreater) New(kind unversioned.GroupVersionKind) (runtime.Object, er
...
@@ -300,10 +355,15 @@ func (c *mockCreater) New(kind unversioned.GroupVersionKind) (runtime.Object, er
}
}
type
mockTyper
struct
{
type
mockTyper
struct
{
gvk
*
unversioned
.
GroupVersionKind
gvks
[]
unversioned
.
GroupVersionKind
err
error
unversioned
bool
err
error
}
func
(
t
*
mockTyper
)
ObjectKinds
(
obj
runtime
.
Object
)
([]
unversioned
.
GroupVersionKind
,
bool
,
error
)
{
return
t
.
gvks
,
t
.
unversioned
,
t
.
err
}
}
func
(
t
*
mockTyper
)
ObjectKind
(
obj
runtime
.
Object
)
(
*
unversioned
.
GroupVersionKind
,
bool
,
error
)
{
func
(
t
*
mockTyper
)
Recognizes
(
_
unversioned
.
GroupVersionKind
)
bool
{
return
t
.
gvk
,
false
,
t
.
err
return
t
rue
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment