Merge pull request #59264 from atlassian/set-gvk-on-conversion-to-unstructured

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Conversion from typed to unstructured should set GVK

**What this PR does / why we need it**:
By convention typed objects do not have `TypeMeta` information filled. When the scheme converts a typed object into Unstructured it should set type meta information explicitly otherwise Unstructured object is not recognizable.

**Special notes for your reviewer**:
Bug was not visible to tests because tests were working with a typed object with `TypeMeta` information filled. It was filled by previous tests. I have refactored tests for better isolation. Also fixed some other issues in tests.

Add `?w=1` to the PR's URL to see the diff with whitespace changes ignored.

**Release note**:
```release-note
NONE
```
/kind bug
/sig api-machinery
/cc @smarterclayton @deads2k
pull/6/head
Kubernetes Submit Queue 2018-02-22 07:36:52 -08:00 committed by GitHub
commit aded0d9225
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 190 additions and 148 deletions

View File

@ -431,6 +431,7 @@ func (s *Scheme) Convert(in, out interface{}, context interface{}) error {
return err return err
} }
unstructuredOut.SetUnstructuredContent(content) unstructuredOut.SetUnstructuredContent(content)
unstructuredOut.GetObjectKind().SetGroupVersionKind(gvk)
return nil return nil
} }

View File

