...
1 package conditions
2
3 import (
4 "sort"
5
6 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7 )
8
9
10 type localizedCondition struct {
11 *metav1.Condition
12 Getter
13 }
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 func merge(conditions []localizedCondition, targetCondition string, options *mergeOptions) *metav1.Condition {
39 g := getConditionGroups(conditions, options)
40 if len(g) == 0 {
41 return nil
42 }
43
44 topGroup := g.TopGroup()
45 targetReason := getReason(g, options)
46 targetMessage := getMessage(g, options)
47 targetNegativePolarity := stringInSlice(options.negativePolarityConditionTypes, targetCondition)
48
49 switch topGroup.status {
50 case metav1.ConditionTrue:
51
52 if topGroup.negativePolarity != targetNegativePolarity {
53 return FalseCondition(targetCondition, targetReason, "%s", targetMessage)
54 }
55 return TrueCondition(targetCondition, targetReason, "%s", targetMessage)
56 case metav1.ConditionFalse:
57
58 if topGroup.negativePolarity != targetNegativePolarity {
59 return TrueCondition(targetCondition, targetReason, "%s", targetMessage)
60 }
61 return FalseCondition(targetCondition, targetReason, "%s", targetMessage)
62 default:
63 return UnknownCondition(targetCondition, targetReason, "%s", targetMessage)
64 }
65 }
66
67
68
69 func getConditionGroups(conditions []localizedCondition, options *mergeOptions) conditionGroups {
70 groups := conditionGroups{}
71
72 for _, condition := range conditions {
73 if condition.Condition == nil {
74 continue
75 }
76
77 added := false
78 for i := range groups {
79 if groups[i].status == condition.Status &&
80 groups[i].negativePolarity == stringInSlice(options.negativePolarityConditionTypes, condition.Type) {
81
82 if options.withLatestGeneration && groups[i].generation != condition.ObservedGeneration {
83 continue
84 }
85 groups[i].conditions = append(groups[i].conditions, condition)
86 added = true
87 break
88 }
89 }
90 if !added {
91 groups = append(groups, conditionGroup{
92 conditions: []localizedCondition{condition},
93 status: condition.Status,
94 negativePolarity: stringInSlice(options.negativePolarityConditionTypes, condition.Type),
95 generation: condition.ObservedGeneration,
96 })
97 }
98 }
99
100
101
102 if options.withLatestGeneration {
103 latestGen := groups.latestGeneration()
104 latestGroups := conditionGroups{}
105 for _, g := range groups {
106 if g.generation == latestGen {
107 latestGroups = append(latestGroups, g)
108 }
109 }
110 groups = latestGroups
111 }
112
113
114 sort.Sort(groups)
115
116
117
118
119 if len(groups) > 0 {
120 sort.Slice(groups[0].conditions, func(i, j int) bool {
121 a := groups[0].conditions[i]
122 b := groups[0].conditions[j]
123 if a.Type != b.Type {
124 return lexicographicLess(a.Condition, b.Condition)
125 }
126 return a.GetName() < b.GetName()
127 })
128 }
129
130 return groups
131 }
132
133
134
135 type conditionGroups []conditionGroup
136
137 func (g conditionGroups) Len() int {
138 return len(g)
139 }
140
141 func (g conditionGroups) Less(i, j int) bool {
142 return g[i].mergePriority() < g[j].mergePriority()
143 }
144
145 func (g conditionGroups) Swap(i, j int) {
146 g[i], g[j] = g[j], g[i]
147 }
148
149
150 func (g conditionGroups) TopGroup() *conditionGroup {
151 if len(g) == 0 {
152 return nil
153 }
154 return &g[0]
155 }
156
157
158 func (g conditionGroups) TruePositivePolarityGroup() *conditionGroup {
159 if g.Len() == 0 {
160 return nil
161 }
162 for _, group := range g {
163 if !group.negativePolarity && group.status == metav1.ConditionTrue {
164 return &group
165 }
166 }
167 return nil
168 }
169
170
171 func (g conditionGroups) latestGeneration() int64 {
172 var max int64
173 for _, group := range g {
174 if group.generation > max {
175 max = group.generation
176 }
177 }
178 return max
179 }
180
181
182
183 type conditionGroup struct {
184 status metav1.ConditionStatus
185 negativePolarity bool
186 conditions []localizedCondition
187 generation int64
188 }
189
190
191
192 func (g conditionGroup) mergePriority() (p int) {
193 switch g.status {
194 case metav1.ConditionTrue:
195 p = 0
196 if !g.negativePolarity {
197 p = 2
198 }
199 return
200 case metav1.ConditionFalse:
201 p = 1
202 if g.negativePolarity {
203 p = 3
204 }
205 return
206 case metav1.ConditionUnknown:
207 return 4
208 default:
209 return 99
210 }
211 }
212
213 func stringInSlice(s []string, val string) bool {
214 for _, s := range s {
215 if s == val {
216 return true
217 }
218 }
219 return false
220 }
221
View as plain text