Skip to content

Commit f40768c

Browse files
committed
Add finalizer support to PostgresCluster controller
1 parent b1e8392 commit f40768c

8 files changed

Lines changed: 249 additions & 68 deletions

api/v4/postgrescluster_types.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type ManagedRole struct {
4545
// Validation rules ensure immutability of Class, and that Storage and PostgresVersion can only be set once and cannot be removed or downgraded.
4646
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.postgresVersion) || (has(self.postgresVersion) && int(self.postgresVersion.split('.')[0]) >= int(oldSelf.postgresVersion.split('.')[0]))",messageExpression="!has(self.postgresVersion) ? 'postgresVersion cannot be removed once set (was: ' + oldSelf.postgresVersion + ')' : 'postgresVersion major version cannot be downgraded (from: ' + oldSelf.postgresVersion + ', to: ' + self.postgresVersion + ')'"
4747
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.storage) || (has(self.storage) && quantity(self.storage).compareTo(quantity(oldSelf.storage)) >= 0)",messageExpression="!has(self.storage) ? 'storage cannot be removed once set (was: ' + string(oldSelf.storage) + ')' : 'storage size cannot be decreased (from: ' + string(oldSelf.storage) + ', to: ' + string(self.storage) + ')'"
48-
// +kubebuilder:validation:XValidation:rule="!has(self.connectionPoolerEnabled) || !self.connectionPoolerEnabled || has(self.connectionPoolerConfig)",message="connectionPoolerConfig must be set when connectionPoolerEnabled is true"
48+
// +kubebuilder:validation:XValidation:rule="!has(self.connectionPoolerConfig)",message="connectionPoolerConfig cannot be overridden on PostgresCluster"
4949
type PostgresClusterSpec struct {
5050
// This field is IMMUTABLE after creation.
5151
// +kubebuilder:validation:Required
@@ -97,7 +97,6 @@ type PostgresClusterSpec struct {
9797
// +optional
9898
ConnectionPoolerEnabled *bool `json:"connectionPoolerEnabled,omitempty"`
9999

100-
// ConnectionPoolerConfig overrides the connection pooler configuration from the class.
101100
// Only takes effect when connection pooling is enabled.
102101
// +optional
103102
ConnectionPoolerConfig *ConnectionPoolerConfig `json:"connectionPoolerConfig,omitempty"`
@@ -109,6 +108,12 @@ type PostgresClusterSpec struct {
109108
// +listType=map
110109
// +listMapKey=name
111110
ManagedRoles []ManagedRole `json:"managedRoles,omitempty"`
111+
112+
// ClusterDeletionPolicy controls the deletion behavior of the underlying CNPG Cluster when the PostgresCluster is deleted.
113+
// +kubebuilder:validation:Enum=Delete;Retain
114+
// +kubebuilder:default=Retain
115+
// +optional
116+
ClusterDeletionPolicy string `json:"clusterDeletionPolicy,omitempty"`
112117
}
113118

114119
// PostgresClusterResources defines references to Kubernetes resources related to the PostgresCluster, such as ConfigMaps and Secrets.

api/v4/postgresclusterclass_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2323
)
2424

25+
// +kubebuilder:validation:XValidation:rule="!has(self.config) || !has(self.config.connectionPoolerEnabled) || !self.config.connectionPoolerEnabled || (has(self.cnpg) && has(self.cnpg.connectionPooler))",message="cnpg.connectionPooler must be set when config.connectionPoolerEnabled is true"
2526
// PostgresClusterClassSpec defines the desired state of PostgresClusterClass.
2627
// PostgresClusterClass is immutable after creation - it serves as a template for Cluster CRs.
2728
type PostgresClusterClassSpec struct {

config/crd/bases/enterprise.splunk.com_postgresclusterclasses.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ spec:
244244
required:
245245
- provisioner
246246
type: object
247+
x-kubernetes-validations:
248+
- message: cnpg.connectionPooler must be set when config.connectionPoolerEnabled
249+
is true
250+
rule: '!has(self.config) || !has(self.config.connectionPoolerEnabled)
251+
|| !self.config.connectionPoolerEnabled || (has(self.cnpg) && has(self.cnpg.connectionPooler))'
247252
status:
248253
description: PostgresClusterClassStatus defines the observed state of
249254
PostgresClusterClass.

config/crd/bases/enterprise.splunk.com_postgresclusters.yaml

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,65 @@ spec:
5858
x-kubernetes-validations:
5959
- message: class is immutable
6060
rule: self == oldSelf
61+
cnpg:
62+
description: CNPG contains the resolved CloudNativePG-specific configuration,
63+
merged from the class.
64+
properties:
65+
connectionPooler:
66+
description: |-
67+
ConnectionPooler contains PgBouncer connection pooler configuration.
68+
When enabled, creates RW and RO pooler deployments for clusters using this class.
69+
properties:
70+
config:
71+
additionalProperties:
72+
type: string
73+
description: |-
74+
Config contains PgBouncer configuration parameters.
75+
Passed directly to CNPG Pooler spec.pgbouncer.parameters.
76+
See: https://cloudnative-pg.io/docs/1.28/connection_pooling/#pgbouncer-configuration-options
77+
type: object
78+
instances:
79+
default: 3
80+
description: |-
81+
Instances is the number of PgBouncer pod replicas.
82+
Higher values provide better availability and load distribution.
83+
format: int32
84+
maximum: 10
85+
minimum: 1
86+
type: integer
87+
mode:
88+
default: transaction
89+
description: Mode defines the connection pooling strategy.
90+
enum:
91+
- session
92+
- transaction
93+
- statement
94+
type: string
95+
type: object
96+
primaryUpdateMethod:
97+
default: switchover
98+
description: |-
99+
PrimaryUpdateMethod determines how the primary instance is updated.
100+
"restart" - tolerate brief downtime (suitable for development)
101+
"switchover" - minimal downtime via automated failover (production-grade)
102+
103+
NOTE: When using "switchover", ensure clusterConfig.instances > 1.
104+
Switchover requires at least one replica to fail over to.
105+
enum:
106+
- restart
107+
- switchover
108+
type: string
109+
type: object
110+
cnpgDeletionPolicy:
111+
default: Retain
112+
description: CNPGDeletionPolicy controls the deletion behavior of
113+
the underlying CNPG Cluster when the PostgresCluster is deleted.
114+
enum:
115+
- Delete
116+
- Retain
117+
type: string
61118
connectionPoolerConfig:
62-
description: |-
63-
ConnectionPoolerConfig overrides the connection pooler configuration from the class.
64-
Only takes effect when connection pooling is enabled.
119+
description: Only takes effect when connection pooling is enabled.
65120
properties:
66121
config:
67122
additionalProperties:
@@ -258,10 +313,8 @@ spec:
258313
'' + string(self.storage) + '')'''
259314
rule: '!has(oldSelf.storage) || (has(self.storage) && quantity(self.storage).compareTo(quantity(oldSelf.storage))
260315
>= 0)'
261-
- message: connectionPoolerConfig must be set when connectionPoolerEnabled
262-
is true
263-
rule: '!self.connectionPoolerEnabled || self.connectionPoolerConfig
264-
!= null'
316+
- message: connectionPoolerConfig cannot be overridden on PostgresCluster
317+
rule: '!has(self.connectionPoolerConfig)'
265318
status:
266319
description: PostgresClusterStatus defines the observed state of PostgresCluster.
267320
properties:

config/samples/enterprise_v4_postgrescluster_override.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ metadata:
1111
spec:
1212
# Reference the ClusterClass to inherit defaults - this is required, immutable, and must match the name of an existing ClusterClass
1313
class: postgresql-dev
14+
# ClusterDeletionPolicy is set to "Retain" to keep the underlying CNPG Cluster when this PostgresCluster is deleted
15+
clusterDeletionPolicy: Delete
1416
instances: 2
1517
# Storage and PostgreSQL version are overridden from the ClusterClass defaults. Validation rules on the PostgresCluster resource will prevent removing these fields or setting them to lower values than the original overrides.
1618
storage: 1Gi

0 commit comments

Comments
 (0)