/
vmsingle_types.go
348 lines (317 loc) · 13.6 KB
/
vmsingle_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 v1beta1
import (
"fmt"
"strings"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/utils/pointer"
)
// VMSingleSpec defines the desired state of VMSingle
// +k8s:openapi-gen=true
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="The version of VMSingle"
// +kubebuilder:printcolumn:name="RetentionPeriod",type="string",JSONPath=".spec.RetentionPeriod",description="The desired RetentionPeriod for vm single"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
type VMSingleSpec struct {
// PodMetadata configures Labels and Annotations which are propagated to the VMSingle pods.
// +optional
PodMetadata *EmbeddedObjectMetadata `json:"podMetadata,omitempty"`
// Image - docker image settings for VMSingle
// if no specified operator uses default config version
// +optional
Image Image `json:"image,omitempty"`
// ImagePullSecrets An optional list of references to secrets in the same namespace
// to use for pulling images from registries
// see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod
// +optional
ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
// Secrets is a list of Secrets in the same namespace as the VMSingle
// object, which shall be mounted into the VMSingle Pods.
// +optional
Secrets []string `json:"secrets,omitempty"`
// ConfigMaps is a list of ConfigMaps in the same namespace as the VMSingle
// object, which shall be mounted into the VMSingle Pods.
// +optional
ConfigMaps []string `json:"configMaps,omitempty"`
// LogLevel for victoria metrics single to be configured with.
// +optional
// +kubebuilder:validation:Enum=INFO;WARN;ERROR;FATAL;PANIC
LogLevel string `json:"logLevel,omitempty"`
// LogFormat for VMSingle to be configured with.
// +optional
// +kubebuilder:validation:Enum=default;json
LogFormat string `json:"logFormat,omitempty"`
// ReplicaCount is the expected size of the VMSingle
// it can be 0 or 1
// if you need more - use vm cluster
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Number of pods",xDescriptors="urn:alm:descriptor:com.tectonic.ui:podCount,urn:alm:descriptor:io.kubernetes:custom"
ReplicaCount *int32 `json:"replicaCount,omitempty"`
// StorageDataPath disables spec.storage option and overrides arg for victoria-metrics binary --storageDataPath,
// its users responsibility to mount proper device into given path.
// + optional
StorageDataPath string `json:"storageDataPath,omitempty"`
// Storage is the definition of how storage will be used by the VMSingle
// by default it`s empty dir
// +optional
Storage *v1.PersistentVolumeClaimSpec `json:"storage,omitempty"`
// StorageMeta defines annotations and labels attached to PVC for given vmsingle CR
// +optional
StorageMetadata EmbeddedObjectMetadata `json:"storageMetadata,omitempty"`
// Volumes allows configuration of additional volumes on the output deploy definition.
// Volumes specified will be appended to other volumes that are generated as a result of
// StorageSpec objects.
// +optional
Volumes []v1.Volume `json:"volumes,omitempty"`
// VolumeMounts allows configuration of additional VolumeMounts on the output Deployment definition.
// VolumeMounts specified will be appended to other VolumeMounts in the VMSingle container,
// that are generated as a result of StorageSpec objects.
// +optional
VolumeMounts []v1.VolumeMount `json:"volumeMounts,omitempty"`
// Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
// if not defined default resources from operator config will be used
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resources",xDescriptors="urn:alm:descriptor:com.tectonic.ui:resourceRequirements"
// +optional
Resources v1.ResourceRequirements `json:"resources,omitempty"`
// Affinity If specified, the pod's scheduling constraints.
// +optional
Affinity *v1.Affinity `json:"affinity,omitempty"`
// Tolerations If specified, the pod's tolerations.
// +optional
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
// SecurityContext holds pod-level security attributes and common container settings.
// This defaults to the default PodSecurityContext.
// +optional
SecurityContext *v1.PodSecurityContext `json:"securityContext,omitempty"`
// ServiceAccountName is the name of the ServiceAccount to use to run the
// VMSingle Pods.
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// SchedulerName - defines kubernetes scheduler name
// +optional
SchedulerName string `json:"schedulerName,omitempty"`
// RuntimeClassName - defines runtime class for kubernetes pod.
// https://kubernetes.io/docs/concepts/containers/runtime-class/
// +optional
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
// PodSecurityPolicyName - defines name for podSecurityPolicy
// in case of empty value, prefixedName will be used.
// +optional
PodSecurityPolicyName string `json:"podSecurityPolicyName,omitempty"`
// HostAliases provides mapping for ip and hostname,
// that would be propagated to pod,
// cannot be used with HostNetwork.
// +optional
HostAliases []v1.HostAlias `json:"hostAliases,omitempty"`
// Containers property allows to inject additions sidecars or to patch existing containers.
// It can be useful for proxies, backup, etc.
// +optional
Containers []v1.Container `json:"containers,omitempty"`
// InitContainers allows adding initContainers to the pod definition. Those can be used to e.g.
// fetch secrets for injection into the vmSingle configuration from external sources. Any
// errors during the execution of an initContainer will lead to a restart of the Pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
// Using initContainers for any use case other then secret fetching is entirely outside the scope
// of what the maintainers will support and by doing so, you accept that this behaviour may break
// at any time without notice.
// +optional
InitContainers []v1.Container `json:"initContainers,omitempty"`
// PriorityClassName assigned to the Pods
// +optional
PriorityClassName string `json:"priorityClassName,omitempty"`
// HostNetwork controls whether the pod may use the node network namespace
// +optional
HostNetwork bool `json:"hostNetwork,omitempty"`
// DNSPolicy sets DNS policy for the pod
// +optional
DNSPolicy v1.DNSPolicy `json:"dnsPolicy,omitempty"`
// Specifies the DNS parameters of a pod.
// Parameters specified here will be merged to the generated DNS
// configuration based on DNSPolicy.
// +optional
DNSConfig *v1.PodDNSConfig `json:"dnsConfig,omitempty"`
// TopologySpreadConstraints embedded kubernetes pod configuration option,
// controls how pods are spread across your cluster among failure-domains
// such as regions, zones, nodes, and other user-defined topology domains
// https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
// +optional
TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
// InsertPorts - additional listen ports for data ingestion.
InsertPorts *InsertPorts `json:"insertPorts,omitempty"`
// Port listen port
// +optional
Port string `json:"port,omitempty"`
// RemovePvcAfterDelete - if true, controller adds ownership to pvc
// and after VMSingle objest deletion - pvc will be garbage collected
// by controller manager
// +optional
RemovePvcAfterDelete bool `json:"removePvcAfterDelete,omitempty"`
// RetentionPeriod for the stored metrics
// Note VictoriaMetrics has data/ and indexdb/ folders
// metrics from data/ removed eventually as soon as partition leaves retention period
// reverse index data at indexdb rotates once at the half of configured retention period
// https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#retention
RetentionPeriod string `json:"retentionPeriod"`
// VMBackup configuration for backup
// +optional
VMBackup *VMBackup `json:"vmBackup,omitempty"`
// ExtraArgs that will be passed to VMSingle pod
// for example remoteWrite.tmpDataPath: /tmp
// +optional
ExtraArgs map[string]string `json:"extraArgs,omitempty"`
// ExtraEnvs that will be added to VMSingle pod
// +optional
ExtraEnvs []v1.EnvVar `json:"extraEnvs,omitempty"`
// ServiceSpec that will be added to vmsingle service spec
// +optional
ServiceSpec *ServiceSpec `json:"serviceSpec,omitempty"`
// ServiceScrapeSpec that will be added to vmselect VMServiceScrape spec
// +optional
ServiceScrapeSpec *VMServiceScrapeSpec `json:"serviceScrapeSpec,omitempty"`
// LivenessProbe that will be added to VMSingle pod
*EmbeddedProbes `json:",inline"`
// NodeSelector Define which Nodes the Pods are scheduled on.
// +optional
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// TerminationGracePeriodSeconds period for container graceful termination
// +optional
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
}
// VMSingleStatus defines the observed state of VMSingle
// +k8s:openapi-gen=true
type VMSingleStatus struct {
// ReplicaCount Total number of non-terminated pods targeted by this VMAlert
// cluster (their labels match the selector).
Replicas int32 `json:"replicas"`
// UpdatedReplicas Total number of non-terminated pods targeted by this VMAlert
// cluster that have the desired version spec.
UpdatedReplicas int32 `json:"updatedReplicas"`
// AvailableReplicas Total number of available pods (ready for at least minReadySeconds)
// targeted by this VMAlert cluster.
AvailableReplicas int32 `json:"availableReplicas"`
// UnavailableReplicas Total number of unavailable pods targeted by this VMAlert cluster.
UnavailableReplicas int32 `json:"unavailableReplicas"`
}
// VMSingle is fast, cost-effective and scalable time-series database.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +operator-sdk:gen-csv:customresourcedefinitions.displayName="VMSingle App"
// +operator-sdk:gen-csv:customresourcedefinitions.resources="Deployment,apps"
// +operator-sdk:gen-csv:customresourcedefinitions.resources="Service,v1"
// +operator-sdk:gen-csv:customresourcedefinitions.resources="Secret,v1"
// +genclient
// +k8s:openapi-gen=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=vmsingles,scope=Namespaced
type VMSingle struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec VMSingleSpec `json:"spec,omitempty"`
Status VMSingleStatus `json:"status,omitempty"`
}
func (cr *VMSingle) Probe() *EmbeddedProbes {
return cr.Spec.EmbeddedProbes
}
func (cr *VMSingle) ProbePath() string {
return buildPathWithPrefixFlag(cr.Spec.ExtraArgs, healthPath)
}
func (cr *VMSingle) ProbeScheme() string {
return strings.ToUpper(protoFromFlags(cr.Spec.ExtraArgs))
}
func (cr *VMSingle) ProbePort() string {
return cr.Spec.Port
}
func (cr *VMSingle) ProbeNeedLiveness() bool {
return false
}
// VMSingleList contains a list of VMSingle
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type VMSingleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []VMSingle `json:"items"`
}
func (cr *VMSingle) AsOwner() []metav1.OwnerReference {
return []metav1.OwnerReference{
{
APIVersion: cr.APIVersion,
Kind: cr.Kind,
Name: cr.Name,
UID: cr.UID,
Controller: pointer.BoolPtr(true),
BlockOwnerDeletion: pointer.BoolPtr(true),
},
}
}
func (cr VMSingle) PodAnnotations() map[string]string {
annotations := map[string]string{}
if cr.Spec.PodMetadata != nil {
for annotation, value := range cr.Spec.PodMetadata.Annotations {
annotations[annotation] = value
}
}
return annotations
}
func (cr VMSingle) AnnotationsFiltered() map[string]string {
annotations := make(map[string]string)
for annotation, value := range cr.ObjectMeta.Annotations {
if !strings.HasPrefix(annotation, "kubectl.kubernetes.io/") {
annotations[annotation] = value
}
}
return annotations
}
func (cr VMSingle) SelectorLabels() map[string]string {
return map[string]string{
"app.kubernetes.io/name": "vmsingle",
"app.kubernetes.io/instance": cr.Name,
"app.kubernetes.io/component": "monitoring",
"managed-by": "vm-operator",
}
}
func (cr VMSingle) PodLabels() map[string]string {
lbls := cr.SelectorLabels()
if cr.Spec.PodMetadata == nil {
return lbls
}
return labels.Merge(cr.Spec.PodMetadata.Labels, lbls)
}
func (cr VMSingle) AllLabels() map[string]string {
lbls := cr.SelectorLabels()
if cr.ObjectMeta.Labels == nil {
return lbls
}
return labels.Merge(cr.ObjectMeta.Labels, lbls)
}
func (cr VMSingle) PrefixedName() string {
return fmt.Sprintf("vmsingle-%s", cr.Name)
}
func (cr VMSingle) MetricPath() string {
return buildPathWithPrefixFlag(cr.Spec.ExtraArgs, metricPath)
}
func (cr VMSingle) GetServiceAccountName() string {
if cr.Spec.ServiceAccountName == "" {
return cr.PrefixedName()
}
return cr.Spec.ServiceAccountName
}
func (cr VMSingle) GetPSPName() string {
if cr.Spec.PodSecurityPolicyName == "" {
return cr.PrefixedName()
}
return cr.Spec.PodSecurityPolicyName
}
func (cr VMSingle) GetNSName() string {
return cr.GetNamespace()
}
func (cr *VMSingle) AsURL() string {
port := cr.Spec.Port
if port == "" {
port = "8429"
}
return fmt.Sprintf("http://%s.%s.svc:%s", cr.PrefixedName(), cr.Namespace, port)
}
// AsCRDOwner implements interface
func (cr *VMSingle) AsCRDOwner() []metav1.OwnerReference {
return GetCRDAsOwner(Single)
}
func init() {
SchemeBuilder.Register(&VMSingle{}, &VMSingleList{})
}