mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 00:07:50 +00:00
unstructured helpers: print path in error
This commit is contained in:
parent
eb3196b1b4
commit
4139594e66
@ -43,14 +43,15 @@ func NestedFieldCopy(obj map[string]interface{}, fields ...string) (interface{},
|
|||||||
|
|
||||||
func nestedFieldNoCopy(obj map[string]interface{}, fields ...string) (interface{}, bool, error) {
|
func nestedFieldNoCopy(obj map[string]interface{}, fields ...string) (interface{}, bool, error) {
|
||||||
var val interface{} = obj
|
var val interface{} = obj
|
||||||
for _, field := range fields {
|
|
||||||
|
for i, field := range fields {
|
||||||
if m, ok := val.(map[string]interface{}); ok {
|
if m, ok := val.(map[string]interface{}); ok {
|
||||||
val, ok = m[field]
|
val, ok = m[field]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, false, fmt.Errorf("%v is of the type %T, expected map[string]interface{}", val, val)
|
return nil, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected map[string]interface{}", jsonPath(fields[:i+1]), val, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return val, true, nil
|
return val, true, nil
|
||||||
@ -65,7 +66,7 @@ func NestedString(obj map[string]interface{}, fields ...string) (string, bool, e
|
|||||||
}
|
}
|
||||||
s, ok := val.(string)
|
s, ok := val.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", false, fmt.Errorf("%v is of the type %T, expected string", val, val)
|
return "", false, fmt.Errorf("%v accessor error: %v is of the type %T, expected string", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
return s, true, nil
|
return s, true, nil
|
||||||
}
|
}
|
||||||
@ -79,7 +80,7 @@ func NestedBool(obj map[string]interface{}, fields ...string) (bool, bool, error
|
|||||||
}
|
}
|
||||||
b, ok := val.(bool)
|
b, ok := val.(bool)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, false, fmt.Errorf("%v is of the type %T, expected bool", val, val)
|
return false, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected bool", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
return b, true, nil
|
return b, true, nil
|
||||||
}
|
}
|
||||||
@ -93,7 +94,7 @@ func NestedFloat64(obj map[string]interface{}, fields ...string) (float64, bool,
|
|||||||
}
|
}
|
||||||
f, ok := val.(float64)
|
f, ok := val.(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, false, fmt.Errorf("%v is of the type %T, expected float64", val, val)
|
return 0, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected float64", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
return f, true, nil
|
return f, true, nil
|
||||||
}
|
}
|
||||||
@ -107,7 +108,7 @@ func NestedInt64(obj map[string]interface{}, fields ...string) (int64, bool, err
|
|||||||
}
|
}
|
||||||
i, ok := val.(int64)
|
i, ok := val.(int64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, false, fmt.Errorf("%v is of the type %T, expected int64", val, val)
|
return 0, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected int64", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
return i, true, nil
|
return i, true, nil
|
||||||
}
|
}
|
||||||
@ -121,14 +122,14 @@ func NestedStringSlice(obj map[string]interface{}, fields ...string) ([]string,
|
|||||||
}
|
}
|
||||||
m, ok := val.([]interface{})
|
m, ok := val.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false, fmt.Errorf("%v is of the type %T, expected []interface{}", val, val)
|
return nil, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected []interface{}", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
strSlice := make([]string, 0, len(m))
|
strSlice := make([]string, 0, len(m))
|
||||||
for _, v := range m {
|
for _, v := range m {
|
||||||
if str, ok := v.(string); ok {
|
if str, ok := v.(string); ok {
|
||||||
strSlice = append(strSlice, str)
|
strSlice = append(strSlice, str)
|
||||||
} else {
|
} else {
|
||||||
return nil, false, fmt.Errorf("contains non-string key in the slice: %v is of the type %T, expected string", v, v)
|
return nil, false, fmt.Errorf("%v accessor error: contains non-string key in the slice: %v is of the type %T, expected string", jsonPath(fields), v, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strSlice, true, nil
|
return strSlice, true, nil
|
||||||
@ -143,7 +144,7 @@ func NestedSlice(obj map[string]interface{}, fields ...string) ([]interface{}, b
|
|||||||
}
|
}
|
||||||
_, ok := val.([]interface{})
|
_, ok := val.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false, fmt.Errorf("%v is of the type %T, expected []interface{}", val, val)
|
return nil, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected []interface{}", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
return runtime.DeepCopyJSONValue(val).([]interface{}), true, nil
|
return runtime.DeepCopyJSONValue(val).([]interface{}), true, nil
|
||||||
}
|
}
|
||||||
@ -160,7 +161,7 @@ func NestedStringMap(obj map[string]interface{}, fields ...string) (map[string]s
|
|||||||
if str, ok := v.(string); ok {
|
if str, ok := v.(string); ok {
|
||||||
strMap[k] = str
|
strMap[k] = str
|
||||||
} else {
|
} else {
|
||||||
return nil, false, fmt.Errorf("contains non-string key in the map: %v is of the type %T, expected string", v, v)
|
return nil, false, fmt.Errorf("%v accessor error: contains non-string key in the map: %v is of the type %T, expected string", jsonPath(fields), v, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strMap, true, nil
|
return strMap, true, nil
|
||||||
@ -185,25 +186,26 @@ func nestedMapNoCopy(obj map[string]interface{}, fields ...string) (map[string]i
|
|||||||
}
|
}
|
||||||
m, ok := val.(map[string]interface{})
|
m, ok := val.(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false, fmt.Errorf("%v is of the type %T, expected map[string]interface{}", val, val)
|
return nil, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected map[string]interface{}", jsonPath(fields), val, val)
|
||||||
}
|
}
|
||||||
return m, true, nil
|
return m, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
// Returns false if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
// Returns an error if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
||||||
func SetNestedField(obj map[string]interface{}, value interface{}, fields ...string) bool {
|
func SetNestedField(obj map[string]interface{}, value interface{}, fields ...string) error {
|
||||||
return setNestedFieldNoCopy(obj, runtime.DeepCopyJSONValue(value), fields...)
|
return setNestedFieldNoCopy(obj, runtime.DeepCopyJSONValue(value), fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNestedFieldNoCopy(obj map[string]interface{}, value interface{}, fields ...string) bool {
|
func setNestedFieldNoCopy(obj map[string]interface{}, value interface{}, fields ...string) error {
|
||||||
m := obj
|
m := obj
|
||||||
for _, field := range fields[:len(fields)-1] {
|
|
||||||
|
for i, field := range fields[:len(fields)-1] {
|
||||||
if val, ok := m[field]; ok {
|
if val, ok := m[field]; ok {
|
||||||
if valMap, ok := val.(map[string]interface{}); ok {
|
if valMap, ok := val.(map[string]interface{}); ok {
|
||||||
m = valMap
|
m = valMap
|
||||||
} else {
|
} else {
|
||||||
return false
|
return fmt.Errorf("value cannot be set because %v is not a map[string]interface{}", jsonPath(fields[:i+1]))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newVal := make(map[string]interface{})
|
newVal := make(map[string]interface{})
|
||||||
@ -212,12 +214,12 @@ func setNestedFieldNoCopy(obj map[string]interface{}, value interface{}, fields
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m[fields[len(fields)-1]] = value
|
m[fields[len(fields)-1]] = value
|
||||||
return true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNestedStringSlice sets the string slice value of a nested field.
|
// SetNestedStringSlice sets the string slice value of a nested field.
|
||||||
// Returns false if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
// Returns an error if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
||||||
func SetNestedStringSlice(obj map[string]interface{}, value []string, fields ...string) bool {
|
func SetNestedStringSlice(obj map[string]interface{}, value []string, fields ...string) error {
|
||||||
m := make([]interface{}, 0, len(value)) // convert []string into []interface{}
|
m := make([]interface{}, 0, len(value)) // convert []string into []interface{}
|
||||||
for _, v := range value {
|
for _, v := range value {
|
||||||
m = append(m, v)
|
m = append(m, v)
|
||||||
@ -226,14 +228,14 @@ func SetNestedStringSlice(obj map[string]interface{}, value []string, fields ...
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetNestedSlice sets the slice value of a nested field.
|
// SetNestedSlice sets the slice value of a nested field.
|
||||||
// Returns false if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
// Returns an error if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
||||||
func SetNestedSlice(obj map[string]interface{}, value []interface{}, fields ...string) bool {
|
func SetNestedSlice(obj map[string]interface{}, value []interface{}, fields ...string) error {
|
||||||
return SetNestedField(obj, value, fields...)
|
return SetNestedField(obj, value, fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNestedStringMap sets the map[string]string value of a nested field.
|
// SetNestedStringMap sets the map[string]string value of a nested field.
|
||||||
// Returns false if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
// Returns an error if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
||||||
func SetNestedStringMap(obj map[string]interface{}, value map[string]string, fields ...string) bool {
|
func SetNestedStringMap(obj map[string]interface{}, value map[string]string, fields ...string) error {
|
||||||
m := make(map[string]interface{}, len(value)) // convert map[string]string into map[string]interface{}
|
m := make(map[string]interface{}, len(value)) // convert map[string]string into map[string]interface{}
|
||||||
for k, v := range value {
|
for k, v := range value {
|
||||||
m[k] = v
|
m[k] = v
|
||||||
@ -242,8 +244,8 @@ func SetNestedStringMap(obj map[string]interface{}, value map[string]string, fie
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetNestedMap sets the map[string]interface{} value of a nested field.
|
// SetNestedMap sets the map[string]interface{} value of a nested field.
|
||||||
// Returns false if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
// Returns an error if value cannot be set because one of the nesting levels is not a map[string]interface{}.
|
||||||
func SetNestedMap(obj map[string]interface{}, value map[string]interface{}, fields ...string) bool {
|
func SetNestedMap(obj map[string]interface{}, value map[string]interface{}, fields ...string) error {
|
||||||
return SetNestedField(obj, value, fields...)
|
return SetNestedField(obj, value, fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +270,10 @@ func getNestedString(obj map[string]interface{}, fields ...string) string {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func jsonPath(fields []string) string {
|
||||||
|
return "." + strings.Join(fields, ".")
|
||||||
|
}
|
||||||
|
|
||||||
func extractOwnerReference(v map[string]interface{}) metav1.OwnerReference {
|
func extractOwnerReference(v map[string]interface{}) metav1.OwnerReference {
|
||||||
// though this field is a *bool, but when decoded from JSON, it's
|
// though this field is a *bool, but when decoded from JSON, it's
|
||||||
// unmarshalled as bool.
|
// unmarshalled as bool.
|
||||||
|
Loading…
Reference in New Issue
Block a user