Simplify Codec and split responsibilities
Break Codec into two general purpose interfaces, Encoder and Decoder, and move parameter codec responsibilities to ParameterCodec. Make unversioned types explicit when registering - these types go through conversion without modification. Switch to use "__internal" instead of "" to represent the internal version. Future commits will also add group defaulting (so that "" is expanded internally into a known group version, and only cleared during set). For embedded types like runtime.Object -> runtime.RawExtension, put the responsibility on the caller of Decode/Encode to handle transformation into destination serialization. Future commits will expand RawExtension and Unknown to accept a content encoding as well as bytes. Make Unknown a bit more powerful and use it to carry unrecognized types.
This commit is contained in:
@@ -18,9 +18,7 @@ package runtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"io"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
@@ -28,36 +26,19 @@ import (
|
||||
|
||||
// UnstructuredJSONScheme is capable of converting JSON data into the Unstructured
|
||||
// type, which can be used for generic access to objects without a predefined scheme.
|
||||
var UnstructuredJSONScheme ObjectDecoder = unstructuredJSONScheme{}
|
||||
// TODO: move into serializer/json.
|
||||
var UnstructuredJSONScheme Decoder = unstructuredJSONScheme{}
|
||||
|
||||
type unstructuredJSONScheme struct{}
|
||||
|
||||
var _ Decoder = unstructuredJSONScheme{}
|
||||
var _ ObjectDecoder = unstructuredJSONScheme{}
|
||||
var _ Codec = unstructuredJSONScheme{}
|
||||
|
||||
// Recognizes returns true for any version or kind that is specified (internal
|
||||
// versions are specifically excluded).
|
||||
func (unstructuredJSONScheme) Recognizes(gvk unversioned.GroupVersionKind) bool {
|
||||
return !gvk.GroupVersion().IsEmpty() && len(gvk.Kind) > 0
|
||||
}
|
||||
|
||||
func (s unstructuredJSONScheme) Decode(data []byte) (Object, error) {
|
||||
func (s unstructuredJSONScheme) Decode(data []byte, _ *unversioned.GroupVersionKind, _ Object) (Object, *unversioned.GroupVersionKind, error) {
|
||||
unstruct := &Unstructured{}
|
||||
if err := DecodeInto(s, data, unstruct); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return unstruct, nil
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) DecodeInto(data []byte, obj Object) error {
|
||||
unstruct, ok := obj.(*Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("the unstructured JSON scheme does not recognize %v", reflect.TypeOf(obj))
|
||||
}
|
||||
|
||||
m := make(map[string]interface{})
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
if v, ok := m["kind"]; ok {
|
||||
if s, ok := v.(string); ok {
|
||||
@@ -69,44 +50,30 @@ func (unstructuredJSONScheme) DecodeInto(data []byte, obj Object) error {
|
||||
unstruct.APIVersion = s
|
||||
}
|
||||
}
|
||||
|
||||
if len(unstruct.APIVersion) == 0 {
|
||||
return conversion.NewMissingVersionErr(string(data))
|
||||
return nil, nil, conversion.NewMissingVersionErr(string(data))
|
||||
}
|
||||
gv, err := unversioned.ParseGroupVersion(unstruct.APIVersion)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
gvk := gv.WithKind(unstruct.Kind)
|
||||
if len(unstruct.Kind) == 0 {
|
||||
return conversion.NewMissingKindErr(string(data))
|
||||
return nil, &gvk, conversion.NewMissingKindErr(string(data))
|
||||
}
|
||||
unstruct.Object = m
|
||||
return nil
|
||||
return unstruct, &gvk, nil
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj Object, gvk unversioned.GroupVersionKind) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) DecodeToVersion(data []byte, gv unversioned.GroupVersion) (Object, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) DecodeParametersInto(paramaters url.Values, obj Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) DataKind(data []byte) (unversioned.GroupVersionKind, error) {
|
||||
obj := TypeMeta{}
|
||||
if err := json.Unmarshal(data, &obj); err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
func (s unstructuredJSONScheme) EncodeToStream(obj Object, w io.Writer, overrides ...unversioned.GroupVersion) error {
|
||||
switch t := obj.(type) {
|
||||
case *Unstructured:
|
||||
return json.NewEncoder(w).Encode(t.Object)
|
||||
case *Unknown:
|
||||
_, err := w.Write(t.RawJSON)
|
||||
return err
|
||||
default:
|
||||
return json.NewEncoder(w).Encode(t)
|
||||
}
|
||||
if len(obj.APIVersion) == 0 {
|
||||
return unversioned.GroupVersionKind{}, conversion.NewMissingVersionErr(string(data))
|
||||
}
|
||||
if len(obj.Kind) == 0 {
|
||||
return unversioned.GroupVersionKind{}, conversion.NewMissingKindErr(string(data))
|
||||
}
|
||||
|
||||
gv, err := unversioned.ParseGroupVersion(obj.APIVersion)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
|
||||
return gv.WithKind(obj.Kind), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user