Skip to content

Commit 31a3b69

Browse files
committed
feat(operator): wire backup retention, health, and metrics
- add retention fields to the backup API and default them through the resolver - extend backup health evaluation with integrity and retention checks - register backup lifecycle metrics and regenerate CRD and deepcopy artifacts Signed-off-by: Veronica Lopez <veronica.lopez@supabase.io>
1 parent 07acad2 commit 31a3b69

File tree

8 files changed

+476
-34
lines changed

8 files changed

+476
-34
lines changed

api/v1alpha1/common_types.go

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ type BackupConfig struct {
159159
// When SecretName is empty, the operator auto-generates and rotates certificates.
160160
// +optional
161161
PgBackRestTLS *PgBackRestTLSConfig `json:"pgbackrestTLS,omitempty"`
162+
163+
// Retention configures pgBackRest backup retention.
164+
// +optional
165+
Retention *RetentionPolicy `json:"retention,omitempty"`
162166
}
163167

164168
// FilesystemBackupConfig defines settings for filesystem-based backups.
@@ -190,12 +194,18 @@ type S3BackupConfig struct {
190194
// +optional
191195
CredentialsSecret string `json:"credentialsSecret,omitempty"`
192196

193-
// ServiceAccountName is the name of the ServiceAccount to use for IRSA-based S3 authentication.
194-
// The ServiceAccount must exist in the same namespace and be annotated with
195-
// eks.amazonaws.com/role-arn pointing to an IAM role with S3 permissions.
196-
// The operator does NOT create this ServiceAccount — the user must create it externally.
197+
// ServiceAccountName is the ServiceAccount used for IRSA-based S3 authentication.
197198
// +optional
198199
ServiceAccountName string `json:"serviceAccountName,omitempty"`
200+
201+
// CleanupOnDelete deletes S3 backup data during cluster deletion.
202+
// +optional
203+
CleanupOnDelete *bool `json:"cleanupOnDelete,omitempty"`
204+
205+
// AllowStaleMetadataRecovery allows automatic recovery from stale stanza metadata.
206+
// WARNING: This may delete existing backup data.
207+
// +optional
208+
AllowStaleMetadataRecovery *bool `json:"allowStaleMetadataRecovery,omitempty"`
199209
}
200210

201211
// PgBackRestTLSConfig configures TLS for pgBackRest inter-node communication.
@@ -208,6 +218,21 @@ type PgBackRestTLSConfig struct {
208218
SecretName string `json:"secretName,omitempty"`
209219
}
210220

221+
// RetentionPolicy configures pgBackRest backup retention.
222+
type RetentionPolicy struct {
223+
// FullCount is the number of full backups to retain.
224+
// +kubebuilder:validation:Minimum=1
225+
// +kubebuilder:validation:Maximum=30
226+
// +optional
227+
FullCount *int32 `json:"fullCount,omitempty"`
228+
229+
// DifferentialCount is the number of differential backups to retain per full backup.
230+
// +kubebuilder:validation:Minimum=1
231+
// +kubebuilder:validation:Maximum=30
232+
// +optional
233+
DifferentialCount *int32 `json:"differentialCount,omitempty"`
234+
}
235+
211236
// ============================================================================
212237
// Domain Specific Types (Strong Typing)
213238
// ============================================================================
@@ -429,21 +454,38 @@ func MergeBackupConfig(child, parent *BackupConfig) *BackupConfig {
429454
if child.S3.KeyPrefix != "" {
430455
merged.S3.KeyPrefix = child.S3.KeyPrefix
431456
}
432-
// Bool fields are tricky in merge (is false explicitly set or default?)
433-
// For simplicity in v1alpha1, we assume if struct is present, we take the value
457+
// UseEnvCredentials follows child.S3 when the child S3 block is present.
434458
merged.S3.UseEnvCredentials = child.S3.UseEnvCredentials
435459
if child.S3.CredentialsSecret != "" {
436460
merged.S3.CredentialsSecret = child.S3.CredentialsSecret
437461
}
438462
if child.S3.ServiceAccountName != "" {
439463
merged.S3.ServiceAccountName = child.S3.ServiceAccountName
440464
}
465+
if child.S3.CleanupOnDelete != nil {
466+
merged.S3.CleanupOnDelete = child.S3.CleanupOnDelete
467+
}
468+
if child.S3.AllowStaleMetadataRecovery != nil {
469+
merged.S3.AllowStaleMetadataRecovery = child.S3.AllowStaleMetadataRecovery
470+
}
441471
}
442472
}
443473

