func TestRecognizer(t *testing.T) { s := runtime.NewScheme() s.AddKnownTypes(schema.GroupVersion{Version: "v1"}, &A{}) d := recognizer.NewDecoder( json.NewSerializer(json.DefaultMetaFactory, s, s, false), json.NewYAMLSerializer(json.DefaultMetaFactory, s, s), ) out, _, err := d.Decode([]byte(` kind: A apiVersion: v1 `), nil, nil) if err != nil { t.Fatal(err) } t.Logf("%#v", out) out, _, err = d.Decode([]byte(` { "kind":"A", "apiVersion":"v1" } `), nil, nil) if err != nil { t.Fatal(err) } t.Logf("%#v", out) }
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory) []serializerType { jsonSerializer := json.NewSerializer(mf, scheme, scheme, false) jsonPrettySerializer := json.NewSerializer(mf, scheme, scheme, true) yamlSerializer := json.NewYAMLSerializer(mf, scheme, scheme) serializers := []serializerType{ { AcceptContentTypes: []string{"application/json"}, ContentType: "application/json", FileExtensions: []string{"json"}, EncodesAsText: true, Serializer: jsonSerializer, PrettySerializer: jsonPrettySerializer, Framer: json.Framer, StreamSerializer: jsonSerializer, }, { AcceptContentTypes: []string{"application/yaml"}, ContentType: "application/yaml", FileExtensions: []string{"yaml"}, EncodesAsText: true, Serializer: yamlSerializer, }, } for _, fn := range serializerExtensions { if serializer, ok := fn(scheme); ok { serializers = append(serializers, serializer) } } return serializers }
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory) []serializerType { jsonSerializer := json.NewSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme), false) jsonPrettySerializer := json.NewSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme), true) serializers := []serializerType{ { AcceptContentTypes: []string{"application/json"}, ContentType: "application/json", FileExtensions: []string{"json"}, Serializer: jsonSerializer, PrettySerializer: jsonPrettySerializer, }, } yamlSerializer := json.NewYAMLSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme)) serializers = append(serializers, serializerType{ AcceptContentTypes: []string{"application/yaml"}, ContentType: "application/yaml", FileExtensions: []string{"yaml"}, Serializer: yamlSerializer, }) for _, fn := range serializerExtensions { if serializer, ok := fn(scheme); ok { serializers = append(serializers, serializer) } } return serializers }
func init() { yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, api.Scheme) Codec = versioning.NewCodecForScheme( api.Scheme, yamlSerializer, yamlSerializer, unversioned.GroupVersion{Version: Version}, runtime.InternalGroupVersioner, ) }
func init() { yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme)) Codec = versioning.NewCodecForScheme( api.Scheme, yamlSerializer, yamlSerializer, []unversioned.GroupVersion{{Version: Version}}, []unversioned.GroupVersion{{Version: runtime.APIVersionInternal}}, ) }
func init() { Scheme = runtime.NewScheme() if err := api.AddToScheme(Scheme); err != nil { // Programmer error, detect immediately panic(err) } if err := v1.AddToScheme(Scheme); err != nil { // Programmer error, detect immediately panic(err) } yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, Scheme, Scheme) Codec = versioning.NewCodecForScheme( Scheme, yamlSerializer, yamlSerializer, unversioned.GroupVersion{Version: Version}, runtime.InternalGroupVersioner, ) }
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory) []serializerType { jsonSerializer := json.NewSerializer(mf, scheme, scheme, false) jsonPrettySerializer := json.NewSerializer(mf, scheme, scheme, true) yamlSerializer := json.NewYAMLSerializer(mf, scheme, scheme) serializers := []serializerType{ { AcceptContentTypes: []string{"application/json"}, ContentType: "application/json", FileExtensions: []string{"json"}, EncodesAsText: true, Serializer: jsonSerializer, PrettySerializer: jsonPrettySerializer, AcceptStreamContentTypes: []string{"application/json", "application/json;stream=watch"}, StreamContentType: "application/json", Framer: json.Framer, StreamSerializer: jsonSerializer, }, { AcceptContentTypes: []string{"application/yaml"}, ContentType: "application/yaml", FileExtensions: []string{"yaml"}, EncodesAsText: true, Serializer: yamlSerializer, // TODO: requires runtime.RawExtension to properly distinguish when the nested content is // yaml, because the yaml encoder invokes MarshalJSON first //AcceptStreamContentTypes: []string{"application/yaml", "application/yaml;stream=watch"}, //StreamContentType: "application/yaml;stream=watch", //Framer: json.YAMLFramer, //StreamSerializer: yamlSerializer, }, } for _, fn := range serializerExtensions { if serializer, ok := fn(scheme); ok { serializers = append(serializers, serializer) } } return serializers }
// newCodecFactory is a helper for testing that allows a different metafactory to be specified. func newCodecFactory(scheme *runtime.Scheme, mf json.MetaFactory) CodecFactory { jsonSerializer := json.NewSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme), false) jsonPrettySerializer := json.NewSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme), true) yamlSerializer := json.NewYAMLSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme)) serializers := []serializerType{ { AcceptContentTypes: []string{"application/json"}, ContentType: "application/json", FileExtensions: []string{"json"}, Serializer: jsonSerializer, PrettySerializer: jsonPrettySerializer, }, { AcceptContentTypes: []string{"application/yaml"}, ContentType: "application/yaml", FileExtensions: []string{"yaml"}, Serializer: yamlSerializer, }, } decoders := make([]runtime.Decoder, 0, len(serializers)) accepts := []string{} alreadyAccepted := make(map[string]struct{}) for _, d := range serializers { decoders = append(decoders, d.Serializer) for _, mediaType := range d.AcceptContentTypes { if _, ok := alreadyAccepted[mediaType]; ok { continue } alreadyAccepted[mediaType] = struct{}{} accepts = append(accepts, mediaType) } } return CodecFactory{ scheme: scheme, serializers: serializers, universal: recognizer.NewDecoder(decoders...), accepts: accepts, legacySerializer: jsonSerializer, } }
func TestDecode(t *testing.T) { testCases := []struct { creater runtime.ObjectCreater typer runtime.ObjectTyper yaml bool pretty bool data []byte defaultGVK *schema.GroupVersionKind into runtime.Object errFn func(error) bool expectedObject runtime.Object expectedGVK *schema.GroupVersionKind }{ { data: []byte("{}"), expectedGVK: &schema.GroupVersionKind{}, errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'Kind' is missing in") }, }, { data: []byte("{}"), defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, creater: &mockCreater{err: fmt.Errorf("fake error")}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, errFn: func(err error) bool { return err.Error() == "fake error" }, }, { data: []byte("{}"), defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, creater: &mockCreater{obj: &testDecodable{}}, expectedObject: &testDecodable{}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, }, // version without group is not defaulted { data: []byte(`{"apiVersion":"blah"}`), defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, creater: &mockCreater{obj: &testDecodable{}}, expectedObject: &testDecodable{}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "", Version: "blah"}, }, // group without version is defaulted { data: []byte(`{"apiVersion":"other/"}`), defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, creater: &mockCreater{obj: &testDecodable{}}, expectedObject: &testDecodable{}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, }, // accept runtime.Unknown as into and bypass creator { data: []byte(`{}`), into: &runtime.Unknown{}, expectedGVK: &schema.GroupVersionKind{}, expectedObject: &runtime.Unknown{ Raw: []byte(`{}`), ContentType: runtime.ContentTypeJSON, }, }, { data: []byte(`{"test":"object"}`), into: &runtime.Unknown{}, expectedGVK: &schema.GroupVersionKind{}, expectedObject: &runtime.Unknown{ Raw: []byte(`{"test":"object"}`), ContentType: runtime.ContentTypeJSON, }, }, { data: []byte(`{"test":"object"}`), into: &runtime.Unknown{}, defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedObject: &runtime.Unknown{ TypeMeta: runtime.TypeMeta{APIVersion: "other/blah", Kind: "Test"}, Raw: []byte(`{"test":"object"}`), ContentType: runtime.ContentTypeJSON, }, }, // unregistered objects can be decoded into directly { data: []byte(`{"kind":"Test","apiVersion":"other/blah","value":1,"Other":"test"}`), into: &testDecodable{}, typer: &mockTyper{err: runtime.NewNotRegisteredErr(schema.GroupVersionKind{}, nil)}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedObject: &testDecodable{ Other: "test", Value: 1, }, }, // registered types get defaulted by the into object kind { data: []byte(`{"value":1,"Other":"test"}`), into: &testDecodable{}, typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedObject: &testDecodable{ Other: "test", Value: 1, }, }, // registered types get defaulted by the into object kind even without version, but return an error { data: []byte(`{"value":1,"Other":"test"}`), into: &testDecodable{}, typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""}}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""}, errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'apiVersion' is missing in") }, expectedObject: &testDecodable{ Other: "test", Value: 1, }, }, // runtime.VersionedObjects are decoded { data: []byte(`{"value":1,"Other":"test"}`), into: &runtime.VersionedObjects{Objects: []runtime.Object{}}, creater: &mockCreater{obj: &testDecodable{}}, typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}}, defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedObject: &runtime.VersionedObjects{ Objects: []runtime.Object{ &testDecodable{ Other: "test", Value: 1, }, }, }, }, // runtime.VersionedObjects with an object are decoded into { data: []byte(`{"Other":"test"}`), into: &runtime.VersionedObjects{Objects: []runtime.Object{&testDecodable{Value: 2}}}, typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}}, expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}, expectedObject: &runtime.VersionedObjects{ Objects: []runtime.Object{ &testDecodable{ Other: "test", Value: 2, }, }, }, }, } for i, test := range testCases { var s runtime.Serializer if test.yaml { s = json.NewYAMLSerializer(json.DefaultMetaFactory, test.creater, test.typer) } else { s = json.NewSerializer(json.DefaultMetaFactory, test.creater, test.typer, test.pretty) } obj, gvk, err := s.Decode([]byte(test.data), test.defaultGVK, test.into) if !reflect.DeepEqual(test.expectedGVK, gvk) { t.Errorf("%d: unexpected GVK: %v", i, gvk) } switch { case err == nil && test.errFn != nil: t.Errorf("%d: failed: %v", i, err) continue case err != nil && test.errFn == nil: t.Errorf("%d: failed: %v", i, err) continue case err != nil: if !test.errFn(err) { t.Errorf("%d: failed: %v", i, err) } if obj != nil { t.Errorf("%d: should have returned nil object", i) } continue } if test.into != nil && test.into != obj { t.Errorf("%d: expected into to be returned: %v", i, obj) continue } if !reflect.DeepEqual(test.expectedObject, obj) { t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj)) } } }
import ( "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" _ "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/serializer/json" "k8s.io/kubernetes/pkg/runtime/serializer/versioning" ) // Version is the string that represents the current external default version. const Version = "v1" var ExternalVersion = unversioned.GroupVersion{Group: "", Version: "v1"} // OldestVersion is the string that represents the oldest server version supported, // for client code that wants to hardcode the lowest common denominator. const OldestVersion = "v1" // Versions is the list of versions that are recognized in code. The order provided // may be assumed to be least feature rich to most feature rich, and clients may // choose to prefer the latter items in the list over the former items when presented // with a set of versions to choose. var Versions = []string{"v1"} var Codec = versioning.NewCodecForScheme( api.Scheme, json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme)), []unversioned.GroupVersion{{Version: Version}}, []unversioned.GroupVersion{{Version: runtime.APIVersionInternal}}, )