-
Notifications
You must be signed in to change notification settings - Fork 398
/
Copy pathcluster_types.go
2458 lines (2020 loc) · 99 KB
/
cluster_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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
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.
SPDX-License-Identifier: Apache-2.0
*/
package v1
import (
"regexp"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// PrimaryPodDisruptionBudgetSuffix is the suffix appended to the cluster name
// to get the name of the PDB used for the cluster primary
PrimaryPodDisruptionBudgetSuffix = "-primary"
// ReplicationSecretSuffix is the suffix appended to the cluster name to
// get the name of the generated replication secret for PostgreSQL
ReplicationSecretSuffix = "-replication" // #nosec
// SuperUserSecretSuffix is the suffix appended to the cluster name to
// get the name of the PostgreSQL superuser secret
SuperUserSecretSuffix = "-superuser"
// ApplicationUserSecretSuffix is the suffix appended to the cluster name to
// get the name of the application user secret
ApplicationUserSecretSuffix = "-app"
// DefaultServerCaSecretSuffix is the suffix appended to the secret containing
// the generated CA for the cluster
DefaultServerCaSecretSuffix = "-ca"
// ClientCaSecretSuffix is the suffix appended to the secret containing
// the generated CA for the client certificates
ClientCaSecretSuffix = "-ca"
// ServerSecretSuffix is the suffix appended to the secret containing
// the generated server secret for PostgreSQL
ServerSecretSuffix = "-server"
// ServiceAnySuffix is the suffix appended to the cluster name to get the
// service name for every node (including non-ready ones)
ServiceAnySuffix = "-any"
// ServiceReadSuffix is the suffix appended to the cluster name to get the
// service name for every ready node that you can use to read data (including the primary)
ServiceReadSuffix = "-r"
// ServiceReadOnlySuffix is the suffix appended to the cluster name to get the
// service name for every ready node that you can use to read data (excluding the primary)
ServiceReadOnlySuffix = "-ro"
// ServiceReadWriteSuffix is the suffix appended to the cluster name to get
// the se service name for every node that you can use to read and write
// data
ServiceReadWriteSuffix = "-rw"
// ClusterSecretSuffix is the suffix appended to the cluster name to
// get the name of the pull secret
ClusterSecretSuffix = "-pull-secret"
// WalArchiveVolumeSuffix is the suffix appended to the instance name to
// get the name of the PVC dedicated to WAL files.
WalArchiveVolumeSuffix = "-wal"
// TablespaceVolumeInfix is the infix added between the instance name
// and tablespace name to get the name of PVC for a certain tablespace
TablespaceVolumeInfix = "-tbs-"
// StreamingReplicationUser is the name of the user we'll use for
// streaming replication purposes
StreamingReplicationUser = "streaming_replica"
// DefaultPostgresUID is the default UID which is used by PostgreSQL
DefaultPostgresUID = 26
// DefaultPostgresGID is the default GID which is used by PostgreSQL
DefaultPostgresGID = 26
// PodAntiAffinityTypeRequired is the label for required anti-affinity type
PodAntiAffinityTypeRequired = "required"
// PodAntiAffinityTypePreferred is the label for preferred anti-affinity type
PodAntiAffinityTypePreferred = "preferred"
// DefaultPgBouncerPoolerSecretSuffix is the suffix for the default pgbouncer Pooler secret
DefaultPgBouncerPoolerSecretSuffix = "-pooler"
// PendingFailoverMarker is used as target primary to signal that a failover is required
PendingFailoverMarker = "pending"
// PGBouncerPoolerUserName is the name of the role to be used for
PGBouncerPoolerUserName = "cnpg_pooler_pgbouncer"
// MissingWALDiskSpaceExitCode is the exit code the instance manager
// will use to signal that there's no more WAL disk space
MissingWALDiskSpaceExitCode = 4
)
// SnapshotOwnerReference defines the reference type for the owner of the snapshot.
// This specifies which owner the processed resources should relate to.
type SnapshotOwnerReference string
// Constants to represent the allowed types for SnapshotOwnerReference.
const (
// ShapshotOwnerReferenceNone indicates that the snapshot does not have any owner reference.
ShapshotOwnerReferenceNone SnapshotOwnerReference = "none"
// SnapshotOwnerReferenceBackup indicates that the snapshot is owned by the backup resource.
SnapshotOwnerReferenceBackup SnapshotOwnerReference = "backup"
// SnapshotOwnerReferenceCluster indicates that the snapshot is owned by the cluster resource.
SnapshotOwnerReferenceCluster SnapshotOwnerReference = "cluster"
)
// VolumeSnapshotConfiguration represents the configuration for the execution of snapshot backups.
type VolumeSnapshotConfiguration struct {
// Labels are key-value pairs that will be added to .metadata.labels snapshot resources.
// +optional
Labels map[string]string `json:"labels,omitempty"`
// Annotations key-value pairs that will be added to .metadata.annotations snapshot resources.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// ClassName specifies the Snapshot Class to be used for PG_DATA PersistentVolumeClaim.
// It is the default class for the other types if no specific class is present
// +optional
ClassName string `json:"className,omitempty"`
// WalClassName specifies the Snapshot Class to be used for the PG_WAL PersistentVolumeClaim.
// +optional
WalClassName string `json:"walClassName,omitempty"`
// TablespaceClassName specifies the Snapshot Class to be used for the tablespaces.
// defaults to the PGDATA Snapshot Class, if set
// +optional
TablespaceClassName map[string]string `json:"tablespaceClassName,omitempty"`
// SnapshotOwnerReference indicates the type of owner reference the snapshot should have
// +optional
// +kubebuilder:validation:Enum:=none;cluster;backup
// +kubebuilder:default:=none
SnapshotOwnerReference SnapshotOwnerReference `json:"snapshotOwnerReference,omitempty"`
// Whether the default type of backup with volume snapshots is
// online/hot (`true`, default) or offline/cold (`false`)
// +optional
// +kubebuilder:default:=true
Online *bool `json:"online,omitempty"`
// Configuration parameters to control the online/hot backup with volume snapshots
// +kubebuilder:default:={waitForArchive:true,immediateCheckpoint:false}
// +optional
OnlineConfiguration OnlineConfiguration `json:"onlineConfiguration,omitempty"`
}
// OnlineConfiguration contains the configuration parameters for the online volume snapshot
type OnlineConfiguration struct {
// If false, the function will return immediately after the backup is completed,
// without waiting for WAL to be archived.
// This behavior is only useful with backup software that independently monitors WAL archiving.
// Otherwise, WAL required to make the backup consistent might be missing and make the backup useless.
// By default, or when this parameter is true, pg_backup_stop will wait for WAL to be archived when archiving is
// enabled.
// On a standby, this means that it will wait only when archive_mode = always.
// If write activity on the primary is low, it may be useful to run pg_switch_wal on the primary in order to trigger
// an immediate segment switch.
// +kubebuilder:default:=true
// +optional
WaitForArchive *bool `json:"waitForArchive,omitempty"`
// Control whether the I/O workload for the backup initial checkpoint will
// be limited, according to the `checkpoint_completion_target` setting on
// the PostgreSQL server. If set to true, an immediate checkpoint will be
// used, meaning PostgreSQL will complete the checkpoint as soon as
// possible. `false` by default.
// +optional
ImmediateCheckpoint *bool `json:"immediateCheckpoint,omitempty"`
}
// ImageCatalogRef defines the reference to a major version in an ImageCatalog
type ImageCatalogRef struct {
// +kubebuilder:validation:XValidation:rule="self.kind == 'ImageCatalog' || self.kind == 'ClusterImageCatalog'",message="Only image catalogs are supported"
// +kubebuilder:validation:XValidation:rule="self.apiGroup == 'postgresql.cnpg.io'",message="Only image catalogs are supported"
corev1.TypedLocalObjectReference `json:",inline"`
// The major version of PostgreSQL we want to use from the ImageCatalog
Major int `json:"major"`
}
// +kubebuilder:validation:XValidation:rule="!(has(self.imageCatalogRef) && has(self.imageName))",message="imageName and imageCatalogRef are mutually exclusive"
// ClusterSpec defines the desired state of Cluster
type ClusterSpec struct {
// Description of this PostgreSQL cluster
// +optional
Description string `json:"description,omitempty"`
// Metadata that will be inherited by all objects related to the Cluster
// +optional
InheritedMetadata *EmbeddedObjectMetadata `json:"inheritedMetadata,omitempty"`
// Name of the container image, supporting both tags (`<image>:<tag>`)
// and digests for deterministic and repeatable deployments
// (`<image>:<tag>@sha256:<digestValue>`)
// +optional
ImageName string `json:"imageName,omitempty"`
// Defines the major PostgreSQL version we want to use within an ImageCatalog
// +optional
ImageCatalogRef *ImageCatalogRef `json:"imageCatalogRef,omitempty"`
// Image pull policy.
// One of `Always`, `Never` or `IfNotPresent`.
// If not defined, it defaults to `IfNotPresent`.
// Cannot be updated.
// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
// +optional
ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
// If specified, the pod will be dispatched by specified Kubernetes
// scheduler. If not specified, the pod will be dispatched by the default
// scheduler. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/
// +optional
SchedulerName string `json:"schedulerName,omitempty"`
// The UID of the `postgres` user inside the image, defaults to `26`
// +kubebuilder:default:=26
// +optional
PostgresUID int64 `json:"postgresUID,omitempty"`
// The GID of the `postgres` user inside the image, defaults to `26`
// +kubebuilder:default:=26
// +optional
PostgresGID int64 `json:"postgresGID,omitempty"`
// Number of instances required in the cluster
// +kubebuilder:validation:Minimum=1
// +kubebuilder:default:=1
Instances int `json:"instances"`
// Minimum number of instances required in synchronous replication with the
// primary. Undefined or 0 allow writes to complete when no standby is
// available.
// +kubebuilder:default:=0
// +kubebuilder:validation:Minimum=0
// +optional
MinSyncReplicas int `json:"minSyncReplicas,omitempty"`
// The target value for the synchronous replication quorum, that can be
// decreased if the number of ready standbys is lower than this.
// Undefined or 0 disable synchronous replication.
// +kubebuilder:default:=0
// +kubebuilder:validation:Minimum=0
// +optional
MaxSyncReplicas int `json:"maxSyncReplicas,omitempty"`
// Configuration of the PostgreSQL server
// +optional
PostgresConfiguration PostgresConfiguration `json:"postgresql,omitempty"`
// Replication slots management configuration
// +kubebuilder:default:={"highAvailability":{"enabled":true}}
// +optional
ReplicationSlots *ReplicationSlotsConfiguration `json:"replicationSlots,omitempty"`
// Instructions to bootstrap this cluster
// +optional
Bootstrap *BootstrapConfiguration `json:"bootstrap,omitempty"`
// Replica cluster configuration
// +optional
ReplicaCluster *ReplicaClusterConfiguration `json:"replica,omitempty"`
// The secret containing the superuser password. If not defined a new
// secret will be created with a randomly generated password
// +optional
SuperuserSecret *LocalObjectReference `json:"superuserSecret,omitempty"`
// When this option is enabled, the operator will use the `SuperuserSecret`
// to update the `postgres` user password (if the secret is
// not present, the operator will automatically create one). When this
// option is disabled, the operator will ignore the `SuperuserSecret` content, delete
// it when automatically created, and then blank the password of the `postgres`
// user by setting it to `NULL`. Disabled by default.
// +kubebuilder:default:=false
// +optional
EnableSuperuserAccess *bool `json:"enableSuperuserAccess,omitempty"`
// The configuration for the CA and related certificates
// +optional
Certificates *CertificatesConfiguration `json:"certificates,omitempty"`
// The list of pull secrets to be used to pull the images
// +optional
ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"`
// Configuration of the storage of the instances
// +optional
StorageConfiguration StorageConfiguration `json:"storage,omitempty"`
// Configure the generation of the service account
// +optional
ServiceAccountTemplate *ServiceAccountTemplate `json:"serviceAccountTemplate,omitempty"`
// Configuration of the storage for PostgreSQL WAL (Write-Ahead Log)
// +optional
WalStorage *StorageConfiguration `json:"walStorage,omitempty"`
// EphemeralVolumeSource allows the user to configure the source of ephemeral volumes.
// +optional
EphemeralVolumeSource *corev1.EphemeralVolumeSource `json:"ephemeralVolumeSource,omitempty"`
// The time in seconds that is allowed for a PostgreSQL instance to
// successfully start up (default 3600).
// The startup probe failure threshold is derived from this value using the formula:
// ceiling(startDelay / 10).
// +kubebuilder:default:=3600
// +optional
MaxStartDelay int32 `json:"startDelay,omitempty"`
// The time in seconds that is allowed for a PostgreSQL instance to
// gracefully shutdown (default 1800)
// +kubebuilder:default:=1800
// +optional
MaxStopDelay int32 `json:"stopDelay,omitempty"`
// The time in seconds that controls the window of time reserved for the smart shutdown of Postgres to complete.
// Make sure you reserve enough time for the operator to request a fast shutdown of Postgres
// (that is: `stopDelay` - `smartShutdownTimeout`).
// +kubebuilder:default:=180
// +optional
SmartShutdownTimeout *int32 `json:"smartShutdownTimeout,omitempty"`
// The time in seconds that is allowed for a primary PostgreSQL instance
// to gracefully shutdown during a switchover.
// Default value is 3600 seconds (1 hour).
// +kubebuilder:default:=3600
// +optional
MaxSwitchoverDelay int32 `json:"switchoverDelay,omitempty"`
// The amount of time (in seconds) to wait before triggering a failover
// after the primary PostgreSQL instance in the cluster was detected
// to be unhealthy
// +kubebuilder:default:=0
// +optional
FailoverDelay int32 `json:"failoverDelay,omitempty"`
// LivenessProbeTimeout is the time (in seconds) that is allowed for a PostgreSQL instance
// to successfully respond to the liveness probe (default 30).
// The Liveness probe failure threshold is derived from this value using the formula:
// ceiling(livenessProbe / 10).
// +optional
LivenessProbeTimeout *int32 `json:"livenessProbeTimeout,omitempty"`
// Affinity/Anti-affinity rules for Pods
// +optional
Affinity AffinityConfiguration `json:"affinity,omitempty"`
// TopologySpreadConstraints specifies how to spread matching pods among the given topology.
// More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/
// +optional
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
// Resources requirements of every generated Pod. Please refer to
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
// for more information.
// +optional
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
// EphemeralVolumesSizeLimit allows the user to set the limits for the ephemeral
// volumes
// +optional
EphemeralVolumesSizeLimit *EphemeralVolumesSizeLimitConfiguration `json:"ephemeralVolumesSizeLimit,omitempty"`
// Name of the priority class which will be used in every generated Pod, if the PriorityClass
// specified does not exist, the pod will not be able to schedule. Please refer to
// https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass
// for more information
// +optional
PriorityClassName string `json:"priorityClassName,omitempty"`
// Deployment strategy to follow to upgrade the primary server during a rolling
// update procedure, after all replicas have been successfully updated:
// it can be automated (`unsupervised` - default) or manual (`supervised`)
// +kubebuilder:default:=unsupervised
// +kubebuilder:validation:Enum:=unsupervised;supervised
// +optional
PrimaryUpdateStrategy PrimaryUpdateStrategy `json:"primaryUpdateStrategy,omitempty"`
// Method to follow to upgrade the primary server during a rolling
// update procedure, after all replicas have been successfully updated:
// it can be with a switchover (`switchover`) or in-place (`restart` - default)
// +kubebuilder:default:=restart
// +kubebuilder:validation:Enum:=switchover;restart
// +optional
PrimaryUpdateMethod PrimaryUpdateMethod `json:"primaryUpdateMethod,omitempty"`
// The configuration to be used for backups
// +optional
Backup *BackupConfiguration `json:"backup,omitempty"`
// Define a maintenance window for the Kubernetes nodes
// +optional
NodeMaintenanceWindow *NodeMaintenanceWindow `json:"nodeMaintenanceWindow,omitempty"`
// The configuration of the monitoring infrastructure of this cluster
// +optional
Monitoring *MonitoringConfiguration `json:"monitoring,omitempty"`
// The list of external clusters which are used in the configuration
// +optional
ExternalClusters []ExternalCluster `json:"externalClusters,omitempty"`
// The instances' log level, one of the following values: error, warning, info (default), debug, trace
// +kubebuilder:default:=info
// +kubebuilder:validation:Enum:=error;warning;info;debug;trace
// +optional
LogLevel string `json:"logLevel,omitempty"`
// Template to be used to define projected volumes, projected volumes will be mounted
// under `/projected` base folder
// +optional
ProjectedVolumeTemplate *corev1.ProjectedVolumeSource `json:"projectedVolumeTemplate,omitempty"`
// Env follows the Env format to pass environment variables
// to the pods created in the cluster
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
Env []corev1.EnvVar `json:"env,omitempty"`
// EnvFrom follows the EnvFrom format to pass environment variables
// sources to the pods to be used by Env
// +optional
EnvFrom []corev1.EnvFromSource `json:"envFrom,omitempty"`
// The configuration that is used by the portions of PostgreSQL that are managed by the instance manager
// +optional
Managed *ManagedConfiguration `json:"managed,omitempty"`
// The SeccompProfile applied to every Pod and Container.
// Defaults to: `RuntimeDefault`
// +optional
SeccompProfile *corev1.SeccompProfile `json:"seccompProfile,omitempty"`
// The tablespaces configuration
// +optional
Tablespaces []TablespaceConfiguration `json:"tablespaces,omitempty"`
// Manage the `PodDisruptionBudget` resources within the cluster. When
// configured as `true` (default setting), the pod disruption budgets
// will safeguard the primary node from being terminated. Conversely,
// setting it to `false` will result in the absence of any
// `PodDisruptionBudget` resource, permitting the shutdown of all nodes
// hosting the PostgreSQL cluster. This latter configuration is
// advisable for any PostgreSQL cluster employed for
// development/staging purposes.
// +kubebuilder:default:=true
// +optional
EnablePDB *bool `json:"enablePDB,omitempty"`
// The plugins configuration, containing
// any plugin to be loaded with the corresponding configuration
// +optional
Plugins []PluginConfiguration `json:"plugins,omitempty"`
// The configuration of the probes to be injected
// in the PostgreSQL Pods.
// +optional
Probes *ProbesConfiguration `json:"probes,omitempty"`
}
// ProbesConfiguration represent the configuration for the probes
// to be injected in the PostgreSQL Pods
type ProbesConfiguration struct {
// The startup probe configuration
Startup *ProbeWithStrategy `json:"startup,omitempty"`
// The liveness probe configuration
Liveness *Probe `json:"liveness,omitempty"`
// The readiness probe configuration
Readiness *ProbeWithStrategy `json:"readiness,omitempty"`
}
// ProbeWithStrategy is the configuration of the startup probe
type ProbeWithStrategy struct {
// Probe is the standard probe configuration
Probe `json:",inline"`
// The probe strategy
// +kubebuilder:validation:Enum=pg_isready;streaming;query
// +optional
Type ProbeStrategyType `json:"type,omitempty"`
// Lag limit. Used only for `streaming` strategy
// +optional
MaximumLag *resource.Quantity `json:"maximumLag,omitempty"`
}
// ProbeStrategyType is the type of the strategy used to declare a PostgreSQL instance
// ready
type ProbeStrategyType string
const (
// ProbeStrategyPgIsReady means that the pg_isready tool is used to determine
// whether PostgreSQL is started up
ProbeStrategyPgIsReady ProbeStrategyType = "pg_isready"
// ProbeStrategyStreaming means that pg_isready is positive and the replica is
// connected via streaming replication to the current primary and the lag is, if specified,
// within the limit.
ProbeStrategyStreaming ProbeStrategyType = "streaming"
// ProbeStrategyQuery means that the server is able to connect to the superuser database
// and able to execute a simple query like "-- ping"
ProbeStrategyQuery ProbeStrategyType = "query"
)
// Probe describes a health check to be performed against a container to determine whether it is
// alive or ready to receive traffic.
type Probe struct {
// Number of seconds after the container has started before liveness probes are initiated.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty"`
// Number of seconds after which the probe times out.
// Defaults to 1 second. Minimum value is 1.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"`
// How often (in seconds) to perform the probe.
// Default to 10 seconds. Minimum value is 1.
// +optional
PeriodSeconds int32 `json:"periodSeconds,omitempty"`
// Minimum consecutive successes for the probe to be considered successful after having failed.
// Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
// +optional
SuccessThreshold int32 `json:"successThreshold,omitempty"`
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
// Defaults to 3. Minimum value is 1.
// +optional
FailureThreshold int32 `json:"failureThreshold,omitempty"`
// Optional duration in seconds the pod needs to terminate gracefully upon probe failure.
// The grace period is the duration in seconds after the processes running in the pod are sent
// a termination signal and the time when the processes are forcibly halted with a kill signal.
// Set this value longer than the expected cleanup time for your process.
// If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this
// value overrides the value provided by the pod spec.
// Value must be non-negative integer. The value zero indicates stop immediately via
// the kill signal (no opportunity to shut down).
// This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.
// Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.
// +optional
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
}
const (
// PhaseSwitchover when a cluster is changing the primary node
PhaseSwitchover = "Switchover in progress"
// PhaseFailOver in case a pod is missing and need to change primary
PhaseFailOver = "Failing over"
// PhaseFirstPrimary for an starting cluster
PhaseFirstPrimary = "Setting up primary"
// PhaseCreatingReplica everytime we add a new replica
PhaseCreatingReplica = "Creating a new replica"
// PhaseUpgrade upgrade in process
PhaseUpgrade = "Upgrading cluster"
// PhaseMajorUpgrade major version upgrade in process
PhaseMajorUpgrade = "Upgrading Postgres major version"
// PhaseUpgradeDelayed is set when a cluster needs to be upgraded,
// but the operation is being delayed by the operator configuration
PhaseUpgradeDelayed = "Cluster upgrade delayed"
// PhaseWaitingForUser set the status to wait for an action from the user
PhaseWaitingForUser = "Waiting for user action"
// PhaseInplacePrimaryRestart for a cluster restarting the primary instance in-place
PhaseInplacePrimaryRestart = "Primary instance is being restarted in-place"
// PhaseInplaceDeletePrimaryRestart for a cluster restarting the primary instance without a switchover
PhaseInplaceDeletePrimaryRestart = "Primary instance is being restarted without a switchover"
// PhaseHealthy for a cluster doing nothing
PhaseHealthy = "Cluster in healthy state"
// PhaseUnknownPlugin is triggered when the required CNPG-i plugin have not been
// loaded still
PhaseUnknownPlugin = "Cluster cannot proceed to reconciliation due to an unknown plugin being required"
// PhaseImageCatalogError is triggered when the cluster cannot select the image to
// apply because of an invalid or incomplete catalog
PhaseImageCatalogError = "Cluster has incomplete or invalid image catalog"
// PhaseUnrecoverable for an unrecoverable cluster
PhaseUnrecoverable = "Cluster is unrecoverable and needs manual intervention"
// PhaseArchitectureBinaryMissing is the error phase describing a missing architecture
PhaseArchitectureBinaryMissing = "Cluster cannot execute instance online upgrade due to missing architecture binary"
// PhaseWaitingForInstancesToBeActive is a waiting phase that is triggered when an instance pod is not active
PhaseWaitingForInstancesToBeActive = "Waiting for the instances to become active"
// PhaseOnlineUpgrading for when the instance manager is being upgraded in place
PhaseOnlineUpgrading = "Online upgrade in progress"
// PhaseApplyingConfiguration is set by the instance manager when a configuration
// change is being detected
PhaseApplyingConfiguration = "Applying configuration"
// PhaseReplicaClusterPromotion is the phase
PhaseReplicaClusterPromotion = "Promoting to primary cluster"
// PhaseCannotCreateClusterObjects is set by the operator when is unable to create cluster resources
PhaseCannotCreateClusterObjects = "Unable to create required cluster objects"
)
// EphemeralVolumesSizeLimitConfiguration contains the configuration of the ephemeral
// storage
type EphemeralVolumesSizeLimitConfiguration struct {
// Shm is the size limit of the shared memory volume
// +optional
Shm *resource.Quantity `json:"shm,omitempty"`
// TemporaryData is the size limit of the temporary data volume
// +optional
TemporaryData *resource.Quantity `json:"temporaryData,omitempty"`
}
// ServiceAccountTemplate contains the template needed to generate the service accounts
type ServiceAccountTemplate struct {
// Metadata are the metadata to be used for the generated
// service account
Metadata Metadata `json:"metadata"`
}
// PodTopologyLabels represent the topology of a Pod. map[labelName]labelValue
type PodTopologyLabels map[string]string
// PodName is the name of a Pod
type PodName string
// Topology contains the cluster topology
type Topology struct {
// Instances contains the pod topology of the instances
// +optional
Instances map[PodName]PodTopologyLabels `json:"instances,omitempty"`
// NodesUsed represents the count of distinct nodes accommodating the instances.
// A value of '1' suggests that all instances are hosted on a single node,
// implying the absence of High Availability (HA). Ideally, this value should
// be the same as the number of instances in the Postgres HA cluster, implying
// shared nothing architecture on the compute side.
// +optional
NodesUsed int32 `json:"nodesUsed,omitempty"`
// SuccessfullyExtracted indicates if the topology data was extract. It is useful to enact fallback behaviors
// in synchronous replica election in case of failures
// +optional
SuccessfullyExtracted bool `json:"successfullyExtracted,omitempty"`
}
// RoleStatus represents the status of a managed role in the cluster
type RoleStatus string
const (
// RoleStatusReconciled indicates the role in DB matches the Spec
RoleStatusReconciled RoleStatus = "reconciled"
// RoleStatusNotManaged indicates the role is not in the Spec, therefore not managed
RoleStatusNotManaged RoleStatus = "not-managed"
// RoleStatusPendingReconciliation indicates the role in Spec requires updated/creation in DB
RoleStatusPendingReconciliation RoleStatus = "pending-reconciliation"
// RoleStatusReserved indicates this is one of the roles reserved by the operator. E.g. `postgres`
RoleStatusReserved RoleStatus = "reserved"
)
// PasswordState represents the state of the password of a managed RoleConfiguration
type PasswordState struct {
// the last transaction ID to affect the role definition in PostgreSQL
// +optional
TransactionID int64 `json:"transactionID,omitempty"`
// the resource version of the password secret
// +optional
SecretResourceVersion string `json:"resourceVersion,omitempty"`
}
// ManagedRoles tracks the status of a cluster's managed roles
type ManagedRoles struct {
// ByStatus gives the list of roles in each state
// +optional
ByStatus map[RoleStatus][]string `json:"byStatus,omitempty"`
// CannotReconcile lists roles that cannot be reconciled in PostgreSQL,
// with an explanation of the cause
// +optional
CannotReconcile map[string][]string `json:"cannotReconcile,omitempty"`
// PasswordStatus gives the last transaction id and password secret version for each managed role
// +optional
PasswordStatus map[string]PasswordState `json:"passwordStatus,omitempty"`
}
// TablespaceState represents the state of a tablespace in a cluster
type TablespaceState struct {
// Name is the name of the tablespace
Name string `json:"name"`
// Owner is the PostgreSQL user owning the tablespace
// +optional
Owner string `json:"owner,omitempty"`
// State is the latest reconciliation state
State TablespaceStatus `json:"state"`
// Error is the reconciliation error, if any
// +optional
Error string `json:"error,omitempty"`
}
// TablespaceStatus represents the status of a tablespace in the cluster
type TablespaceStatus string
const (
// TablespaceStatusReconciled indicates the tablespace in DB matches the Spec
TablespaceStatusReconciled TablespaceStatus = "reconciled"
// TablespaceStatusPendingReconciliation indicates the tablespace in Spec requires creation in the DB
TablespaceStatusPendingReconciliation TablespaceStatus = "pending"
)
// AvailableArchitecture represents the state of a cluster's architecture
type AvailableArchitecture struct {
// GoArch is the name of the executable architecture
GoArch string `json:"goArch"`
// Hash is the hash of the executable
Hash string `json:"hash"`
}
// ClusterStatus defines the observed state of Cluster
type ClusterStatus struct {
// The total number of PVC Groups detected in the cluster. It may differ from the number of existing instance pods.
// +optional
Instances int `json:"instances,omitempty"`
// The total number of ready instances in the cluster. It is equal to the number of ready instance pods.
// +optional
ReadyInstances int `json:"readyInstances,omitempty"`
// InstancesStatus indicates in which status the instances are
// +optional
InstancesStatus map[PodStatus][]string `json:"instancesStatus,omitempty"`
// The reported state of the instances during the last reconciliation loop
// +optional
InstancesReportedState map[PodName]InstanceReportedState `json:"instancesReportedState,omitempty"`
// ManagedRolesStatus reports the state of the managed roles in the cluster
// +optional
ManagedRolesStatus ManagedRoles `json:"managedRolesStatus,omitempty"`
// TablespacesStatus reports the state of the declarative tablespaces in the cluster
// +optional
TablespacesStatus []TablespaceState `json:"tablespacesStatus,omitempty"`
// The timeline of the Postgres cluster
// +optional
TimelineID int `json:"timelineID,omitempty"`
// Instances topology.
// +optional
Topology Topology `json:"topology,omitempty"`
// ID of the latest generated node (used to avoid node name clashing)
// +optional
LatestGeneratedNode int `json:"latestGeneratedNode,omitempty"`
// Current primary instance
// +optional
CurrentPrimary string `json:"currentPrimary,omitempty"`
// Target primary instance, this is different from the previous one
// during a switchover or a failover
// +optional
TargetPrimary string `json:"targetPrimary,omitempty"`
// LastPromotionToken is the last verified promotion token that
// was used to promote a replica cluster
// +optional
LastPromotionToken string `json:"lastPromotionToken,omitempty"`
// How many PVCs have been created by this cluster
// +optional
PVCCount int32 `json:"pvcCount,omitempty"`
// How many Jobs have been created by this cluster
// +optional
JobCount int32 `json:"jobCount,omitempty"`
// List of all the PVCs created by this cluster and still available
// which are not attached to a Pod
// +optional
DanglingPVC []string `json:"danglingPVC,omitempty"`
// List of all the PVCs that have ResizingPVC condition.
// +optional
ResizingPVC []string `json:"resizingPVC,omitempty"`
// List of all the PVCs that are being initialized by this cluster
// +optional
InitializingPVC []string `json:"initializingPVC,omitempty"`
// List of all the PVCs not dangling nor initializing
// +optional
HealthyPVC []string `json:"healthyPVC,omitempty"`
// List of all the PVCs that are unusable because another PVC is missing
// +optional
UnusablePVC []string `json:"unusablePVC,omitempty"`
// Current write pod
// +optional
WriteService string `json:"writeService,omitempty"`
// Current list of read pods
// +optional
ReadService string `json:"readService,omitempty"`
// Current phase of the cluster
// +optional
Phase string `json:"phase,omitempty"`
// Reason for the current phase
// +optional
PhaseReason string `json:"phaseReason,omitempty"`
// The list of resource versions of the secrets
// managed by the operator. Every change here is done in the
// interest of the instance manager, which will refresh the
// secret data
// +optional
SecretsResourceVersion SecretsResourceVersion `json:"secretsResourceVersion,omitempty"`
// The list of resource versions of the configmaps,
// managed by the operator. Every change here is done in the
// interest of the instance manager, which will refresh the
// configmap data
// +optional
ConfigMapResourceVersion ConfigMapResourceVersion `json:"configMapResourceVersion,omitempty"`
// The configuration for the CA and related certificates, initialized with defaults.
// +optional
Certificates CertificatesStatus `json:"certificates,omitempty"`
// The first recoverability point, stored as a date in RFC3339 format.
// This field is calculated from the content of FirstRecoverabilityPointByMethod
// +optional
FirstRecoverabilityPoint string `json:"firstRecoverabilityPoint,omitempty"`
// The first recoverability point, stored as a date in RFC3339 format, per backup method type
// +optional
FirstRecoverabilityPointByMethod map[BackupMethod]metav1.Time `json:"firstRecoverabilityPointByMethod,omitempty"`
// Last successful backup, stored as a date in RFC3339 format
// This field is calculated from the content of LastSuccessfulBackupByMethod
// +optional
LastSuccessfulBackup string `json:"lastSuccessfulBackup,omitempty"`
// Last successful backup, stored as a date in RFC3339 format, per backup method type
// +optional
LastSuccessfulBackupByMethod map[BackupMethod]metav1.Time `json:"lastSuccessfulBackupByMethod,omitempty"`
// Stored as a date in RFC3339 format
// +optional
LastFailedBackup string `json:"lastFailedBackup,omitempty"`
// The commit hash number of which this operator running
// +optional
CommitHash string `json:"cloudNativePGCommitHash,omitempty"`
// The timestamp when the last actual promotion to primary has occurred
// +optional
CurrentPrimaryTimestamp string `json:"currentPrimaryTimestamp,omitempty"`
// The timestamp when the primary was detected to be unhealthy
// This field is reported when `.spec.failoverDelay` is populated or during online upgrades
// +optional
CurrentPrimaryFailingSinceTimestamp string `json:"currentPrimaryFailingSinceTimestamp,omitempty"`
// The timestamp when the last request for a new primary has occurred
// +optional
TargetPrimaryTimestamp string `json:"targetPrimaryTimestamp,omitempty"`
// The integration needed by poolers referencing the cluster
// +optional
PoolerIntegrations *PoolerIntegrations `json:"poolerIntegrations,omitempty"`
// The hash of the binary of the operator
// +optional
OperatorHash string `json:"cloudNativePGOperatorHash,omitempty"`
// AvailableArchitectures reports the available architectures of a cluster
// +optional
AvailableArchitectures []AvailableArchitecture `json:"availableArchitectures,omitempty"`
// Conditions for cluster object
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
// List of instance names in the cluster
// +optional
InstanceNames []string `json:"instanceNames,omitempty"`
// OnlineUpdateEnabled shows if the online upgrade is enabled inside the cluster
// +optional
OnlineUpdateEnabled bool `json:"onlineUpdateEnabled,omitempty"`
// Image contains the image name used by the pods
// +optional
Image string `json:"image,omitempty"`
// MajorVersionUpgradeFromImage contains the image that was
// running before the major version upgrade started.
// +optional
MajorVersionUpgradeFromImage *string `json:"majorVersionUpgradeFromImage,omitempty"`
// PluginStatus is the status of the loaded plugins
// +optional
PluginStatus []PluginStatus `json:"pluginStatus,omitempty"`
// SwitchReplicaClusterStatus is the status of the switch to replica cluster
// +optional
SwitchReplicaClusterStatus SwitchReplicaClusterStatus `json:"switchReplicaClusterStatus,omitempty"`
// DemotionToken is a JSON token containing the information
// from pg_controldata such as Database system identifier, Latest checkpoint's
// TimeLineID, Latest checkpoint's REDO location, Latest checkpoint's REDO
// WAL file, and Time of latest checkpoint
// +optional
DemotionToken string `json:"demotionToken,omitempty"`
}
// SwitchReplicaClusterStatus contains all the statuses regarding the switch of a cluster to a replica cluster
type SwitchReplicaClusterStatus struct {
// InProgress indicates if there is an ongoing procedure of switching a cluster to a replica cluster.
// +optional
InProgress bool `json:"inProgress,omitempty"`
}
// InstanceReportedState describes the last reported state of an instance during a reconciliation loop
type InstanceReportedState struct {
// indicates if an instance is the primary one
IsPrimary bool `json:"isPrimary"`
// indicates on which TimelineId the instance is
// +optional
TimeLineID int `json:"timeLineID,omitempty"`
}
// ClusterConditionType defines types of cluster conditions
type ClusterConditionType string
// These are valid conditions of a Cluster, some of the conditions could be owned by
// Instance Manager and some of them could be owned by reconciler.
const (
// ConditionContinuousArchiving represents whether WAL archiving is working
ConditionContinuousArchiving ClusterConditionType = "ContinuousArchiving"
// ConditionBackup represents the last backup's status
ConditionBackup ClusterConditionType = "LastBackupSucceeded"
// ConditionClusterReady represents whether a cluster is Ready
ConditionClusterReady ClusterConditionType = "Ready"
)
// ConditionStatus defines conditions of resources
type ConditionStatus string
// These are valid condition statuses. "ConditionTrue" means a resource is in the condition;
// "ConditionFalse" means a resource is not in the condition; "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded