ignore null value in fieldspec

This commit is contained in:
Donny Xia
2020-09-14 13:20:20 -07:00
parent 6a0a909e73
commit f0bc926640
7 changed files with 96 additions and 51 deletions

View File

@@ -51,6 +51,9 @@ func (fltr Filter) filter(obj *yaml.RNode) error {
// found the field -- set its value // found the field -- set its value
return fltr.SetValue(obj) return fltr.SetValue(obj)
} }
if obj.IsTaggedNull() {
return nil
}
switch obj.YNode().Kind { switch obj.YNode().Kind {
case yaml.SequenceNode: case yaml.SequenceNode:
return fltr.seq(obj) return fltr.seq(obj)
@@ -67,7 +70,7 @@ func (fltr Filter) field(obj *yaml.RNode) error {
// lookup the field matching the next path element // lookup the field matching the next path element
var lookupField yaml.Filter var lookupField yaml.Filter
var kind yaml.Kind var kind yaml.Kind
tag := "" // TODO: change to yaml.NodeTagEmpty tag := yaml.NodeTagEmpty
switch { switch {
case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq: case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq:
// dont' create the field if we don't find it // dont' create the field if we don't find it
@@ -95,9 +98,10 @@ func (fltr Filter) field(obj *yaml.RNode) error {
return errors.WrapPrefixf(err, "fieldName: %s", fieldName) return errors.WrapPrefixf(err, "fieldName: %s", fieldName)
} }
// if the value exists, but is null, then change it to the creation type // if the value exists, but is null and kind is set,
// then change it to the creation type
// TODO: update yaml.LookupCreate to support this // TODO: update yaml.LookupCreate to support this
if field.YNode().Tag == yaml.NodeTagNull { if field.YNode().Tag == yaml.NodeTagNull && yaml.IsCreate(kind) {
field.YNode().Kind = kind field.YNode().Kind = kind
field.YNode().Tag = tag field.YNode().Tag = tag
} }

View File

@@ -433,7 +433,6 @@ spec:
SetValue: filtersutil.SetScalar("bar"), SetValue: filtersutil.SetScalar("bar"),
CreateKind: yaml.ScalarNode, CreateKind: yaml.ScalarNode,
}, },
error: "obj '' at path 'spec/containers/image': expected sequence or mapping node",
}, },
{ {
name: "filedname with slash '/'", name: "filedname with slash '/'",

View File

@@ -168,6 +168,44 @@ metadata:
map: map:
name: newName name: newName
namespace: oldNs namespace: oldNs
`,
filter: Filter{
FieldSpec: types.FieldSpec{Path: "map"},
Target: resid.Gvk{
Group: "apps",
Version: "v1",
Kind: "Secret",
},
},
},
"null value": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
map:
name: null
`,
candidates: `
apiVersion: apps/v1
kind: Secret
metadata:
name: newName
---
apiVersion: apps/v1
kind: NotSecret
metadata:
name: newName2
`,
originalNames: []string{"oldName", ""},
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
map:
name: null
`, `,
filter: Filter{ filter: Filter{
FieldSpec: types.FieldSpec{Path: "map"}, FieldSpec: types.FieldSpec{Path: "map"},
@@ -217,27 +255,6 @@ func TestNamerefFilterUnhappy(t *testing.T) {
filter Filter filter Filter
originalNames []string originalNames []string
}{ }{
"invalid node type": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
ref:
name: null
`,
candidates: "",
originalNames: []string{},
expected: "obj '' at path 'ref/name': node is expected to be either a string or a slice of string or a map of string",
filter: Filter{
FieldSpec: types.FieldSpec{Path: "ref/name"},
Target: resid.Gvk{
Group: "apps",
Version: "v1",
Kind: "Secret",
},
},
},
"multiple match": { "multiple match": {
input: ` input: `
apiVersion: apps/v1 apiVersion: apps/v1

View File

@@ -188,6 +188,26 @@ data:
FieldSpec: types.FieldSpec{Path: "data/slice2"}, FieldSpec: types.FieldSpec{Path: "data/slice2"},
}, },
}, },
"null value": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
data:
FOO: null`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
data:
FOO: null`,
filter: Filter{
MappingFunc: expansion2.MappingFuncFor(replacementCounts, map[string]interface{}{}),
FieldSpec: types.FieldSpec{Path: "data/FOO"},
},
},
} }
for tn, tc := range testCases { for tn, tc := range testCases {
@@ -260,20 +280,6 @@ data:
FieldSpec: types.FieldSpec{Path: "data"}, FieldSpec: types.FieldSpec{Path: "data"},
}, },
}, },
"null input": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep
data:
FOO: null`,
expectedError: "obj '' at path 'data/FOO': invalid type encountered 0",
filter: Filter{
MappingFunc: expansion2.MappingFuncFor(replacementCounts, map[string]interface{}{}),
FieldSpec: types.FieldSpec{Path: "data/FOO"},
},
},
} }
for tn, tc := range testCases { for tn, tc := range testCases {

View File

@@ -132,7 +132,7 @@ func TestRefVarTransformer(t *testing.T) {
' at path 'data/slice': invalid value type expect a string`, ' at path 'data/slice': invalid value type expect a string`,
}, },
{ {
description: "var replacement panic in nil", description: "var replacement in nil",
given: given{ given: given{
varMap: map[string]interface{}{}, varMap: map[string]interface{}{},
fs: []types.FieldSpec{ fs: []types.FieldSpec{
@@ -150,7 +150,19 @@ func TestRefVarTransformer(t *testing.T) {
"nil": nil, // noticeably *not* a []string "nil": nil, // noticeably *not* a []string
}}).ResMap(), }}).ResMap(),
}, },
errMessage: `obj '' at path 'data/nil': invalid type encountered 0`, expected: expected{
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
"data": map[string]interface{}{
"nil": nil, // noticeably *not* a []string
}}).ResMap(),
},
}, },
} }

View File

@@ -4,7 +4,6 @@
package krusty_test package krusty_test
import ( import (
"strings"
"testing" "testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
@@ -73,7 +72,7 @@ metadata:
name: test name: test
spec: spec:
template: template:
spec: spec:
containers: containers:
- name: test - name: test
volumes: null volumes: null
@@ -82,12 +81,17 @@ spec:
resources: resources:
- deploy.yaml - deploy.yaml
`) `)
err := th.RunWithErr(".", th.MakeDefaultOptions()) m := th.Run(".", th.MakeDefaultOptions())
if err == nil { th.AssertActualEqualsExpected(m, `
t.Fatalf("expected trouble") apiVersion: apps/v1
} kind: Deployment
if !strings.Contains( metadata:
err.Error(), "expected sequence or mapping node") { name: test
t.Fatalf("Unexpected err: %v", err) spec:
} template:
spec:
containers:
- name: test
volumes: null
`)
} }

View File

@@ -1,3 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package commands package commands
import ( import (