From 47e52d2981dc2a5c5950042f50688cf24dd92eda Mon Sep 17 00:00:00 2001 From: leigh capili Date: Thu, 4 Apr 2019 19:01:01 -0600 Subject: [PATCH] Refactor loops over SupportedMediaTypes() where mediaType is used to match a single SerializerInfo{} We have an existing helper function for this: runtime.SerializerInfoForMediaType() This is common prep-work for encoding runtime.Objects into JSON/YAML for transmission over the wire or writing to ComponentConfigs. --- cmd/kube-proxy/app/BUILD | 1 - cmd/kube-proxy/app/server.go | 19 ++++-------- cmd/kube-scheduler/app/options/BUILD | 1 - cmd/kube-scheduler/app/options/configfile.go | 21 +++++-------- cmd/kubeadm/app/util/marshal.go | 4 +-- .../src/k8s.io/apiserver/pkg/audit/request.go | 30 +++++++++---------- .../handlers/negotiation/negotiate.go | 5 +--- .../apiserver/pkg/endpoints/handlers/watch.go | 11 ++----- .../k8s.io/cli-runtime/pkg/resource/scheme.go | 10 ++----- .../client-go/deprecated-dynamic/bad_debt.go | 8 +---- 10 files changed, 37 insertions(+), 73 deletions(-) diff --git a/cmd/kube-proxy/app/BUILD b/cmd/kube-proxy/app/BUILD index d30c4dcc11..38459a7bce 100644 --- a/cmd/kube-proxy/app/BUILD +++ b/cmd/kube-proxy/app/BUILD @@ -47,7 +47,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_library", diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 51f1a2e63f..58ae6ed0c8 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -32,7 +32,6 @@ import ( v1meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/runtime/serializer/json" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/server/healthz" @@ -334,19 +333,13 @@ func (o *Options) runLoop() error { } func (o *Options) writeConfigFile() error { - var encoder runtime.Encoder - mediaTypes := o.codecs.SupportedMediaTypes() - for _, info := range mediaTypes { - if info.MediaType == "application/yaml" { - encoder = info.Serializer - break - } + const mediaType = runtime.ContentTypeYAML + info, ok := runtime.SerializerInfoForMediaType(o.codecs.SupportedMediaTypes(), mediaType) + if !ok { + return fmt.Errorf("unable to locate encoder -- %q is not a supported media type", mediaType) } - if encoder == nil { - return errors.New("unable to locate yaml encoder") - } - encoder = json.NewYAMLSerializer(json.DefaultMetaFactory, o.scheme, o.scheme) - encoder = o.codecs.EncoderForVersion(encoder, v1alpha1.SchemeGroupVersion) + + encoder := o.codecs.EncoderForVersion(info.Serializer, v1alpha1.SchemeGroupVersion) configFile, err := os.Create(o.WriteConfigTo) if err != nil { diff --git a/cmd/kube-scheduler/app/options/BUILD b/cmd/kube-scheduler/app/options/BUILD index c681c3e4e9..a6cb174dd1 100644 --- a/cmd/kube-scheduler/app/options/BUILD +++ b/cmd/kube-scheduler/app/options/BUILD @@ -23,7 +23,6 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library", diff --git a/cmd/kube-scheduler/app/options/configfile.go b/cmd/kube-scheduler/app/options/configfile.go index 25303ee347..cdd03b4726 100644 --- a/cmd/kube-scheduler/app/options/configfile.go +++ b/cmd/kube-scheduler/app/options/configfile.go @@ -17,12 +17,11 @@ limitations under the License. package options import ( - "errors" + "fmt" "io/ioutil" "os" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer/json" kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config" kubeschedulerscheme "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme" kubeschedulerconfigv1alpha1 "k8s.io/kubernetes/pkg/scheduler/apis/config/v1alpha1" @@ -48,19 +47,13 @@ func loadConfig(data []byte) (*kubeschedulerconfig.KubeSchedulerConfiguration, e // WriteConfigFile writes the config into the given file name as YAML. func WriteConfigFile(fileName string, cfg *kubeschedulerconfig.KubeSchedulerConfiguration) error { - var encoder runtime.Encoder - mediaTypes := kubeschedulerscheme.Codecs.SupportedMediaTypes() - for _, info := range mediaTypes { - if info.MediaType == "application/yaml" { - encoder = info.Serializer - break - } + const mediaType = runtime.ContentTypeYAML + info, ok := runtime.SerializerInfoForMediaType(kubeschedulerscheme.Codecs.SupportedMediaTypes(), mediaType) + if !ok { + return fmt.Errorf("unable to locate encoder -- %q is not a supported media type", mediaType) } - if encoder == nil { - return errors.New("unable to locate yaml encoder") - } - encoder = json.NewYAMLSerializer(json.DefaultMetaFactory, kubeschedulerscheme.Scheme, kubeschedulerscheme.Scheme) - encoder = kubeschedulerscheme.Codecs.EncoderForVersion(encoder, kubeschedulerconfigv1alpha1.SchemeGroupVersion) + + encoder := kubeschedulerscheme.Codecs.EncoderForVersion(info.Serializer, kubeschedulerconfigv1alpha1.SchemeGroupVersion) configFile, err := os.Create(fileName) if err != nil { diff --git a/cmd/kubeadm/app/util/marshal.go b/cmd/kubeadm/app/util/marshal.go index 5fca9950ad..de890f64ca 100644 --- a/cmd/kubeadm/app/util/marshal.go +++ b/cmd/kubeadm/app/util/marshal.go @@ -42,7 +42,7 @@ func MarshalToYaml(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) { // TODO: Is specifying the gv really needed here? // TODO: Can we support json out of the box easily here? func MarshalToYamlForCodecs(obj runtime.Object, gv schema.GroupVersion, codecs serializer.CodecFactory) ([]byte, error) { - mediaType := "application/yaml" + const mediaType = runtime.ContentTypeYAML info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType) if !ok { return []byte{}, errors.Errorf("unsupported media type %q", mediaType) @@ -61,7 +61,7 @@ func UnmarshalFromYaml(buffer []byte, gv schema.GroupVersion) (runtime.Object, e // TODO: Is specifying the gv really needed here? // TODO: Can we support json out of the box easily here? func UnmarshalFromYamlForCodecs(buffer []byte, gv schema.GroupVersion, codecs serializer.CodecFactory) (runtime.Object, error) { - mediaType := "application/yaml" + const mediaType = runtime.ContentTypeYAML info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType) if !ok { return nil, errors.Errorf("unsupported media type %q", mediaType) diff --git a/staging/src/k8s.io/apiserver/pkg/audit/request.go b/staging/src/k8s.io/apiserver/pkg/audit/request.go index 7ddf764ba6..9cbbb90dad 100644 --- a/staging/src/k8s.io/apiserver/pkg/audit/request.go +++ b/staging/src/k8s.io/apiserver/pkg/audit/request.go @@ -197,22 +197,22 @@ func LogResponseObject(ae *auditinternal.Event, obj runtime.Object, gv schema.Gr } func encodeObject(obj runtime.Object, gv schema.GroupVersion, serializer runtime.NegotiatedSerializer) (*runtime.Unknown, error) { - supported := serializer.SupportedMediaTypes() - for i := range supported { - if supported[i].MediaType == "application/json" { - enc := serializer.EncoderForVersion(supported[i].Serializer, gv) - var buf bytes.Buffer - if err := enc.Encode(obj, &buf); err != nil { - return nil, fmt.Errorf("encoding failed: %v", err) - } - - return &runtime.Unknown{ - Raw: buf.Bytes(), - ContentType: runtime.ContentTypeJSON, - }, nil - } + const mediaType = runtime.ContentTypeJSON + info, ok := runtime.SerializerInfoForMediaType(serializer.SupportedMediaTypes(), mediaType) + if !ok { + return nil, fmt.Errorf("unable to locate encoder -- %q is not a supported media type", mediaType) } - return nil, fmt.Errorf("no json encoder found") + + enc := serializer.EncoderForVersion(info.Serializer, gv) + var buf bytes.Buffer + if err := enc.Encode(obj, &buf); err != nil { + return nil, fmt.Errorf("encoding failed: %v", err) + } + + return &runtime.Unknown{ + Raw: buf.Bytes(), + ContentType: runtime.ContentTypeJSON, + }, nil } // LogAnnotation fills in the Annotations according to the key value pair. diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation/negotiate.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation/negotiate.go index 8ac1e8f356..c00d4f3ac6 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation/negotiate.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation/negotiate.go @@ -79,10 +79,7 @@ func NegotiateInputSerializerForMediaType(mediaType string, streaming bool, ns r mediaType = mediaTypes[0].MediaType } if mediaType, _, err := mime.ParseMediaType(mediaType); err == nil { - for _, info := range mediaTypes { - if info.MediaType != mediaType { - continue - } + if info, ok := runtime.SerializerInfoForMediaType(mediaTypes, mediaType); ok { return info, nil } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go index 7dd515ee1d..e7ab679988 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go @@ -94,17 +94,12 @@ func serveWatch(watcher watch.Interface, scope *RequestScope, mediaTypeOptions n var embeddedEncoder runtime.Encoder contentKind, contentSerializer, transform := targetEncodingForTransform(scope, mediaTypeOptions, req) if transform { - var embedded runtime.Serializer - for _, supported := range contentSerializer.SupportedMediaTypes() { - if supported.MediaType == serializer.MediaType { - embedded = supported.Serializer - } - } - if embedded == nil { + info, ok := runtime.SerializerInfoForMediaType(contentSerializer.SupportedMediaTypes(), serializer.MediaType) + if !ok { scope.err(fmt.Errorf("no encoder for %q exists in the requested target %#v", serializer.MediaType, contentSerializer), w, req) return } - embeddedEncoder = contentSerializer.EncoderForVersion(embedded, contentKind.GroupVersion()) + embeddedEncoder = contentSerializer.EncoderForVersion(info.Serializer, contentKind.GroupVersion()) } else { embeddedEncoder = scope.Serializer.EncoderForVersion(serializer.Serializer, contentKind.GroupVersion()) } diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go b/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go index fef6edfc1b..5459fdded9 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go @@ -56,18 +56,12 @@ func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error { return unstructured.UnstructuredJSONScheme.Encode(obj, w) } -// ContentConfig returns a rest.ContentConfig for dynamic types. It includes enough codecs to act as a "normal" +// UnstructuredPlusDefaultContentConfig returns a rest.ContentConfig for dynamic types. It includes enough codecs to act as a "normal" // serializer for the rest.client with options, status and the like. func UnstructuredPlusDefaultContentConfig() rest.ContentConfig { - var jsonInfo runtime.SerializerInfo // TODO: scheme.Codecs here should become "pkg/apis/server/scheme" which is the minimal core you need // to talk to a kubernetes server - for _, info := range scheme.Codecs.SupportedMediaTypes() { - if info.MediaType == runtime.ContentTypeJSON { - jsonInfo = info - break - } - } + jsonInfo, _ := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) jsonInfo.Serializer = dynamicCodec{} jsonInfo.PrettySerializer = nil diff --git a/staging/src/k8s.io/client-go/deprecated-dynamic/bad_debt.go b/staging/src/k8s.io/client-go/deprecated-dynamic/bad_debt.go index 51e4a5830e..7478b49b9a 100644 --- a/staging/src/k8s.io/client-go/deprecated-dynamic/bad_debt.go +++ b/staging/src/k8s.io/client-go/deprecated-dynamic/bad_debt.go @@ -59,15 +59,9 @@ func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error { // ContentConfig returns a rest.ContentConfig for dynamic types. // Deprecated only used by test code and its wrong func ContentConfig() rest.ContentConfig { - var jsonInfo runtime.SerializerInfo // TODO: scheme.Codecs here should become "pkg/apis/server/scheme" which is the minimal core you need // to talk to a kubernetes server - for _, info := range scheme.Codecs.SupportedMediaTypes() { - if info.MediaType == runtime.ContentTypeJSON { - jsonInfo = info - break - } - } + jsonInfo, _ := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) jsonInfo.Serializer = dynamicCodec{} jsonInfo.PrettySerializer = nil