@ -37,11 +37,13 @@ var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.")
func TestScheme(t *testing.T) { func TestScheme(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
internalGVK := internalGV.WithKind("Simple")
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
externalGVK := externalGV.WithKind("Simple")
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{}) scheme.AddKnownTypeWithName(internalGVK, &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{}) scheme.AddKnownTypeWithName(externalGVK, &runtimetesting.ExternalSimple{})
// If set, would clear TypeMeta during conversion. // If set, would clear TypeMeta during conversion.
//scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{}) //scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{})
@ -55,14 +57,26 @@ func TestScheme(t *testing.T) {
// Register functions to verify that scope.Meta() gets set correctly. // Register functions to verify that scope.Meta() gets set correctly.
err := scheme.AddConversionFuncs( err := scheme.AddConversionFuncs(
func(in *runtimetesting.InternalSimple, out *runtimetesting.ExternalSimple, scope conversion.Scope) error { func(in *runtimetesting.InternalSimple, out *runtimetesting.ExternalSimple, scope conversion.Scope) error {
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) err := scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
scope.Convert(&in.TestString, &out.TestString, 0) if err != nil {
return err
}
err = scope.Convert(&in.TestString, &out.TestString, 0)
if err != nil {
return err
}
internalToExternalCalls++ internalToExternalCalls++
return nil return nil
}, },
func(in *runtimetesting.ExternalSimple, out *runtimetesting.InternalSimple, scope conversion.Scope) error { func(in *runtimetesting.ExternalSimple, out *runtimetesting.InternalSimple, scope conversion.Scope) error {
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) err := scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
scope.Convert(&in.TestString, &out.TestString, 0) if err != nil {
return err
}
err = scope.Convert(&in.TestString, &out.TestString, 0)
if err != nil {
return err
}
externalToInternalCalls++ externalToInternalCalls++
return nil return nil
}, },
@ -71,140 +85,160 @@ func TestScheme(t *testing.T) {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
codecs := serializer.NewCodecFactory(scheme) t.Run("Encode, Decode, DecodeInto, and DecodeToVersion", func(t *testing.T) {
codec := codecs.LegacyCodec(externalGV) simple := &runtimetesting.InternalSimple{
info, _ := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) TestString: "foo",
jsonserializer := info.Serializer }
simple := &runtimetesting.InternalSimple{ codecs := serializer.NewCodecFactory(scheme)
TestString: "foo", codec := codecs.LegacyCodec(externalGV)
} info, _ := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON)
jsonserializer := info.Serializer
// Test Encode, Decode, DecodeInto, and DecodeToVersion obj := runtime.Object(simple)
obj := runtime.Object(simple) data, err := runtime.Encode(codec, obj)
data, err := runtime.Encode(codec, obj) if err != nil {
if err != nil { t.Fatal(err)
t.Fatal(err) }
}
obj2, err := runtime.Decode(codec, data) obj2, err := runtime.Decode(codec, data)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, ok := obj2.(*runtimetesting.InternalSimple); !ok { if _, ok := obj2.(*runtimetesting.InternalSimple); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
if e, a := simple, obj2; !reflect.DeepEqual(e, a) { if e, a := simple, obj2; !reflect.DeepEqual(e, a) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
} }
obj3 := &runtimetesting.InternalSimple{} obj3 := &runtimetesting.InternalSimple{}
if err := runtime.DecodeInto(codec, data, obj3); err != nil { if err := runtime.DecodeInto(codec, data, obj3); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// clearing TypeMeta is a function of the scheme, which we do not test here (ConvertToVersion // clearing TypeMeta is a function of the scheme, which we do not test here (ConvertToVersion
// does not automatically clear TypeMeta anymore). // does not automatically clear TypeMeta anymore).
simple.TypeMeta = runtime.TypeMeta{Kind: "Simple", APIVersion: externalGV.String()} simple.TypeMeta = runtime.TypeMeta{Kind: "Simple", APIVersion: externalGV.String()}
if e, a := simple, obj3; !reflect.DeepEqual(e, a) { if e, a := simple, obj3; !reflect.DeepEqual(e, a) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
} }
obj4, err := runtime.Decode(jsonserializer, data) obj4, err := runtime.Decode(jsonserializer, data)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, ok := obj4.(*runtimetesting.ExternalSimple); !ok { if _, ok := obj4.(*runtimetesting.ExternalSimple); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
})
t.Run("Convert", func(t *testing.T) {
simple := &runtimetesting.InternalSimple{
TestString: "foo",
}
// Test Convert external := &runtimetesting.ExternalSimple{}
external := &runtimetesting.ExternalSimple{} err = scheme.Convert(simple, external, nil)
err = scheme.Convert(simple, external, nil) if err != nil {
if err != nil { t.Fatalf("Unexpected error: %v", err)
t.Fatalf("Unexpected error: %v", err) }
} if e, a := simple.TestString, external.TestString; e != a {
if e, a := simple.TestString, external.TestString; e != a { t.Errorf("Expected %q, got %q", e, a)
t.Errorf("Expected %v, got %v", e, a) }
} })
t.Run("Convert internal to unstructured", func(t *testing.T) {
simple := &runtimetesting.InternalSimple{
TestString: "foo",
}
// Test convert internal to unstructured unstructuredObj := &runtimetesting.Unstructured{}
unstructuredObj := &runtimetesting.Unstructured{} err = scheme.Convert(simple, unstructuredObj, nil)
err = scheme.Convert(simple, unstructuredObj, nil) if err == nil || !strings.Contains(err.Error(), "to Unstructured without providing a preferred version to convert to") {
if err == nil || !strings.Contains(err.Error(), "to Unstructured without providing a preferred version to convert to") { t.Fatalf("Unexpected non-error: %v", err)
t.Fatalf("Unexpected non-error: %v", err) }
} err = scheme.Convert(simple, unstructuredObj, externalGV)
err = scheme.Convert(simple, unstructuredObj, schema.GroupVersion{Group: "test.group", Version: "testExternal"}) if err != nil {
if err != nil { t.Fatalf("Unexpected error: %v", err)
t.Fatalf("Unexpected error: %v", err) }
} if e, a := simple.TestString, unstructuredObj.Object["testString"].(string); e != a {
if e, a := simple.TestString, unstructuredObj.Object["testString"].(string); e != a { t.Errorf("Expected %q, got %q", e, a)
t.Errorf("Expected %v, got %v", e, a) }
} if e := unstructuredObj.GetObjectKind().GroupVersionKind(); e != externalGVK {
if e := unstructuredObj.GetObjectKind().GroupVersionKind(); !reflect.DeepEqual(e, schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) { t.Errorf("Unexpected object kind: %#v", e)
t.Errorf("Unexpected object kind: %#v", e) }
} if gvks, unversioned, err := scheme.ObjectKinds(unstructuredObj); err != nil || gvks[0] != externalGVK || unversioned {
if gvks, unversioned, err := scheme.ObjectKinds(unstructuredObj); err != nil || !reflect.DeepEqual(gvks[0], schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) || unversioned { t.Errorf("Scheme did not recognize unversioned: %v, %#v %t", err, gvks, unversioned)
t.Errorf("Scheme did not recognize unversioned: %v, %#v %t", err, gvks, unversioned) }
} })
t.Run("Convert external to unstructured", func(t *testing.T) {
unstructuredObj := &runtimetesting.Unstructured{}
external := &runtimetesting.ExternalSimple{
TestString: "foo",
}
// Test convert external to unstructured err = scheme.Convert(external, unstructuredObj, nil)
unstructuredObj = &runtimetesting.Unstructured{} if err != nil {
err = scheme.Convert(external, unstructuredObj, nil) t.Fatalf("Unexpected error: %v", err)
if err != nil { }
t.Fatalf("Unexpected error: %v", err) if e, a := external.TestString, unstructuredObj.Object["testString"].(string); e != a {
} t.Errorf("Expected %q, got %q", e, a)
if e, a := simple.TestString, unstructuredObj.Object["testString"].(string); e != a { }
t.Errorf("Expected %v, got %v", e, a) if e := unstructuredObj.GetObjectKind().GroupVersionKind(); e != externalGVK {
} t.Errorf("Unexpected object kind: %#v", e)
if e := unstructuredObj.GetObjectKind().GroupVersionKind(); !reflect.DeepEqual(e, schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) { }
t.Errorf("Unexpected object kind: %#v", e) })
} t.Run("Convert unstructured to unstructured", func(t *testing.T) {
uIn := &runtimetesting.Unstructured{Object: map[string]interface{}{
// Test convert unstructured to unstructured "test": []interface{}{"other", "test"},
uIn := &runtimetesting.Unstructured{Object: map[string]interface{}{ }}
"test": []interface{}{"other", "test"}, uOut := &runtimetesting.Unstructured{}
}} err = scheme.Convert(uIn, uOut, nil)
uOut := &runtimetesting.Unstructured{} if err != nil {
err = scheme.Convert(uIn, uOut, nil) t.Fatalf("Unexpected error: %v", err)
if err != nil { }
t.Fatalf("Unexpected error: %v", err) if !reflect.DeepEqual(uIn.Object, uOut.Object) {
} t.Errorf("Unexpected object contents: %#v", uOut.Object)
if !reflect.DeepEqual(uIn.Object, uOut.Object) { }
t.Errorf("Unexpected object contents: %#v", uOut.Object) })
} t.Run("Convert unstructured to structured", func(t *testing.T) {
unstructuredObj := &runtimetesting.Unstructured{
// Test convert unstructured to structured Object: map[string]interface{}{
externalOut := &runtimetesting.ExternalSimple{} "testString": "bla",
err = scheme.Convert(unstructuredObj, externalOut, nil) },
if err != nil { }
t.Fatalf("Unexpected error: %v", err) unstructuredObj.SetGroupVersionKind(externalGV.WithKind("Simple"))
} externalOut := &runtimetesting.ExternalSimple{}
if !reflect.DeepEqual(external, externalOut) { err = scheme.Convert(unstructuredObj, externalOut, nil)
t.Errorf("Unexpected object contents: %#v", externalOut) if err != nil {
} t.Fatalf("Unexpected error: %v", err)
}
// Encode and Convert should each have caused an increment. if externalOut.TestString != "bla" {
if e, a := 3, internalToExternalCalls; e != a { t.Errorf("Unexpected object contents: %#v", externalOut)
t.Errorf("Expected %v, got %v", e, a) }
} })
// DecodeInto and Decode should each have caused an increment because of a conversion t.Run("Encode and Convert should each have caused an increment", func(t *testing.T) {
if e, a := 2, externalToInternalCalls; e != a { if e, a := 3, internalToExternalCalls; e != a {
t.Errorf("Expected %v, got %v", e, a) t.Errorf("Expected %v, got %v", e, a)
} }
})
// Verify that unstructured types must have V and K set t.Run("DecodeInto and Decode should each have caused an increment because of a conversion", func(t *testing.T) {
emptyObj := &runtimetesting.Unstructured{Object: make(map[string]interface{})} if e, a := 2, externalToInternalCalls; e != a {
if _, _, err := scheme.ObjectKinds(emptyObj); !runtime.IsMissingKind(err) { t.Errorf("Expected %v, got %v", e, a)
t.Errorf("unexpected error: %v", err) }
} })
emptyObj.SetGroupVersionKind(schema.GroupVersionKind{Kind: "Test"}) t.Run("Verify that unstructured types must have V and K set", func(t *testing.T) {
if _, _, err := scheme.ObjectKinds(emptyObj); !runtime.IsMissingVersion(err) { emptyObj := &runtimetesting.Unstructured{Object: make(map[string]interface{})}
t.Errorf("unexpected error: %v", err) if _, _, err := scheme.ObjectKinds(emptyObj); !runtime.IsMissingKind(err) {
} t.Errorf("unexpected error: %v", err)
emptyObj.SetGroupVersionKind(schema.GroupVersionKind{Kind: "Test", Version: "v1"}) }
if _, _, err := scheme.ObjectKinds(emptyObj); err != nil { emptyObj.SetGroupVersionKind(schema.GroupVersionKind{Kind: "Test"})
t.Errorf("unexpected error: %v", err) if _, _, err := scheme.ObjectKinds(emptyObj); !runtime.IsMissingVersion(err) {
} t.Errorf("unexpected error: %v", err)
}
emptyObj.SetGroupVersionKind(schema.GroupVersionKind{Kind: "Test", Version: "v1"})
if _, _, err := scheme.ObjectKinds(emptyObj); err != nil {
t.Errorf("unexpected error: %v", err)
}
})
} }
func TestBadJSONRejection(t *testing.T) { func TestBadJSONRejection(t *testing.T) {
@ -334,11 +368,13 @@ func TestExtensionMapping(t *testing.T) {
func TestEncode(t *testing.T) { func TestEncode(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
internalGVK := internalGV.WithKind("Simple")
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
externalGVK := externalGV.WithKind("Simple")
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{}) scheme.AddKnownTypeWithName(internalGVK, &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{}) scheme.AddKnownTypeWithName(externalGVK, &runtimetesting.ExternalSimple{})
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
@ -357,20 +393,22 @@ func TestEncode(t *testing.T) {
if !reflect.DeepEqual(obj2, test) { if !reflect.DeepEqual(obj2, test) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2) t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2)
} }
if !reflect.DeepEqual(gvk, &schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) { if *gvk != externalGVK {
t.Errorf("unexpected gvk returned by decode: %#v", gvk) t.Errorf("unexpected gvk returned by decode: %#v", *gvk)
} }
} }
func TestUnversionedTypes(t *testing.T) { func TestUnversionedTypes(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
internalGVK := internalGV.WithKind("Simple")
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
externalGVK := externalGV.WithKind("Simple")
otherGV := schema.GroupVersion{Group: "group", Version: "other"} otherGV := schema.GroupVersion{Group: "group", Version: "other"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddUnversionedTypes(externalGV, &runtimetesting.InternalSimple{}) scheme.AddUnversionedTypes(externalGV, &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{}) scheme.AddKnownTypeWithName(internalGVK, &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{}) scheme.AddKnownTypeWithName(externalGVK, &runtimetesting.ExternalSimple{})
scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &runtimetesting.ExternalSimple{}) scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &runtimetesting.ExternalSimple{})
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
@ -407,8 +445,8 @@ func TestUnversionedTypes(t *testing.T) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2) t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2)
} }
// object is serialized as an unversioned object (in the group and version it was defined in) // object is serialized as an unversioned object (in the group and version it was defined in)
if !reflect.DeepEqual(gvk, &schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "InternalSimple"}) { if *gvk != externalGV.WithKind("InternalSimple") {
t.Errorf("unexpected gvk returned by decode: %#v", gvk) t.Errorf("unexpected gvk returned by decode: %#v", *gvk)
} }
// when serialized to a different group, the object is kept in its preferred name // when serialized to a different group, the object is kept in its preferred name
@ -435,10 +473,10 @@ var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
// Returns a new Scheme set up with the test objects. // Returns a new Scheme set up with the test objects.
func GetTestScheme() *runtime.Scheme { func GetTestScheme() *runtime.Scheme {
internalGV := schema.GroupVersion{Version: "__internal"} internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Version: "v1"} externalGV := schema.GroupVersion{Version: "v1"}
alternateExternalGV := schema.GroupVersion{Group: "custom", Version: "v1"} alternateExternalGV := schema.GroupVersion{Group: "custom", Version: "v1"}
alternateInternalGV := schema.GroupVersion{Group: "custom", Version: "__internal"} alternateInternalGV := schema.GroupVersion{Group: "custom", Version: runtime.APIVersionInternal}
differentExternalGV := schema.GroupVersion{Group: "other", Version: "v2"} differentExternalGV := schema.GroupVersion{Group: "other", Version: "v2"}
s := runtime.NewScheme() s := runtime.NewScheme()
@ -614,7 +652,7 @@ func TestConvertToVersion(t *testing.T) {
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &runtimetesting.ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersion{Version: "__internal"}, gv: schema.GroupVersion{Version: runtime.APIVersionInternal},
out: &runtimetesting.TestType1{A: "test"}, out: &runtimetesting.TestType1{A: "test"},
}, },
// converts from unstructured to internal // converts from unstructured to internal
@ -625,7 +663,7 @@ func TestConvertToVersion(t *testing.T) {
"kind": "TestType3", "kind": "TestType3",
"A": "test", "A": "test",
}}, }},
gv: schema.GroupVersion{Version: "__internal"}, gv: schema.GroupVersion{Version: runtime.APIVersionInternal},
out: &runtimetesting.TestType1{A: "test"}, out: &runtimetesting.TestType1{A: "test"},
}, },
// converts from unstructured to external // converts from unstructured to external
@ -643,7 +681,7 @@ func TestConvertToVersion(t *testing.T) {
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &runtimetesting.ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "__internal"}, {Version: "v1"}}, gv: schema.GroupVersions{{Version: runtime.APIVersionInternal}, {Version: "v1"}},
out: &runtimetesting.ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
@ -686,7 +724,7 @@ func TestConvertToVersion(t *testing.T) {
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &runtimetesting.ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}}, gv: schema.GroupVersions{{Version: "v1"}, {Version: runtime.APIVersionInternal}},
same: true, same: true,
out: &runtimetesting.ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
@ -697,7 +735,7 @@ func TestConvertToVersion(t *testing.T) {
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &runtimetesting.ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}}, gv: schema.GroupVersions{{Version: "v1"}, {Version: runtime.APIVersionInternal}},
same: true, same: true,
out: &runtimetesting.ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
@ -896,7 +934,7 @@ func TestConvert(t *testing.T) {
} }
func TestMetaValues(t *testing.T) { func TestMetaValues(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: "__internal"} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Group: "test.group", Version: "externalVersion"} externalGV := schema.GroupVersion{Group: "test.group", Version: "externalVersion"}
s := runtime.NewScheme() s := runtime.NewScheme()

View File

@ -315,6 +315,9 @@ func (u *Unstructured) GroupVersionKind() schema.GroupVersionKind {
} }
func (u *Unstructured) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (u *Unstructured) SetGroupVersionKind(gvk schema.GroupVersionKind) {
if u.Object == nil {
u.Object = make(map[string]interface{})
}
u.Object["apiVersion"] = gvk.GroupVersion().String() u.Object["apiVersion"] = gvk.GroupVersion().String()
u.Object["kind"] = gvk.Kind u.Object["kind"] = gvk.Kind
} }