mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
support merge strategy in list
This commit is contained in:
@@ -142,6 +142,234 @@ spec:
|
|||||||
- name: nginx
|
- name: nginx
|
||||||
args:
|
args:
|
||||||
- def
|
- 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
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,3 +22,5 @@ exclude (
|
|||||||
replace sigs.k8s.io/kustomize/cmd/config v0.8.1 => ../cmd/config
|
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/api v0.6.2 => ../api
|
||||||
|
|
||||||
|
replace sigs.k8s.io/kustomize/kyaml v0.8.1 => ../kyaml
|
||||||
|
|||||||
@@ -142,6 +142,109 @@ spec:
|
|||||||
- name: foo3
|
- 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`,
|
{description: `replace List -- different value in dest`,
|
||||||
source: `
|
source: `
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func (m Merger) VisitMap(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.R
|
|||||||
return walk.ClearNode, nil
|
return walk.ClearNode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ps, err := determineMappingNodePatchStrategy(nodes.Origin())
|
ps, err := determineSmpDirective(nodes.Origin())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -115,8 +115,20 @@ func (m Merger) VisitList(nodes walk.Sources, s *openapi.ResourceSchema, kind wa
|
|||||||
if nodes.Origin().IsTaggedNull() {
|
if nodes.Origin().IsTaggedNull() {
|
||||||
return walk.ClearNode, nil
|
return walk.ClearNode, nil
|
||||||
}
|
}
|
||||||
// Recursively Merge dest
|
|
||||||
return nodes.Dest(), nil
|
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 {
|
func (m Merger) SetStyle(sources walk.Sources) error {
|
||||||
|
|||||||
@@ -42,9 +42,31 @@ func determineSmpDirective(patch *yaml.RNode) (smpDirective, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: what should this do?
|
func determineSequenceNodePatchStrategy(patch *yaml.RNode) (smpDirective, error) {
|
||||||
func determineSequenceNodePatchStrategy(_ *yaml.RNode) (smpDirective, error) {
|
// get the $patch element
|
||||||
return smpMerge, nil
|
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) {
|
func determineMappingNodePatchStrategy(patch *yaml.RNode) (smpDirective, error) {
|
||||||
@@ -54,18 +76,26 @@ func determineMappingNodePatchStrategy(patch *yaml.RNode) (smpDirective, error)
|
|||||||
}
|
}
|
||||||
v := node.YNode().Value
|
v := node.YNode().Value
|
||||||
if v == smpDelete.String() {
|
if v == smpDelete.String() {
|
||||||
return smpDelete, elidePatchDirective(patch)
|
return smpDelete, elideMappingPatchDirective(patch)
|
||||||
}
|
}
|
||||||
if v == smpReplace.String() {
|
if v == smpReplace.String() {
|
||||||
return smpReplace, elidePatchDirective(patch)
|
return smpReplace, elideMappingPatchDirective(patch)
|
||||||
}
|
}
|
||||||
if v == smpMerge.String() {
|
if v == smpMerge.String() {
|
||||||
return smpMerge, elidePatchDirective(patch)
|
return smpMerge, elideMappingPatchDirective(patch)
|
||||||
}
|
}
|
||||||
return smpUnknown, fmt.Errorf(
|
return smpUnknown, fmt.Errorf(
|
||||||
"unknown patch strategy '%s'", v)
|
"unknown patch strategy '%s'", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func elidePatchDirective(patch *yaml.RNode) error {
|
func elideMappingPatchDirective(patch *yaml.RNode) error {
|
||||||
return patch.PipeE(yaml.Clear(strategicMergePatchDirectiveKey))
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,6 +26,45 @@ func Test_determineSmpDirective(t *testing.T) {
|
|||||||
- one
|
- one
|
||||||
- two
|
- two
|
||||||
- three
|
- 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,
|
expected: smpMerge,
|
||||||
elided: `- one
|
elided: `- one
|
||||||
|
|||||||
Reference in New Issue
Block a user