mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-22 23:07:00 +00:00
Merge pull request #3277 from monopole/moreRNodeSetters
More RNode setters and WNode delegation
This commit is contained in:
@@ -174,36 +174,40 @@ func (wn *WNode) MatchesLabelSelector(string) (bool, error) {
|
||||
|
||||
// SetAnnotations implements ifc.Kunstructured.
|
||||
func (wn *WNode) SetAnnotations(annotations map[string]string) {
|
||||
wn.setField(yaml.NewMapRNode(&annotations), yaml.MetadataField, yaml.AnnotationsField)
|
||||
if err := wn.node.SetAnnotations(annotations); err != nil {
|
||||
log.Fatal(err) // interface doesn't allow error.
|
||||
}
|
||||
}
|
||||
|
||||
// SetGvk implements ifc.Kunstructured.
|
||||
func (wn *WNode) SetGvk(gvk resid.Gvk) {
|
||||
wn.setField(yaml.NewScalarRNode(gvk.Kind), yaml.KindField)
|
||||
wn.setField(yaml.NewScalarRNode(fmt.Sprintf("%s/%s", gvk.Group, gvk.Version)), yaml.APIVersionField)
|
||||
wn.setMapField(yaml.NewScalarRNode(gvk.Kind), yaml.KindField)
|
||||
wn.setMapField(
|
||||
yaml.NewScalarRNode(
|
||||
fmt.Sprintf("%s/%s", gvk.Group, gvk.Version)), yaml.APIVersionField)
|
||||
}
|
||||
|
||||
// SetLabels implements ifc.Kunstructured.
|
||||
func (wn *WNode) SetLabels(labels map[string]string) {
|
||||
wn.setField(yaml.NewMapRNode(&labels), yaml.MetadataField, yaml.LabelsField)
|
||||
if err := wn.node.SetLabels(labels); err != nil {
|
||||
log.Fatal(err) // interface doesn't allow error.
|
||||
}
|
||||
}
|
||||
|
||||
// SetName implements ifc.Kunstructured.
|
||||
func (wn *WNode) SetName(name string) {
|
||||
wn.setField(yaml.NewScalarRNode(name), yaml.MetadataField, yaml.NameField)
|
||||
wn.setMapField(yaml.NewScalarRNode(name), yaml.MetadataField, yaml.NameField)
|
||||
}
|
||||
|
||||
// SetNamespace implements ifc.Kunstructured.
|
||||
func (wn *WNode) SetNamespace(ns string) {
|
||||
wn.setField(yaml.NewScalarRNode(ns), yaml.MetadataField, yaml.NamespaceField)
|
||||
if err := wn.node.SetNamespace(ns); err != nil {
|
||||
log.Fatal(err) // interface doesn't allow error.
|
||||
}
|
||||
}
|
||||
|
||||
func (wn *WNode) setField(value *yaml.RNode, path ...string) {
|
||||
err := wn.node.PipeE(
|
||||
yaml.LookupCreate(yaml.MappingNode, path[0:len(path)-1]...),
|
||||
yaml.SetField(path[len(path)-1], value),
|
||||
)
|
||||
if err != nil {
|
||||
func (wn *WNode) setMapField(value *yaml.RNode, path ...string) {
|
||||
if err := wn.node.SetMapField(value, path...); err != nil {
|
||||
// Log and die since interface doesn't allow error.
|
||||
log.Fatalf("failed to set field %v: %v", path, err)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"sigs.k8s.io/kustomize/api/resid"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
"sigs.k8s.io/kustomize/api/resid"
|
||||
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resid"
|
||||
. "sigs.k8s.io/kustomize/api/resmap"
|
||||
@@ -687,21 +688,25 @@ func makeMap2(b types.GenerationBehavior) ResMap {
|
||||
}
|
||||
|
||||
func TestAbsorbAll(t *testing.T) {
|
||||
metadata := map[string]interface{}{
|
||||
"name": "cmap",
|
||||
}
|
||||
if !konfig.FlagEnableKyamlDefaultValue {
|
||||
metadata["annotations"] = map[string]interface{}{}
|
||||
metadata["labels"] = map[string]interface{}{}
|
||||
}
|
||||
expected := rmF.FromResource(rf.FromMapAndOption(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": map[string]interface{}{
|
||||
"annotations": map[string]interface{}{},
|
||||
"labels": map[string]interface{}{},
|
||||
"name": "cmap",
|
||||
},
|
||||
"metadata": metadata,
|
||||
"data": map[string]interface{}{
|
||||
"a": "u",
|
||||
"b": "v",
|
||||
"c": "w",
|
||||
},
|
||||
}, &types.GeneratorArgs{
|
||||
},
|
||||
&types.GeneratorArgs{
|
||||
Behavior: "create",
|
||||
}))
|
||||
w := makeMap1()
|
||||
@@ -718,9 +723,9 @@ func TestAbsorbAll(t *testing.T) {
|
||||
w = makeMap1()
|
||||
w2 = makeMap2(types.BehaviorUnspecified)
|
||||
err := w.AbsorbAll(w2)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error with unspecified behavior")
|
||||
}
|
||||
assert.Error(t, err)
|
||||
assert.True(
|
||||
t, strings.Contains(err.Error(), "behavior must be merge or replace"))
|
||||
}
|
||||
|
||||
func TestToRNodeSlice(t *testing.T) {
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/api/filesys"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
@@ -341,7 +343,15 @@ kind: List
|
||||
name: "listWithAnchorReference",
|
||||
input: []types.PatchStrategicMerge{patchList2},
|
||||
expectedOut: []*Resource{testDeploymentA, testDeploymentB},
|
||||
expectedErr: false,
|
||||
// See https://github.com/kubernetes-sigs/kustomize/issues/3271
|
||||
// This test should not have an error, but does when kyaml is used.
|
||||
// The error using kyaml is:
|
||||
// json: unsupported type: map[interface {}]interface {}
|
||||
// probably arising from too many conversions between
|
||||
// yaml, json, Resource, RNode, Unstructured etc.
|
||||
// These conversions can be removed after closing
|
||||
// https://github.com/kubernetes-sigs/kustomize/issues/2506
|
||||
expectedErr: konfig.FlagEnableKyamlDefaultValue,
|
||||
},
|
||||
{
|
||||
name: "listWithNoEntries",
|
||||
@@ -363,7 +373,7 @@ kind: List
|
||||
fmt.Sprintf("in test %s, got unexpected error: %v", test.name, err))
|
||||
continue
|
||||
}
|
||||
assert.False(t, test.expectedErr, "expected no error")
|
||||
assert.False(t, test.expectedErr, "expected no error in "+test.name)
|
||||
assert.Equal(t, len(test.expectedOut), len(rs))
|
||||
for i := range rs {
|
||||
expYaml, err := test.expectedOut[i].AsYAML()
|
||||
|
||||
@@ -333,6 +333,88 @@ func (rn *RNode) SetYNode(node *yaml.Node) {
|
||||
*rn.value = *node
|
||||
}
|
||||
|
||||
// GetNamespace gets the metadata namespace field.
|
||||
func (rn *RNode) GetNamespace() (string, error) {
|
||||
meta, err := rn.GetMeta()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return meta.Namespace, nil
|
||||
}
|
||||
|
||||
// SetNamespace tries to set the metadata namespace field.
|
||||
func (rn *RNode) SetNamespace(ns string) error {
|
||||
meta, err := rn.Pipe(Lookup(MetadataField))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ns == "" {
|
||||
if rn == nil {
|
||||
return nil
|
||||
}
|
||||
return meta.PipeE(Clear(NamespaceField))
|
||||
}
|
||||
return rn.SetMapField(
|
||||
NewScalarRNode(ns), MetadataField, NamespaceField)
|
||||
}
|
||||
|
||||
// GetAnnotations gets the metadata annotations field.
|
||||
func (rn *RNode) GetAnnotations() (map[string]string, error) {
|
||||
meta, err := rn.GetMeta()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return meta.Annotations, nil
|
||||
}
|
||||
|
||||
// SetAnnotations tries to set the metadata annotations field.
|
||||
func (rn *RNode) SetAnnotations(m map[string]string) error {
|
||||
meta, err := rn.Pipe(Lookup(MetadataField))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(m) == 0 {
|
||||
if meta == nil {
|
||||
return nil
|
||||
}
|
||||
return meta.PipeE(Clear(AnnotationsField))
|
||||
}
|
||||
return rn.SetMapField(
|
||||
NewMapRNode(&m), MetadataField, AnnotationsField)
|
||||
}
|
||||
|
||||
// GetLabels gets the metadata labels field.
|
||||
func (rn *RNode) GetLabels() (map[string]string, error) {
|
||||
meta, err := rn.GetMeta()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return meta.Labels, nil
|
||||
}
|
||||
|
||||
// SetLabels sets the metadata labels field.
|
||||
func (rn *RNode) SetLabels(m map[string]string) error {
|
||||
meta, err := rn.Pipe(Lookup(MetadataField))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(m) == 0 {
|
||||
if meta == nil {
|
||||
return nil
|
||||
}
|
||||
return meta.PipeE(Clear(LabelsField))
|
||||
}
|
||||
return rn.SetMapField(
|
||||
NewMapRNode(&m), MetadataField, LabelsField)
|
||||
}
|
||||
|
||||
func (rn *RNode) SetMapField(value *RNode, path ...string) error {
|
||||
return rn.PipeE(
|
||||
LookupCreate(yaml.MappingNode, path[0:len(path)-1]...),
|
||||
SetField(path[len(path)-1], value),
|
||||
)
|
||||
}
|
||||
|
||||
// AppendToFieldPath appends a field name to the FieldPath.
|
||||
func (rn *RNode) AppendToFieldPath(parts ...string) {
|
||||
rn.fieldPath = append(rn.fieldPath, parts...)
|
||||
|
||||
@@ -751,3 +751,104 @@ func TestRNodeIsNilOrEmpty(t *testing.T) {
|
||||
t.Fatalf("non-empty list should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
const deploymentJSON = `
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "homer",
|
||||
"namespace": "simpsons",
|
||||
"labels": {
|
||||
"fruit": "apple",
|
||||
"veggie": "carrot"
|
||||
},
|
||||
"annotations": {
|
||||
"area": "51",
|
||||
"greeting": "Take me to your leader."
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
func getNamespaceOrDie(t *testing.T, n *RNode) string {
|
||||
m, err := n.GetNamespace()
|
||||
assert.NoError(t, err)
|
||||
return m
|
||||
}
|
||||
|
||||
func TestRNodeSetNamespace(t *testing.T) {
|
||||
n := NewRNode(nil)
|
||||
assert.Equal(t, "", getNamespaceOrDie(t, n))
|
||||
assert.NoError(t, n.SetNamespace(""))
|
||||
assert.Equal(t, "", getNamespaceOrDie(t, n))
|
||||
if err := n.UnmarshalJSON([]byte(deploymentJSON)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
assert.NoError(t, n.SetNamespace("flanders"))
|
||||
assert.Equal(t, "flanders", getNamespaceOrDie(t, n))
|
||||
}
|
||||
|
||||
func getLabelsOrDie(t *testing.T, n *RNode) map[string]string {
|
||||
m, err := n.GetLabels()
|
||||
assert.NoError(t, err)
|
||||
return m
|
||||
}
|
||||
|
||||
func TestRNodeSetLabels(t *testing.T) {
|
||||
n := NewRNode(nil)
|
||||
assert.Equal(t, 0, len(getLabelsOrDie(t, n)))
|
||||
assert.NoError(t, n.SetLabels(map[string]string{}))
|
||||
assert.Equal(t, 0, len(getLabelsOrDie(t, n)))
|
||||
|
||||
n = NewRNode(nil)
|
||||
if err := n.UnmarshalJSON([]byte(deploymentJSON)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
labels := getLabelsOrDie(t, n)
|
||||
assert.Equal(t, 2, len(labels))
|
||||
assert.Equal(t, "apple", labels["fruit"])
|
||||
assert.Equal(t, "carrot", labels["veggie"])
|
||||
assert.NoError(t, n.SetLabels(map[string]string{
|
||||
"label1": "foo",
|
||||
"label2": "bar",
|
||||
}))
|
||||
labels = getLabelsOrDie(t, n)
|
||||
assert.Equal(t, 2, len(labels))
|
||||
assert.Equal(t, "foo", labels["label1"])
|
||||
assert.Equal(t, "bar", labels["label2"])
|
||||
assert.NoError(t, n.SetLabels(map[string]string{}))
|
||||
assert.Equal(t, 0, len(getLabelsOrDie(t, n)))
|
||||
}
|
||||
|
||||
func getAnnotationsOrDie(t *testing.T, n *RNode) map[string]string {
|
||||
m, err := n.GetAnnotations()
|
||||
assert.NoError(t, err)
|
||||
return m
|
||||
}
|
||||
|
||||
func TestRNodeGetAnnotations(t *testing.T) {
|
||||
n := NewRNode(nil)
|
||||
assert.Equal(t, 0, len(getAnnotationsOrDie(t, n)))
|
||||
assert.NoError(t, n.SetAnnotations(map[string]string{}))
|
||||
assert.Equal(t, 0, len(getAnnotationsOrDie(t, n)))
|
||||
|
||||
n = NewRNode(nil)
|
||||
if err := n.UnmarshalJSON([]byte(deploymentJSON)); err != nil {
|
||||
t.Fatalf("unexpected unmarshaljson err: %v", err)
|
||||
}
|
||||
annotations := getAnnotationsOrDie(t, n)
|
||||
assert.Equal(t, 2, len(annotations))
|
||||
assert.Equal(t, "51", annotations["area"])
|
||||
assert.Equal(t, "Take me to your leader.", annotations["greeting"])
|
||||
assert.NoError(t, n.SetAnnotations(map[string]string{
|
||||
"annotation1": "foo",
|
||||
"annotation2": "bar",
|
||||
}))
|
||||
annotations = getAnnotationsOrDie(t, n)
|
||||
assert.Equal(t, 2, len(annotations))
|
||||
assert.Equal(t, "foo", annotations["annotation1"])
|
||||
assert.Equal(t, "bar", annotations["annotation2"])
|
||||
assert.NoError(t, n.SetAnnotations(map[string]string{}))
|
||||
assert.Equal(t, 0, len(getAnnotationsOrDie(t, n)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user