Convert() should accept the new conversion Context value

Allows Convert() to reuse the same conversions as ConvertToVersion
without being overly coupled to the version.
This commit is contained in:
Clayton Coleman 2016-07-04 16:13:27 -04:00
parent a7a7fd4631
commit 5f8366aac3
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3
25 changed files with 37 additions and 35 deletions

View File

@ -50,7 +50,7 @@ type ProxyServerConfig struct {
func NewProxyConfig() *ProxyServerConfig { func NewProxyConfig() *ProxyServerConfig {
config := componentconfig.KubeProxyConfiguration{} config := componentconfig.KubeProxyConfiguration{}
api.Scheme.Convert(&v1alpha1.KubeProxyConfiguration{}, &config) api.Scheme.Convert(&v1alpha1.KubeProxyConfiguration{}, &config, nil)
return &ProxyServerConfig{ return &ProxyServerConfig{
KubeProxyConfiguration: config, KubeProxyConfiguration: config,
ContentType: "application/vnd.kubernetes.protobuf", ContentType: "application/vnd.kubernetes.protobuf",

View File

@ -58,7 +58,7 @@ type KubeletServer struct {
// NewKubeletServer will create a new KubeletServer with default values. // NewKubeletServer will create a new KubeletServer with default values.
func NewKubeletServer() *KubeletServer { func NewKubeletServer() *KubeletServer {
config := componentconfig.KubeletConfiguration{} config := componentconfig.KubeletConfiguration{}
api.Scheme.Convert(&v1alpha1.KubeletConfiguration{}, &config) api.Scheme.Convert(&v1alpha1.KubeletConfiguration{}, &config, nil)
return &KubeletServer{ return &KubeletServer{
AuthPath: util.NewStringFlag("/var/lib/kubelet/kubernetes_auth"), // deprecated AuthPath: util.NewStringFlag("/var/lib/kubelet/kubernetes_auth"), // deprecated
KubeConfig: util.NewStringFlag("/var/lib/kubelet/kubeconfig"), KubeConfig: util.NewStringFlag("/var/lib/kubelet/kubeconfig"),

View File

@ -28,7 +28,7 @@ import (
type fakeConvertor struct{} type fakeConvertor struct{}
func (fakeConvertor) Convert(in, out interface{}) error { func (fakeConvertor) Convert(in, out, context interface{}) error {
return nil return nil
} }

View File

@ -106,7 +106,7 @@ func BenchmarkEncodeCodecFromInternalProtobuf(b *testing.B) {
width := len(items) width := len(items)
encodable := make([]api.Pod, width) encodable := make([]api.Pod, width)
for i := range items { 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) b.Fatal(err)
} }
} }

View File

@ -482,7 +482,7 @@ func BenchmarkEncodeCodecFromInternal(b *testing.B) {
width := len(items) width := len(items)
encodable := make([]api.Pod, width) encodable := make([]api.Pod, width)
for i := range items { 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) b.Fatal(err)
} }
} }

View File

@ -127,7 +127,7 @@ func TestPodSpecConversion(t *testing.T) {
ServiceAccountName: name, ServiceAccountName: name,
} }
v := versioned.PodSpec{} 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) t.Fatalf("unexpected error: %v", err)
} }
if v.ServiceAccountName != name { if v.ServiceAccountName != name {
@ -152,7 +152,7 @@ func TestPodSpecConversion(t *testing.T) {
} }
for k, v := range testCases { for k, v := range testCases {
got := api.PodSpec{} got := api.PodSpec{}
err := api.Scheme.Convert(v, &got) err := api.Scheme.Convert(v, &got, nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error for case %d: %v", k, err) t.Fatalf("unexpected error for case %d: %v", k, err)
} }
@ -206,7 +206,7 @@ func TestResourceListConversion(t *testing.T) {
for i, test := range tests { for i, test := range tests {
output := api.ResourceList{} output := api.ResourceList{}
err := api.Scheme.Convert(&test.input, &output) err := api.Scheme.Convert(&test.input, &output, nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error for case %d: %v", i, err) t.Fatalf("unexpected error for case %d: %v", i, err)
} }

View File

@ -40,7 +40,7 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
return nil return nil
} }
obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) 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 { if err != nil {
t.Errorf("%v\nSource: %#v", err, obj2) t.Errorf("%v\nSource: %#v", err, obj2)
return nil return nil

View File

@ -67,7 +67,7 @@ func TestConversion(t *testing.T) {
} }
for k, tc := range testcases { for k, tc := range testcases {
internal := &api.Policy{} 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) t.Errorf("%s: unexpected error: %v", k, err)
} }
if !reflect.DeepEqual(internal, tc.expected) { if !reflect.DeepEqual(internal, tc.expected) {

View File

@ -59,7 +59,7 @@ func TestJobSpecConversion(t *testing.T) {
ManualSelector: test.in, ManualSelector: test.in,
} }
v := versioned.JobSpec{} 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) t.Fatalf("unexpected error: %v", err)
} }
if !reflect.DeepEqual(test.expectOut, v.AutoSelector) { if !reflect.DeepEqual(test.expectOut, v.AutoSelector) {
@ -73,7 +73,7 @@ func TestJobSpecConversion(t *testing.T) {
AutoSelector: test.in, AutoSelector: test.in,
} }
e := batch.JobSpec{} 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) t.Fatalf("unexpected error: %v", err)
} }
if !reflect.DeepEqual(test.expectOut, e.ManualSelector) { if !reflect.DeepEqual(test.expectOut, e.ManualSelector) {

View File

@ -728,7 +728,7 @@ func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
return nil return nil
} }
obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) 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 { if err != nil {
t.Errorf("%v\nSource: %#v", err, obj2) t.Errorf("%v\nSource: %#v", err, obj2)
return nil return nil

View File

@ -89,7 +89,7 @@ func NewFromFile(path string) (policyList, error) {
if err := runtime.DecodeInto(decoder, b, oldPolicy); err != nil { if err := runtime.DecodeInto(decoder, b, oldPolicy); err != nil {
return nil, policyLoadError{path, i, b, err} 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} return nil, policyLoadError{path, i, b, err}
} }
pl = append(pl, p) pl = append(pl, p)

View File

@ -562,7 +562,7 @@ func TestSubjectMatches(t *testing.T) {
for k, tc := range testCases { for k, tc := range testCases {
policy := &api.Policy{} 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) t.Errorf("%s: error converting: %v", k, err)
continue continue
} }
@ -950,7 +950,7 @@ func TestPolicy(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
policy := &api.Policy{} 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) t.Errorf("%s: error converting: %v", test.name, err)
continue continue
} }