444474
if child.PgBackRestTLS != nil {
445475
merged.PgBackRestTLS = child.PgBackRestTLS.DeepCopy()
446476
}
447477

478+
if child.Retention != nil {
479+
if merged.Retention == nil {
480+
merged.Retention = &RetentionPolicy{}
481+
}
482+
if child.Retention.FullCount != nil {
483+
merged.Retention.FullCount = child.Retention.FullCount
484+
}
485+
if child.Retention.DifferentialCount != nil {
486+
merged.Retention.DifferentialCount = child.Retention.DifferentialCount
487+
}
488+
}
489+
448490
return merged
449491
}

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 41 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/multigres.com_multigresclusters.yaml

Lines changed: 118 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,40 @@ spec:
105105
When empty, the operator generates and rotates certificates automatically.
106106
type: string
107107
type: object
108+
retention:
109+
description: Retention configures pgBackRest backup retention.
110+
properties:
111+
differentialCount:
112+
description: DifferentialCount is the number of differential
113+
backups to retain per full backup.
114+
format: int32
115+
maximum: 30
116+
minimum: 1
117+
type: integer
118+
fullCount:
119+
description: FullCount is the number of full backups to retain.
120+
format: int32
121+
maximum: 30
122+
minimum: 1
123+
type: integer
124+
type: object
108125
s3:
109126
description: |-
110127
S3 defines the S3-compatible storage configuration.
111128
Required when type is "s3".
112129
properties:
130+
allowStaleMetadataRecovery:
131+
description: |-
132+
AllowStaleMetadataRecovery allows automatic recovery from stale stanza metadata.
133+
WARNING: This may delete existing backup data.
134+
type: boolean
113135
bucket:
114136
minLength: 1
115137
type: string
138+
cleanupOnDelete:
139+
description: CleanupOnDelete deletes S3 backup data during
140+
cluster deletion.
141+
type: boolean
116142
credentialsSecret:
117143
description: CredentialsSecret is the name of the Secret containing
118144
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
@@ -125,11 +151,8 @@ spec:
125151
minLength: 1
126152
type: string
127153
serviceAccountName:
128-
description: |-
129-
ServiceAccountName is the name of the ServiceAccount to use for IRSA-based S3 authentication.
130-
The ServiceAccount must exist in the same namespace and be annotated with
131-
eks.amazonaws.com/role-arn pointing to an IAM role with S3 permissions.
132-
The operator does NOT create this ServiceAccount — the user must create it externally.
154+
description: ServiceAccountName is the ServiceAccount used
155+
for IRSA-based S3 authentication.
133156
type: string
134157
useEnvCredentials:
135158
type: boolean
@@ -2524,14 +2547,41 @@ spec:
25242547
When empty, the operator generates and rotates certificates automatically.
25252548
type: string
25262549
type: object
2550+
retention:
2551+
description: Retention configures pgBackRest backup retention.
2552+
properties:
2553+
differentialCount:
2554+
description: DifferentialCount is the number of differential
2555+
backups to retain per full backup.
2556+
format: int32
2557+
maximum: 30
2558+
minimum: 1
2559+
type: integer
2560+
fullCount:
2561+
description: FullCount is the number of full backups
2562+
to retain.
2563+
format: int32
2564+
maximum: 30
2565+
minimum: 1
2566+
type: integer
2567+
type: object
25272568
s3:
25282569
description: |-
25292570
S3 defines the S3-compatible storage configuration.
25302571
Required when type is "s3".
25312572
properties:
2573+
allowStaleMetadataRecovery:
2574+
description: |-
2575+
AllowStaleMetadataRecovery allows automatic recovery from stale stanza metadata.
2576+
WARNING: This may delete existing backup data.
2577+
type: boolean
25322578
bucket:
25332579
minLength: 1
25342580
type: string
2581+
cleanupOnDelete:
2582+
description: CleanupOnDelete deletes S3 backup data
2583+
during cluster deletion.
2584+
type: boolean
25352585
credentialsSecret:
25362586
description: CredentialsSecret is the name of the Secret
25372587
containing AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
@@ -2544,11 +2594,8 @@ spec:
25442594
minLength: 1
25452595
type: string
25462596
serviceAccountName:
2547-
description: |-
2548-
ServiceAccountName is the name of the ServiceAccount to use for IRSA-based S3 authentication.
2549-
The ServiceAccount must exist in the same namespace and be annotated with
2550-
eks.amazonaws.com/role-arn pointing to an IAM role with S3 permissions.
2551-
The operator does NOT create this ServiceAccount — the user must create it externally.
2597+
description: ServiceAccountName is the ServiceAccount
2598+
used for IRSA-based S3 authentication.
25522599
type: string
25532600
useEnvCredentials:
25542601
type: boolean
@@ -2655,14 +2702,42 @@ spec:
26552702
When empty, the operator generates and rotates certificates automatically.
26562703
type: string
26572704
type: object
2705+
retention:
2706+
description: Retention configures pgBackRest backup
2707+
retention.
2708+
properties:
2709+
differentialCount:
2710+
description: DifferentialCount is the number of
2711+
differential backups to retain per full backup.
2712+
format: int32
2713+
maximum: 30
2714+
minimum: 1
2715+
type: integer
2716+
fullCount:
2717+
description: FullCount is the number of full backups
2718+
to retain.
2719+
format: int32
2720+
maximum: 30
2721+
minimum: 1
2722+
type: integer
2723+
type: object
26582724
s3:
26592725
description: |-
26602726
S3 defines the S3-compatible storage configuration.
26612727
Required when type is "s3".
26622728
properties:
2729+
allowStaleMetadataRecovery:
2730+
description: |-
2731+
AllowStaleMetadataRecovery allows automatic recovery from stale stanza metadata.
2732+
WARNING: This may delete existing backup data.
2733+
type: boolean
26632734
bucket:
26642735
minLength: 1
26652736
type: string
2737+
cleanupOnDelete:
2738+
description: CleanupOnDelete deletes S3 backup
2739+
data during cluster deletion.
2740+
type: boolean
26662741
credentialsSecret:
26672742
description: CredentialsSecret is the name of
26682743
the Secret containing AWS_ACCESS_KEY_ID and
@@ -2676,11 +2751,8 @@ spec:
26762751
minLength: 1
26772752
type: string
26782753
serviceAccountName:
2679-
description: |-
2680-
ServiceAccountName is the name of the ServiceAccount to use for IRSA-based S3 authentication.
2681-
The ServiceAccount must exist in the same namespace and be annotated with
2682-
eks.amazonaws.com/role-arn pointing to an IAM role with S3 permissions.
2683-
The operator does NOT create this ServiceAccount — the user must create it externally.
2754+
description: ServiceAccountName is the ServiceAccount
2755+
used for IRSA-based S3 authentication.
26842756
type: string
26852757
useEnvCredentials:
26862758
type: boolean
@@ -2811,14 +2883,43 @@ spec:
28112883
When empty, the operator generates and rotates certificates automatically.
28122884
type: string
28132885
type: object
2886+
retention:
2887+
description: Retention configures pgBackRest
2888+
backup retention.
2889+
properties:
2890+
differentialCount:
2891+
description: DifferentialCount is the number
2892+
of differential backups to retain per
2893+
full backup.
2894+
format: int32
2895+
maximum: 30
2896+
minimum: 1
2897+
type: integer
2898+
fullCount:
2899+
description: FullCount is the number of
2900+
full backups to retain.
2901+
format: int32
2902+
maximum: 30
2903+
minimum: 1
2904+
type: integer
2905+
type: object
28142906
s3:
28152907
description: |-
28162908
S3 defines the S3-compatible storage configuration.
28172909
Required when type is "s3".
28182910
properties:
2911+
allowStaleMetadataRecovery:
2912+
description: |-
2913+
AllowStaleMetadataRecovery allows automatic recovery from stale stanza metadata.
2914+
WARNING: This may delete existing backup data.
2915+
type: boolean
28192916
bucket:
28202917
minLength: 1
28212918
type: string
2919+
cleanupOnDelete:
2920+
description: CleanupOnDelete deletes S3
2921+
backup data during cluster deletion.
2922+
type: boolean
28222923
credentialsSecret:
28232924
description: CredentialsSecret is the name
28242925
of the Secret containing AWS_ACCESS_KEY_ID
@@ -2832,11 +2933,8 @@ spec:
28322933
minLength: 1
28332934
type: string
28342935
serviceAccountName:
2835-
description: |-
2836-
ServiceAccountName is the name of the ServiceAccount to use for IRSA-based S3 authentication.
2837-
The ServiceAccount must exist in the same namespace and be annotated with
2838-
eks.amazonaws.com/role-arn pointing to an IAM role with S3 permissions.
2839-
The operator does NOT create this ServiceAccount — the user must create it externally.
2936+
description: ServiceAccountName is the ServiceAccount
2937+
used for IRSA-based S3 authentication.
28402938
type: string
28412939
useEnvCredentials:
28422940
type: boolean

0 commit comments

Comments
 (0)