-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
significant.go
77 lines (69 loc) · 2.52 KB
/
significant.go
1
2
3
4
5
6
7
8
9
10
11
12
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package pod
import (
"os"
apiv1 "k8s.io/api/core/v1"
)
func SignificantPodChange(from *apiv1.Pod, to *apiv1.Pod) bool {
return os.Getenv("ALL_POD_CHANGES_SIGNIFICANT") == "true" ||
from.Spec.NodeName != to.Spec.NodeName ||
from.Status.Phase != to.Status.Phase ||
from.Status.Message != to.Status.Message ||
from.Status.PodIP != to.Status.PodIP ||
from.GetDeletionTimestamp() != to.GetDeletionTimestamp() ||
significantMetadataChange(from.Annotations, to.Annotations) ||
significantMetadataChange(from.Labels, to.Labels) ||
significantContainerStatusesChange(from.Status.ContainerStatuses, to.Status.ContainerStatuses) ||
significantContainerStatusesChange(from.Status.InitContainerStatuses, to.Status.InitContainerStatuses) ||
significantConditionsChange(from.Status.Conditions, to.Status.Conditions)
}
func significantMetadataChange(from map[string]string, to map[string]string) bool {
if len(from) != len(to) {
return true
}
for k, v := range from {
if to[k] != v {
return true
}
}
// as both annotations must be the same length, the above loop will always catch all changes,
// we don't need to range with `to`
return false
}
func significantContainerStatusesChange(from []apiv1.ContainerStatus, to []apiv1.ContainerStatus) bool {
if len(from) != len(to) {
return true
}
statuses := map[string]apiv1.ContainerStatus{}
for _, s := range from {
statuses[s.Name] = s
}
for _, s := range to {
if significantContainerStatusChange(statuses[s.Name], s) {
return true
}
}
return false
}
func significantContainerStatusChange(from apiv1.ContainerStatus, to apiv1.ContainerStatus) bool {
return from.Ready != to.Ready || significantContainerStateChange(from.State, to.State)
}
func significantContainerStateChange(from apiv1.ContainerState, to apiv1.ContainerState) bool {
// waiting has two significant fields and either could potentially change
return to.Waiting != nil && (from.Waiting == nil || from.Waiting.Message != to.Waiting.Message || from.Waiting.Reason != to.Waiting.Reason) ||
// running only has one field which is immutable - so any change is significant
(to.Running != nil && from.Running == nil) ||
// I'm assuming this field is immutable - so any change is significant
(to.Terminated != nil && from.Terminated == nil)
}
func significantConditionsChange(from []apiv1.PodCondition, to []apiv1.PodCondition) bool {
if len(from) != len(to) {
return true
}
for i, a := range from {
b := to[i]
if a.Message != b.Message || a.Reason != b.Reason {
return true
}
}
return false
}