View File

@ -458,7 +458,7 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje
if controllerRef != nil { if controllerRef != nil {
pod.OwnerReferences = append(pod.OwnerReferences, *controllerRef) 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 nil, fmt.Errorf("unable to convert pod template: %v", err)
} }
return pod, nil return pod, nil

View File

@ -209,7 +209,7 @@ func getJobFromTemplate(sj *batch.ScheduledJob, scheduledTime time.Time) (*batch
Name: name, 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 nil, fmt.Errorf("unable to convert job template: %v", err)
} }
return job, nil return job, nil

View File

@ -129,7 +129,7 @@ func TestReadPodsFromFile(t *testing.T) {
for _, testCase := range testCases { for _, testCase := range testCases {
func() { func() {
var versionedPod runtime.Object var versionedPod runtime.Object
err := testapi.Default.Converter().Convert(&testCase.pod, &versionedPod) err := testapi.Default.Converter().Convert(&testCase.pod, &versionedPod, nil)
if err != nil { if err != nil {
t.Fatalf("%s: error in versioning the pod: %v", testCase.desc, err) t.Fatalf("%s: error in versioning the pod: %v", testCase.desc, err)
} }

View File

@ -276,7 +276,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
for _, testCase := range testCases { for _, testCase := range testCases {
var versionedPods runtime.Object var versionedPods runtime.Object
err := testapi.Default.Converter().Convert(&testCase.pods, &versionedPods) err := testapi.Default.Converter().Convert(&testCase.pods, &versionedPods, nil)
if err != nil { if err != nil {
t.Fatalf("%s: error in versioning the pods: %s", testCase.desc, err) t.Fatalf("%s: error in versioning the pods: %s", testCase.desc, err)
} }

View File

@ -53,8 +53,8 @@ func (t *thirdPartyObjectConverter) ConvertToVersion(in runtime.Object, outVersi
} }
} }
func (t *thirdPartyObjectConverter) Convert(in, out interface{}) error { func (t *thirdPartyObjectConverter) Convert(in, out, context interface{}) error {
return t.converter.Convert(in, out) return t.converter.Convert(in, out, context)
} }
func (t *thirdPartyObjectConverter) ConvertFieldLabel(version, kind, label, value string) (string, string, error) { func (t *thirdPartyObjectConverter) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {

View File

@ -145,16 +145,16 @@ func (c *parameterCodec) DecodeParameters(parameters url.Values, from unversione
} }
targetGVK := targetGVKs[0] targetGVK := targetGVKs[0]
if targetGVK.GroupVersion() == from { if targetGVK.GroupVersion() == from {
return c.convertor.Convert(&parameters, into) return c.convertor.Convert(&parameters, into, nil)
} }
input, err := c.creator.New(from.WithKind(targetGVK.Kind)) input, err := c.creator.New(from.WithKind(targetGVK.Kind))
if err != nil { if err != nil {
return err return err
} }
if err := c.convertor.Convert(&parameters, input); err != nil { if err := c.convertor.Convert(&parameters, input, nil); err != nil {
return err 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. // EncodeParameters converts the provided object into the to version, then converts that object to url.Values.

View File

@ -122,7 +122,7 @@ func TestStringMapConversion(t *testing.T) {
for k, tc := range testCases { for k, tc := range testCases {
out := &ExternalComplex{} 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) t.Errorf("%s: unexpected error: %v", k, err)
continue continue
} else if err != nil { } else if err != nil {

View File

@ -176,10 +176,12 @@ type ObjectVersioner interface {
// ObjectConvertor converts an object to a different version. // ObjectConvertor converts an object to a different version.
type ObjectConvertor interface { type ObjectConvertor interface {
// Convert attempts to convert one object into another, or returns an error. This method does // Convert attempts to convert one object into another, or returns an error. This method does
// not guarantee the in object is not mutated. // not guarantee the in object is not mutated. The context argument will be passed to
Convert(in, out interface{}) error // all nested conversions.
Convert(in, out, context interface{}) error
// ConvertToVersion takes the provided object and converts it the provided version. This // 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) ConvertToVersion(in Object, gv GroupVersioner) (out Object, err error)
ConvertFieldLabel(version, kind, label, value string) (string, string, error) ConvertFieldLabel(version, kind, label, value string) (string, string, error)
} }

View File

@ -129,7 +129,7 @@ func TestScheme(t *testing.T) {
// Test Convert // Test Convert
external := &ExternalSimple{} external := &ExternalSimple{}
err = scheme.Convert(simple, external) err = scheme.Convert(simple, external, nil)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
@ -894,7 +894,7 @@ func TestMetaValuesUnregisteredConvert(t *testing.T) {
simple := &InternalSimple{TestString: "foo"} simple := &InternalSimple{TestString: "foo"}
external := &ExternalSimple{} external := &ExternalSimple{}
err = s.Convert(simple, external) err = s.Convert(simple, external, nil)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }

View File

@ -102,7 +102,7 @@ func (c *codec) Decode(data []byte, defaultGVK *unversioned.GroupVersionKind, in
} }
return into, gvk, nil 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 return nil, gvk, err
} }
if isVersioned { if isVersioned {

View File

@ -298,7 +298,7 @@ type checkConvertor struct {
directConvert bool directConvert bool
} }
func (c *checkConvertor) Convert(in, out interface{}) error { func (c *checkConvertor) Convert(in, out, context interface{}) error {
if !c.directConvert { if !c.directConvert {
return fmt.Errorf("unexpected call to Convert") return fmt.Errorf("unexpected call to Convert")
} }

View File

@ -168,7 +168,7 @@ func (s unstructuredJSONScheme) decodeToList(data []byte, list *UnstructuredList
// sane implementation for APIs that require an object converter. // sane implementation for APIs that require an object converter.
type UnstructuredObjectConverter struct{} type UnstructuredObjectConverter struct{}
func (UnstructuredObjectConverter) Convert(in, out interface{}) error { func (UnstructuredObjectConverter) Convert(in, out, context interface{}) error {
unstructIn, ok := in.(*Unstructured) unstructIn, ok := in.(*Unstructured)
if !ok { if !ok {
return fmt.Errorf("input type %T in not valid for unstructured conversion", in) return fmt.Errorf("input type %T in not valid for unstructured conversion", in)

View File

@ -41,7 +41,7 @@ type SchedulerServer struct {
// NewSchedulerServer creates a new SchedulerServer with default parameters // NewSchedulerServer creates a new SchedulerServer with default parameters
func NewSchedulerServer() *SchedulerServer { func NewSchedulerServer() *SchedulerServer {
config := componentconfig.KubeSchedulerConfiguration{} config := componentconfig.KubeSchedulerConfiguration{}
api.Scheme.Convert(&v1alpha1.KubeSchedulerConfiguration{}, &config) api.Scheme.Convert(&v1alpha1.KubeSchedulerConfiguration{}, &config, nil)
config.LeaderElection.LeaderElect = true config.LeaderElection.LeaderElect = true
s := SchedulerServer{ s := SchedulerServer{
KubeSchedulerConfiguration: config, KubeSchedulerConfiguration: config,