mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
Unstructured cleanups
This commit is contained in:
parent
d52d160239
commit
160cf97fa4
@ -138,11 +138,10 @@ func NestedSlice(obj map[string]interface{}, fields ...string) ([]interface{}, b
|
|||||||
// NestedStringMap returns a copy of map[string]string value of a nested field.
|
// NestedStringMap returns a copy of map[string]string value of a nested field.
|
||||||
// Returns false if value is not found, is not a map[string]interface{} or contains non-string values in the map.
|
// Returns false if value is not found, is not a map[string]interface{} or contains non-string values in the map.
|
||||||
func NestedStringMap(obj map[string]interface{}, fields ...string) (map[string]string, bool) {
|
func NestedStringMap(obj map[string]interface{}, fields ...string) (map[string]string, bool) {
|
||||||
val, ok := nestedFieldNoCopy(obj, fields...)
|
m, ok := nestedMapNoCopy(obj, fields...)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
if m, ok := val.(map[string]interface{}); ok {
|
|
||||||
strMap := make(map[string]string, len(m))
|
strMap := make(map[string]string, len(m))
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
if str, ok := v.(string); ok {
|
if str, ok := v.(string); ok {
|
||||||
@ -153,20 +152,26 @@ func NestedStringMap(obj map[string]interface{}, fields ...string) (map[string]s
|
|||||||
}
|
}
|
||||||
return strMap, true
|
return strMap, true
|
||||||
}
|
}
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NestedMap returns a deep copy of map[string]interface{} value of a nested field.
|
// NestedMap returns a deep copy of map[string]interface{} value of a nested field.
|
||||||
// Returns false if value is not found or is not a map[string]interface{}.
|
// Returns false if value is not found or is not a map[string]interface{}.
|
||||||
func NestedMap(obj map[string]interface{}, fields ...string) (map[string]interface{}, bool) {
|
func NestedMap(obj map[string]interface{}, fields ...string) (map[string]interface{}, bool) {
|
||||||
|
m, ok := nestedMapNoCopy(obj, fields...)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return runtime.DeepCopyJSON(m), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// nestedMapNoCopy returns a map[string]interface{} value of a nested field.
|
||||||
|
// Returns false if value is not found or is not a map[string]interface{}.
|
||||||
|
func nestedMapNoCopy(obj map[string]interface{}, fields ...string) (map[string]interface{}, bool) {
|
||||||
val, ok := nestedFieldNoCopy(obj, fields...)
|
val, ok := nestedFieldNoCopy(obj, fields...)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
if m, ok := val.(map[string]interface{}); ok {
|
m, ok := val.(map[string]interface{})
|
||||||
return runtime.DeepCopyJSON(m), true
|
return m, ok
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNestedField sets the value of a nested field to a deep copy of the value provided.
|
// SetNestedField sets the value of a nested field to a deep copy of the value provided.
|
||||||
@ -268,25 +273,6 @@ func extractOwnerReference(v map[string]interface{}) metav1.OwnerReference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setOwnerReference(src metav1.OwnerReference) map[string]interface{} {
|
|
||||||
ret := map[string]interface{}{
|
|
||||||
"kind": src.Kind,
|
|
||||||
"name": src.Name,
|
|
||||||
"apiVersion": src.APIVersion,
|
|
||||||
"uid": string(src.UID),
|
|
||||||
}
|
|
||||||
// json.Unmarshal() extracts boolean json fields as bool, not as *bool and hence extractOwnerReference()
|
|
||||||
// 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 {
|
|
||||||
ret["controller"] = *src.Controller
|
|
||||||
}
|
|
||||||
if src.BlockOwnerDeletion != nil {
|
|
||||||
ret["blockOwnerDeletion"] = *src.BlockOwnerDeletion
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnstructuredJSONScheme is capable of converting JSON data into the Unstructured
|
// UnstructuredJSONScheme is capable of converting JSON data into the Unstructured
|
||||||
// type, which can be used for generic access to objects without a predefined scheme.
|
// type, which can be used for generic access to objects without a predefined scheme.
|
||||||
// TODO: move into serializer/json.
|
// TODO: move into serializer/json.
|
||||||
@ -444,7 +430,7 @@ func (UnstructuredObjectConverter) Convert(in, out, context interface{}) error {
|
|||||||
|
|
||||||
// maybe deep copy the map? It is documented in the
|
// maybe deep copy the map? It is documented in the
|
||||||
// ObjectConverter interface that this function is not
|
// ObjectConverter interface that this function is not
|
||||||
// guaranteeed to not mutate the input. Or maybe set the input
|
// guaranteed to not mutate the input. Or maybe set the input
|
||||||
// object to nil.
|
// object to nil.
|
||||||
unstructOut.Object = unstructIn.Object
|
unstructOut.Object = unstructIn.Object
|
||||||
return nil
|
return nil
|
||||||
|
@ -18,6 +18,7 @@ package unstructured
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -50,29 +51,27 @@ var _ runtime.Unstructured = &Unstructured{}
|
|||||||
func (obj *Unstructured) GetObjectKind() schema.ObjectKind { return obj }
|
func (obj *Unstructured) GetObjectKind() schema.ObjectKind { return obj }
|
||||||
|
|
||||||
func (obj *Unstructured) IsList() bool {
|
func (obj *Unstructured) IsList() bool {
|
||||||
if obj.Object != nil {
|
field, ok := obj.Object["items"]
|
||||||
_, ok := obj.Object["items"]
|
if !ok {
|
||||||
return ok
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
_, ok = field.([]interface{})
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
|
func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
|
||||||
if obj.Object == nil {
|
|
||||||
return fmt.Errorf("content is not a list")
|
|
||||||
}
|
|
||||||
field, ok := obj.Object["items"]
|
field, ok := obj.Object["items"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("content is not a list")
|
return errors.New("content is not a list")
|
||||||
}
|
}
|
||||||
items, ok := field.([]interface{})
|
items, ok := field.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return fmt.Errorf("content is not a list: %T", field)
|
||||||
}
|
}
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
child, ok := item.(map[string]interface{})
|
child, ok := item.(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("items member is not an object")
|
return fmt.Errorf("items member is not an object: %T", child)
|
||||||
}
|
}
|
||||||
if err := fn(&Unstructured{Object: child}); err != nil {
|
if err := fn(&Unstructured{Object: child}); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -162,7 +161,12 @@ func (u *Unstructured) GetOwnerReferences() []metav1.OwnerReference {
|
|||||||
func (u *Unstructured) SetOwnerReferences(references []metav1.OwnerReference) {
|
func (u *Unstructured) SetOwnerReferences(references []metav1.OwnerReference) {
|
||||||
newReferences := make([]interface{}, 0, len(references))
|
newReferences := make([]interface{}, 0, len(references))
|
||||||
for _, reference := range references {
|
for _, reference := range references {
|
||||||
newReferences = append(newReferences, setOwnerReference(reference))
|
out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&reference)
|
||||||
|
if err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("unable to convert Owner Reference: %v", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newReferences = append(newReferences, out)
|
||||||
}
|
}
|
||||||
u.setNestedField(newReferences, "metadata", "ownerReferences")
|
u.setNestedField(newReferences, "metadata", "ownerReferences")
|
||||||
}
|
}
|
||||||
@ -301,10 +305,7 @@ func (u *Unstructured) SetDeletionGracePeriodSeconds(deletionGracePeriodSeconds
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *Unstructured) GetLabels() map[string]string {
|
func (u *Unstructured) GetLabels() map[string]string {
|
||||||
m, ok := NestedStringMap(u.Object, "metadata", "labels")
|
m, _ := NestedStringMap(u.Object, "metadata", "labels")
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +314,7 @@ func (u *Unstructured) SetLabels(labels map[string]string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *Unstructured) GetAnnotations() map[string]string {
|
func (u *Unstructured) GetAnnotations() map[string]string {
|
||||||
m, ok := NestedStringMap(u.Object, "metadata", "annotations")
|
m, _ := NestedStringMap(u.Object, "metadata", "annotations")
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,18 +337,14 @@ func (u *Unstructured) GroupVersionKind() schema.GroupVersionKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *Unstructured) GetInitializers() *metav1.Initializers {
|
func (u *Unstructured) GetInitializers() *metav1.Initializers {
|
||||||
field, ok := nestedFieldNoCopy(u.Object, "metadata", "initializers")
|
m, ok := nestedMapNoCopy(u.Object, "metadata", "initializers")
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
obj, ok := field.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
// expected map[string]interface{}, got something else
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := &metav1.Initializers{}
|
out := &metav1.Initializers{}
|
||||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj, out); err != nil {
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, out); err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err))
|
utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -368,10 +362,7 @@ func (u *Unstructured) SetInitializers(initializers *metav1.Initializers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *Unstructured) GetFinalizers() []string {
|
func (u *Unstructured) GetFinalizers() []string {
|
||||||
val, ok := NestedStringSlice(u.Object, "metadata", "finalizers")
|
val, _ := NestedStringSlice(u.Object, "metadata", "finalizers")
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user