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
// WARNING: generated by kopium - manual changes will be overwritten
// kopium command: kopium -D Default backups.postgresql.cnpg.io -A
// kopium version: 0.16.5

use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Specification of the desired behavior of the backup. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
#[kube(
    group = "postgresql.cnpg.io",
    version = "v1",
    kind = "Backup",
    plural = "backups"
)]
#[kube(namespaced)]
#[kube(status = "BackupStatus")]
pub struct BackupSpec {
    /// The cluster to backup
    pub cluster: BackupCluster,
    /// The backup method to be used, possible options are `barmanObjectStore` and `volumeSnapshot`. Defaults to: `barmanObjectStore`.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub method: Option<BackupMethod>,
    /// Whether the default type of backup with volume snapshots is online/hot (`true`, default) or offline/cold (`false`) Overrides the default setting specified in the cluster field '.spec.backup.volumeSnapshot.online'
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub online: Option<bool>,
    /// Configuration parameters to control the online/hot backup with volume snapshots Overrides the default settings specified in the cluster '.backup.volumeSnapshot.onlineConfiguration' stanza
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "onlineConfiguration"
    )]
    pub online_configuration: Option<BackupOnlineConfiguration>,
    /// The policy to decide which instance should perform this backup. If empty, it defaults to `cluster.spec.backup.target`. Available options are empty string, `primary` and `prefer-standby`. `primary` to have backups run always on primary instances, `prefer-standby` to have backups run preferably on the most updated standby, if available.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub target: Option<BackupTarget>,
}

/// The cluster to backup
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupCluster {
    /// Name of the referent.
    pub name: String,
}

/// Specification of the desired behavior of the backup. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, PartialEq)]
pub enum BackupMethod {
    #[serde(rename = "barmanObjectStore")]
    BarmanObjectStore,
    #[serde(rename = "volumeSnapshot")]
    VolumeSnapshot,
}

/// Configuration parameters to control the online/hot backup with volume snapshots Overrides the default settings specified in the cluster '.backup.volumeSnapshot.onlineConfiguration' stanza
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupOnlineConfiguration {
    /// 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.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "immediateCheckpoint"
    )]
    pub immediate_checkpoint: Option<bool>,
    /// 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.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "waitForArchive"
    )]
    pub wait_for_archive: Option<bool>,
}

/// Specification of the desired behavior of the backup. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub enum BackupTarget {
    #[serde(rename = "primary")]
    Primary,
    #[serde(rename = "prefer-standby")]
    PreferStandby,
}

/// Most recently observed status of the backup. This data may not be up to date. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatus {
    /// The credentials to use to upload data to Azure Blob Storage
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "azureCredentials"
    )]
    pub azure_credentials: Option<BackupStatusAzureCredentials>,
    /// The ID of the Barman backup
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "backupId")]
    pub backup_id: Option<String>,
    /// Backup label file content as returned by Postgres in case of online (hot) backups
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "backupLabelFile"
    )]
    pub backup_label_file: Option<String>,
    /// The Name of the Barman backup
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "backupName"
    )]
    pub backup_name: Option<String>,
    /// The starting xlog
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "beginLSN")]
    pub begin_lsn: Option<String>,
    /// The starting WAL
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "beginWal")]
    pub begin_wal: Option<String>,
    /// The backup command output in case of error
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "commandError"
    )]
    pub command_error: Option<String>,
    /// Unused. Retained for compatibility with old versions.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "commandOutput"
    )]
    pub command_output: Option<String>,
    /// The path where to store the backup (i.e. s3://bucket/path/to/folder) this path, with different destination folders, will be used for WALs and for data. This may not be populated in case of errors.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "destinationPath"
    )]
    pub destination_path: Option<String>,
    /// Encryption method required to S3 API
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub encryption: Option<String>,
    /// The ending xlog
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "endLSN")]
    pub end_lsn: Option<String>,
    /// The ending WAL
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "endWal")]
    pub end_wal: Option<String>,
    /// EndpointCA store the CA bundle of the barman endpoint. Useful when using self-signed certificates to avoid errors with certificate issuer and barman-cloud-wal-archive.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "endpointCA"
    )]
    pub endpoint_ca: Option<BackupStatusEndpointCa>,
    /// Endpoint to be used to upload data to the cloud, overriding the automatic endpoint discovery
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "endpointURL"
    )]
    pub endpoint_url: Option<String>,
    /// The detected error
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub error: Option<String>,
    /// The credentials to use to upload data to Google Cloud Storage
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "googleCredentials"
    )]
    pub google_credentials: Option<BackupStatusGoogleCredentials>,
    /// Information to identify the instance where the backup has been taken from
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "instanceID"
    )]
    pub instance_id: Option<BackupStatusInstanceId>,
    /// The backup method being used
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub method: Option<String>,
    /// Whether the backup was online/hot (`true`) or offline/cold (`false`)
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub online: Option<bool>,
    /// The last backup status
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub phase: Option<String>,
    /// The credentials to use to upload data to S3
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "s3Credentials"
    )]
    pub s3_credentials: Option<BackupStatusS3Credentials>,
    /// The server name on S3, the cluster name is used if this parameter is omitted
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "serverName"
    )]
    pub server_name: Option<String>,
    /// Status of the volumeSnapshot backup
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "snapshotBackupStatus"
    )]
    pub snapshot_backup_status: Option<BackupStatusSnapshotBackupStatus>,
    /// When the backup was started
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "startedAt")]
    pub started_at: Option<String>,
    /// When the backup was terminated
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "stoppedAt")]
    pub stopped_at: Option<String>,
    /// Tablespace map file content as returned by Postgres in case of online (hot) backups
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "tablespaceMapFile"
    )]
    pub tablespace_map_file: Option<String>,
}

