mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-10 08:20:59 +00:00
replacements allow to replace multi values
This commit is contained in:
@@ -119,13 +119,14 @@ func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelect
|
||||
if target.Options != nil && target.Options.Create {
|
||||
t, err = node.Pipe(yaml.LookupCreate(value.YNode().Kind, fieldPath...))
|
||||
} else {
|
||||
t, err = node.Pipe(yaml.Lookup(fieldPath...))
|
||||
// t, err = node.Pipe(yaml.Lookup(fieldPath...))
|
||||
t, err = node.Pipe(&yaml.PathMatcher{Path: fieldPath})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if t != nil {
|
||||
if err = setTargetValue(target.Options, t, value); err != nil {
|
||||
if err = applyToOneNode(target.Options, t, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -133,6 +134,27 @@ func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelect
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyToOneNode(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
|
||||
if len(t.YNode().Content) == 0 {
|
||||
if err := setTargetValue(options, t, value); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, scalarNode := range t.YNode().Content {
|
||||
if options != nil && options.Create {
|
||||
return fmt.Errorf("cannot use create option in a multi-value target")
|
||||
}
|
||||
rn := yaml.NewRNode(scalarNode)
|
||||
if err := setTargetValue(options, rn, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
|
||||
value = value.Copy()
|
||||
if options != nil && options.Delimiter != "" {
|
||||
@@ -152,7 +174,9 @@ func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNod
|
||||
}
|
||||
value.YNode().Value = strings.Join(tv, options.Delimiter)
|
||||
}
|
||||
|
||||
t.SetYNode(value.YNode())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -782,6 +782,13 @@ func IsListIndex(p string) bool {
|
||||
return strings.HasPrefix(p, "[") && strings.HasSuffix(p, "]")
|
||||
}
|
||||
|
||||
// IsIdxNumber returns true if p is an index number.
|
||||
// e.g. 1
|
||||
func IsIdxNumber(p string) bool {
|
||||
idx, err := strconv.Atoi(p)
|
||||
return err == nil && idx >= 0
|
||||
}
|
||||
|
||||
// SplitIndexNameValue splits a lookup part Val index into the field name
|
||||
// and field value to match.
|
||||
// e.g. splits [name=nginx] into (name, nginx)
|
||||
|
||||
@@ -5,6 +5,7 @@ package yaml
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -42,9 +43,10 @@ type PathMatcher struct {
|
||||
// This is useful for if the nodes are to be printed in FlowStyle.
|
||||
StripComments bool
|
||||
|
||||
val *RNode
|
||||
field string
|
||||
matchRegex string
|
||||
val *RNode
|
||||
field string
|
||||
matchRegex string
|
||||
indexNumber int
|
||||
}
|
||||
|
||||
func (p *PathMatcher) stripComments(n *Node) {
|
||||
@@ -79,6 +81,10 @@ func (p *PathMatcher) filter(rn *RNode) (*RNode, error) {
|
||||
return p.val, nil
|
||||
}
|
||||
|
||||
if IsIdxNumber(p.Path[0]) {
|
||||
return p.doIndexSeq(rn)
|
||||
}
|
||||
|
||||
if IsListIndex(p.Path[0]) {
|
||||
// match seq elements
|
||||
return p.doSeq(rn)
|
||||
@@ -98,7 +104,6 @@ func (p *PathMatcher) doMatchEvery(rn *RNode) (*RNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// fmt.Println(p.val.String())
|
||||
return p.val, nil
|
||||
}
|
||||
|
||||
@@ -134,6 +139,36 @@ func (p *PathMatcher) doField(rn *RNode) (*RNode, error) {
|
||||
return p.val, err
|
||||
}
|
||||
|
||||
// doIndexSeq iterates over a sequence and appends elements matching the index p.Val
|
||||
func (p *PathMatcher) doIndexSeq(rn *RNode) (*RNode, error) {
|
||||
// parse to index number
|
||||
idx, err := strconv.Atoi(p.Path[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.indexNumber = idx
|
||||
|
||||
elements, err := rn.Elements()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get target element
|
||||
element := elements[idx]
|
||||
|
||||
// recurse on the matching element
|
||||
pm := &PathMatcher{Path: p.Path[1:]}
|
||||
add, err := pm.filter(element)
|
||||
for k, v := range pm.Matches {
|
||||
p.Matches[k] = v
|
||||
}
|
||||
if err != nil || add == nil {
|
||||
return nil, err
|
||||
}
|
||||
p.append("", add.Content()...)
|
||||
return p.val, nil
|
||||
}
|
||||
|
||||
// doSeq iterates over a sequence and appends elements matching the path regex to p.Val
|
||||
func (p *PathMatcher) doSeq(rn *RNode) (*RNode, error) {
|
||||
// parse the field + match pair
|
||||
|
||||
Reference in New Issue
Block a user