support merge strategy in list

This commit is contained in:
Donny Xia
2020-09-28 16:56:54 -07:00
parent dd8edb1b01
commit ff927fd11a
6 changed files with 424 additions and 10 deletions

View File

@@ -142,6 +142,234 @@ spec:
- name: nginx
args:
- def
`,
},
"remove mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
$patch: delete
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers: []
`,
},
"replace mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
$patch: replace
containers:
- name: new
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: new
`,
},
"merge mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test1
$patch: merge
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test1
`,
},
"remove list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- whatever
- $patch: delete
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec: {}
`,
},
"replace list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: replace
image: replace
- $patch: replace
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: replace
image: replace
`,
},
"merge list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test2
image: test2
- $patch: merge
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
- name: test2
image: test2
`,
},
}

View File

@@ -22,3 +22,5 @@ exclude (
replace sigs.k8s.io/kustomize/cmd/config v0.8.1 => ../cmd/config
replace sigs.k8s.io/kustomize/api v0.6.2 => ../api
replace sigs.k8s.io/kustomize/kyaml v0.8.1 => ../kyaml

View File

@@ -142,6 +142,109 @@ spec:
- name: foo3
`,
},
{description: `merge k8s deployment containers -- $patch directive`,
source: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- $patch: merge
`,
dest: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo4
- name: foo5
`,
expected: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- name: foo4
- name: foo5
`,
},
{description: `replace k8s deployment containers -- $patch directive`,
source: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- $patch: replace
`,
dest: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo4
- name: foo5
`,
expected: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
`,
},
{description: `remove k8s deployment containers -- $patch directive`,
source: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- $patch: delete
`,
dest: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo4
- name: foo5
`,
expected: `
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec: {}
`,
},
{description: `replace List -- different value in dest`,
source: `

View File

@@ -61,7 +61,7 @@ func (m Merger) VisitMap(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.R
return walk.ClearNode, nil
}
ps, err := determineMappingNodePatchStrategy(nodes.Origin())
ps, err := determineSmpDirective(nodes.Origin())
if err != nil {
return nil, err
}
@@ -115,8 +115,20 @@ func (m Merger) VisitList(nodes walk.Sources, s *openapi.ResourceSchema, kind wa
if nodes.Origin().IsTaggedNull() {
return walk.ClearNode, nil
}
// Recursively Merge dest
ps, err := determineSmpDirective(nodes.Origin())
if err != nil {
return nil, err
}
switch ps {
case smpDelete:
return walk.ClearNode, nil
case smpReplace:
return nodes.Origin(), nil
default:
return nodes.Dest(), nil
}
}
func (m Merger) SetStyle(sources walk.Sources) error {

View File

@@ -42,9 +42,31 @@ func determineSmpDirective(patch *yaml.RNode) (smpDirective, error) {
}
}
// TODO: what should this do?
func determineSequenceNodePatchStrategy(_ *yaml.RNode) (smpDirective, error) {
func determineSequenceNodePatchStrategy(patch *yaml.RNode) (smpDirective, error) {
// get the $patch element
node, err := patch.Pipe(yaml.GetElementByKey(strategicMergePatchDirectiveKey))
// if there are more than 1 key/value pair in the map, then this $patch
// is not for the sequence
if err != nil || node == nil || node.YNode() == nil || len(node.Content()) > 2 {
return smpMerge, nil
}
// get the value
value, err := node.Pipe(yaml.Get(strategicMergePatchDirectiveKey))
if err != nil || value == nil || value.YNode() == nil {
return smpMerge, nil
}
v := value.YNode().Value
if v == smpDelete.String() {
return smpDelete, elideSequencePatchDirective(patch, v)
}
if v == smpReplace.String() {
return smpReplace, elideSequencePatchDirective(patch, v)
}
if v == smpMerge.String() {
return smpMerge, elideSequencePatchDirective(patch, v)
}
return smpUnknown, fmt.Errorf(
"unknown patch strategy '%s'", v)
}
func determineMappingNodePatchStrategy(patch *yaml.RNode) (smpDirective, error) {
@@ -54,18 +76,26 @@ func determineMappingNodePatchStrategy(patch *yaml.RNode) (smpDirective, error)
}
v := node.YNode().Value
if v == smpDelete.String() {
return smpDelete, elidePatchDirective(patch)
return smpDelete, elideMappingPatchDirective(patch)
}
if v == smpReplace.String() {
return smpReplace, elidePatchDirective(patch)
return smpReplace, elideMappingPatchDirective(patch)
}
if v == smpMerge.String() {
return smpMerge, elidePatchDirective(patch)
return smpMerge, elideMappingPatchDirective(patch)
}
return smpUnknown, fmt.Errorf(
"unknown patch strategy '%s'", v)
}
func elidePatchDirective(patch *yaml.RNode) error {
func elideMappingPatchDirective(patch *yaml.RNode) error {
return patch.PipeE(yaml.Clear(strategicMergePatchDirectiveKey))
}
func elideSequencePatchDirective(patch *yaml.RNode, value string) error {
return patch.PipeE(yaml.ElementSetter{
Element: nil,
Key: strategicMergePatchDirectiveKey,
Value: value,
})
}

View File

@@ -26,6 +26,45 @@ func Test_determineSmpDirective(t *testing.T) {
- one
- two
- three
- $patch: merge
`,
expected: smpMerge,
elided: `- one
- two
- three
`,
},
"list replace": {
patch: `
- one
- two
- three
- $patch: replace
`,
expected: smpReplace,
elided: `- one
- two
- three
`,
},
"list delete": {
patch: `
- one
- two
- three
- $patch: delete
`,
expected: smpDelete,
elided: `- one
- two
- three
`,
},
"list default": {
patch: `
- one
- two
- three
`,
expected: smpMerge,
elided: `- one