Make defaulting part of versioning codec

Most normal codec use should perform defaulting. DirectCodecs should not
perform defaulting. Update the defaulting_test to fuzz the list of known
defaulters. Use the new versioning.NewDefaultingCodec() method.
This commit is contained in:
Clayton Coleman
2016-09-25 12:09:52 -04:00
parent 742fb698d4
commit 1694cfb72d
9 changed files with 191 additions and 48 deletions

View File

@@ -21,6 +21,7 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
)
// NewCodecForScheme is a convenience method for callers that are using a scheme.
@@ -32,7 +33,19 @@ func NewCodecForScheme(
encodeVersion runtime.GroupVersioner,
decodeVersion runtime.GroupVersioner,
) runtime.Codec {
return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, scheme, encodeVersion, decodeVersion)
return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, scheme, nil, encodeVersion, decodeVersion)
}
// NewDefaultingCodecForScheme is a convenience method for callers that are using a scheme.
func NewDefaultingCodecForScheme(
// TODO: I should be a scheme interface?
scheme *runtime.Scheme,
encoder runtime.Encoder,
decoder runtime.Decoder,
encodeVersion runtime.GroupVersioner,
decodeVersion runtime.GroupVersioner,
) runtime.Codec {
return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, scheme, scheme, encodeVersion, decodeVersion)
}
// NewCodec takes objects in their internal versions and converts them to external versions before
@@ -45,6 +58,7 @@ func NewCodec(
creater runtime.ObjectCreater,
copier runtime.ObjectCopier,
typer runtime.ObjectTyper,
defaulter runtime.ObjectDefaulter,
encodeVersion runtime.GroupVersioner,
decodeVersion runtime.GroupVersioner,
) runtime.Codec {
@@ -55,6 +69,7 @@ func NewCodec(
creater: creater,
copier: copier,
typer: typer,
defaulter: defaulter,
encodeVersion: encodeVersion,
decodeVersion: decodeVersion,
@@ -69,6 +84,7 @@ type codec struct {
creater runtime.ObjectCreater
copier runtime.ObjectCopier
typer runtime.ObjectTyper
defaulter runtime.ObjectDefaulter
encodeVersion runtime.GroupVersioner
decodeVersion runtime.GroupVersioner
@@ -102,11 +118,31 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
}
return into, gvk, nil
}
// perform defaulting if requested
if c.defaulter != nil {
// create a copy to ensure defaulting is not applied to the original versioned objects
if isVersioned {
copied, err := c.copier.Copy(obj)
if err != nil {
utilruntime.HandleError(err)
copied = obj
}
versioned.Objects = []runtime.Object{copied}
}
c.defaulter.Default(obj)
} else {
if isVersioned {
versioned.Objects = []runtime.Object{obj}
}
}
if err := c.convertor.Convert(obj, into, c.decodeVersion); err != nil {
return nil, gvk, err
}
if isVersioned {
versioned.Objects = []runtime.Object{obj, into}
versioned.Objects = append(versioned.Objects, into)
return versioned, gvk, nil
}
return into, gvk, nil
@@ -117,10 +153,17 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
// create a copy, because ConvertToVersion does not guarantee non-mutation of objects
copied, err := c.copier.Copy(obj)
if err != nil {
utilruntime.HandleError(err)
copied = obj
}
versioned.Objects = []runtime.Object{copied}
}
// perform defaulting if requested
if c.defaulter != nil {
c.defaulter.Default(obj)
}
out, err := c.convertor.ConvertToVersion(obj, c.decodeVersion)
if err != nil {
return nil, gvk, err