From 5f8366aac3094ee8dc5b560829130ecb1eb6b04d Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 4 Jul 2016 16:13:27 -0400 Subject: [PATCH] Convert() should accept the new conversion Context value Allows Convert() to reuse the same conversions as ConvertToVersion without being overly coupled to the version. --- cmd/kube-proxy/app/options/options.go | 2 +- cmd/kubelet/app/options/options.go | 2 +- pkg/api/meta/restmapper_test.go | 2 +- pkg/api/serialization_proto_test.go | 2 +- pkg/api/serialization_test.go | 2 +- pkg/api/v1/conversion_test.go | 6 +++--- pkg/api/v1/defaults_test.go | 2 +- pkg/apis/abac/v0/conversion_test.go | 2 +- pkg/apis/extensions/v1beta1/conversion_test.go | 4 ++-- pkg/apis/extensions/v1beta1/defaults_test.go | 2 +- pkg/auth/authorizer/abac/abac.go | 2 +- pkg/auth/authorizer/abac/abac_test.go | 4 ++-- pkg/controller/controller_utils.go | 2 +- pkg/controller/scheduledjob/utils.go | 2 +- pkg/kubelet/config/file_test.go | 2 +- pkg/kubelet/config/http_test.go | 2 +- pkg/registry/thirdpartyresourcedata/codec.go | 4 ++-- pkg/runtime/codec.go | 6 +++--- pkg/runtime/conversion_test.go | 2 +- pkg/runtime/interfaces.go | 8 +++++--- pkg/runtime/scheme_test.go | 4 ++-- pkg/runtime/serializer/versioning/versioning.go | 2 +- pkg/runtime/serializer/versioning/versioning_test.go | 2 +- pkg/runtime/unstructured.go | 2 +- plugin/cmd/kube-scheduler/app/options/options.go | 2 +- 25 files changed, 37 insertions(+), 35 deletions(-) diff --git a/cmd/kube-proxy/app/options/options.go b/cmd/kube-proxy/app/options/options.go index 0f492cd9f67..27382dd0054 100644 --- a/cmd/kube-proxy/app/options/options.go +++ b/cmd/kube-proxy/app/options/options.go @@ -50,7 +50,7 @@ type ProxyServerConfig struct { func NewProxyConfig() *ProxyServerConfig { config := componentconfig.KubeProxyConfiguration{} - api.Scheme.Convert(&v1alpha1.KubeProxyConfiguration{}, &config) + api.Scheme.Convert(&v1alpha1.KubeProxyConfiguration{}, &config, nil) return &ProxyServerConfig{ KubeProxyConfiguration: config, ContentType: "application/vnd.kubernetes.protobuf", diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index 45aad5afa6e..f175c177745 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -58,7 +58,7 @@ type KubeletServer struct { // NewKubeletServer will create a new KubeletServer with default values. func NewKubeletServer() *KubeletServer { config := componentconfig.KubeletConfiguration{} - api.Scheme.Convert(&v1alpha1.KubeletConfiguration{}, &config) + api.Scheme.Convert(&v1alpha1.KubeletConfiguration{}, &config, nil) return &KubeletServer{ AuthPath: util.NewStringFlag("/var/lib/kubelet/kubernetes_auth"), // deprecated KubeConfig: util.NewStringFlag("/var/lib/kubelet/kubeconfig"), diff --git a/pkg/api/meta/restmapper_test.go b/pkg/api/meta/restmapper_test.go index c4900d4aa44..11d7c11be0a 100644 --- a/pkg/api/meta/restmapper_test.go +++ b/pkg/api/meta/restmapper_test.go @@ -28,7 +28,7 @@ import ( type fakeConvertor struct{} -func (fakeConvertor) Convert(in, out interface{}) error { +func (fakeConvertor) Convert(in, out, context interface{}) error { return nil } diff --git a/pkg/api/serialization_proto_test.go b/pkg/api/serialization_proto_test.go index b899a71314b..5a75071e0dd 100644 --- a/pkg/api/serialization_proto_test.go +++ b/pkg/api/serialization_proto_test.go @@ -106,7 +106,7 @@ func BenchmarkEncodeCodecFromInternalProtobuf(b *testing.B) { width := len(items) encodable := make([]api.Pod, width) for i := range items { - if err := api.Scheme.Convert(&items[i], &encodable[i]); err != nil { + if err := api.Scheme.Convert(&items[i], &encodable[i], nil); err != nil { b.Fatal(err) } } diff --git a/pkg/api/serialization_test.go b/pkg/api/serialization_test.go index f3af252aec5..dcaf1880f3f 100644 --- a/pkg/api/serialization_test.go +++ b/pkg/api/serialization_test.go @@ -482,7 +482,7 @@ func BenchmarkEncodeCodecFromInternal(b *testing.B) { width := len(items) encodable := make([]api.Pod, width) for i := range items { - if err := api.Scheme.Convert(&items[i], &encodable[i]); err != nil { + if err := api.Scheme.Convert(&items[i], &encodable[i], nil); err != nil { b.Fatal(err) } } diff --git a/pkg/api/v1/conversion_test.go b/pkg/api/v1/conversion_test.go index 27c215f3cfe..1384de341f7 100644 --- a/pkg/api/v1/conversion_test.go +++ b/pkg/api/v1/conversion_test.go @@ -127,7 +127,7 @@ func TestPodSpecConversion(t *testing.T) { ServiceAccountName: name, } v := versioned.PodSpec{} - if err := api.Scheme.Convert(i, &v); err != nil { + if err := api.Scheme.Convert(i, &v, nil); err != nil { t.Fatalf("unexpected error: %v", err) } if v.ServiceAccountName != name { @@ -152,7 +152,7 @@ func TestPodSpecConversion(t *testing.T) { } for k, v := range testCases { got := api.PodSpec{} - err := api.Scheme.Convert(v, &got) + err := api.Scheme.Convert(v, &got, nil) if err != nil { t.Fatalf("unexpected error for case %d: %v", k, err) } @@ -206,7 +206,7 @@ func TestResourceListConversion(t *testing.T) { for i, test := range tests { output := api.ResourceList{} - err := api.Scheme.Convert(&test.input, &output) + err := api.Scheme.Convert(&test.input, &output, nil) if err != nil { t.Fatalf("unexpected error for case %d: %v", i, err) } diff --git a/pkg/api/v1/defaults_test.go b/pkg/api/v1/defaults_test.go index 6987d0f301c..e7c802f6166 100644 --- a/pkg/api/v1/defaults_test.go +++ b/pkg/api/v1/defaults_test.go @@ -40,7 +40,7 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { return nil } obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) - err = api.Scheme.Convert(obj2, obj3) + err = api.Scheme.Convert(obj2, obj3, nil) if err != nil { t.Errorf("%v\nSource: %#v", err, obj2) return nil diff --git a/pkg/apis/abac/v0/conversion_test.go b/pkg/apis/abac/v0/conversion_test.go index 827e8ce3681..30a433b5e35 100644 --- a/pkg/apis/abac/v0/conversion_test.go +++ b/pkg/apis/abac/v0/conversion_test.go @@ -67,7 +67,7 @@ func TestConversion(t *testing.T) { } for k, tc := range testcases { internal := &api.Policy{} - if err := api.Scheme.Convert(tc.old, internal); err != nil { + if err := api.Scheme.Convert(tc.old, internal, nil); err != nil { t.Errorf("%s: unexpected error: %v", k, err) } if !reflect.DeepEqual(internal, tc.expected) { diff --git a/pkg/apis/extensions/v1beta1/conversion_test.go b/pkg/apis/extensions/v1beta1/conversion_test.go index 5fab6b2f463..82fd46009e6 100644 --- a/pkg/apis/extensions/v1beta1/conversion_test.go +++ b/pkg/apis/extensions/v1beta1/conversion_test.go @@ -59,7 +59,7 @@ func TestJobSpecConversion(t *testing.T) { ManualSelector: test.in, } v := versioned.JobSpec{} - if err := api.Scheme.Convert(i, &v); err != nil { + if err := api.Scheme.Convert(i, &v, nil); err != nil { t.Fatalf("unexpected error: %v", err) } if !reflect.DeepEqual(test.expectOut, v.AutoSelector) { @@ -73,7 +73,7 @@ func TestJobSpecConversion(t *testing.T) { AutoSelector: test.in, } e := batch.JobSpec{} - if err := api.Scheme.Convert(i, &e); err != nil { + if err := api.Scheme.Convert(i, &e, nil); err != nil { t.Fatalf("unexpected error: %v", err) } if !reflect.DeepEqual(test.expectOut, e.ManualSelector) { diff --git a/pkg/apis/extensions/v1beta1/defaults_test.go b/pkg/apis/extensions/v1beta1/defaults_test.go index 092cbe4b2e4..4a90f178215 100644 --- a/pkg/apis/extensions/v1beta1/defaults_test.go +++ b/pkg/apis/extensions/v1beta1/defaults_test.go @@ -728,7 +728,7 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { return nil } obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) - err = api.Scheme.Convert(obj2, obj3) + err = api.Scheme.Convert(obj2, obj3, nil) if err != nil { t.Errorf("%v\nSource: %#v", err, obj2) return nil diff --git a/pkg/auth/authorizer/abac/abac.go b/pkg/auth/authorizer/abac/abac.go index 75db334e819..ef4b74d694a 100644 --- a/pkg/auth/authorizer/abac/abac.go +++ b/pkg/auth/authorizer/abac/abac.go @@ -89,7 +89,7 @@ func NewFromFile(path string) (policyList, error) { if err := runtime.DecodeInto(decoder, b, oldPolicy); err != nil { return nil, policyLoadError{path, i, b, err} } - if err := api.Scheme.Convert(oldPolicy, p); err != nil { + if err := api.Scheme.Convert(oldPolicy, p, nil); err != nil { return nil, policyLoadError{path, i, b, err} } pl = append(pl, p) diff --git a/pkg/auth/authorizer/abac/abac_test.go b/pkg/auth/authorizer/abac/abac_test.go index 0070fbdea32..05d09aa51c8 100644 --- a/pkg/auth/authorizer/abac/abac_test.go +++ b/pkg/auth/authorizer/abac/abac_test.go @@ -562,7 +562,7 @@ func TestSubjectMatches(t *testing.T) { for k, tc := range testCases { policy := &api.Policy{} - if err := api.Scheme.Convert(tc.Policy, policy); err != nil { + if err := api.Scheme.Convert(tc.Policy, policy, nil); err != nil { t.Errorf("%s: error converting: %v", k, err) continue } @@ -950,7 +950,7 @@ func TestPolicy(t *testing.T) { } for _, test := range tests { policy := &api.Policy{} - if err := api.Scheme.Convert(test.policy, policy); err != nil { + if err := api.Scheme.Convert(test.policy, policy, nil); err != nil { t.Errorf("%s: error converting: %v", test.name, err) continue } diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go index 81930422eba..0a851c23f81 100644 --- a/pkg/controller/controller_utils.go +++ b/pkg/controller/controller_utils.go @@ -458,7 +458,7 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje if controllerRef != nil { pod.OwnerReferences = append(pod.OwnerReferences, *controllerRef) } - if err := api.Scheme.Convert(&template.Spec, &pod.Spec); err != nil { + if err := api.Scheme.Convert(&template.Spec, &pod.Spec, nil); err != nil { return nil, fmt.Errorf("unable to convert pod template: %v", err) } return pod, nil diff --git a/pkg/controller/scheduledjob/utils.go b/pkg/controller/scheduledjob/utils.go index a5d716baf0e..f65b2a2d136 100644 --- a/pkg/controller/scheduledjob/utils.go +++ b/pkg/controller/scheduledjob/utils.go @@ -209,7 +209,7 @@ func getJobFromTemplate(sj *batch.ScheduledJob, scheduledTime time.Time) (*batch Name: name, }, } - if err := api.Scheme.Convert(&sj.Spec.JobTemplate.Spec, &job.Spec); err != nil { + if err := api.Scheme.Convert(&sj.Spec.JobTemplate.Spec, &job.Spec, nil); err != nil { return nil, fmt.Errorf("unable to convert job template: %v", err) } return job, nil diff --git a/pkg/kubelet/config/file_test.go b/pkg/kubelet/config/file_test.go index ce79d88f4cf..f6bb67e81bb 100644 --- a/pkg/kubelet/config/file_test.go +++ b/pkg/kubelet/config/file_test.go @@ -129,7 +129,7 @@ func TestReadPodsFromFile(t *testing.T) { for _, testCase := range testCases { func() { var versionedPod runtime.Object - err := testapi.Default.Converter().Convert(&testCase.pod, &versionedPod) + err := testapi.Default.Converter().Convert(&testCase.pod, &versionedPod, nil) if err != nil { t.Fatalf("%s: error in versioning the pod: %v", testCase.desc, err) } diff --git a/pkg/kubelet/config/http_test.go b/pkg/kubelet/config/http_test.go index 20b4dc39e1c..9e70d9eecad 100644 --- a/pkg/kubelet/config/http_test.go +++ b/pkg/kubelet/config/http_test.go @@ -276,7 +276,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { for _, testCase := range testCases { var versionedPods runtime.Object - err := testapi.Default.Converter().Convert(&testCase.pods, &versionedPods) + err := testapi.Default.Converter().Convert(&testCase.pods, &versionedPods, nil) if err != nil { t.Fatalf("%s: error in versioning the pods: %s", testCase.desc, err) } diff --git a/pkg/registry/thirdpartyresourcedata/codec.go b/pkg/registry/thirdpartyresourcedata/codec.go index 323b640324d..64308565e77 100644 --- a/pkg/registry/thirdpartyresourcedata/codec.go +++ b/pkg/registry/thirdpartyresourcedata/codec.go @@ -53,8 +53,8 @@ func (t *thirdPartyObjectConverter) ConvertToVersion(in runtime.Object, outVersi } } -func (t *thirdPartyObjectConverter) Convert(in, out interface{}) error { - return t.converter.Convert(in, out) +func (t *thirdPartyObjectConverter) Convert(in, out, context interface{}) error { + return t.converter.Convert(in, out, context) } func (t *thirdPartyObjectConverter) ConvertFieldLabel(version, kind, label, value string) (string, string, error) { diff --git a/pkg/runtime/codec.go b/pkg/runtime/codec.go index 58e1d3b6784..9077f0fcd73 100644 --- a/pkg/runtime/codec.go +++ b/pkg/runtime/codec.go @@ -145,16 +145,16 @@ func (c *parameterCodec) DecodeParameters(parameters url.Values, from unversione } targetGVK := targetGVKs[0] if targetGVK.GroupVersion() == from { - return c.convertor.Convert(¶meters, into) + return c.convertor.Convert(¶meters, into, nil) } input, err := c.creator.New(from.WithKind(targetGVK.Kind)) if err != nil { return err } - if err := c.convertor.Convert(¶meters, input); err != nil { + if err := c.convertor.Convert(¶meters, input, nil); err != nil { return err } - return c.convertor.Convert(input, into) + return c.convertor.Convert(input, into, nil) } // EncodeParameters converts the provided object into the to version, then converts that object to url.Values. diff --git a/pkg/runtime/conversion_test.go b/pkg/runtime/conversion_test.go index c364d8fd2d4..9c2e7f9f81a 100644 --- a/pkg/runtime/conversion_test.go +++ b/pkg/runtime/conversion_test.go @@ -122,7 +122,7 @@ func TestStringMapConversion(t *testing.T) { for k, tc := range testCases { out := &ExternalComplex{} - if err := scheme.Convert(&tc.input, out); (tc.errFn == nil && err != nil) || (tc.errFn != nil && !tc.errFn(err)) { + if err := scheme.Convert(&tc.input, out, nil); (tc.errFn == nil && err != nil) || (tc.errFn != nil && !tc.errFn(err)) { t.Errorf("%s: unexpected error: %v", k, err) continue } else if err != nil { diff --git a/pkg/runtime/interfaces.go b/pkg/runtime/interfaces.go index 117f43a4a50..07f77ca1b9f 100644 --- a/pkg/runtime/interfaces.go +++ b/pkg/runtime/interfaces.go @@ -176,10 +176,12 @@ type ObjectVersioner interface { // ObjectConvertor converts an object to a different version. type ObjectConvertor interface { // Convert attempts to convert one object into another, or returns an error. This method does - // not guarantee the in object is not mutated. - Convert(in, out interface{}) error + // not guarantee the in object is not mutated. The context argument will be passed to + // all nested conversions. + Convert(in, out, context interface{}) error // ConvertToVersion takes the provided object and converts it the provided version. This - // method does not guarantee that the in object is not mutated. + // method does not guarantee that the in object is not mutated. This method is similar to + // Convert() but handles specific details of choosing the correct output version. ConvertToVersion(in Object, gv GroupVersioner) (out Object, err error) ConvertFieldLabel(version, kind, label, value string) (string, string, error) } diff --git a/pkg/runtime/scheme_test.go b/pkg/runtime/scheme_test.go index 135d9c2f93c..beeafe72176 100644 --- a/pkg/runtime/scheme_test.go +++ b/pkg/runtime/scheme_test.go @@ -129,7 +129,7 @@ func TestScheme(t *testing.T) { // Test Convert external := &ExternalSimple{} - err = scheme.Convert(simple, external) + err = scheme.Convert(simple, external, nil) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -894,7 +894,7 @@ func TestMetaValuesUnregisteredConvert(t *testing.T) { simple := &InternalSimple{TestString: "foo"} external := &ExternalSimple{} - err = s.Convert(simple, external) + err = s.Convert(simple, external, nil) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/runtime/serializer/versioning/versioning.go b/pkg/runtime/serializer/versioning/versioning.go index 4bd25e83156..9f47d00f1ab 100644 --- a/pkg/runtime/serializer/versioning/versioning.go +++ b/pkg/runtime/serializer/versioning/versioning.go @@ -102,7 +102,7 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in } return into, gvk, nil } - if err := c.convertor.Convert(obj, into); err != nil { + if err := c.convertor.Convert(obj, into, c.decodeVersion); err != nil { return nil, gvk, err } if isVersioned { diff --git a/pkg/runtime/serializer/versioning/versioning_test.go b/pkg/runtime/serializer/versioning/versioning_test.go index 0ae74b2c9ae..ce5d944d1e8 100644 --- a/pkg/runtime/serializer/versioning/versioning_test.go +++ b/pkg/runtime/serializer/versioning/versioning_test.go @@ -298,7 +298,7 @@ type checkConvertor struct { directConvert bool } -func (c *checkConvertor) Convert(in, out interface{}) error { +func (c *checkConvertor) Convert(in, out, context interface{}) error { if !c.directConvert { return fmt.Errorf("unexpected call to Convert") } diff --git a/pkg/runtime/unstructured.go b/pkg/runtime/unstructured.go index 0e3488792d2..7f275ef1a9a 100644 --- a/pkg/runtime/unstructured.go +++ b/pkg/runtime/unstructured.go @@ -168,7 +168,7 @@ func (s unstructuredJSONScheme) decodeToList(data []byte, list *UnstructuredList // sane implementation for APIs that require an object converter. type UnstructuredObjectConverter struct{} -func (UnstructuredObjectConverter) Convert(in, out interface{}) error { +func (UnstructuredObjectConverter) Convert(in, out, context interface{}) error { unstructIn, ok := in.(*Unstructured) if !ok { return fmt.Errorf("input type %T in not valid for unstructured conversion", in) diff --git a/plugin/cmd/kube-scheduler/app/options/options.go b/plugin/cmd/kube-scheduler/app/options/options.go index 4d84dcd225f..69ec1db955f 100644 --- a/plugin/cmd/kube-scheduler/app/options/options.go +++ b/plugin/cmd/kube-scheduler/app/options/options.go @@ -41,7 +41,7 @@ type SchedulerServer struct { // NewSchedulerServer creates a new SchedulerServer with default parameters func NewSchedulerServer() *SchedulerServer { config := componentconfig.KubeSchedulerConfiguration{} - api.Scheme.Convert(&v1alpha1.KubeSchedulerConfiguration{}, &config) + api.Scheme.Convert(&v1alpha1.KubeSchedulerConfiguration{}, &config, nil) config.LeaderElection.LeaderElect = true s := SchedulerServer{ KubeSchedulerConfiguration: config,