Skip to content

Commit

Permalink
feat: Add regex support for Replacement selectors
Browse files Browse the repository at this point in the history
  • Loading branch information
sda399 committed Feb 16, 2025
1 parent 3be1af6 commit 8f75c39
Show file tree
Hide file tree
Showing 3 changed files with 349 additions and 16 deletions.
21 changes: 5 additions & 16 deletions api/filters/replacement/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/resid"
kyaml_utils "sigs.k8s.io/kustomize/kyaml/utils"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
Expand Down Expand Up @@ -110,6 +109,10 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targetSelectors []
if len(selector.FieldPaths) == 0 {
selector.FieldPaths = []string{types.DefaultReplacementFieldPath}
}
tsr, err := types.NewTargetSelectorRegex(selector)
if err != nil {
return nil, err
}
for _, possibleTarget := range nodes {
ids, err := utils.MakeResIds(possibleTarget)
if err != nil {
Expand All @@ -127,7 +130,7 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targetSelectors []

// filter targets by matching resource IDs
for _, id := range ids {
if id.IsSelectedBy(selector.Select.ResId) && !containsRejectId(selector.Reject, ids) {
if tsr.Selects(id) && !tsr.RejectsAny(ids) {
err := copyValueToTarget(possibleTarget, value, selector)
if err != nil {
return nil, err
Expand Down Expand Up @@ -168,20 +171,6 @@ func matchesAnnoAndLabelSelector(n *yaml.RNode, selector *types.Selector) (bool,
return annoMatch && labelMatch, nil
}

func containsRejectId(rejects []*types.Selector, ids []resid.ResId) bool {
for _, r := range rejects {
if r.ResId.IsEmpty() {
continue
}
for _, id := range ids {
if id.IsSelectedBy(r.ResId) {
return true
}
}
}
return false
}

func copyValueToTarget(target *yaml.RNode, value *yaml.RNode, selector *types.TargetSelector) error {
for _, fp := range selector.FieldPaths {
createKind := yaml.Kind(0) // do not create
Expand Down
297 changes: 297 additions & 0 deletions api/filters/replacement/replacement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2830,6 +2830,303 @@ spec:
`,
expectedErr: "unable to find or create field \"spec.tls.5.hosts.5\" in replacement target: index 5 specified but only 0 elements found",
},

"reject 1 with regex": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: deploy1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy2
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy3
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: Deployment
name: deploy2
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
kind: Deploy.*
reject:
- name: .*ploy2|deploy3
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy2
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy3
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
},
"reject 2 with regex": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: StatefulSet
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: Deployment
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
version: v1
reject:
- kind: Deplo.*
name: my-name
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: StatefulSet
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
`,
},
// the only difference in the inputs between this and the previous test
// is the dash before `name: my-name`
"reject 3 with regex": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: StatefulSet
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: Deployment
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
version: v1
reject:
- kind: Deployment
- name: my.n.me
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: StatefulSet
metadata:
name: my-name
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
},
"simple with regex": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
kind: StatefulSet
metadata:
name: deploy
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: Deployment
name: deploy
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
kind: Deployment|StatefulSet
name: deploy
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
---
kind: StatefulSet
metadata:
name: deploy
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
`,
},

}

for tn, tc := range testCases {
Expand Down
Loading

0 comments on commit 8f75c39

Please sign in to comment.