Skip to content
Merged
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
6 changes: 3 additions & 3 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ resources:
controller: true
domain: splunk.com
group: enterprise
kind: Database
kind: PostgresCluster
path: github.com/splunk/splunk-operator/api/v4
version: v4
- api:
Expand All @@ -128,7 +128,7 @@ resources:
controller: true
domain: splunk.com
group: enterprise
kind: DatabaseClass
kind: PostgresClusterClass
path: github.com/splunk/splunk-operator/api/v4
version: v4
- api:
Expand All @@ -137,7 +137,7 @@ resources:
controller: true
domain: splunk.com
group: enterprise
kind: PostgresCluster
kind: PostgresDatabase
path: github.com/splunk/splunk-operator/api/v4
version: v4
version: "3"
2 changes: 1 addition & 1 deletion api/v3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/v4/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021.
Copyright 2026.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
120 changes: 120 additions & 0 deletions api/v4/postgrescluster_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
Copyright 2026.

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 v4

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// PostgresClusterSpec defines the desired state of PostgresCluster.
// 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) || semver(self.postgresVersion, true).compareTo(semver(oldSelf.postgresVersion, true)) >= 0",message="Postgres version cannot be downgraded"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.storage) || (has(self.storage) && quantity(self.storage).compareTo(quantity(oldSelf.storage)) >= 0)",message="Storage size cannot be removed and can only be increased"
type PostgresClusterSpec struct {
// This field is IMMUTABLE after creation.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="class is immutable"
Class string `json:"class"`

// Storage overrides the storage size from ClusterClass.
// Example: "5Gi"
// +optional
Storage *resource.Quantity `json:"storage,omitempty"`

// Instances overrides the number of PostgreSQL instances from ClusterClass.
// +optional
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=10
Instances *int32 `json:"instances,omitempty"`

// PostgresVersion is the PostgreSQL version (major or major.minor).
// Examples: "18" (latest 18.x), "18.1" (specific minor), "17", "16"
// +kubebuilder:validation:Pattern=`^[0-9]+(\.[0-9]+)?$`
// +kubebuilder:default="18"
// +optional
PostgresVersion *string `json:"postgresVersion,omitempty"`

// Resources overrides CPU/memory resources from ClusterClass.
// +optional
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`

// PostgreSQL overrides PostgreSQL engine parameters from ClusterClass.
// Maps to postgresql.conf settings.
// Default empty map prevents panic.
// Example: {"shared_buffers": "128MB", "log_min_duration_statement": "500ms"}
// +optional
// +kubebuilder:default={}
PostgreSQLConfig map[string]string `json:"postgresqlConfig,omitempty"`

// PgHBA contains pg_hba.conf host-based authentication rules.
// Defines client authentication and connection security (cluster-wide).
// Maps to pg_hba.conf settings.
// Default empty array prevents panic.
// Example: ["hostssl all all 0.0.0.0/0 scram-sha-256"]
// +optional
// +kubebuilder:default={}
PgHBA []string `json:"pgHBA,omitempty"`
}

// PostgresClusterStatus defines the observed state of PostgresCluster.
type PostgresClusterStatus struct {
// Phase represents the current phase of the PostgresCluster.
// Values: "Pending", "Provisioning", "Failed", "Ready", "Deleting"
// +optional
Phase string `json:"phase,omitempty"`

// Conditions represent the latest available observations of the PostgresCluster's state.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ProvisionerRef contains reference to the provisioner resource managing this PostgresCluster.
// Right now, only CNPG is supported.
// +optional
ProvisionerRef *corev1.ObjectReference `json:"provisionerRef,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Namespaced
// +kubebuilder:printcolumn:name="Class",type=string,JSONPath=`.spec.class`
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

// PostgresCluster is the Schema for the postgresclusters API.
type PostgresCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec PostgresClusterSpec `json:"spec,omitempty"`
Status PostgresClusterStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// PostgresClusterList contains a list of PostgresCluster.
type PostgresClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []PostgresCluster `json:"items"`
}

