/
status.go
184 lines (155 loc) · 5.85 KB
/
status.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
Copyright 2018 Pressinfra SRL
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mysqlcluster
import (
"fmt"
"time"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
api "github.com/presslabs/mysql-operator/pkg/apis/mysql/v1alpha1"
)
var log = logf.Log.WithName("update-status")
// UpdateStatusCondition sets the condition to a status.
// for example Ready condition to True, or False
func (c *MysqlCluster) UpdateStatusCondition(condType api.ClusterConditionType,
status core.ConditionStatus, reason, msg string) {
newCondition := api.ClusterCondition{
Type: condType,
Status: status,
Reason: reason,
Message: msg,
}
t := time.Now()
if len(c.Status.Conditions) == 0 {
log.V(4).Info(fmt.Sprintf("Setting lastTransitionTime for mysql cluster "+
"%q condition %q to %v", c.Name, condType, t))
newCondition.LastTransitionTime = metav1.NewTime(t)
c.Status.Conditions = []api.ClusterCondition{newCondition}
} else {
if i, exist := c.condIndex(condType); exist {
cond := c.Status.Conditions[i]
if cond.Status != newCondition.Status {
log.V(3).Info(fmt.Sprintf("Found status change for mysql cluster "+
"%q condition %q: %q -> %q; setting lastTransitionTime to %v",
c.Name, condType, cond.Status, status, t))
newCondition.LastTransitionTime = metav1.NewTime(t)
} else {
newCondition.LastTransitionTime = cond.LastTransitionTime
}
log.V(4).Info(fmt.Sprintf("Setting lastTransitionTime for mysql cluster "+
"%q condition %q to %q", c.Name, condType, status))
c.Status.Conditions[i] = newCondition
} else {
log.V(4).Info(fmt.Sprintf("Setting new condition for mysql cluster %q, condition %q to %q",
c.Name, condType, status))
newCondition.LastTransitionTime = metav1.NewTime(t)
c.Status.Conditions = append(c.Status.Conditions, newCondition)
}
}
}
func (c *MysqlCluster) condIndex(condType api.ClusterConditionType) (int, bool) {
for i, cond := range c.Status.Conditions {
if cond.Type == condType {
return i, true
}
}
return 0, false
}
// GetClusterCondition returns the cluster condition of the given type
func (c *MysqlCluster) GetClusterCondition(condType api.ClusterConditionType) *api.ClusterCondition {
i, found := c.condIndex(condType)
if found {
return &c.Status.Conditions[i]
}
return nil
}
// UpdateNodeConditionStatus updates the status of the condition for a given name and type
func (c *MysqlCluster) UpdateNodeConditionStatus(nodeName string, condType api.NodeConditionType, status core.ConditionStatus) bool {
i := c.GetNodeStatusIndex(nodeName)
return updateNodeCondition(&c.Status.Nodes[i], condType, status)
}
// UpdateNodeCondition updates the condition for a given type
func updateNodeCondition(ns *api.NodeStatus, cType api.NodeConditionType,
cStatus core.ConditionStatus) bool {
newCondition := api.NodeCondition{
Type: cType,
Status: cStatus,
}
changed := false
t := time.Now()
if len(ns.Conditions) == 0 {
log.V(3).Info(fmt.Sprintf("Setting lastTransitionTime for node "+
"%q condition %q to %v", ns.Name, cType, t))
newCondition.LastTransitionTime = metav1.NewTime(t)
ns.Conditions = []api.NodeCondition{newCondition}
changed = true
} else {
if i, exist := GetNodeConditionIndex(ns, cType); exist {
cond := ns.Conditions[i]
if cond.Status != newCondition.Status {
log.V(3).Info(fmt.Sprintf("Found status change for node "+
"%q condition %q: %q -> %q; setting lastTransitionTime to %v",
ns.Name, cType, cond.Status, cStatus, t))
newCondition.LastTransitionTime = metav1.NewTime(t)
changed = true
} else {
newCondition.LastTransitionTime = cond.LastTransitionTime
}
log.V(3).Info(fmt.Sprintf("Setting lastTransitionTime for node "+
"%q condition %q to %q", ns.Name, cType, cStatus))
ns.Conditions[i] = newCondition
} else {
log.V(3).Info(fmt.Sprintf("Setting new condition for node %q, condition %q to %q",
ns.Name, cType, cStatus))
newCondition.LastTransitionTime = metav1.NewTime(t)
ns.Conditions = append(ns.Conditions, newCondition)
changed = true
}
}
return changed
}
// GetNodeConditionIndex returns the index of a condition. The boolean value is
// true if the conditions exists otherwise is false.
func GetNodeConditionIndex(nodeStatus *api.NodeStatus, condType api.NodeConditionType) (int, bool) {
for i, cond := range nodeStatus.Conditions {
if cond.Type == condType {
return i, true
}
}
return 0, false
}
// GetNodeStatusIndex get index of node given the name
func (c *MysqlCluster) GetNodeStatusIndex(name string) int {
for i := 0; i < len(c.Status.Nodes); i++ {
if c.Status.Nodes[i].Name == name {
return i
}
}
c.Status.Nodes = append(c.Status.Nodes, api.NodeStatus{Name: name})
return c.GetNodeStatusIndex(name)
}
// GetNodeCondition get NodeCondigion given the name and condType
func (c *MysqlCluster) GetNodeCondition(name string, condType api.NodeConditionType) *api.NodeCondition {
nodeStatusIndex := c.GetNodeStatusIndex(name)
condIndex, exists := GetNodeConditionIndex(&c.Status.Nodes[nodeStatusIndex], condType)
if exists {
return &c.Status.Nodes[nodeStatusIndex].Conditions[condIndex]
}
return nil
}
// GetNodeStatusFor returns the node status for specified hostname
func (c *MysqlCluster) GetNodeStatusFor(name string) api.NodeStatus {
nodeStatusIndex := c.GetNodeStatusIndex(name)
return c.Status.Nodes[nodeStatusIndex]
}