Unified unstructured converter interface and setup

This commit is contained in:
Wojciech Tyczynski 2017-02-17 19:11:40 +01:00
parent 975db6ff9a
commit 924e9a5b3a
3 changed files with 30 additions and 17 deletions

View File

@ -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)
}
}

View File

@ -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{}{}

View File

@ -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)
}