Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion api/v4/postgrescluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type ManagedRole struct {
// Validation rules ensure immutability of Class, and that Storage and PostgresVersion can only be set once and cannot be removed or downgraded.
// +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 + ')'"
// +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) + ')'"
// +kubebuilder:validation:XValidation:rule="!self.connectionPoolerEnabled || self.connectionPoolerConfig != null || (self.cnpg != null && self.cnpg.connectionPooler != null)",message="connectionPoolerConfig must be set in cluster spec or class when connectionPoolerEnabled is true"
// +kubebuilder:validation:XValidation:rule="!self.connectionPoolerEnabled || self.connectionPoolerConfig != null",message="connectionPoolerConfig must be set when connectionPoolerEnabled is true"
type PostgresClusterSpec struct {
// This field is IMMUTABLE after creation.
// +kubebuilder:validation:Required
Expand Down Expand Up @@ -111,6 +111,19 @@ type PostgresClusterSpec struct {
ManagedRoles []ManagedRole `json:"managedRoles,omitempty"`
}

// PostgresClusterResources defines references to Kubernetes resources related to the PostgresCluster, such as ConfigMaps and Secrets.
type PostgresClusterResources struct {
// ConfigMapRef references the ConfigMap with connection endpoints.
// Contains: CLUSTER_ENDPOINTS, POOLER_ENDPOINTS (if connection pooler enabled)
// +optional
ConfigMapRef *corev1.LocalObjectReference `json:"configMapRef,omitempty"`

// SecretRef references the Secret with superuser credentials.
// Contains: passwords for superuser
// +optional
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
}

// PostgresClusterStatus defines the observed state of PostgresCluster.
type PostgresClusterStatus struct {
// Phase represents the current phase of the PostgresCluster.
Expand All @@ -135,6 +148,10 @@ type PostgresClusterStatus struct {
// ManagedRolesStatus tracks the reconciliation status of managed roles.
// +optional
ManagedRolesStatus *ManagedRolesStatus `json:"managedRolesStatus,omitempty"`

// Resources contains references to related Kubernetes resources like ConfigMaps and Secrets.
// +optional
Resources *PostgresClusterResources `json:"resources,omitempty"`
}

// ManagedRolesStatus tracks the state of managed PostgreSQL roles.
Expand Down
1 change: 0 additions & 1 deletion api/v4/postgresclusterclass_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ const (

// ConnectionPoolerConfig defines PgBouncer connection pooler configuration.
// When enabled, creates RW and RO pooler deployments for clusters using this class.
// +kubebuilder:validation:XValidation:rule="!self.connectionPoolerEnabled || self.connectionPoolerConfig != null || (self.cnpg != null && self.cnpg.connectionPooler != null)",message="connectionPoolerConfig must be set in cluster spec or class when connectionPoolerEnabled is true"
type ConnectionPoolerConfig struct {
// Instances is the number of PgBouncer pod replicas.
// Higher values provide better availability and load distribution.
Expand Down
84 changes: 82 additions & 2 deletions config/crd/bases/enterprise.splunk.com_postgresclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,37 @@ spec:
x-kubernetes-validations:
- message: class is immutable
rule: self == oldSelf
connectionPoolerConfig:
description: |-
ConnectionPoolerConfig overrides the connection pooler configuration from the class.
Only takes effect when connection pooling is enabled.
properties:
config:
additionalProperties:
type: string
description: |-
Config contains PgBouncer configuration parameters.
Passed directly to CNPG Pooler spec.pgbouncer.parameters.
See: https://cloudnative-pg.io/docs/1.28/connection_pooling/#pgbouncer-configuration-options
type: object
instances:
default: 3
description: |-
Instances is the number of PgBouncer pod replicas.
Higher values provide better availability and load distribution.
format: int32
maximum: 10
minimum: 1
type: integer
mode:
default: transaction
description: Mode defines the connection pooling strategy.
enum:
- session
- transaction
- statement
type: string
type: object
connectionPoolerEnabled:
default: false
description: |-
Expand Down Expand Up @@ -128,7 +159,6 @@ spec:
type: string
type: array
postgresVersion:
default: "18"
description: |-
PostgresVersion is the PostgreSQL version (major or major.minor).
Examples: "18" (latest 18.x), "18.1" (specific minor), "17", "16"
Expand Down Expand Up @@ -216,9 +246,22 @@ spec:
- class
type: object
x-kubernetes-validations:
- message: Storage size cannot be removed and can only be increased
- 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 + '')'''
rule: '!has(oldSelf.postgresVersion) || (has(self.postgresVersion) &&
int(self.postgresVersion.split(''.'')[0]) >= int(oldSelf.postgresVersion.split(''.'')[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) + '')'''
rule: '!has(oldSelf.storage) || (has(self.storage) && quantity(self.storage).compareTo(quantity(oldSelf.storage))
>= 0)'
- message: connectionPoolerConfig must be set when connectionPoolerEnabled
is true
rule: '!self.connectionPoolerEnabled || self.connectionPoolerConfig
!= null'
status:
description: PostgresClusterStatus defines the observed state of PostgresCluster.
properties:
Expand Down Expand Up @@ -363,6 +406,43 @@ spec:
type: string
type: object
x-kubernetes-map-type: atomic
resources:
description: Resources contains references to related Kubernetes resources
like ConfigMaps and Secrets.
properties:
configMapRef:
description: |-
ConfigMapRef references the ConfigMap with connection endpoints.
Contains: CLUSTER_ENDPOINTS, POOLER_ENDPOINTS (if connection pooler enabled)
properties:
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
type: object
x-kubernetes-map-type: atomic
secretRef:
description: |-
SecretRef references the Secret with superuser credentials.
Contains: passwords for superuser
properties:
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
type: object
x-kubernetes-map-type: atomic
type: object
type: object
type: object
served: true
Expand Down
2 changes: 2 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ rules:
resources:
- clusters
- databases
- poolers
verbs:
- create
- delete
Expand All @@ -122,5 +123,6 @@ rules:
- postgresql.cnpg.io
resources:
- clusters/status
- poolers/status
verbs:
- get
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/onsi/gomega v1.39.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.23.2
github.com/sethvargo/go-password v0.3.1
github.com/stretchr/testify v1.11.1
github.com/wk8/go-ordered-map/v2 v2.1.7
go.uber.org/zap v1.27.1
Expand All @@ -31,6 +32,7 @@ require (
k8s.io/apimachinery v0.34.2
k8s.io/client-go v0.34.2
k8s.io/kubectl v0.26.2
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
sigs.k8s.io/controller-runtime v0.22.4
)

Expand Down Expand Up @@ -183,7 +185,6 @@ require (
k8s.io/component-base v0.34.2 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250905212525-66792eed8611 // indirect
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
Expand Down
Loading
Loading