mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 13:55:41 +00:00
Add CBOR serializer option to disable JSON transcoding of raw types.
This commit is contained in:
parent
db1239d354
commit
d638d64572
@ -68,17 +68,30 @@ type Serializer interface {
|
|||||||
var _ Serializer = &serializer{}
|
var _ Serializer = &serializer{}
|
||||||
|
|
||||||
type options struct {
|
type options struct {
|
||||||
strict bool
|
strict bool
|
||||||
|
transcode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(*options)
|
type Option func(*options)
|
||||||
|
|
||||||
|
// Strict configures a serializer to return a strict decoding error when it encounters map keys that
|
||||||
|
// do not correspond to a field in the target object of a decode operation. This option is disabled
|
||||||
|
// by default.
|
||||||
func Strict(s bool) Option {
|
func Strict(s bool) Option {
|
||||||
return func(opts *options) {
|
return func(opts *options) {
|
||||||
opts.strict = s
|
opts.strict = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transcode configures a serializer to transcode the "raw" bytes of a decoded runtime.RawExtension
|
||||||
|
// or metav1.FieldsV1 object to JSON. This is enabled by default to support existing programs that
|
||||||
|
// depend on the assumption that objects of either type contain valid JSON.
|
||||||
|
func Transcode(s bool) Option {
|
||||||
|
return func(opts *options) {
|
||||||
|
opts.transcode = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type serializer struct {
|
type serializer struct {
|
||||||
metaFactory metaFactory
|
metaFactory metaFactory
|
||||||
creater runtime.ObjectCreater
|
creater runtime.ObjectCreater
|
||||||
@ -88,6 +101,8 @@ type serializer struct {
|
|||||||
|
|
||||||
func (serializer) private() {}
|
func (serializer) private() {}
|
||||||
|
|
||||||
|
// NewSerializer creates and returns a serializer configured with the provided options. The default
|
||||||
|
// options are equivalent to explicitly passing Strict(false) and Transcode(true).
|
||||||
func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, options ...Option) Serializer {
|
func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, options ...Option) Serializer {
|
||||||
return newSerializer(&defaultMetaFactory{}, creater, typer, options...)
|
return newSerializer(&defaultMetaFactory{}, creater, typer, options...)
|
||||||
}
|
}
|
||||||
@ -98,6 +113,7 @@ func newSerializer(metaFactory metaFactory, creater runtime.ObjectCreater, typer
|
|||||||
creater: creater,
|
creater: creater,
|
||||||
typer: typer,
|
typer: typer,
|
||||||
}
|
}
|
||||||
|
s.options.transcode = true
|
||||||
for _, o := range options {
|
for _, o := range options {
|
||||||
o(&s.options)
|
o(&s.options)
|
||||||
}
|
}
|
||||||
@ -337,9 +353,10 @@ func (s *serializer) Decode(data []byte, gvk *schema.GroupVersionKind, into runt
|
|||||||
return nil, actual, err
|
return nil, actual, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make possible to disable this behavior.
|
if s.options.transcode {
|
||||||
if err := transcodeRawTypes(obj); err != nil {
|
if err := transcodeRawTypes(obj); err != nil {
|
||||||
return nil, actual, err
|
return nil, actual, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj, actual, strict
|
return obj, actual, strict
|
||||||
|
@ -345,6 +345,33 @@ func TestDecode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "raw types not transcoded",
|
||||||
|
options: []Option{Transcode(false)},
|
||||||
|
data: []byte{0xa4, 0x41, 'f', 0xa1, 0x41, 'a', 0x01, 0x42, 'f', 'p', 0xa1, 0x41, 'z', 0x02, 0x41, 'r', 0xa1, 0x41, 'b', 0x03, 0x42, 'r', 'p', 0xa1, 0x41, 'y', 0x04},
|
||||||
|
gvk: &schema.GroupVersionKind{},
|
||||||
|
metaFactory: stubMetaFactory{gvk: &schema.GroupVersionKind{}},
|
||||||
|
typer: stubTyper{gvks: []schema.GroupVersionKind{{Group: "x", Version: "y", Kind: "z"}}},
|
||||||
|
into: &structWithRawFields{},
|
||||||
|
expectedObj: &structWithRawFields{
|
||||||
|
FieldsV1: metav1.FieldsV1{Raw: []byte{0xa1, 0x41, 'a', 0x01}},
|
||||||
|
FieldsV1Pointer: &metav1.FieldsV1{Raw: []byte{0xa1, 0x41, 'z', 0x02}},
|
||||||
|
// RawExtension's UnmarshalCBOR ensures the self-described CBOR tag
|
||||||
|
// is present in the result so that there is never any ambiguity in
|
||||||
|
// distinguishing CBOR from JSON or Protobuf. It is unnecessary for
|
||||||
|
// FieldsV1 to do the same because the initial byte is always
|
||||||
|
// sufficient to distinguish a valid JSON-encoded FieldsV1 from a
|
||||||
|
// valid CBOR-encoded FieldsV1.
|
||||||
|
RawExtension: runtime.RawExtension{Raw: []byte{0xd9, 0xd9, 0xf7, 0xa1, 0x41, 'b', 0x03}},
|
||||||
|
RawExtensionPointer: &runtime.RawExtension{Raw: []byte{0xd9, 0xd9, 0xf7, 0xa1, 0x41, 'y', 0x04}},
|
||||||
|
},
|
||||||
|
expectedGVK: &schema.GroupVersionKind{Group: "x", Version: "y", Kind: "z"},
|
||||||
|
assertOnError: func(t *testing.T, err error) {
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected nil error, got: %v", err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "object with embedded typemeta and objectmeta",
|
name: "object with embedded typemeta and objectmeta",
|
||||||
data: []byte("\xa2\x48metadata\xa1\x44name\x43foo\x44spec\xa0"), // {"metadata": {"name": "foo"}}
|
data: []byte("\xa2\x48metadata\xa1\x44name\x43foo\x44spec\xa0"), // {"metadata": {"name": "foo"}}
|
||||||
|
Loading…
Reference in New Issue
Block a user