/// The credentials to use to upload data to Azure Blob Storage
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusAzureCredentials {
    /// The connection string to be used
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "connectionString"
    )]
    pub connection_string: Option<BackupStatusAzureCredentialsConnectionString>,
    /// Use the Azure AD based authentication without providing explicitly the keys.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "inheritFromAzureAD"
    )]
    pub inherit_from_azure_ad: Option<bool>,
    /// The storage account where to upload data
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "storageAccount"
    )]
    pub storage_account: Option<BackupStatusAzureCredentialsStorageAccount>,
    /// The storage account key to be used in conjunction with the storage account name
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "storageKey"
    )]
    pub storage_key: Option<BackupStatusAzureCredentialsStorageKey>,
    /// A shared-access-signature to be used in conjunction with the storage account name
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "storageSasToken"
    )]
    pub storage_sas_token: Option<BackupStatusAzureCredentialsStorageSasToken>,
}

/// The connection string to be used
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusAzureCredentialsConnectionString {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// The storage account where to upload data
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusAzureCredentialsStorageAccount {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// The storage account key to be used in conjunction with the storage account name
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusAzureCredentialsStorageKey {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// A shared-access-signature to be used in conjunction with the storage account name
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusAzureCredentialsStorageSasToken {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// EndpointCA store the CA bundle of the barman endpoint. Useful when using self-signed certificates to avoid errors with certificate issuer and barman-cloud-wal-archive.
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusEndpointCa {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// The credentials to use to upload data to Google Cloud Storage
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusGoogleCredentials {
    /// The secret containing the Google Cloud Storage JSON file with the credentials
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "applicationCredentials"
    )]
    pub application_credentials: Option<BackupStatusGoogleCredentialsApplicationCredentials>,
    /// If set to true, will presume that it's running inside a GKE environment, default to false.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "gkeEnvironment"
    )]
    pub gke_environment: Option<bool>,
}

/// The secret containing the Google Cloud Storage JSON file with the credentials
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusGoogleCredentialsApplicationCredentials {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// Information to identify the instance where the backup has been taken from
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusInstanceId {
    /// The container ID
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "ContainerID"
    )]
    pub container_id: Option<String>,
    /// The pod name
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "podName")]
    pub pod_name: Option<String>,
}

/// The credentials to use to upload data to S3
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusS3Credentials {
    /// The reference to the access key id
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "accessKeyId"
    )]
    pub access_key_id: Option<BackupStatusS3CredentialsAccessKeyId>,
    /// Use the role based authentication without providing explicitly the keys.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "inheritFromIAMRole"
    )]
    pub inherit_from_iam_role: Option<bool>,
    /// The reference to the secret containing the region name
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub region: Option<BackupStatusS3CredentialsRegion>,
    /// The reference to the secret access key
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "secretAccessKey"
    )]
    pub secret_access_key: Option<BackupStatusS3CredentialsSecretAccessKey>,
    /// The references to the session key
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "sessionToken"
    )]
    pub session_token: Option<BackupStatusS3CredentialsSessionToken>,
}

/// The reference to the access key id
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusS3CredentialsAccessKeyId {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// The reference to the secret containing the region name
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusS3CredentialsRegion {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// The reference to the secret access key
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusS3CredentialsSecretAccessKey {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// The references to the session key
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusS3CredentialsSessionToken {
    /// The key to select
    pub key: String,
    /// Name of the referent.
    pub name: String,
}

/// Status of the volumeSnapshot backup
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusSnapshotBackupStatus {
    /// The elements list, populated with the gathered volume snapshots
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub elements: Option<Vec<BackupStatusSnapshotBackupStatusElements>>,
}

/// BackupSnapshotElementStatus is a volume snapshot that is part of a volume snapshot method backup
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct BackupStatusSnapshotBackupStatusElements {
    /// Name is the snapshot resource name
    pub name: String,
    /// TablespaceName is the name of the snapshotted tablespace. Only set when type is PG_TABLESPACE
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "tablespaceName"
    )]
    pub tablespace_name: Option<String>,
    /// Type is tho role of the snapshot in the cluster, such as PG_DATA, PG_WAL and PG_TABLESPACE
    #[serde(rename = "type")]
    pub r#type: String,
}