mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Merge pull request #3773 from natasha41575/ReplacementFieldOptions
use field options to refine replacements
This commit is contained in:
@@ -66,18 +66,50 @@ func rejectId(rejects []*types.Selector, nodeId *types.KrmId) bool {
|
|||||||
|
|
||||||
func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
|
func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
|
||||||
for _, fp := range target.FieldPaths {
|
for _, fp := range target.FieldPaths {
|
||||||
t, err := node.Pipe(yaml.Lookup(strings.Split(fp, ".")...))
|
fieldPath := strings.Split(fp, ".")
|
||||||
|
var t *yaml.RNode
|
||||||
|
var err error
|
||||||
|
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...))
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if t != nil {
|
if t != nil {
|
||||||
// TODO (#3492): Use the field options to refine interpretation of the field
|
if err = setTargetValue(target.Options, t, value); err != nil {
|
||||||
t.SetYNode(value.YNode())
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
|
||||||
|
if options != nil && options.Delimiter != "" {
|
||||||
|
|
||||||
|
if t.YNode().Kind != yaml.ScalarNode {
|
||||||
|
return fmt.Errorf("delimiter option can only be used with scalar nodes")
|
||||||
|
}
|
||||||
|
|
||||||
|
tv := strings.Split(t.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)
|
||||||
|
}
|
||||||
|
t.SetYNode(value.YNode())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, error) {
|
func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, error) {
|
||||||
source, err := selectSourceNode(nodes, r.Source)
|
source, err := selectSourceNode(nodes, r.Source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,10 +125,28 @@ func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// TODO (#3492): Use the field options to refine interpretation of the field
|
if !rn.IsNilOrEmpty() {
|
||||||
|
return getRefinedValue(r.Source.Options, rn)
|
||||||
|
}
|
||||||
return rn, nil
|
return rn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode, error) {
|
||||||
|
if options == nil || options.Delimiter == "" {
|
||||||
|
return rn, nil
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
n := rn.Copy()
|
||||||
|
n.YNode().Value = value[options.Index]
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
// selectSourceNode finds the node that matches the selector, returning
|
// selectSourceNode finds the node that matches the selector, returning
|
||||||
// an error if multiple or none are found
|
// an error if multiple or none are found
|
||||||
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
|
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
|
||||||
|
|||||||
@@ -761,6 +761,583 @@ spec:
|
|||||||
name: postgresdb
|
name: postgresdb
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
"partial string replacement - 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: ':'
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy1
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx:1.7.9
|
||||||
|
name: nginx-tagged
|
||||||
|
- image: nginx: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
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"partial string replacement - prefix": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group/config
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod1
|
||||||
|
fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 0
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
name: pod2
|
||||||
|
fieldPaths:
|
||||||
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: -1
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group/config
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"partial string replacement - suffix": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group/config
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod2
|
||||||
|
fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 1
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
name: pod1
|
||||||
|
fieldPaths:
|
||||||
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 2
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group/config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group/config
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"partial string replacement - last element": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group2
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod2
|
||||||
|
fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 0
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
name: pod1
|
||||||
|
fieldPaths:
|
||||||
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 1
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group2
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group2
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"partial string replacement - first element": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group1/config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group2
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod2
|
||||||
|
fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 0
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
name: pod1
|
||||||
|
fieldPaths:
|
||||||
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 0
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group2/config
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group2
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"options.index out of bounds": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod1
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: my/group1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod2
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- projected:
|
||||||
|
sources:
|
||||||
|
- configMap:
|
||||||
|
name: myconfigmap
|
||||||
|
items:
|
||||||
|
- key: config
|
||||||
|
path: group2
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod2
|
||||||
|
fieldPath: spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: -1
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
name: pod1
|
||||||
|
fieldPaths:
|
||||||
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
|
options:
|
||||||
|
delimiter: '/'
|
||||||
|
index: 1
|
||||||
|
`,
|
||||||
|
expectedErr: "options.index -1 is out of bounds for value group2",
|
||||||
|
},
|
||||||
|
"create": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy1
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy2
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
name: deploy1
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers
|
||||||
|
options:
|
||||||
|
create: true
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
name: deploy2
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy1
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy2
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"complex type with delimiter in source": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy2
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers: {}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy3
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers: {}
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers
|
||||||
|
options:
|
||||||
|
delimiter: "/"
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers
|
||||||
|
`,
|
||||||
|
expectedErr: "delimiter option can only be used with scalar nodes",
|
||||||
|
},
|
||||||
|
"complex type with delimiter in target": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy2
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers: {}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy3
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers: {}
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers
|
||||||
|
options:
|
||||||
|
delimiter: "/"
|
||||||
|
`,
|
||||||
|
expectedErr: "delimiter option can only be used with scalar nodes",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ type TargetSelector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FieldOptions refine the interpretation of FieldPaths.
|
// FieldOptions refine the interpretation of FieldPaths.
|
||||||
// TODO (#3492): Implement use of these options, they are
|
|
||||||
// currently unused
|
|
||||||
type FieldOptions struct {
|
type FieldOptions struct {
|
||||||
// Used to split/join the field.
|
// Used to split/join the field.
|
||||||
Delimiter string `json:"delimiter" yaml:"delimiter"`
|
Delimiter string `json:"delimiter" yaml:"delimiter"`
|
||||||
@@ -52,8 +50,9 @@ type FieldOptions struct {
|
|||||||
// Which position in the split to consider.
|
// Which position in the split to consider.
|
||||||
Index int `json:"index" yaml:"index"`
|
Index int `json:"index" yaml:"index"`
|
||||||
|
|
||||||
// None, Base64, URL, Hex, etc.
|
// TODO (#3492): Implement use of this option
|
||||||
Encoding string `json:"encoding" yaml:"index"`
|
// None, Base64, URL, Hex, etc
|
||||||
|
Encoding string `json:"encoding" yaml:"encoding"`
|
||||||
|
|
||||||
// If field missing, add it.
|
// If field missing, add it.
|
||||||
Create bool `json:"create" yaml:"create"`
|
Create bool `json:"create" yaml:"create"`
|
||||||
|
|||||||
Reference in New Issue
Block a user