mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Handle arb length paths in GetFieldName
This commit is contained in:
@@ -22,7 +22,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@@ -316,10 +315,9 @@ func (a *applicationImpl) resolveRefVars(resources resmap.ResMap) (map[string]st
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, refvar := range vars {
|
for _, refvar := range vars {
|
||||||
refGVKN := resource.NewResId(refvar.ObjRef.GroupVersionKind(), refvar.ObjRef.Name)
|
id := resource.NewResId(refvar.ObjRef.GroupVersionKind(), refvar.ObjRef.Name)
|
||||||
if r, found := resources[refGVKN]; found {
|
if r, found := resources[id]; found {
|
||||||
s, err := resource.GetFieldValue(
|
s, err := r.GetFieldValue(refvar.FieldRef.FieldPath)
|
||||||
r.UnstructuredContent(), strings.Split(refvar.FieldRef.FieldPath, "."))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to resolve referred var: %+v", refvar)
|
return nil, fmt.Errorf("failed to resolve referred var: %+v", refvar)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"strings"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
@@ -49,6 +51,13 @@ func NewBehaviorlessResource(u *unstructured.Unstructured) *Resource {
|
|||||||
return &Resource{Unstructured: *u, b: BehaviorUnspecified}
|
return &Resource{Unstructured: *u, b: BehaviorUnspecified}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewResource returns a new instance of Resource.
|
||||||
|
func NewResource(m map[string]interface{}) *Resource {
|
||||||
|
return &Resource{
|
||||||
|
Unstructured: unstructured.Unstructured{Object: m},
|
||||||
|
b: BehaviorUnspecified}
|
||||||
|
}
|
||||||
|
|
||||||
// Behavior returns the behavior for the resource.
|
// Behavior returns the behavior for the resource.
|
||||||
func (r *Resource) Behavior() GenerationBehavior {
|
func (r *Resource) Behavior() GenerationBehavior {
|
||||||
return r.b
|
return r.b
|
||||||
@@ -94,21 +103,14 @@ func mergeStringMaps(maps ...map[string]string) map[string]string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUnstructuredFromObject(in runtime.Object) (*unstructured.Unstructured, error) {
|
func (r *Resource) GetFieldValue(fieldPath string) (string, error) {
|
||||||
marshaled, err := json.Marshal(in)
|
return getFieldValue(r.UnstructuredContent(), strings.Split(fieldPath, "."))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var out unstructured.Unstructured
|
|
||||||
err = out.UnmarshalJSON(marshaled)
|
|
||||||
return &out, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFieldValue(m map[string]interface{}, pathToField []string) (string, error) {
|
func getFieldValue(m map[string]interface{}, pathToField []string) (string, error) {
|
||||||
if len(pathToField) == 0 {
|
if len(pathToField) == 0 {
|
||||||
return "", fmt.Errorf("Field not found")
|
return "", fmt.Errorf("Field not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pathToField) == 1 {
|
if len(pathToField) == 1 {
|
||||||
if v, found := m[pathToField[0]]; found {
|
if v, found := m[pathToField[0]]; found {
|
||||||
if s, ok := v.(string); ok {
|
if s, ok := v.(string); ok {
|
||||||
@@ -118,13 +120,10 @@ func GetFieldValue(m map[string]interface{}, pathToField []string) (string, erro
|
|||||||
}
|
}
|
||||||
return "", fmt.Errorf("field at given fieldpath does not exist")
|
return "", fmt.Errorf("field at given fieldpath does not exist")
|
||||||
}
|
}
|
||||||
|
v := m[pathToField[0]]
|
||||||
curr, rest := pathToField[0], pathToField[1]
|
|
||||||
|
|
||||||
v := m[curr]
|
|
||||||
switch typedV := v.(type) {
|
switch typedV := v.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
return GetFieldValue(typedV, []string{rest})
|
return getFieldValue(typedV, pathToField[1:])
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("%#v is not expected to be a primitive type", typedV)
|
return "", fmt.Errorf("%#v is not expected to be a primitive type", typedV)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetFieldAsString(t *testing.T) {
|
func TestGetFieldValue(t *testing.T) {
|
||||||
m := map[string]interface{}{
|
res := NewResource(map[string]interface{}{
|
||||||
"Kind": "Service",
|
"Kind": "Service",
|
||||||
"metadata": map[string]interface{}{
|
"metadata": map[string]interface{}{
|
||||||
"labels": map[string]string{
|
"labels": map[string]string{
|
||||||
@@ -29,37 +29,47 @@ func TestGetFieldAsString(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"name": "service-name",
|
"name": "service-name",
|
||||||
},
|
},
|
||||||
}
|
"spec": map[string]interface{}{
|
||||||
|
"ports": map[string]interface{}{
|
||||||
|
"port": "80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
pathToField []string
|
pathToField string
|
||||||
expectedName string
|
expectedValue string
|
||||||
expectedError bool
|
errorExpected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
pathToField: []string{"Kind"},
|
pathToField: "Kind",
|
||||||
expectedName: "Service",
|
expectedValue: "Service",
|
||||||
expectedError: false,
|
errorExpected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pathToField: []string{"metadata", "name"},
|
pathToField: "metadata.name",
|
||||||
expectedName: "service-name",
|
expectedValue: "service-name",
|
||||||
expectedError: false,
|
errorExpected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pathToField: []string{"metadata", "non-existing-field"},
|
pathToField: "metadata.non-existing-field",
|
||||||
expectedName: "",
|
expectedValue: "",
|
||||||
expectedError: true,
|
errorExpected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathToField: "spec.ports.port",
|
||||||
|
expectedValue: "80",
|
||||||
|
errorExpected: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
s, err := GetFieldValue(m, test.pathToField)
|
s, err := res.GetFieldValue(test.pathToField)
|
||||||
if test.expectedError && err == nil {
|
if test.errorExpected && err == nil {
|
||||||
t.Fatalf("should return error, but no error returned")
|
t.Fatalf("should return error, but no error returned")
|
||||||
} else {
|
} else {
|
||||||
if test.expectedName != s {
|
if test.expectedValue != s {
|
||||||
t.Fatalf("Got:%s expected:%s", s, test.expectedName)
|
t.Fatalf("Got:%s expected:%s", s, test.expectedValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user