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 }
// New creates a new WebhookAuthorizer from the provided kubeconfig file. // // The config's cluster field is used to refer to the remote service, user refers to the returned authorizer. // // # clusters refers to the remote service. // clusters: // - name: name-of-remote-authz-service // cluster: // certificate-authority: /path/to/ca.pem # CA for verifying the remote service. // server: https://authz.example.com/authorize # URL of remote service to query. Must use 'https'. // // # users refers to the API server's webhook configuration. // users: // - name: name-of-api-server // user: // client-certificate: /path/to/cert.pem # cert for the webhook plugin to use // client-key: /path/to/key.pem # key matching the cert // // For additional HTTP configuration, refer to the kubeconfig documentation // http://kubernetes.io/v1.1/docs/user-guide/kubeconfig-file.html. func New(kubeConfigFile string) (*WebhookAuthorizer, error) { for _, groupVersion := range requireEnabled { if !registered.IsEnabledVersion(groupVersion) { return nil, fmt.Errorf("webhook authz plugin requires enabling extension resource: %s", groupVersion) } } loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules.ExplicitPath = kubeConfigFile loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) clientConfig, err := loader.ClientConfig() if err != nil { return nil, err } serializer := json.NewSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), false) clientConfig.ContentConfig.Codec = versioning.NewCodecForScheme(api.Scheme, serializer, serializer, encodeVersions, decodeVersions) restClient, err := restclient.UnversionedRESTClientFor(clientConfig) if err != nil { return nil, err } // TODO(ericchiang): Can we ensure remote service is reachable? return &WebhookAuthorizer{restClient}, nil }
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 init() { jsonSerializer := json.NewSerializer(json.DefaultMetaFactory, api.Scheme, api.Scheme, true) Codec = versioning.NewCodecForScheme( api.Scheme, jsonSerializer, jsonSerializer, []unversioned.GroupVersion{{Version: Version}}, []unversioned.GroupVersion{{Version: runtime.APIVersionInternal}}, ) }
func init() { jsonSerializer := json.NewSerializer(json.DefaultMetaFactory, api.Scheme, api.Scheme, true) Codec = versioning.NewDefaultingCodecForScheme( api.Scheme, jsonSerializer, jsonSerializer, 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/runtime" "k8s.io/kubernetes/pkg/runtime/serializer/json" "k8s.io/kubernetes/pkg/runtime/serializer/versioning" "k8s.io/kubernetes/plugin/pkg/scheduler/api" _ "k8s.io/kubernetes/plugin/pkg/scheduler/api/v1" ) // Version is the string that represents the current external default version. const Version = "v1" // OldestVersion is the string that represents the oldest server version supported. 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"} // Codec is the default codec for serializing input that should use // the latest supported version. It supports JSON by default. var Codec = versioning.NewCodecForScheme( api.Scheme, json.NewSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), true), []unversioned.GroupVersion{{Version: Version}}, []unversioned.GroupVersion{{Version: runtime.APIVersionInternal}}, )