diff --git a/pkg/api/unstructured_test.go b/pkg/api/unstructured_test.go index dc90f8bbfc8..e158d595b2c 100644 --- a/pkg/api/unstructured_test.go +++ b/pkg/api/unstructured_test.go @@ -98,14 +98,14 @@ func doRoundTrip(t *testing.T, group testapi.TestGroup, kind string) { } newUnstr := make(map[string]interface{}) - err = unstructured.Converter.ToUnstructured(item, &newUnstr) + err = unstructured.DefaultConverter.ToUnstructured(item, &newUnstr) if err != nil { t.Errorf("ToUnstructured failed: %v", err) return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) - err = unstructured.Converter.FromUnstructured(newUnstr, newObj) + err = unstructured.DefaultConverter.FromUnstructured(newUnstr, newObj) if err != nil { t.Errorf("FromUnstructured failed: %v", err) return @@ -139,11 +139,11 @@ func BenchmarkToFromUnstructured(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { unstr := map[string]interface{}{} - if err := unstructured.Converter.ToUnstructured(&items[i%size], &unstr); err != nil { + if err := unstructured.DefaultConverter.ToUnstructured(&items[i%size], &unstr); err != nil { b.Fatalf("unexpected error: %v", err) } obj := v1.Pod{} - if err := unstructured.Converter.FromUnstructured(unstr, &obj); err != nil { + if err := unstructured.DefaultConverter.FromUnstructured(unstr, &obj); err != nil { b.Fatalf("unexpected error: %v", err) } } diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go index b56cd9226cf..1ce53d0ebbf 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go +++ b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go @@ -35,6 +35,13 @@ import ( "github.com/golang/glog" ) +// Converter is an interface for converting between runtime.Object +// and map[string]interface representation. +type Converter interface { + ToUnstructured(obj runtime.Object, u *map[string]interface{}) error + FromUnstructured(u map[string]interface{}, obj runtime.Object) error +} + type structField struct { structType reflect.Type field int @@ -69,27 +76,33 @@ var ( float64Type = reflect.TypeOf(float64(0)) boolType = reflect.TypeOf(bool(false)) fieldCache = newFieldsCache() - Converter = newConverter() - + DefaultConverter = NewConverter(parseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR"))) ) +func parseBool(key string) bool { + value, err := strconv.ParseBool(key) + if err != nil { + glog.Errorf("Couldn't parse %s as bool", key) + } + return value +} + // ConverterImpl knows how to convert betweek runtime.Object and // Unstructured in both ways. -type ConverterImpl struct { +type converterImpl struct { // If true, we will be additionally running conversion via json // to ensure that the result is true. // This is supposed to be set only in tests. mismatchDetection bool } -func newConverter() *ConverterImpl { - mismatchDetection, _ := strconv.ParseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR")) - return &ConverterImpl{ +func NewConverter(mismatchDetection bool) Converter { + return &converterImpl{ mismatchDetection: mismatchDetection, } } -func (c *ConverterImpl) FromUnstructured(u map[string]interface{}, obj runtime.Object) error { +func (c *converterImpl) FromUnstructured(u map[string]interface{}, obj runtime.Object) error { err := fromUnstructured(reflect.ValueOf(u), reflect.ValueOf(obj).Elem()) if c.mismatchDetection { newObj := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) @@ -362,7 +375,7 @@ func interfaceFromUnstructured(sv, dv reflect.Value) error { return nil } -func (c *ConverterImpl) ToUnstructured(obj runtime.Object, u *map[string]interface{}) error { +func (c *converterImpl) ToUnstructured(obj runtime.Object, u *map[string]interface{}) error { err := toUnstructured(reflect.ValueOf(obj).Elem(), reflect.ValueOf(u).Elem()) if c.mismatchDetection { newUnstr := &map[string]interface{}{} diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter_test.go b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter_test.go index b589a276994..9a8b595c9d9 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter_test.go @@ -42,8 +42,8 @@ type B struct { } type C struct { - A []A `json:"ca"` - B `json:",inline"` + A []A `json:"ca"` + B `json:",inline"` C string `json:"cc"` D *int64 `json:"cd"` E map[string]int `json:"ce"` @@ -122,14 +122,14 @@ func doRoundTrip(t *testing.T, item runtime.Object) { } newUnstr := make(map[string]interface{}) - err = Converter.ToUnstructured(item, &newUnstr) + err = DefaultConverter.ToUnstructured(item, &newUnstr) if err != nil { t.Errorf("ToUnstructured failed: %v", err) return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) - err = Converter.FromUnstructured(newUnstr, newObj) + err = DefaultConverter.FromUnstructured(newUnstr, newObj) if err != nil { t.Errorf("FromUnstructured failed: %v", err) return @@ -239,7 +239,7 @@ func doUnrecognized(t *testing.T, jsonData string, item runtime.Object, expected return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) - err = Converter.FromUnstructured(unstr, newObj) + err = DefaultConverter.FromUnstructured(unstr, newObj) if (err != nil) != (expectedErr != nil) { t.Errorf("Unexpected error in FromUnstructured: %v, expected: %v", err, expectedErr) }