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,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
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 {

View File

@@ -42,9 +42,31 @@ func determineSmpDirective(patch *yaml.RNode) (smpDirective, error) {
}
}
// TODO: what should this do?
func determineSequenceNodePatchStrategy(_ *yaml.RNode) (smpDirective, error) {
return smpMerge, nil
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