Skip to content

Commit

Permalink
add ability to change MergeOptions for Patch Strategic Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
awakair committed Oct 8, 2024
1 parent 01cce4f commit d526cd1
Show file tree
Hide file tree
Showing 14 changed files with 733 additions and 31 deletions.
11 changes: 7 additions & 4 deletions api/filters/patchstrategicmerge/patchstrategicmerge.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,29 @@
package patchstrategicmerge

import (
"cmp"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/kustomize/kyaml/yaml/merge2"
)

type Filter struct {
Patch *yaml.RNode
Patch *yaml.RNode
MergeOptions *yaml.MergeOptions
}

var _ kio.Filter = Filter{}

// Filter does a strategic merge patch, which can delete nodes.
func (pf Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
var result []*yaml.RNode
mergeOptions := *cmp.Or(pf.MergeOptions, &yaml.MergeOptions{
ListIncreaseDirection: yaml.MergeOptionsListPrepend,
})
for i := range nodes {
r, err := merge2.Merge(
pf.Patch, nodes[i],
yaml.MergeOptions{
ListIncreaseDirection: yaml.MergeOptionsListPrepend,
},
mergeOptions,
)
if err != nil {
return nil, err
Expand Down
147 changes: 147 additions & 0 deletions api/filters/patchstrategicmerge/patchstrategicmerge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -921,3 +921,150 @@ data:
})
}
}

func TestFilterMergeOptionsListAppend(t *testing.T) {
testCases := map[string]struct {
input string
patch *yaml.RNode
expected string
}{
"container patch": {
input: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo0
`),
expected: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"volumes patch": {
input: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo1
- name: foo2
- name: foo3
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo0
`),
expected: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"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
`,
},
}

for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
f := Filter{
Patch: tc.patch,
MergeOptions: &yaml.MergeOptions{
ListIncreaseDirection: yaml.MergeOptionsListAppend,
},
}
if !assert.Equal(t,
strings.TrimSpace(tc.expected),
strings.TrimSpace(
filtertest.RunFilter(t, tc.input, f))) {
t.FailNow()
}
})
}
}
5 changes: 5 additions & 0 deletions api/internal/builtins/PatchStrategicMergeTransformer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions api/internal/builtins/PatchTransformer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions api/internal/target/kusttarget.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/openapi"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/yaml"
)

Expand All @@ -36,19 +37,22 @@ type KustTarget struct {
rFactory *resmap.Factory
pLdr *loader.Loader
origin *resource.Origin
mergeOptions *kyaml.MergeOptions
}

// NewKustTarget returns a new instance of KustTarget.
func NewKustTarget(
ldr ifc.Loader,
validator ifc.Validator,
rFactory *resmap.Factory,
pLdr *loader.Loader) *KustTarget {
pLdr *loader.Loader,
mOpts *kyaml.MergeOptions) *KustTarget {
return &KustTarget{
ldr: ldr,
validator: validator,
rFactory: rFactory,
pLdr: pLdr.LoaderWithWorkingDir(ldr.Root()),
ldr: ldr,
validator: validator,
rFactory: rFactory,
pLdr: pLdr.LoaderWithWorkingDir(ldr.Root()),
mergeOptions: mOpts,
}
}

Expand Down Expand Up @@ -488,7 +492,7 @@ func (kt *KustTarget) accumulateComponents(
func (kt *KustTarget) accumulateDirectory(
ra *accumulator.ResAccumulator, ldr ifc.Loader, isComponent bool) (*accumulator.ResAccumulator, error) {
defer ldr.Cleanup()
subKt := NewKustTarget(ldr, kt.validator, kt.rFactory, kt.pLdr)
subKt := NewKustTarget(ldr, kt.validator, kt.rFactory, kt.pLdr, kt.mergeOptions)
err := subKt.Load()
if err != nil {
return nil, errors.WrapPrefixf(
Expand Down
14 changes: 9 additions & 5 deletions api/internal/target/kusttarget_configplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,11 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
return
}
var c struct {
Paths []types.PatchStrategicMerge `json:"paths,omitempty" yaml:"paths,omitempty"`
Paths []types.PatchStrategicMerge `json:"paths,omitempty" yaml:"paths,omitempty"`
MergeOptions *yaml.MergeOptions `json:"mergeOptions,omitempty" yaml:"mergeOptions,omitempty"`
}
c.Paths = kt.kustomization.PatchesStrategicMerge
c.MergeOptions = kt.mergeOptions
p := f()
err = kt.configureBuiltinPlugin(p, c, bpt)
if err != nil {
Expand All @@ -250,16 +252,18 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
return
}
var c struct {
Path string `json:"path,omitempty" yaml:"path,omitempty"`
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"`
MergeOptions *yaml.MergeOptions `json:"mergeOptions,omitempty" yaml:"mergeOptions,omitempty"`
}
for _, pc := range kt.kustomization.Patches {
c.Target = pc.Target
c.Patch = pc.Patch
c.Path = pc.Path
c.Options = pc.Options
c.MergeOptions = kt.mergeOptions
p := f()
err = kt.configureBuiltinPlugin(p, c, bpt)
if err != nil {
Expand Down
6 changes: 5 additions & 1 deletion api/internal/target/maker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package target_test

import (
"sigs.k8s.io/kustomize/kyaml/yaml"
"testing"

"sigs.k8s.io/kustomize/api/ifc"
Expand Down Expand Up @@ -68,5 +69,8 @@ func makeKustTargetWithRfAndLoaderOverride(
ldr,
valtest_test.MakeFakeValidator(),
rf,
pLdr.NewLoader(pc, rf, fSys))
pLdr.NewLoader(pc, rf, fSys),
&yaml.MergeOptions{
ListIncreaseDirection: yaml.MergeOptionsListPrepend,
})
}
Loading

0 comments on commit d526cd1

Please sign in to comment.