...
1
2
3
4 package refvar
5
6 import (
7 "fmt"
8 "strconv"
9
10 "sigs.k8s.io/kustomize/api/filters/fieldspec"
11 "sigs.k8s.io/kustomize/api/types"
12 "sigs.k8s.io/kustomize/kyaml/kio"
13 "sigs.k8s.io/kustomize/kyaml/yaml"
14 )
15
16
17
18 type Filter struct {
19 MappingFunc MappingFunc `json:"mappingFunc,omitempty" yaml:"mappingFunc,omitempty"`
20 FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"`
21 }
22
23 func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
24 return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes)
25 }
26
27 func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
28 err := node.PipeE(fieldspec.Filter{
29 FieldSpec: f.FieldSpec,
30 SetValue: f.set,
31 })
32 return node, err
33 }
34
35 func (f Filter) set(node *yaml.RNode) error {
36 if yaml.IsMissingOrNull(node) {
37 return nil
38 }
39 switch node.YNode().Kind {
40 case yaml.ScalarNode:
41 return f.setScalar(node)
42 case yaml.MappingNode:
43 return f.setMap(node)
44 case yaml.SequenceNode:
45 return f.setSeq(node)
46 default:
47 return fmt.Errorf("invalid type encountered %v", node.YNode().Kind)
48 }
49 }
50
51 func updateNodeValue(node *yaml.Node, newValue interface{}) {
52 switch newValue := newValue.(type) {
53 case int:
54 node.Value = strconv.FormatInt(int64(newValue), 10)
55 node.Tag = yaml.NodeTagInt
56 case int32:
57 node.Value = strconv.FormatInt(int64(newValue), 10)
58 node.Tag = yaml.NodeTagInt
59 case int64:
60 node.Value = strconv.FormatInt(newValue, 10)
61 node.Tag = yaml.NodeTagInt
62 case bool:
63 node.SetString(strconv.FormatBool(newValue))
64 node.Tag = yaml.NodeTagBool
65 case float32:
66 node.SetString(strconv.FormatFloat(float64(newValue), 'f', -1, 32))
67 node.Tag = yaml.NodeTagFloat
68 case float64:
69 node.SetString(strconv.FormatFloat(newValue, 'f', -1, 64))
70 node.Tag = yaml.NodeTagFloat
71 default:
72 node.SetString(newValue.(string))
73 node.Tag = yaml.NodeTagString
74 }
75 node.Style = 0
76 }
77
78 func (f Filter) setScalar(node *yaml.RNode) error {
79 if !yaml.IsYNodeString(node.YNode()) {
80 return nil
81 }
82 v := DoReplacements(node.YNode().Value, f.MappingFunc)
83 updateNodeValue(node.YNode(), v)
84 return nil
85 }
86
87 func (f Filter) setMap(node *yaml.RNode) error {
88 contents := node.YNode().Content
89 for i := 0; i < len(contents); i += 2 {
90 if !yaml.IsYNodeString(contents[i]) {
91 return fmt.Errorf(
92 "invalid map key: value='%s', tag='%s'",
93 contents[i].Value, contents[i].Tag)
94 }
95 if !yaml.IsYNodeString(contents[i+1]) {
96 continue
97 }
98 newValue := DoReplacements(contents[i+1].Value, f.MappingFunc)
99 updateNodeValue(contents[i+1], newValue)
100 }
101 return nil
102 }
103
104 func (f Filter) setSeq(node *yaml.RNode) error {
105 for _, item := range node.YNode().Content {
106 if !yaml.IsYNodeString(item) {
107 return fmt.Errorf("invalid value type expect a string")
108 }
109 newValue := DoReplacements(item.Value, f.MappingFunc)
110 updateNodeValue(item, newValue)
111 }
112 return nil
113 }
114
View as plain text