mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Remove the wrappy layer.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -336,6 +337,33 @@ func (rn *RNode) SetYNode(node *yaml.Node) {
|
||||
*rn.value = *node
|
||||
}
|
||||
|
||||
// GetKind returns the kind.
|
||||
func (rn *RNode) GetKind() string {
|
||||
node, err := rn.Pipe(FieldMatcher{Name: KindField})
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return GetValue(node)
|
||||
}
|
||||
|
||||
// GetName returns the name.
|
||||
func (rn *RNode) GetName() string {
|
||||
f := rn.Field(MetadataField)
|
||||
if f.IsNilOrEmpty() {
|
||||
return ""
|
||||
}
|
||||
f = f.Value.Field(NameField)
|
||||
if f.IsNilOrEmpty() {
|
||||
return ""
|
||||
}
|
||||
return f.Value.YNode().Value
|
||||
}
|
||||
|
||||
// SetName sets the metadata name field.
|
||||
func (rn *RNode) SetName(name string) error {
|
||||
return rn.SetMapField(NewScalarRNode(name), MetadataField, NameField)
|
||||
}
|
||||
|
||||
// GetNamespace gets the metadata namespace field.
|
||||
func (rn *RNode) GetNamespace() (string, error) {
|
||||
meta, err := rn.GetMeta()
|
||||
@@ -752,7 +780,7 @@ func (rn *RNode) GetValidatedMetadata() (ResourceMeta, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// MatchesAnnotationSelector implements ifc.Kunstructured.
|
||||
// MatchesAnnotationSelector returns true on a selector match to annotations.
|
||||
func (rn *RNode) MatchesAnnotationSelector(selector string) (bool, error) {
|
||||
s, err := labels.Parse(selector)
|
||||
if err != nil {
|
||||
@@ -765,7 +793,7 @@ func (rn *RNode) MatchesAnnotationSelector(selector string) (bool, error) {
|
||||
return s.Matches(labels.Set(slice)), nil
|
||||
}
|
||||
|
||||
// MatchesLabelSelector implements ifc.Kunstructured.
|
||||
// MatchesLabelSelector returns true on a selector match to labels.
|
||||
func (rn *RNode) MatchesLabelSelector(selector string) (bool, error) {
|
||||
s, err := labels.Parse(selector)
|
||||
if err != nil {
|
||||
@@ -859,3 +887,123 @@ func checkKey(key string, elems []*Node) bool {
|
||||
}
|
||||
return count == len(elems)
|
||||
}
|
||||
|
||||
// Deprecated: use pipes instead.
|
||||
// GetSlice returns the contents of the slice field at the given path.
|
||||
func (rn *RNode) GetSlice(path string) ([]interface{}, error) {
|
||||
value, err := rn.GetFieldValue(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sliceValue, ok := value.([]interface{}); ok {
|
||||
return sliceValue, nil
|
||||
}
|
||||
return nil, fmt.Errorf("node %s is not a slice", path)
|
||||
}
|
||||
|
||||
// Deprecated: use pipes instead.
|
||||
// GetString returns the contents of the string field at the given path.
|
||||
func (rn *RNode) GetString(path string) (string, error) {
|
||||
value, err := rn.GetFieldValue(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if v, ok := value.(string); ok {
|
||||
return v, nil
|
||||
}
|
||||
return "", fmt.Errorf("node %s is not a string: %v", path, value)
|
||||
}
|
||||
|
||||
// Deprecated: use slash paths instead.
|
||||
// GetFieldValue finds period delimited fields.
|
||||
// TODO: When doing kustomize var replacement, which is likely a
|
||||
// a primary use of this function and the reason it returns interface{}
|
||||
// rather than string, we do conversion from Nodes to Go types and back
|
||||
// to nodes. We should figure out how to do replacement using raw nodes,
|
||||
// assuming we keep the var feature in kustomize.
|
||||
// The other end of this is: refvar.go:updateNodeValue.
|
||||
func (rn *RNode) GetFieldValue(path string) (interface{}, error) {
|
||||
fields := convertSliceIndex(strings.Split(path, "."))
|
||||
rn, err := rn.Pipe(Lookup(fields...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rn == nil {
|
||||
return nil, NoFieldError{path}
|
||||
}
|
||||
yn := rn.YNode()
|
||||
|
||||
// If this is an alias node, resolve it
|
||||
if yn.Kind == yaml.AliasNode {
|
||||
yn = yn.Alias
|
||||
}
|
||||
|
||||
// Return value as map for DocumentNode and MappingNode kinds
|
||||
if yn.Kind == yaml.DocumentNode || yn.Kind == yaml.MappingNode {
|
||||
var result map[string]interface{}
|
||||
if err := yn.Decode(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Return value as slice for SequenceNode kind
|
||||
if yn.Kind == yaml.SequenceNode {
|
||||
var result []interface{}
|
||||
if err := yn.Decode(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
if yn.Kind != yaml.ScalarNode {
|
||||
return nil, fmt.Errorf("expected ScalarNode, got Kind=%d", yn.Kind)
|
||||
}
|
||||
|
||||
switch yn.Tag {
|
||||
case NodeTagString:
|
||||
return yn.Value, nil
|
||||
case NodeTagInt:
|
||||
return strconv.Atoi(yn.Value)
|
||||
case NodeTagFloat:
|
||||
return strconv.ParseFloat(yn.Value, 64)
|
||||
case NodeTagBool:
|
||||
return strconv.ParseBool(yn.Value)
|
||||
default:
|
||||
// Possibly this should be an error or log.
|
||||
return yn.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
// convertSliceIndex traverses the items in `fields` and find
|
||||
// if there is a slice index in the item and change it to a
|
||||
// valid Lookup field path. For example, 'ports[0]' will be
|
||||
// converted to 'ports' and '0'.
|
||||
func convertSliceIndex(fields []string) []string {
|
||||
var res []string
|
||||
for _, s := range fields {
|
||||
if !strings.HasSuffix(s, "]") {
|
||||
res = append(res, s)
|
||||
continue
|
||||
}
|
||||
re := regexp.MustCompile(`^(.*)\[(\d+)\]$`)
|
||||
groups := re.FindStringSubmatch(s)
|
||||
if len(groups) == 0 {
|
||||
// no match, add to result
|
||||
res = append(res, s)
|
||||
continue
|
||||
}
|
||||
if groups[1] != "" {
|
||||
res = append(res, groups[1])
|
||||
}
|
||||
res = append(res, groups[2])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
type NoFieldError struct {
|
||||
Field string
|
||||
}
|
||||
|
||||
func (e NoFieldError) Error() string {
|
||||
return fmt.Sprintf("no field named '%s'", e.Field)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestRNodeHasNilEntryInList(t *testing.T) {
|
||||
@@ -1130,3 +1131,627 @@ func TestRNodeMatchesLabelSelector(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
deploymentLittleJson = `{"apiVersion":"apps/v1","kind":"Deployment",` +
|
||||
`"metadata":{"name":"homer","namespace":"simpsons"}}`
|
||||
|
||||
deploymentBiggerJson = `
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "homer",
|
||||
"namespace": "simpsons",
|
||||
"labels": {
|
||||
"fruit": "apple",
|
||||
"veggie": "carrot"
|
||||
},
|
||||
"annotations": {
|
||||
"area": "51",
|
||||
"greeting": "Take me to your leader."
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"template": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "CM_FOO",
|
||||
"valueFrom": {
|
||||
"configMapKeyRef": {
|
||||
"key": "somekey",
|
||||
"name": "myCm"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SECRET_FOO",
|
||||
"valueFrom": {
|
||||
"secretKeyRef": {
|
||||
"key": "someKey",
|
||||
"name": "mySecret"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"image": "nginx:1.7.9",
|
||||
"name": "nginx"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
bigMapYaml = `Kind: Service
|
||||
complextree:
|
||||
- field1:
|
||||
- boolfield: true
|
||||
floatsubfield: 1.01
|
||||
intsubfield: 1010
|
||||
stringsubfield: idx1010
|
||||
- boolfield: false
|
||||
floatsubfield: 1.011
|
||||
intsubfield: 1011
|
||||
stringsubfield: idx1011
|
||||
field2:
|
||||
- boolfield: true
|
||||
floatsubfield: 1.02
|
||||
intsubfield: 1020
|
||||
stringsubfield: idx1020
|
||||
- boolfield: false
|
||||
floatsubfield: 1.021
|
||||
intsubfield: 1021
|
||||
stringsubfield: idx1021
|
||||
- field1:
|
||||
- boolfield: true
|
||||
floatsubfield: 1.11
|
||||
intsubfield: 1110
|
||||
stringsubfield: idx1110
|
||||
- boolfield: false
|
||||
floatsubfield: 1.111
|
||||
intsubfield: 1111
|
||||
stringsubfield: idx1111
|
||||
field2:
|
||||
- boolfield: true
|
||||
floatsubfield: 1.112
|
||||
intsubfield: 1120
|
||||
stringsubfield: idx1120
|
||||
- boolfield: false
|
||||
floatsubfield: 1.1121
|
||||
intsubfield: 1121
|
||||
stringsubfield: idx1121
|
||||
metadata:
|
||||
labels:
|
||||
app: application-name
|
||||
name: service-name
|
||||
spec:
|
||||
ports:
|
||||
port: 80
|
||||
that:
|
||||
- idx0
|
||||
- idx1
|
||||
- idx2
|
||||
- idx3
|
||||
these:
|
||||
- field1:
|
||||
- idx010
|
||||
- idx011
|
||||
field2:
|
||||
- idx020
|
||||
- idx021
|
||||
- field1:
|
||||
- idx110
|
||||
- idx111
|
||||
field2:
|
||||
- idx120
|
||||
- idx121
|
||||
- field1:
|
||||
- idx210
|
||||
- idx211
|
||||
field2:
|
||||
- idx220
|
||||
- idx221
|
||||
this:
|
||||
is:
|
||||
aBool: true
|
||||
aFloat: 1.001
|
||||
aNilValue: null
|
||||
aNumber: 1000
|
||||
anEmptyMap: {}
|
||||
anEmptySlice: []
|
||||
those:
|
||||
- field1: idx0foo
|
||||
field2: idx0bar
|
||||
- field1: idx1foo
|
||||
field2: idx1bar
|
||||
- field1: idx2foo
|
||||
field2: idx2bar
|
||||
`
|
||||
)
|
||||
|
||||
func TestGetFieldValueReturnsMap(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
expected := map[string]interface{}{
|
||||
"fruit": "apple",
|
||||
"veggie": "carrot",
|
||||
}
|
||||
actual, err := rn.GetFieldValue("metadata.labels")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting field value: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Fatalf("actual map does not deep equal expected map:\n%v", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFieldValueReturnsStuff(t *testing.T) {
|
||||
wn := NewRNode(nil)
|
||||
if err := wn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
expected := []interface{}{
|
||||
map[string]interface{}{
|
||||
"env": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "CM_FOO",
|
||||
"valueFrom": map[string]interface{}{
|
||||
"configMapKeyRef": map[string]interface{}{
|
||||
"key": "somekey",
|
||||
"name": "myCm",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"name": "SECRET_FOO",
|
||||
"valueFrom": map[string]interface{}{
|
||||
"secretKeyRef": map[string]interface{}{
|
||||
"key": "someKey",
|
||||
"name": "mySecret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"image": string("nginx:1.7.9"),
|
||||
"name": string("nginx"),
|
||||
},
|
||||
}
|
||||
actual, err := wn.GetFieldValue("spec.template.spec.containers")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting field value: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Fatalf("actual map does not deep equal expected map:\n%v", diff)
|
||||
}
|
||||
// Cannot go deeper yet.
|
||||
_, err = wn.GetFieldValue("spec.template.spec.containers.env")
|
||||
if err == nil {
|
||||
t.Fatalf("expected err %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func makeBigMap() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"Kind": "Service",
|
||||
"metadata": map[string]interface{}{
|
||||
"labels": map[string]interface{}{
|
||||
"app": "application-name",
|
||||
},
|
||||
"name": "service-name",
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"ports": map[string]interface{}{
|
||||
"port": int64(80),
|
||||
},
|
||||
},
|
||||
"this": map[string]interface{}{
|
||||
"is": map[string]interface{}{
|
||||
"aNumber": int64(1000),
|
||||
"aFloat": float64(1.001),
|
||||
"aNilValue": nil,
|
||||
"aBool": true,
|
||||
"anEmptyMap": map[string]interface{}{},
|
||||
"anEmptySlice": []interface{}{},
|
||||
/*
|
||||
TODO: test for unrecognizable (e.g. a function)
|
||||
"unrecognizable": testing.InternalExample{
|
||||
Name: "fooBar",
|
||||
},
|
||||
*/
|
||||
},
|
||||
},
|
||||
"that": []interface{}{
|
||||
"idx0",
|
||||
"idx1",
|
||||
"idx2",
|
||||
"idx3",
|
||||
},
|
||||
"those": []interface{}{
|
||||
map[string]interface{}{
|
||||
"field1": "idx0foo",
|
||||
"field2": "idx0bar",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": "idx1foo",
|
||||
"field2": "idx1bar",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": "idx2foo",
|
||||
"field2": "idx2bar",
|
||||
},
|
||||
},
|
||||
"these": []interface{}{
|
||||
map[string]interface{}{
|
||||
"field1": []interface{}{"idx010", "idx011"},
|
||||
"field2": []interface{}{"idx020", "idx021"},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": []interface{}{"idx110", "idx111"},
|
||||
"field2": []interface{}{"idx120", "idx121"},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": []interface{}{"idx210", "idx211"},
|
||||
"field2": []interface{}{"idx220", "idx221"},
|
||||
},
|
||||
},
|
||||
"complextree": []interface{}{
|
||||
map[string]interface{}{
|
||||
"field1": []interface{}{
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1010",
|
||||
"intsubfield": int64(1010),
|
||||
"floatsubfield": float64(1.010),
|
||||
"boolfield": true,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1011",
|
||||
"intsubfield": int64(1011),
|
||||
"floatsubfield": float64(1.011),
|
||||
"boolfield": false,
|
||||
},
|
||||
},
|
||||
"field2": []interface{}{
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1020",
|
||||
"intsubfield": int64(1020),
|
||||
"floatsubfield": float64(1.020),
|
||||
"boolfield": true,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1021",
|
||||
"intsubfield": int64(1021),
|
||||
"floatsubfield": float64(1.021),
|
||||
"boolfield": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": []interface{}{
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1110",
|
||||
"intsubfield": int64(1110),
|
||||
"floatsubfield": float64(1.110),
|
||||
"boolfield": true,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1111",
|
||||
"intsubfield": int64(1111),
|
||||
"floatsubfield": float64(1.111),
|
||||
"boolfield": false,
|
||||
},
|
||||
},
|
||||
"field2": []interface{}{
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1120",
|
||||
"intsubfield": int64(1120),
|
||||
"floatsubfield": float64(1.1120),
|
||||
"boolfield": true,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"stringsubfield": "idx1121",
|
||||
"intsubfield": int64(1121),
|
||||
"floatsubfield": float64(1.1121),
|
||||
"boolfield": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
func TestBasicYamlOperationFromMap(t *testing.T) {
|
||||
bytes, err := Marshal(makeBigMap())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
if string(bytes) != bigMapYaml {
|
||||
t.Fatalf("unexpected string equality")
|
||||
}
|
||||
rNode, err := Parse(string(bytes))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
rNodeString := rNode.MustString()
|
||||
// The result from MustString has more indentation
|
||||
// than bigMapYaml.
|
||||
rNodeStrings := strings.Split(rNodeString, "\n")
|
||||
bigMapStrings := strings.Split(bigMapYaml, "\n")
|
||||
if len(rNodeStrings) != len(bigMapStrings) {
|
||||
t.Fatalf("line count mismatch")
|
||||
}
|
||||
for i := range rNodeStrings {
|
||||
s1 := strings.TrimSpace(rNodeStrings[i])
|
||||
s2 := strings.TrimSpace(bigMapStrings[i])
|
||||
if s1 != s2 {
|
||||
t.Fatalf("expected '%s'=='%s'", s1, s2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFieldValueReturnsSlice(t *testing.T) {
|
||||
bytes, err := yaml.Marshal(makeBigMap())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
rNode, err := Parse(string(bytes))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
expected := []interface{}{"idx0", "idx1", "idx2", "idx3"}
|
||||
actual, err := rNode.GetFieldValue("that")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting slice: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Fatalf("actual slice does not deep equal expected slice:\n%v", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFieldValueReturnsSliceOfMappings(t *testing.T) {
|
||||
bytes, err := yaml.Marshal(makeBigMap())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
rn, err := Parse(string(bytes))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
expected := []interface{}{
|
||||
map[string]interface{}{
|
||||
"field1": "idx0foo",
|
||||
"field2": "idx0bar",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": "idx1foo",
|
||||
"field2": "idx1bar",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"field1": "idx2foo",
|
||||
"field2": "idx2bar",
|
||||
},
|
||||
}
|
||||
actual, err := rn.GetFieldValue("those")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting slice: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Fatalf("actual slice does not deep equal expected slice:\n%v", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFieldValueReturnsString(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
actual, err := rn.GetFieldValue("metadata.labels.fruit")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting field value: %v", err)
|
||||
}
|
||||
v, ok := actual.(string)
|
||||
if !ok || v != "apple" {
|
||||
t.Fatalf("unexpected value '%v'", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFieldValueResolvesAlias(t *testing.T) {
|
||||
yamlWithAlias := `
|
||||
foo: &a theValue
|
||||
bar: *a
|
||||
`
|
||||
rn, err := Parse(yamlWithAlias)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml parse error: %v", err)
|
||||
}
|
||||
actual, err := rn.GetFieldValue("bar")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting field value: %v", err)
|
||||
}
|
||||
v, ok := actual.(string)
|
||||
if !ok || v != "theValue" {
|
||||
t.Fatalf("unexpected value '%v'", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetString(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
expected := "carrot"
|
||||
actual, err := rn.GetString("metadata.labels.veggie")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting string: %v", err)
|
||||
}
|
||||
if expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSlice(t *testing.T) {
|
||||
bytes, err := yaml.Marshal(makeBigMap())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
rn, err := Parse(string(bytes))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected yaml.Marshal err: %v", err)
|
||||
}
|
||||
expected := []interface{}{"idx0", "idx1", "idx2", "idx3"}
|
||||
actual, err := rn.GetSlice("that")
|
||||
if err != nil {
|
||||
t.Fatalf("error getting slice: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Fatalf("actual slice does not deep equal expected slice:\n%v", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundTripJSON(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
err := rn.UnmarshalJSON([]byte(deploymentLittleJson))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected UnmarshalJSON err: %v", err)
|
||||
}
|
||||
data, err := rn.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected MarshalJSON err: %v", err)
|
||||
}
|
||||
actual := string(data)
|
||||
if actual != deploymentLittleJson {
|
||||
t.Fatalf("expected %s, got %s", deploymentLittleJson, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGettingFields(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
err := rn.UnmarshalJSON([]byte(deploymentBiggerJson))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
expected := "Deployment"
|
||||
actual := rn.GetKind()
|
||||
if expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
expected = "homer"
|
||||
actual = rn.GetName()
|
||||
if expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
actualMap, err := rn.GetLabels()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err '%v'", err)
|
||||
}
|
||||
v, ok := actualMap["fruit"]
|
||||
if !ok || v != "apple" {
|
||||
t.Fatalf("unexpected labels '%v'", actualMap)
|
||||
}
|
||||
actualMap, err = rn.GetAnnotations()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err '%v'", err)
|
||||
}
|
||||
v, ok = actualMap["greeting"]
|
||||
if !ok || v != "Take me to your leader." {
|
||||
t.Fatalf("unexpected annotations '%v'", actualMap)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapEmpty(t *testing.T) {
|
||||
newNodeMap, err := NewRNode(nil).Map()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(newNodeMap))
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentLittleJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
|
||||
expected := map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "homer",
|
||||
"namespace": "simpsons",
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := rn.Map()
|
||||
assert.NoError(t, err)
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Fatalf("actual map does not deep equal expected map:\n%v", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetName(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
rn.SetName("marge")
|
||||
if expected, actual := "marge", rn.GetName(); expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetNamespace(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
rn.SetNamespace("flanders")
|
||||
meta, _ := rn.GetMeta()
|
||||
if expected, actual := "flanders", meta.Namespace; expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
}
|
||||
func TestSetLabels(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
rn.SetLabels(map[string]string{
|
||||
"label1": "foo",
|
||||
"label2": "bar",
|
||||
})
|
||||
labels, err := rn.GetLabels()
|
||||
assert.NoError(t, err)
|
||||
if expected, actual := 2, len(labels); expected != actual {
|
||||
t.Fatalf("expected '%d', got '%d'", expected, actual)
|
||||
}
|
||||
if expected, actual := "foo", labels["label1"]; expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
if expected, actual := "bar", labels["label2"]; expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAnnotations(t *testing.T) {
|
||||
rn := NewRNode(nil)
|
||||
if err := rn.UnmarshalJSON([]byte(deploymentBiggerJson)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
rn.SetAnnotations(map[string]string{
|
||||
"annotation1": "foo",
|
||||
"annotation2": "bar",
|
||||
})
|
||||
annotations, err := rn.GetAnnotations()
|
||||
assert.NoError(t, err)
|
||||
if expected, actual := 2, len(annotations); expected != actual {
|
||||
t.Fatalf("expected '%d', got '%d'", expected, actual)
|
||||
}
|
||||
if expected, actual := "foo", annotations["annotation1"]; expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
if expected, actual := "bar", annotations["annotation2"]; expected != actual {
|
||||
t.Fatalf("expected '%s', got '%s'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user