generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 106
/
Copy pathhierarchy_types.go
269 lines (233 loc) · 11.1 KB
/
hierarchy_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
/*
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 v1alpha2
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Constants for types and well-known names
const (
Singleton = "hierarchy"
HierarchyConfigurations = "hierarchyconfigurations"
)
// Constants for labels and annotations
const (
MetaGroup = "hnc.x-k8s.io"
LabelInheritedFrom = MetaGroup + "/inherited-from"
FinalizerHasSubnamespace = MetaGroup + "/hasSubnamespace"
LabelTreeDepthSuffix = ".tree." + MetaGroup + "/depth"
AnnotationManagedBy = MetaGroup + "/managed-by"
AnnotationPropagatePrefix = "propagate." + MetaGroup
AnnotationSelector = AnnotationPropagatePrefix + "/select"
AnnotationTreeSelector = AnnotationPropagatePrefix + "/treeSelect"
AnnotationNoneSelector = AnnotationPropagatePrefix + "/none"
// LabelManagedByStandard will eventually replace our own managed-by annotation (we didn't know
// about this standard label when we invented our own).
LabelManagedByApps = "app.kubernetes.io/managed-by"
// LabelIncludedNamespace is the label added by HNC on the namespaces that
// should be enforced by our validators.
LabelIncludedNamespace = MetaGroup + "/included-namespace"
)
const (
// Condition types.
ConditionActivitiesHalted string = "ActivitiesHalted"
ConditionBadConfiguration string = "BadConfiguration"
// Condition reasons. Please keep this list in alphabetical order. IF ADDING ANYTHING HERE, PLEASE
// ALSO ADD THEM TO AllConditions, BELOW.
ReasonAncestor string = "AncestorHaltActivities"
ReasonAnchorMissing string = "SubnamespaceAnchorMissing"
ReasonDeletingCRD string = "DeletingCRD"
ReasonIllegalManagedAnnotation string = "IllegalManagedAnnotation"
ReasonIllegalManagedLabel string = "IllegalManagedLabel"
ReasonIllegalParent string = "IllegalParent"
ReasonInCycle string = "InCycle"
ReasonParentMissing string = "ParentMissing"
)
// AllConditions have all the conditions by type and reason. Please keep this
// list in alphabetic order. This is specifically used to clear (set to 0)
// conditions in the metrics.
var AllConditions = map[string][]string{
ConditionActivitiesHalted: {
ReasonAncestor,
ReasonDeletingCRD,
ReasonIllegalManagedAnnotation,
ReasonIllegalManagedLabel,
ReasonIllegalParent,
ReasonInCycle,
ReasonParentMissing,
},
ConditionBadConfiguration: {
ReasonAnchorMissing,
},
}
const (
// EventCannotPropagate is for events when a namespace contains an object that
// couldn't be propagated *out* of the namespace, to one or more of its
// descendants. If the object couldn't be propagated to *any* descendants - for
// example, because it has a finalizer on it (HNC can't propagate objects with
// finalizers), the error message will point to the object in this namespace.
// Otherwise, if it couldn't be propagated to *some* descendant, the error
// message will point to the descendant.
EventCannotPropagate string = "CannotPropagateObject"
// EventCannotUpdate is for events when a namespace has an object that couldn't
// be propagated *into* this namespace - that is, it couldn't be created in
// the first place, or it couldn't be updated. The error message will point to
// the source namespace.
EventCannotUpdate string = "CannotUpdateObject"
// EventCannotGetSelector is for events when an object has annotations that cannot be
// parsed into a valid selector
EventCannotParseSelector string = "CannotParseSelector"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// Hierarchy is the Schema for the hierarchies API
type HierarchyConfiguration struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec HierarchyConfigurationSpec `json:"spec,omitempty"`
Status HierarchyConfigurationStatus `json:"status,omitempty"`
}
// HierarchySpec defines the desired state of Hierarchy
type HierarchyConfigurationSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Parent indicates the parent of this namespace, if any.
Parent string `json:"parent,omitempty"`
// AllowCascadingDeletion indicates if the subnamespaces of this namespace are
// allowed to cascading delete.
AllowCascadingDeletion bool `json:"allowCascadingDeletion,omitempty"`
// Lables is a list of labels and values to apply to the current namespace and all of its
// descendants. All label keys must match a regex specified on the command line by
// --managed-namespace-label. A namespace cannot have a KVP that conflicts with one of its
// ancestors.
Labels []MetaKVP `json:"labels,omitempty"`
// Annotations is a list of annotations and values to apply to the current namespace and all of
// its descendants. All annotation keys must match a regex specified on the command line by
// --managed-namespace-annotation. A namespace cannot have a KVP that conflicts with one of its
// ancestors.
Annotations []MetaKVP `json:"annotations,omitempty"`
}
// HierarchyStatus defines the observed state of Hierarchy
type HierarchyConfigurationStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Children indicates the direct children of this namespace, if any.
Children []string `json:"children,omitempty"`
// Conditions describes the errors, if any.
Conditions []Condition `json:"conditions,omitempty"`
}
// +kubebuilder:object:root=true
// HierarchyList contains a list of Hierarchy
type HierarchyConfigurationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []HierarchyConfiguration `json:"items"`
}
// MetaKVP represents a label or annotation
type MetaKVP struct {
// Key is the name of the label or annotation. It must conform to the normal rules for Kubernetes
// label/annotation keys.
Key string `json:"key"`
// Value is the value of the label or annotation. It must confirm to the normal rules for
// Kubernetes label or annoation values, which are far more restrictive for labels than for
// anntations.
Value string `json:"value"`
}
// metav1.Condition is introduced in k8s.io/apimachinery v0.20.0-alpha.1 and we
// don't want to take a dependency on it yet, thus we copied the below struct from
// https://github.com/kubernetes/apimachinery/blob/master/pkg/apis/meta/v1/types.go:
// Condition contains details for one aspect of the current state of this API Resource.
// ---
// This struct is intended for direct use as an array at the field path .status.conditions. For example,
// type FooStatus struct{
// // Represents the observations of a foo's current state.
// // Known .status.conditions.type are: "Available", "Progressing", and "Degraded"
// // +patchMergeKey=type
// // +patchStrategy=merge
// // +listType=map
// // +listMapKey=type
// Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
//
// // other fields
// }
type Condition struct {
// 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
// +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 string `json:"type" protobuf:"bytes,1,opt,name=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" protobuf:"bytes,2,opt,name=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" protobuf:"varint,3,opt,name=observedGeneration"`
// 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" protobuf:"bytes,4,opt,name=lastTransitionTime"`
// 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" protobuf:"bytes,5,opt,name=reason"`
// message is a human readable message indicating details about the transition.
// This may be an empty string.
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:MaxLength=32768
Message string `json:"message" protobuf:"bytes,6,opt,name=message"`
}
// NewCondition fills some required field with default values for schema
// validation, e.g. Status and LastTransitionTime.
func NewCondition(tp, reason, msg string) Condition {
return Condition{
Type: tp,
Status: "True",
// Set time as an obviously wrong value 1970-01-01T00:00:00Z since we
// overwrite conditions every time.
LastTransitionTime: metav1.Unix(0, 0),
Reason: reason,
Message: msg,
}
}
func (c Condition) String() string {
msg := c.Message
if len(msg) > 100 {
msg = msg[:100] + "..."
}
return fmt.Sprintf("%s (%s): %s", c.Type, c.Reason, msg)
}
func init() {
SchemeBuilder.Register(&HierarchyConfiguration{}, &HierarchyConfigurationList{})
}