Skip to content

Commit

Permalink
feat: added first draft of replacement between delimiter
Browse files Browse the repository at this point in the history
  • Loading branch information
Yingrjimsch authored and Nobel Gabriel ABRAXAS committed Mar 21, 2024
1 parent e9fc57a commit 45f492a
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 12 deletions.
58 changes: 46 additions & 12 deletions api/filters/replacement/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package replacement
import (
"fmt"
"strings"
"regexp"

"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/resource"
Expand Down Expand Up @@ -93,7 +94,24 @@ func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode,
if rn.YNode().Kind != yaml.ScalarNode {
return nil, fmt.Errorf("delimiter option can only be used with scalar nodes")
}
value := strings.Split(yaml.GetValue(rn), options.Delimiter)
value := []string{}
if options.EndDelimiter == "" {
value = strings.Split(yaml.GetValue(rn), options.Delimiter)
} else {
mapper := func(s string) string {
s = strings.ReplaceAll(s, options.Delimiter, "")
s = strings.ReplaceAll(s, options.EndDelimiter, "")
return s
}
if options.Delimiter == "" {
return nil, fmt.Errorf("delimiter needs to be set if enddelimiter is set")
}
re := regexp.MustCompile(regexp.QuoteMeta(options.Delimiter) + `(.*?)` + regexp.QuoteMeta(options.EndDelimiter))
dv := re.FindAllString(yaml.GetValue(rn), -1)
for _, s := range dv {
value = append(value, mapper(s))
}
}
if options.Index >= len(value) || options.Index < 0 {
return nil, fmt.Errorf("options.index %d is out of bounds for value %s", options.Index, yaml.GetValue(rn))
}
Expand Down Expand Up @@ -224,18 +242,34 @@ func setFieldValue(options *types.FieldOptions, targetField *yaml.RNode, value *
if targetField.YNode().Kind != yaml.ScalarNode {
return fmt.Errorf("delimiter option can only be used with scalar nodes")
}
tv := strings.Split(targetField.YNode().Value, options.Delimiter)
v := yaml.GetValue(value)
// TODO: Add a way to remove an element
switch {
case options.Index < 0: // prefix
tv = append([]string{v}, tv...)
case options.Index >= len(tv): // suffix
tv = append(tv, v)
default: // replace an element
tv[options.Index] = v
}
value.YNode().Value = strings.Join(tv, options.Delimiter)
if options.EndDelimiter == "" {
tv := strings.Split(targetField.YNode().Value, options.Delimiter)
// TODO: Add a way to remove an element
switch {
case options.Index < 0: // prefix
tv = append([]string{v}, tv...)
case options.Index >= len(tv): // suffix
tv = append(tv, v)
default: // replace an element
tv[options.Index] = v
}
value.YNode().Value = strings.Join(tv, options.Delimiter)
} else {
if options.Delimiter == "" {
return fmt.Errorf("delimiter needs to be set if enddelimiter is set")
}
re := regexp.MustCompile(regexp.QuoteMeta(options.Delimiter) + `(.*?)` + regexp.QuoteMeta(options.EndDelimiter))
counter := 0
value.YNode().Value = re.ReplaceAllStringFunc(targetField.YNode().Value, func(value string) string {
if counter != options.Index {
return value
}

counter++
return re.ReplaceAllString(value, options.Delimiter + v + options.EndDelimiter)
})
}
}

if targetField.YNode().Kind == yaml.ScalarNode {
Expand Down
142 changes: 142 additions & 0 deletions api/filters/replacement/replacement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2830,6 +2830,148 @@ spec:
`,
expectedErr: "unable to find or create field \"spec.tls.5.hosts.5\" in replacement target: index 5 specified but only 0 elements found",
},
"partial string replacement with enddelimiter in source - replace": {
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:2.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
options:
delimiter: ':'
enddelimiter: '.'
targets:
- select:
kind: Deployment
name: deploy1
fieldPaths:
- spec.template.spec.containers.1.image
options:
delimiter: ':'
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: 2:1.8.0
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy2
spec:
template:
spec:
containers:
- image: nginx:2.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
},
"partial string replacement with enddelimiter in target - replace": {
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
`,
replacements: `replacements:
- source:
kind: Deployment
name: deploy2
fieldPath: spec.template.spec.containers.0.image
options:
delimiter: ':'
targets:
- select:
kind: Deployment
name: deploy1
fieldPaths:
- spec.template.spec.containers.1.image
options:
delimiter: ':'
enddelimiter: '.'
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:nginx.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
`,
},
}

for tn, tc := range testCases {
Expand Down
2 changes: 2 additions & 0 deletions api/types/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ type FieldOptions struct {
// Used to split/join the field.
Delimiter string `json:"delimiter,omitempty" yaml:"delimiter,omitempty"`

EndDelimiter string `json:"enddelimiter,omitempty" yaml:"enddelimiter,omitempty"`

// Which position in the split to consider.
Index int `json:"index,omitempty" yaml:"index,omitempty"`

Expand Down

0 comments on commit 45f492a

Please sign in to comment.