mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Merge pull request #46683 from atlassian/fix-untructured-owner-references
Automatic merge from submit-queue (batch tested with PRs 44883, 46836, 46765, 46683, 46050) Fix round-trip of Unstructured.OwnerReferences **What this PR does / why we need it**: Previously `setOwnerReference()` was storing pointers but `extractOwnerReference()` is expecting pointer fields as plain values so it cannot read those pointers. And hence you cannot read what you've just stored. **Which issue this PR fixes** #46817 **Special notes for your reviewer**: This is similar to #43346. **Release note**: ```release-note NONE ```
This commit is contained in:
commit
61cd3fca01
@ -19,6 +19,7 @@ package tests
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -270,20 +271,18 @@ func TestUnstructuredSetters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"ownerReferences": []map[string]interface{}{
|
"ownerReferences": []map[string]interface{}{
|
||||||
{
|
{
|
||||||
"kind": "Pod",
|
"kind": "Pod",
|
||||||
"name": "poda",
|
"name": "poda",
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"uid": "1",
|
"uid": "1",
|
||||||
"controller": (*bool)(nil),
|
|
||||||
"blockOwnerDeletion": (*bool)(nil),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"kind": "Pod",
|
"kind": "Pod",
|
||||||
"name": "podb",
|
"name": "podb",
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"uid": "2",
|
"uid": "2",
|
||||||
"controller": &trueVar,
|
"controller": true,
|
||||||
"blockOwnerDeletion": &trueVar,
|
"blockOwnerDeletion": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"finalizers": []interface{}{
|
"finalizers": []interface{}{
|
||||||
@ -333,6 +332,52 @@ func TestUnstructuredSetters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOwnerReferences(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
trueVar := true
|
||||||
|
falseVar := false
|
||||||
|
refs := []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "v2",
|
||||||
|
Kind: "K2",
|
||||||
|
Name: "n2",
|
||||||
|
UID: types.UID("abc1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "K1",
|
||||||
|
Name: "n1",
|
||||||
|
UID: types.UID("abc2"),
|
||||||
|
Controller: &trueVar,
|
||||||
|
BlockOwnerDeletion: &falseVar,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIVersion: "v3",
|
||||||
|
Kind: "K3",
|
||||||
|
Name: "n3",
|
||||||
|
UID: types.UID("abc3"),
|
||||||
|
Controller: &falseVar,
|
||||||
|
BlockOwnerDeletion: &trueVar,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, ref := range refs {
|
||||||
|
ref := ref
|
||||||
|
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
u1 := unstructured.Unstructured{
|
||||||
|
Object: make(map[string]interface{}),
|
||||||
|
}
|
||||||
|
refsX := []metav1.OwnerReference{ref}
|
||||||
|
u1.SetOwnerReferences(refsX)
|
||||||
|
|
||||||
|
have := u1.GetOwnerReferences()
|
||||||
|
if !reflect.DeepEqual(have, refsX) {
|
||||||
|
t.Errorf("Object references are not the same: %#v != %#v", have, refsX)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnstructuredListGetters(t *testing.T) {
|
func TestUnstructuredListGetters(t *testing.T) {
|
||||||
unstruct := unstructured.UnstructuredList{
|
unstruct := unstructured.UnstructuredList{
|
||||||
Object: map[string]interface{}{
|
Object: map[string]interface{}{
|
||||||
|
@ -250,22 +250,19 @@ func extractOwnerReference(src interface{}) metav1.OwnerReference {
|
|||||||
|
|
||||||
func setOwnerReference(src metav1.OwnerReference) map[string]interface{} {
|
func setOwnerReference(src metav1.OwnerReference) map[string]interface{} {
|
||||||
ret := make(map[string]interface{})
|
ret := make(map[string]interface{})
|
||||||
controllerPtr := src.Controller
|
|
||||||
if controllerPtr != nil {
|
|
||||||
controller := *controllerPtr
|
|
||||||
controllerPtr = &controller
|
|
||||||
}
|
|
||||||
blockOwnerDeletionPtr := src.BlockOwnerDeletion
|
|
||||||
if blockOwnerDeletionPtr != nil {
|
|
||||||
blockOwnerDeletion := *blockOwnerDeletionPtr
|
|
||||||
blockOwnerDeletionPtr = &blockOwnerDeletion
|
|
||||||
}
|
|
||||||
setNestedField(ret, src.Kind, "kind")
|
setNestedField(ret, src.Kind, "kind")
|
||||||
setNestedField(ret, src.Name, "name")
|
setNestedField(ret, src.Name, "name")
|
||||||
setNestedField(ret, src.APIVersion, "apiVersion")
|
setNestedField(ret, src.APIVersion, "apiVersion")
|
||||||
setNestedField(ret, string(src.UID), "uid")
|
setNestedField(ret, string(src.UID), "uid")
|
||||||
setNestedField(ret, controllerPtr, "controller")
|
// json.Unmarshal() extracts boolean json fields as bool, not as *bool and hence extractOwnerReference()
|
||||||
setNestedField(ret, blockOwnerDeletionPtr, "blockOwnerDeletion")
|
// expects bool or a missing field, not *bool. So if pointer is nil, fields are omitted from the ret object.
|
||||||
|
// If pointer is non-nil, they are set to the referenced value.
|
||||||
|
if src.Controller != nil {
|
||||||
|
setNestedField(ret, *src.Controller, "controller")
|
||||||
|
}
|
||||||
|
if src.BlockOwnerDeletion != nil {
|
||||||
|
setNestedField(ret, *src.BlockOwnerDeletion, "blockOwnerDeletion")
|
||||||
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user