1
2
3
4 package merge3
5
6 import (
7 "sigs.k8s.io/kustomize/kyaml/openapi"
8 "sigs.k8s.io/kustomize/kyaml/yaml"
9 "sigs.k8s.io/kustomize/kyaml/yaml/walk"
10 )
11
12 type ConflictStrategy uint
13
14 const (
15
16 TakeUpdate ConflictStrategy = 1 + iota
17 )
18
19 type Visitor struct{}
20
21 func (m Visitor) VisitMap(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.RNode, error) {
22 if nodes.Updated().IsTaggedNull() || nodes.Dest().IsTaggedNull() {
23
24 return walk.ClearNode, nil
25 }
26 if nodes.Dest() == nil && nodes.Updated() == nil {
27
28 return walk.ClearNode, nil
29 }
30
31 if nodes.Dest() == nil {
32
33
34 return yaml.NewRNode(&yaml.Node{Kind: yaml.MappingNode}), nil
35 }
36
37
38 return nodes.Dest(), nil
39 }
40
41 func (m Visitor) visitAList(nodes walk.Sources, _ *openapi.ResourceSchema) (*yaml.RNode, error) {
42 if yaml.IsMissingOrNull(nodes.Updated()) && !yaml.IsMissingOrNull(nodes.Origin()) {
43
44 return walk.ClearNode, nil
45 }
46 if yaml.IsMissingOrNull(nodes.Dest()) {
47
48
49 return yaml.NewRNode(&yaml.Node{Kind: yaml.SequenceNode}), nil
50 }
51
52
53 return nodes.Dest(), nil
54 }
55
56 func (m Visitor) VisitScalar(nodes walk.Sources, s *openapi.ResourceSchema) (*yaml.RNode, error) {
57 if nodes.Updated().IsTaggedNull() || nodes.Dest().IsTaggedNull() {
58
59 return nil, nil
60 }
61 if yaml.IsMissingOrNull(nodes.Updated()) != yaml.IsMissingOrNull(nodes.Origin()) {
62
63 return nodes.Updated(), nil
64 }
65 if yaml.IsMissingOrNull(nodes.Updated()) && yaml.IsMissingOrNull(nodes.Origin()) {
66
67 return nodes.Dest(), nil
68 }
69
70 values, err := m.getStrValues(nodes)
71 if err != nil {
72 return nil, err
73 }
74
75 if (values.Dest == "" || values.Dest == values.Origin) && values.Origin != values.Update {
76
77 return nodes.Updated(), nil
78 }
79
80 if nodes.Updated().YNode().Value != nodes.Origin().YNode().Value {
81
82 return nodes.Updated(), nil
83 }
84
85
86 return nodes.Dest(), nil
87 }
88
89 func (m Visitor) visitNAList(nodes walk.Sources) (*yaml.RNode, error) {
90 if nodes.Updated().IsTaggedNull() || nodes.Dest().IsTaggedNull() {
91
92 return walk.ClearNode, nil
93 }
94
95 if yaml.IsMissingOrNull(nodes.Updated()) != yaml.IsMissingOrNull(nodes.Origin()) {
96
97 return nodes.Updated(), nil
98 }
99 if yaml.IsMissingOrNull(nodes.Updated()) && yaml.IsMissingOrNull(nodes.Origin()) {
100
101 return nodes.Dest(), nil
102 }
103
104
105 values, err := m.getStrValues(nodes)
106 if err != nil {
107 return nil, err
108 }
109 if values.Update != values.Origin {
110
111 return nodes.Updated(), nil
112 }
113
114
115 return nodes.Dest(), nil
116 }
117
118 func (m Visitor) VisitList(nodes walk.Sources, s *openapi.ResourceSchema, kind walk.ListKind) (*yaml.RNode, error) {
119 if kind == walk.AssociativeList {
120 return m.visitAList(nodes, s)
121 }
122
123 return m.visitNAList(nodes)
124 }
125
126 func (m Visitor) getStrValues(nodes walk.Sources) (strValues, error) {
127 var uStr, oStr, dStr string
128 var err error
129 if nodes.Updated() != nil && nodes.Updated().YNode() != nil {
130 s := nodes.Updated().YNode().Style
131 defer func() {
132 nodes.Updated().YNode().Style = s
133 }()
134 nodes.Updated().YNode().Style = yaml.FlowStyle | yaml.SingleQuotedStyle
135 uStr, err = nodes.Updated().String()
136 if err != nil {
137 return strValues{}, err
138 }
139 }
140 if nodes.Origin() != nil && nodes.Origin().YNode() != nil {
141 s := nodes.Origin().YNode().Style
142 defer func() {
143 nodes.Origin().YNode().Style = s
144 }()
145 nodes.Origin().YNode().Style = yaml.FlowStyle | yaml.SingleQuotedStyle
146 oStr, err = nodes.Origin().String()
147 if err != nil {
148 return strValues{}, err
149 }
150 }
151 if nodes.Dest() != nil && nodes.Dest().YNode() != nil {
152 s := nodes.Dest().YNode().Style
153 defer func() {
154 nodes.Dest().YNode().Style = s
155 }()
156 nodes.Dest().YNode().Style = yaml.FlowStyle | yaml.SingleQuotedStyle
157 dStr, err = nodes.Dest().String()
158 if err != nil {
159 return strValues{}, err
160 }
161 }
162
163 return strValues{Origin: oStr, Update: uStr, Dest: dStr}, nil
164 }
165
166 type strValues struct {
167 Origin string
168 Update string
169 Dest string
170 }
171
172 var _ walk.Visitor = Visitor{}
173
View as plain text