-
Notifications
You must be signed in to change notification settings - Fork 11
/
condition_types.go
221 lines (198 loc) · 9.14 KB
/
condition_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
/*
* Copyright (C) 2022 Appvia Ltd <info@appvia.io>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ConditionType defines a type of a condition in PascalCase or in foo.example.com/PascalCase
// ---
// Many .condition.type values are consistent across resources like Available, but because arbitrary
// conditions can be useful (see .node.status.conditions), the ability to deconflict is important.
// The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
// +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$`
// +kubebuilder:validation:MaxLength=316
type ConditionType string
const (
// ConditionReady describes the overall status of the resource. All Wayfinder resources should
// set ConditionReady
ConditionReady ConditionType = "Ready"
)
const (
// ReasonNotDetermined is the default reason when a condition's state has not yet been
// determined by the controller
ReasonNotDetermined = "NotDetermined"
// ReasonWarning should be used as a reason whenever an unexpected error has caused the
// condition to be in a non-desired state
ReasonWarning = "Warning"
// ReasonError should be used as a reason whenever an unexpected error has caused the
// condition to be in a non-desired state
ReasonError = "Error"
// ReasonInProgress should be used as a reason whenever a condition status is caused
// by an operation being in progress, e.g. deploying, upgrading, whatever.
ReasonInProgress = "InProgress"
// ReasonReady should be used as a reason whenever a condition status indicates that
// some element is now ready for use and available
ReasonReady = "Ready"
// ReasonDisabled indicated the feature or options behind this condition is currently
// disabled
ReasonDisabled = "Disabled"
// ReasonComplete should be used as a reason whenever a concrete process represented by a
// condition is complete.
ReasonComplete = "Complete"
// ReasonActionRequired should be used as a reason whenever a condition is in the state it is
// in due to needing some sort of user or administrator action to resolve it
ReasonActionRequired = "ActionRequired"
// ReasonDeleting should be used to indicate the thing represented by this condition is
// currently in the process of being deleted
ReasonDeleting = "Deleting"
// ReasonErrorDeleting should be used as a reason whenever an unexpected error has caused the
// condition to be in a non-desired state **while deleting**
ReasonErrorDeleting = "ErrorDeleting"
// ReasonDeleted should be used to indicate the thing represented by this condition has been
// deleted
ReasonDeleted = "Deleted"
)
// ConditionSpec describes the shape of a condition which will be populated onto the status
type ConditionSpec struct {
// The PascalCase condition type, e.g. ServiceAvailable or InsufficientCapacity.
// See ConditionType for the rules on condition types.
Type ConditionType
// Name is a human-readable name for this condition, used for UI and CLI reporting / explanation
// If Name is empty, the Type will be used also as the Name.
Name string
// DefaultStatus is the default status - if unset, metav1.ConditionUnknown will be used.
DefaultStatus metav1.ConditionStatus
}
// Condition is the current observed condition of some aspect of a resource
// +k8s:openapi-gen=true
type Condition struct {
// The first several fields here follow the standard used in metav1.Condition:
// Type of condition in CamelCase or in foo.example.com/CamelCase.
// ---
// Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
// useful (see .node.status.conditions), the ability to deconflict is important.
// The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
// +required
// +kubebuilder:validation:Required
Type ConditionType `json:"type"`
// Status of the condition, one of True, False, Unknown.
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=True;False;Unknown
Status metav1.ConditionStatus `json:"status"`
// ObservedGeneration represents the .metadata.generation that the condition was set based upon.
// For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
// with respect to the current state of the instance.
// +optional
// +kubebuilder:validation:Minimum=0
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// LastTransitionTime is the last time the condition transitioned from one status to another.
// This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Format=date-time
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
// Reason contains a programmatic identifier indicating the reason for the condition's last transition.
// Producers of specific condition types may define expected values and meanings for this field,
// and whether the values are considered a guaranteed API.
// The value should be a CamelCase string.
// This field may not be empty.
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:MaxLength=1024
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$`
Reason string `json:"reason"`
// Message is a human readable message indicating details about the transition.
// This may be an empty string.
// +optional
// +kubebuilder:validation:MaxLength=32768
Message string `json:"message,omitempty"`
// Name is a human-readable name for this condition.
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
// Detail is any additional human-readable detail to understand this condition, for example,
// the full underlying error which caused an issue
// +optional
Detail string `json:"detail,omitempty"`
}
// IsGeneration returns true if the condition was generated by the controller
func (c *Condition) IsGeneration(generation int64) bool {
return c.ObservedGeneration == generation
}
// IsComplete returns true if the resource complete for a specific generation
func (c *Condition) IsComplete(generation int64) bool {
return c.Status == metav1.ConditionTrue && c.ObservedGeneration == generation
}
// IsFailed returns true if the resource has a failed state
func (c *Condition) IsFailed(generation int64) bool {
return c.Reason == ReasonError && c.ObservedGeneration == generation
}
// InProgress returns true if the condition indicates the condition is in progress
func (c *Condition) InProgress() bool {
return c.Reason == ReasonInProgress
}
// IsDeleting returns true if the condition is in status false and has a deleting/deleted reason
// (i.e. deleting, deleted or error deleting)
func (c *Condition) IsDeleting() bool {
if c == nil {
return false
}
return c.Status == metav1.ConditionFalse && (c.Reason == ReasonDeleting || c.Reason == ReasonDeleted || c.Reason == ReasonErrorDeleting)
}
// Conditions is a collection of condition
type Conditions []Condition
// HasCondition returns true if the condition is in the list
func (s *CommonStatus) HasCondition(t ConditionType) bool {
c := s.GetCondition(t)
return c != nil
}
// GetCondition returns the current observed status of a specific element of this resource, or
// nil if the condition does not exist
func (s *CommonStatus) GetCondition(typ ConditionType) *Condition {
for i := range s.Conditions {
if s.Conditions[i].Type == typ {
return &s.Conditions[i]
}
}
return nil
}
// IsComplete returns true if the condition is complete for a specific generation
func (s *CommonStatus) IsComplete(condition ConditionType, generation int64) bool {
cond := s.GetCommonStatus().GetCondition(condition)
if cond == nil {
return false
}
return cond.ObservedGeneration == generation && cond.Status == metav1.ConditionTrue
}
// InCondition returns true if the condition specified by typ is present and set to its true
// state (i.e. metav1.ConditionTrue for a normal condition or metav1.ConditionFalse for a negative
// polarity condition)
func (s *CommonStatus) InCondition(typ ConditionType) bool {
c := s.GetCondition(typ)
if c == nil {
return false
}
return c.Status == metav1.ConditionTrue
}
// GetConditions returns the status of any sub-components of this resource
func (s *CommonStatus) GetConditions() Conditions {
return s.Conditions
}