Add RNode.Set/GetDataMap to ease configmap generation.

This commit is contained in:
jregan
2020-12-21 07:18:51 -08:00
parent f84f8f28fd
commit 35087ed0cc
2 changed files with 171 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"strconv"
"strings"
@@ -417,6 +418,34 @@ func (rn *RNode) SetMapField(value *RNode, path ...string) error {
)
}
func (rn *RNode) GetDataMap() map[string]string {
n, err := rn.Pipe(Lookup(DataField))
if err != nil {
return nil
}
result := map[string]string{}
_ = n.VisitFields(func(node *MapNode) error {
result[GetValue(node.Key)] = GetValue(node.Value)
return nil
})
return result
}
func (rn *RNode) SetDataMap(m map[string]string) {
if rn == nil {
log.Fatal("cannot set data map on nil Rnode")
}
if len(m) == 0 {
if err := rn.PipeE(Clear(DataField)); err != nil {
log.Fatal(err)
}
return
}
if err := rn.SetMapField(NewMapRNode(&m), DataField); err != nil {
log.Fatal(err)
}
}
// AppendToFieldPath appends a field name to the FieldPath.
func (rn *RNode) AppendToFieldPath(parts ...string) {
rn.fieldPath = append(rn.fieldPath, parts...)

View File

@@ -115,6 +115,148 @@ func TestRNodeNewStringRNodeBinary(t *testing.T) {
}
}
func TestRNodeGetDataMap(t *testing.T) {
emptyMap := map[string]string{}
testCases := map[string]struct {
theMap map[string]interface{}
expected map[string]string
}{
"actuallyNil": {
theMap: nil,
expected: emptyMap,
},
"empty": {
theMap: map[string]interface{}{},
expected: emptyMap,
},
"mostlyEmpty": {
theMap: map[string]interface{}{
"hey": "there",
},
expected: emptyMap,
},
"noNameConfigMap": {
theMap: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
},
expected: emptyMap,
},
"configmap": {
theMap: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "winnie",
},
"data": map[string]string{
"wine": "cabernet",
"truck": "ford",
"rocket": "falcon9",
"planet": "mars",
"city": "brownsville",
},
},
// order irrelevant, because assert.Equals is smart about maps.
expected: map[string]string{
"city": "brownsville",
"wine": "cabernet",
"planet": "mars",
"rocket": "falcon9",
"truck": "ford",
},
},
}
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
rn, err := FromMap(tc.theMap)
if !assert.NoError(t, err) {
t.FailNow()
}
m := rn.GetDataMap()
if !assert.Equal(t, tc.expected, m) {
t.FailNow()
}
})
}
}
func TestRNodeSetDataMap(t *testing.T) {
testCases := map[string]struct {
theMap map[string]interface{}
input map[string]string
expected map[string]string
}{
"empty": {
theMap: map[string]interface{}{},
input: map[string]string{
"wine": "cabernet",
"truck": "ford",
},
expected: map[string]string{
"wine": "cabernet",
"truck": "ford",
},
},
"replace": {
theMap: map[string]interface{}{
"foo": 3,
"data": map[string]string{
"rocket": "falcon9",
"planet": "mars",
},
},
input: map[string]string{
"wine": "cabernet",
"truck": "ford",
},
expected: map[string]string{
"wine": "cabernet",
"truck": "ford",
},
},
"clear1": {
theMap: map[string]interface{}{
"foo": 3,
"data": map[string]string{
"rocket": "falcon9",
"planet": "mars",
},
},
input: map[string]string{},
expected: map[string]string{},
},
"clear2": {
theMap: map[string]interface{}{
"foo": 3,
"data": map[string]string{
"rocket": "falcon9",
"planet": "mars",
},
},
input: nil,
expected: map[string]string{},
},
}
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
rn, err := FromMap(tc.theMap)
if !assert.NoError(t, err) {
t.FailNow()
}
rn.SetDataMap(tc.input)
m := rn.GetDataMap()
if !assert.Equal(t, tc.expected, m) {
t.FailNow()
}
})
}
}
func TestRNodeGetValidatedMetadata(t *testing.T) {
testConfigMap := map[string]interface{}{
"apiVersion": "v1",