mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-04 23:17:50 +00:00
Allow objects to serialize their nested objects
Introduce an optional interface for callers to encode themselves.
This commit is contained in:
@@ -88,6 +88,12 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
|
||||
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 into != nil {
|
||||
if into == obj {
|
||||
@@ -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
|
||||
// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
|
||||
func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
switch t := obj.(type) {
|
||||
case *runtime.Unknown:
|
||||
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())
|
||||
}
|
||||
switch obj.(type) {
|
||||
case *runtime.Unknown, *runtime.Unstructured, *runtime.UnstructuredList:
|
||||
return c.encoder.Encode(obj, w)
|
||||
}
|
||||
|
||||
@@ -155,6 +148,11 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
}
|
||||
|
||||
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()
|
||||
old := objectKind.GroupVersionKind()
|
||||
objectKind.SetGroupVersionKind(gvks[0])
|
||||
@@ -170,9 +168,52 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if err != nil {
|
||||
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
|
||||
err = c.encoder.Encode(out, w)
|
||||
// restore the old GVK, in case conversion returned the same object
|
||||
objectKind.SetGroupVersionKind(old)
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user