-
Notifications
You must be signed in to change notification settings - Fork 79
/
upgradeconfig_types.go
348 lines (302 loc) · 12.5 KB
/
upgradeconfig_types.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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
package v1alpha1
import (
"time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// UpgradeType provides a type to declare upgrade types with
type UpgradeType string
const (
// OSD is a type of upgrade
OSD UpgradeType = "OSD"
// ARO is a type of upgrade
ARO UpgradeType = "ARO"
)
// UpgradeConfigSpec defines the desired state of UpgradeConfig and upgrade window and freeze window
type UpgradeConfigSpec struct {
// Specify the desired OpenShift release
Desired Update `json:"desired"`
// Specify the upgrade start time
UpgradeAt string `json:"upgradeAt"`
// +kubebuilder:validation:Minimum:=0
// The maximum grace period granted to a node whose drain is blocked by a Pod Disruption Budget, before that drain is forced. Measured in minutes. The minimum accepted value is 0 and in this case it will trigger force drain after the expectedNodeDrainTime lapsed.
PDBForceDrainTimeout int32 `json:"PDBForceDrainTimeout"`
// +kubebuilder:validation:Enum={"OSD","ARO"}
// Type indicates the ClusterUpgrader implementation to use to perform an upgrade of the cluster
Type UpgradeType `json:"type"`
// Specify if scaling up an extra node for capacity reservation before upgrade starts is needed
CapacityReservation bool `json:"capacityReservation,omitempty"`
}
// UpgradeConfigStatus defines the observed state of UpgradeConfig
type UpgradeConfigStatus struct {
// This record history of every upgrade
// +kubebuilder:validation:Optional
History UpgradeHistories `json:"history,omitempty"`
}
// UpgradeHistories is a slice of UpgradeHistory
type UpgradeHistories []UpgradeHistory
// UpgradeHistory record history of upgrade
type UpgradeHistory struct {
//Desired version of this upgrade
Version string `json:"version,omitempty"`
//Version preceding this upgrade
PrecedingVersion string `json:"precedingVersion,omitempty"`
// +kubebuilder:validation:Enum={"New","Pending","Upgrading","Upgraded", "Failed"}
// This describe the status of the upgrade process
Phase UpgradePhase `json:"phase"`
// Conditions is a set of Condition instances.
Conditions Conditions `json:"conditions,omitempty"`
// +kubebuilder:validation:Optional
StartTime *metav1.Time `json:"startTime,omitempty"`
// +kubebuilder:validation:Optional
CompleteTime *metav1.Time `json:"completeTime,omitempty"`
WorkerStartTime *metav1.Time `json:"workerStartTime,omitempty"`
WorkerCompleteTime *metav1.Time `json:"workerCompleteTime,omitempty"`
}
// UpgradeConditionType is a Go string type.
type UpgradeConditionType string
// UpgradeCondition houses fields that describe the state of an Upgrade including metadata.
type UpgradeCondition struct {
// Type of upgrade condition
Type UpgradeConditionType `json:"type"`
// Status of condition, one of True, False, Unknown
Status corev1.ConditionStatus `json:"status"`
// Last time the condition was checked.
// +kubebuilder:validation:Optional
LastProbeTime *metav1.Time `json:"lastProbeTime,omitempty"`
// Last time the condition transit from one status to another.
// +kubebuilder:validation:Optional
LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
// Start time of this condition.
// +kubebuilder:validation:Optional
StartTime *metav1.Time `json:"startTime,omitempty"`
// Complete time of this condition.
// +kubebuilder:validation:Optional
CompleteTime *metav1.Time `json:"completeTime,omitempty"`
// (brief) reason for the condition's last transition.
// +kubebuilder:validation:Optional
Reason string `json:"reason,omitempty"`
// Human readable message indicating details about last transition.
// +kubebuilder:validation:Optional
Message string `json:"message,omitempty"`
}
const (
// SendStartedNotification is an UpgradeConditionType
SendStartedNotification UpgradeConditionType = "StartedNotificationSent"
// UpgradePreHealthCheck is an UpgradeConditionType
UpgradePreHealthCheck UpgradeConditionType = "ClusterHealthyBeforeUpgrade"
// ExtDepAvailabilityCheck is an UpgradeConditionType
ExtDepAvailabilityCheck UpgradeConditionType = "ExternalDependenciesAvailable"
// UpgradeScaleUpExtraNodes is an UpgradeConditionType
UpgradeScaleUpExtraNodes UpgradeConditionType = "ComputeCapacityReserved"
// ControlPlaneMaintWindow is an UpgradeConditionType
ControlPlaneMaintWindow UpgradeConditionType = "ControlPlaneMaintenanceWindowCreated"
// CommenceUpgrade is an UpgradeConditionType
CommenceUpgrade UpgradeConditionType = "UpgradeCommenced"
// ControlPlaneUpgraded is an UpgradeConditionType
ControlPlaneUpgraded UpgradeConditionType = "ControlPlaneUpgraded"
// RemoveControlPlaneMaintWindow is an UpgradeConditionType
RemoveControlPlaneMaintWindow UpgradeConditionType = "ControlPlaneMaintenanceWindowRemoved"
// WorkersMaintWindow is an UpgradeConditionType
WorkersMaintWindow UpgradeConditionType = "WorkersMaintenanceWindowCreated"
// AllWorkerNodesUpgraded is an UpgradeConditionType
AllWorkerNodesUpgraded UpgradeConditionType = "WorkerNodesUpgraded"
// RemoveExtraScaledNodes is an UpgradeConditionType
RemoveExtraScaledNodes UpgradeConditionType = "ComputeCapacityRemoved"
// RemoveMaintWindow is an UpgradeConditionType
RemoveMaintWindow UpgradeConditionType = "WorkersMaintenanceWindowRemoved"
// PostClusterHealthCheck is an UpgradeConditionType
PostClusterHealthCheck UpgradeConditionType = "ClusterHealthyAfterUpgrade"
// PostUpgradeProcedures is an UpgradeConditionType
PostUpgradeProcedures UpgradeConditionType = "PostUpgradeTasksCompleted"
// SendCompletedNotification is an UpgradeConditionType
SendCompletedNotification UpgradeConditionType = "CompletedNotificationSent"
// IsClusterUpgradable is an UpgradeConditionType
IsClusterUpgradable UpgradeConditionType = "IsClusterUpgradable"
)
// UpgradePhase is a Go string type.
type UpgradePhase string
const (
// UpgradePhaseNew defines that an upgrade is new.
UpgradePhaseNew UpgradePhase = "New"
// UpgradePhasePending defines that an upgrade has been scheduled.
UpgradePhasePending UpgradePhase = "Pending"
// UpgradePhaseUpgrading defines the state of an ongoing upgrade.
UpgradePhaseUpgrading UpgradePhase = "Upgrading"
// UpgradePhaseUpgraded defines a completed upgrade.
UpgradePhaseUpgraded UpgradePhase = "Upgraded"
// UpgradePhaseFailed defines a failed upgrade.
UpgradePhaseFailed UpgradePhase = "Failed"
// UpgradePhaseUnknown defines an unknown upgrade state.
UpgradePhaseUnknown UpgradePhase = "Unknown"
)
// +kubebuilder:object:root=true
// UpgradeConfig is the Schema for the upgradeconfigs API
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=upgradeconfigs,scope=Namespaced,shortName=upgrade
// +kubebuilder:printcolumn:name="desired_version",type="string",JSONPath=".spec.desired.version"
// +kubebuilder:printcolumn:name="phase",type="string",JSONPath=".status.history[0].phase"
// +kubebuilder:printcolumn:name="stage",type="string",JSONPath=".status.history[0].conditions[0].type"
// +kubebuilder:printcolumn:name="status",type="string",JSONPath=".status.history[0].conditions[0].status"
// +kubebuilder:printcolumn:name="reason",type="string",JSONPath=".status.history[0].conditions[0].reason"
// +kubebuilder:printcolumn:name="message",type="string",JSONPath=".status.history[0].conditions[0].message"
type UpgradeConfig struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec UpgradeConfigSpec `json:"spec,omitempty"`
Status UpgradeConfigStatus `json:"status,omitempty"`
}
// GetPDBDrainTimeoutDuration returns the PDB timeout
func (uc *UpgradeConfig) GetPDBDrainTimeoutDuration() time.Duration {
return time.Duration(uc.Spec.PDBForceDrainTimeout) * time.Minute
}
// +kubebuilder:object:root=true
// UpgradeConfigList contains a list of UpgradeConfig
type UpgradeConfigList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []UpgradeConfig `json:"items"`
}
// Update represents a release go gonna upgraded to
type Update struct {
// Version of openshift release
// +kubebuilder:validation:Type=string
// +optional
Version string `json:"version,omitempty"`
// Channel used for upgrades
// +optional
Channel string `json:"channel,omitempty"`
// Image reference used for upgrades
// +optional
Image string `json:"image,omitempty"`
}
// IsTrue Condition whether the condition status is "True".
func (c UpgradeCondition) IsTrue() bool {
return c.Status == corev1.ConditionTrue
}
// IsFalse returns whether the condition status is "False".
func (c UpgradeCondition) IsFalse() bool {
return c.Status == corev1.ConditionFalse
}
// IsUnknown returns whether the condition status is "Unknown".
func (c UpgradeCondition) IsUnknown() bool {
return c.Status == corev1.ConditionUnknown
}
// DeepCopyInto copies in into out.
func (c *UpgradeCondition) DeepCopyInto(cpy *UpgradeCondition) {
*cpy = *c
}
// Conditions is a set of Condition instances.
type Conditions []UpgradeCondition
// NewConditions initializes a set of conditions with the given list of
// conditions.
func NewConditions(conds ...UpgradeCondition) Conditions {
conditions := Conditions{}
for _, c := range conds {
conditions.SetCondition(c)
}
return conditions
}
// IsTrueFor searches the set of conditions for a condition with the given
// ConditionType. If found, it returns `condition.IsTrue()`. If not found,
// it returns false.
func (conditions Conditions) IsTrueFor(t UpgradeConditionType) bool {
for _, condition := range conditions {
if condition.Type == t {
return condition.IsTrue()
}
}
return false
}
// IsFalseFor searches the set of conditions for a condition with the given
// ConditionType. If found, it returns `condition.IsFalse()`. If not found,
// it returns false.
func (conditions Conditions) IsFalseFor(t UpgradeConditionType) bool {
for _, condition := range conditions {
if condition.Type == t {
return condition.IsFalse()
}
}
return false
}
// IsUnknownFor searches the set of conditions for a condition with the given
// ConditionType. If found, it returns `condition.IsUnknown()`. If not found,
// it returns true.
func (conditions Conditions) IsUnknownFor(t UpgradeConditionType) bool {
for _, condition := range conditions {
if condition.Type == t {
return condition.IsUnknown()
}
}
return true
}
// SetCondition adds (or updates) the set of conditions with the given
// condition. It returns a boolean value indicating whether the set condition
// is new or was a change to the existing condition with the same type.
func (conditions *Conditions) SetCondition(newCond UpgradeCondition) bool {
newCond.LastTransitionTime = &metav1.Time{Time: time.Now()}
newCond.LastProbeTime = &metav1.Time{Time: time.Now()}
for i, condition := range *conditions {
if condition.Type == newCond.Type {
if condition.Status == newCond.Status {
newCond.LastTransitionTime = condition.LastTransitionTime
}
changed := condition.Status != newCond.Status ||
condition.Reason != newCond.Reason ||
condition.Message != newCond.Message
(*conditions)[i] = newCond
return changed
}
}
*conditions = append([]UpgradeCondition{newCond}, *conditions...)
return true
}
// GetCondition searches the set of conditions for the condition with the given
// ConditionType and returns it. If the matching condition is not found,
// GetCondition returns nil.
func (conditions Conditions) GetCondition(t UpgradeConditionType) *UpgradeCondition {
for _, condition := range conditions {
if condition.Type == t {
return &condition
}
}
return nil
}
// RemoveCondition removes the condition with the given ConditionType from
// the conditions set. If no condition with that type is found, RemoveCondition
// returns without performing any action. If the passed condition type is not
// found in the set of conditions, RemoveCondition returns false.
func (conditions *Conditions) RemoveCondition(t UpgradeConditionType) bool {
if conditions == nil {
return false
}
for i, condition := range *conditions {
if condition.Type == t {
*conditions = append((*conditions)[:i], (*conditions)[i+1:]...)
return true
}
}
return false
}
// GetHistory returns UpgradeHistory
func (histories UpgradeHistories) GetHistory(version string) *UpgradeHistory {
for _, history := range histories {
if history.Version == version {
return &history
}
}
return nil
}
// SetHistory appends new history to current
func (histories *UpgradeHistories) SetHistory(history UpgradeHistory) {
for i, h := range *histories {
if h.Version == history.Version {
(*histories)[i] = history
return
}
}
*histories = append([]UpgradeHistory{history}, *histories...)
}
func init() {
SchemeBuilder.Register(&UpgradeConfig{}, &UpgradeConfigList{})
}