func init() {
SchemeBuilder.Register(&PostgresCluster{}, &PostgresClusterList{})
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,32 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ClusterClassSpec defines the desired state of ClusterClass.
// ClusterClass is immutable after creation - it serves as a template for Cluster CRs.
type ClusterClassSpec struct {
// PostgresClusterClassSpec defines the desired state of PostgresClusterClass.
// PostgresClusterClass is immutable after creation - it serves as a template for Cluster CRs.
type PostgresClusterClassSpec struct {
// Provisioner identifies which database provisioner to use.
// Currently supported: "postgresql.cnpg.io" (CloudNativePG)
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=postgresql.cnpg.io
Provisioner string `json:"provisioner"`

// ClusterConfig contains cluster-level configuration.
// These settings apply to database cluster infrastructure.
// Can be overridden in Cluster CR.
// PostgresClusterConfig contains cluster-level configuration.
// These settings apply to PostgresCluster infrastructure.
// Can be overridden in PostgresCluster CR.
// +kubebuilder:default={}
// +optional
ClusterConfig ClusterConfig `json:"clusterConfig,omitempty"`
Config PosgresClusterClassConfig `json:"config,omitempty"`

// CNPG contains CloudNativePG-specific configuration and policies.
// Only used when Provisioner is "postgresql.cnpg.io"
// These settings CANNOT be overridden in Cluster CR (platform policy).
// These settings CANNOT be overridden in PostgresCluster CR (platform policy).
// +optional
CNPG *CNPGConfig `json:"cnpg,omitempty"`
}

// ClusterConfig contains provider-agnostic cluster configuration.
// These fields define database cluster infrastructure and can be overridden in Cluster CR.
type ClusterConfig struct {
// PosgresClusterClassConfig contains provider-agnostic cluster configuration.
// These fields define PostgresCluster infrastructure and can be overridden in PostgresCluster CR.
type PosgresClusterClassConfig struct {
// Instances is the number of database instances (1 primary + N replicas).
// Single instance (1) is suitable for development.
// High availability requires at least 3 instances (1 primary + 2 replicas).
Expand Down Expand Up @@ -106,13 +106,13 @@ type CNPGConfig struct {
PrimaryUpdateMethod string `json:"primaryUpdateMethod,omitempty"`
}

// ClusterClassStatus defines the observed state of ClusterClass.
type ClusterClassStatus struct {
// Conditions represent the latest available observations of the ClusterClass state.
// PostgresClusterClassStatus defines the observed state of PostgresClusterClass.
type PostgresClusterClassStatus struct {
// Conditions represent the latest available observations of the PostgresClusterClass state.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// Phase represents the current phase of the ClusterClass.
// Phase represents the current phase of the PostgresClusterClass.
// Valid phases: "Ready", "Invalid"
// +optional
Phase string `json:"phase,omitempty"`
Expand All @@ -122,31 +122,31 @@ type ClusterClassStatus struct {
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:printcolumn:name="Provisioner",type=string,JSONPath=`.spec.provisioner`
// +kubebuilder:printcolumn:name="Instances",type=integer,JSONPath=`.spec.clusterConfig.instances`
// +kubebuilder:printcolumn:name="Storage",type=string,JSONPath=`.spec.clusterConfig.storage`
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.clusterConfig.postgresVersion`
// +kubebuilder:printcolumn:name="Instances",type=integer,JSONPath=`.spec.postgresClusterConfig.instances`
// +kubebuilder:printcolumn:name="Storage",type=string,JSONPath=`.spec.postgresClusterConfig.storage`
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.postgresClusterConfig.postgresVersion`
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

// ClusterClass is the Schema for the clusterclasses API.
// ClusterClass defines a reusable template and policy for database cluster provisioning.
type ClusterClass struct {
// PostgresClusterClass is the Schema for the postgresclusterclasses API.
// PostgresClusterClass defines a reusable template and policy for postgres cluster provisioning.
type PostgresClusterClass struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ClusterClassSpec `json:"spec,omitempty"`
Status ClusterClassStatus `json:"status,omitempty"`
Spec PostgresClusterClassSpec `json:"spec,omitempty"`
Status PostgresClusterClassStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ClusterClassList contains a list of ClusterClass.
type ClusterClassList struct {
// PostgresClusterClassList contains a list of PostgresClusterClass.
type PostgresClusterClassList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ClusterClass `json:"items"`
Items []PostgresClusterClass `json:"items"`
}

func init() {
SchemeBuilder.Register(&ClusterClass{}, &ClusterClassList{})
SchemeBuilder.Register(&PostgresClusterClass{}, &PostgresClusterClassList{})
}
Loading
Loading