Skip to content

Commit 70ddf53

Browse files
Allows Restores Across Namespaces (CrunchyData#2358)
When creating a new PostgreSQL cluster via 'pgbackrest restore' using the pgBackRest backups from another current or former PostgreSQL cluster, it is now possible restore from the backups of a cluster in different namespace (i.e. different than the cluster being created). In support of this functionality, a copy of the pgBackRest Secret corresponding to the repository containing the backups being utilized to bootstrap the cluster is now made specifically for the bootstrap Job (and then removed when bootstrapping is complete). This ensures the new cluster always has the information required to connect to the repository being utilized to bootstrap the cluster, regardless of what namespace it is in. Additionally, DNS for the pgBackRest repository service is now always used when performing the restore to ensure proper connectivity across namespaces if/when needed. And finally, a '--restore-from-namespace' option has been added to the pgo client, which corresponds to a 'spec.pgdatasource.namespace' field in the Pgcluster spec, and allows users to specify the namespace of the cluster specified for bootstrapping the new cluster. Issue: [ch9969] Issue: CrunchyData#2062
1 parent eb9b042 commit 70ddf53

File tree

16 files changed

+229
-72
lines changed

16 files changed

+229
-72
lines changed

cmd/pgo/cmd/cluster.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ func createCluster(args []string, ns string, createClusterCmd *cobra.Command) {
332332
r.WALStorageConfig = WALStorageConfig
333333
r.WALPVCSize = WALPVCSize
334334
r.PGDataSource.RestoreFrom = RestoreFrom
335+
r.PGDataSource.Namespace = RestoreFromNamespace
335336
r.PGDataSource.RestoreOpts = BackupOpts
336337
// set any annotations
337338
r.Annotations = getClusterAnnotations(Annotations, AnnotationsPostgres, AnnotationsBackrest,

cmd/pgo/cmd/create.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var (
7171
WALStorageConfig string
7272
WALPVCSize string
7373
RestoreFrom string
74+
RestoreFromNamespace string
7475
)
7576

7677
// group the annotation requests
@@ -486,6 +487,9 @@ func init() {
486487
"the TLS keypair to use for enabling certificate-based authentication between PostgreSQL instances, "+
487488
"particularly for the purpose of replication. Must be used with \"server-tls-secret\" and \"server-ca-secret\".")
488489
createClusterCmd.Flags().StringVarP(&RestoreFrom, "restore-from", "", "", "The name of cluster to restore from when bootstrapping a new cluster")
490+
createClusterCmd.Flags().StringVarP(&RestoreFromNamespace, "restore-from-namespace", "", "",
491+
"The namespace for the cluster specified using --restore-from. Defaults to the "+
492+
"namespace of the cluster being created if not provided.")
489493
createClusterCmd.Flags().StringVarP(&BackupOpts, "restore-opts", "", "",
490494
"The options to pass into pgbackrest where performing a restore to bootrap the cluster. "+
491495
"Only applicable when a \"restore-from\" value is specified")

docs/content/architecture/disaster-recovery.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ command with several flags:
121121
- `--restore-from`: specifies the name of a PostgreSQL cluster (either one that
122122
is active, or a former cluster whose pgBackRest repository still exists) to
123123
restore from.
124+
- `--restore-from-namespace` (optional): the namespace of the PostgreSQL cluster specified
125+
using `--restore-from` (the namespace of the cluster being created is utilized if a namespace
126+
is not specified using this option)
124127
- `--restore-opts`: used to specify additional options, similar to the ones that
125128
are passed into [`pgbackrest restore`](https://pgbackrest.org/command.html#command-restore).
126129

@@ -143,7 +146,10 @@ pgo create cluster newcluster \
143146

144147
Note that when using this method, the PostgreSQL Operator can only restore one
145148
cluster from each pgBackRest repository at a time. Using the above example, one
146-
can only perform one restore from `oldcluster` at a given time.
149+
can only perform one restore from `oldcluster` at a given time. Additionally,
150+
if the cluster being utilized for restore is in another namespace than the
151+
cluster being created, the proper namespace can be specified using the
152+
`--restore-from-namespace` option.
147153

148154
When using the restore to a new cluster method, the PostgreSQL Operator takes
149155
the following actions:

docs/content/architecture/provisioning.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ the existing pgBackRest repository host for that cluster in order to perform the
173173
restore. If restoring from a former cluster that has since been deleted, a new pgBackRest
174174
repository host will be deployed for the sole purpose of bootstrapping the new cluster, and will
175175
then be destroyed once the restore is complete. Also, please note that it is only possible for
176-
one cluster to bootstrap from another cluster (whether running or not) at any given time.
176+
one cluster to bootstrap from another cluster (whether running or not) at any given time. And
177+
finally, if the cluster being utilized for restore is in another namespace than the cluster being
178+
created, the proper namespace can be specified using the `--restore-from-namespace` option.
177179

178180
## Deprovisioning
179181

docs/content/pgo-client/common-tasks.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,15 @@ execute the following command:
645645
pgo create cluster newcluster --restore-from=oldcluster
646646
```
647647

648+
##### Full Restore Across Namespaces
649+
650+
To create a new PostgreSQL cluster from a backup in another namespace and restore it
651+
fully, you can execute the following command:
652+
653+
```
654+
pgo create cluster newcluster --restore-from=oldcluster --restore-from-namespace=oldnamespace
655+
```
656+
648657
##### Point-in-time-Recovery (PITR)
649658

650659
To create a new PostgreSQL cluster and restore it to specific point-in-time

installers/ansible/roles/pgo-operator/files/pgo-configs/cluster-bootstrap-job.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@
185185
}, {
186186
"name": "sshd",
187187
"secret": {
188-
"secretName": "{{.RestoreFrom}}-backrest-repo-config"
188+
"secretName": "{{.ClusterName}}-bootstrap-backrest-repo-config"
189189
}
190190
}, {
191191
"name": "ssh-config",

installers/ansible/roles/pgo-operator/files/pgo-configs/pgo-backrest-repo-template.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"labels": {
77
{{if .BootstrapCluster}}
88
"pgha-bootstrap": "{{.BootstrapCluster}}",
9+
"pgha-bootstrap-namespace": "{{.BootstrapNamespace}}",
910
{{ end }}
1011
"name": "{{.Name}}",
1112
"pg-cluster": "{{.ClusterName}}",
@@ -34,6 +35,7 @@
3435
"labels": {
3536
{{if .BootstrapCluster}}
3637
"pgha-bootstrap": "{{.BootstrapCluster}}",
38+
"pgha-bootstrap-namespace": "{{.BootstrapNamespace}}",
3739
{{ end }}
3840
"name": "{{.Name}}",
3941
"pg-cluster": "{{.ClusterName}}",

internal/apiserver/clusterservice/clusterimpl.go

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,10 +2335,17 @@ func isMissingExistingDataSourceS3Config(backrestRepoSecret *v1.Secret) bool {
23352335
// to create a new cluster
23362336
func validateDataSourceParms(request *msgs.CreateClusterRequest) error {
23372337
ctx := context.TODO()
2338-
namespace := request.Namespace
2338+
23392339
restoreClusterName := request.PGDataSource.RestoreFrom
23402340
restoreOpts := request.PGDataSource.RestoreOpts
23412341

2342+
var restoreFromNamespace string
2343+
if request.PGDataSource.Namespace != "" {
2344+
restoreFromNamespace = request.PGDataSource.Namespace
2345+
} else {
2346+
restoreFromNamespace = request.Namespace
2347+
}
2348+
23422349
if restoreClusterName == "" && restoreOpts == "" {
23432350
return nil
23442351
}
@@ -2351,21 +2358,23 @@ func validateDataSourceParms(request *msgs.CreateClusterRequest) error {
23512358
}
23522359

23532360
// next verify whether or not a PVC exists for the cluster we are restoring from
2354-
if _, err := apiserver.Clientset.CoreV1().PersistentVolumeClaims(namespace).Get(ctx,
2361+
if _, err := apiserver.Clientset.CoreV1().PersistentVolumeClaims(restoreFromNamespace).Get(ctx,
23552362
fmt.Sprintf(util.BackrestRepoPVCName, restoreClusterName),
23562363
metav1.GetOptions{}); err != nil {
2357-
return fmt.Errorf("Unable to find PVC %s for cluster %s, cannot to restore from the "+
2358-
"specified data source", fmt.Sprintf(util.BackrestRepoPVCName, restoreClusterName),
2359-
restoreClusterName)
2364+
return fmt.Errorf("Unable to find PVC %s for cluster %s (namespace %s), cannot restore "+
2365+
"from the specified data source",
2366+
fmt.Sprintf(util.BackrestRepoPVCName, restoreClusterName),
2367+
restoreClusterName, restoreFromNamespace)
23602368
}
23612369

23622370
// now verify that a pgBackRest repo secret exists for the cluster we are restoring from
2363-
backrestRepoSecret, err := apiserver.Clientset.CoreV1().Secrets(namespace).Get(ctx,
2371+
backrestRepoSecret, err := apiserver.Clientset.CoreV1().Secrets(restoreFromNamespace).Get(ctx,
23642372
fmt.Sprintf(util.BackrestRepoSecretName, restoreClusterName), metav1.GetOptions{})
23652373
if err != nil {
2366-
return fmt.Errorf("Unable to find secret %s for cluster %s, cannot restore from the "+
2367-
"specified data source",
2368-
fmt.Sprintf(util.BackrestRepoSecretName, restoreClusterName), restoreClusterName)
2374+
return fmt.Errorf("Unable to find secret %s for cluster %s (namespace %s), cannot restore "+
2375+
"from the specified data source",
2376+
fmt.Sprintf(util.BackrestRepoSecretName, restoreClusterName),
2377+
restoreClusterName, restoreFromNamespace)
23692378
}
23702379

23712380
// next perform general validation of the restore options
@@ -2377,28 +2386,28 @@ func validateDataSourceParms(request *msgs.CreateClusterRequest) error {
23772386
// settings are present in backrest repo secret for the backup being restored from
23782387
s3Restore := backrest.S3RepoTypeCLIOptionExists(restoreOpts)
23792388
if s3Restore && isMissingExistingDataSourceS3Config(backrestRepoSecret) {
2380-
return fmt.Errorf("Secret %s is missing the S3 configuration required to restore "+
2381-
"from an S3 repository", backrestRepoSecret.GetName())
2389+
return fmt.Errorf("Secret %s (namespace %s) is missing the S3 configuration required to "+
2390+
"restore from an S3 repository", backrestRepoSecret.GetName(), restoreFromNamespace)
23822391
}
23832392

23842393
// finally, verify that the cluster being restored from is in the proper status, and that no
23852394
// other clusters currently being bootstrapping from the same cluster
2386-
clusterList, err := apiserver.Clientset.CrunchydataV1().Pgclusters(namespace).List(ctx, metav1.ListOptions{})
2395+
clusterList, err := apiserver.Clientset.CrunchydataV1().Pgclusters(restoreFromNamespace).List(ctx, metav1.ListOptions{})
23872396
if err != nil {
23882397
return fmt.Errorf("%s: %w", ErrInvalidDataSource, err)
23892398
}
23902399
for _, cl := range clusterList.Items {
23912400

23922401
if cl.GetName() == restoreClusterName &&
23932402
cl.Status.State == crv1.PgclusterStateShutdown {
2394-
return fmt.Errorf("Unable to restore from cluster %s because it has a %s "+
2395-
"status", restoreClusterName, string(cl.Status.State))
2403+
return fmt.Errorf("Unable to restore from cluster %s (namespace %s) because it has "+
2404+
"a %s status", restoreClusterName, restoreFromNamespace, string(cl.Status.State))
23962405
}
23972406

23982407
if cl.Spec.PGDataSource.RestoreFrom == restoreClusterName &&
23992408
cl.Status.State == crv1.PgclusterStateBootstrapping {
2400-
return fmt.Errorf("Cluster %s is currently bootstrapping from cluster %s, please "+
2401-
"try again once it is completes", cl.GetName(), restoreClusterName)
2409+
return fmt.Errorf("Cluster %s (namespace %s) is currently bootstrapping from cluster %s, please "+
2410+
"try again once it is completes", cl.GetName(), cl.GetNamespace(), restoreClusterName)
24022411
}
24032412
}
24042413

internal/config/labels.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,12 @@ const (
177177
const GLOBAL_CUSTOM_CONFIGMAP = "pgo-custom-pg-config"
178178

179179
const (
180-
LABEL_PGHA_SCOPE = "crunchy-pgha-scope"
181-
LABEL_PGHA_CONFIGMAP = "pgha-config"
182-
LABEL_PGHA_BACKUP_TYPE = "pgha-backup-type"
183-
LABEL_PGHA_ROLE = "role"
184-
LABEL_PGHA_ROLE_PRIMARY = "master"
185-
LABEL_PGHA_ROLE_REPLICA = "replica"
186-
LABEL_PGHA_BOOTSTRAP = "pgha-bootstrap"
180+
LABEL_PGHA_SCOPE = "crunchy-pgha-scope"
181+
LABEL_PGHA_CONFIGMAP = "pgha-config"
182+
LABEL_PGHA_BACKUP_TYPE = "pgha-backup-type"
183+
LABEL_PGHA_ROLE = "role"
184+
LABEL_PGHA_ROLE_PRIMARY = "master"
185+
LABEL_PGHA_ROLE_REPLICA = "replica"
186+
LABEL_PGHA_BOOTSTRAP = "pgha-bootstrap"
187+
LABEL_PGHA_BOOTSTRAP_NAMESPACE = "pgha-bootstrap-namespace"
187188
)

internal/controller/job/bootstraphandler.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import (
2222
"fmt"
2323

2424
"github.com/crunchydata/postgres-operator/internal/config"
25+
"github.com/crunchydata/postgres-operator/internal/operator"
2526
backrestoperator "github.com/crunchydata/postgres-operator/internal/operator/backrest"
27+
cl "github.com/crunchydata/postgres-operator/internal/operator/cluster"
2628
"github.com/crunchydata/postgres-operator/internal/util"
2729
crv1 "github.com/crunchydata/postgres-operator/pkg/apis/crunchydata.com/v1"
2830

@@ -130,20 +132,22 @@ func (c *Controller) cleanupBootstrapResources(job *apiv1.Job, cluster *crv1.Pgc
130132
restore bool) error {
131133
ctx := context.TODO()
132134

133-
namespace := job.GetNamespace()
134135
var restoreClusterName string
135136
var repoName string
136137

138+
// get the proper namespace for the bootstrap repo
139+
restoreFromNamespace := operator.GetBootstrapNamespace(cluster)
140+
137141
// clean the repo if a restore, or if a "bootstrap" repo
138142
var cleanRepo bool
139143
if restore {
140144
restoreClusterName = job.GetLabels()[config.LABEL_PG_CLUSTER]
141145
repoName = fmt.Sprintf(util.BackrestRepoDeploymentName, restoreClusterName)
142-
cleanRepo = true
143146
} else {
144147
restoreClusterName = cluster.Spec.PGDataSource.RestoreFrom
145148
repoName = fmt.Sprintf(util.BackrestRepoDeploymentName, restoreClusterName)
146-
repoDeployment, err := c.Client.AppsV1().Deployments(namespace).
149+
150+
repoDeployment, err := c.Client.AppsV1().Deployments(restoreFromNamespace).
147151
Get(ctx, repoName, metav1.GetOptions{})
148152
if err != nil {
149153
return err
@@ -155,18 +159,25 @@ func (c *Controller) cleanupBootstrapResources(job *apiv1.Job, cluster *crv1.Pgc
155159

156160
if cleanRepo {
157161
// now delete the service for the bootstrap repo
158-
if err := c.Client.CoreV1().Services(namespace).Delete(ctx,
162+
if err := c.Client.CoreV1().Services(restoreFromNamespace).Delete(ctx,
159163
fmt.Sprintf(util.BackrestRepoServiceName, restoreClusterName),
160164
metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) {
161165
return err
162166
}
163167

164-
// and finally delete the bootstrap repo deployment
165-
if err := c.Client.AppsV1().Deployments(namespace).Delete(ctx, repoName,
168+
// and now delete the bootstrap repo deployment
169+
if err := c.Client.AppsV1().Deployments(restoreFromNamespace).Delete(ctx, repoName,
166170
metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) {
167171
return err
168172
}
169173
}
170174

175+
// delete the "bootstrap" version of pgBackRest repo Secret
176+
if err := c.Client.CoreV1().Secrets(job.GetNamespace()).Delete(ctx,
177+
fmt.Sprintf(cl.BoostrapConfigPrefix, cluster.GetName(), config.LABEL_BACKREST_REPO_SECRET),
178+
metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) {
179+
return err
180+
}
181+
171182
return nil
172183
}

internal/controller/pod/podcontroller.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (c *Controller) onUpdate(oldObj, newObj interface{}) {
8080
return
8181
}
8282

83-
var clusterName string
83+
var clusterName, namespace string
8484
bootstrapCluster := newPodLabels[config.LABEL_PGHA_BOOTSTRAP]
8585
// Lookup the pgcluster CR for PG cluster associated with this Pod. Typically we will use the
8686
// 'pg-cluster' label, but if a bootstrap pod we use the 'pgha-bootstrap' label.
@@ -89,8 +89,16 @@ func (c *Controller) onUpdate(oldObj, newObj interface{}) {
8989
} else {
9090
clusterName = newPodLabels[config.LABEL_PG_CLUSTER]
9191
}
92-
namespace := newPod.ObjectMeta.Namespace
93-
cluster, err := c.Client.CrunchydataV1().Pgclusters(namespace).Get(ctx, clusterName, metav1.GetOptions{})
92+
// get the proper namespace for the pgcluster, which could be different than the pod if
93+
// restoring across namespaces
94+
bootstrapNamespace := newPodLabels[config.LABEL_PGHA_BOOTSTRAP_NAMESPACE]
95+
if bootstrapNamespace != "" {
96+
namespace = bootstrapNamespace
97+
} else {
98+
namespace = newPod.ObjectMeta.Namespace
99+
}
100+
cluster, err := c.Client.CrunchydataV1().Pgclusters(namespace).Get(ctx, clusterName,
101+
metav1.GetOptions{})
94102
if err != nil {
95103
log.Error(err.Error())
96104
return

internal/operator/backrest/repo.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ type RepoDeploymentTemplateFields struct {
6565
PodAntiAffinityLabelValue string
6666
Replicas int
6767
BootstrapCluster string
68+
BootstrapNamespace string
6869
Tolerations string
6970
}
7071

@@ -75,20 +76,23 @@ type RepoServiceTemplateFields struct {
7576
}
7677

7778
// CreateRepoDeployment creates a pgBackRest repository deployment for a PostgreSQL cluster,
78-
// while also creating the associated Service and PersistentVolumeClaim.
79+
// while also creating the associated Service and PersistentVolumeClaim. Namespace is provided
80+
// as a parameter since is could vary depending on why the repo is being deployed (e.g. for
81+
// a new cluster, or to bootstrap a new cluster using the backups from a former PG cluster, which
82+
// could be in a different namespace).
7983
func CreateRepoDeployment(clientset kubernetes.Interface, cluster *crv1.Pgcluster,
80-
createPVC, bootstrapRepo bool, replicas int) error {
84+
createPVC, bootstrapRepo bool, replicas int, namespace string) error {
8185
ctx := context.TODO()
8286

83-
namespace := cluster.GetNamespace()
8487
restoreClusterName := cluster.Spec.PGDataSource.RestoreFrom
8588

8689
repoFields := getRepoDeploymentFields(clientset, cluster, replicas)
8790

8891
var repoName, serviceName string
8992
// if this is a bootstrap repository then we now override certain fields as needed
9093
if bootstrapRepo {
91-
if err := setBootstrapRepoOverrides(clientset, cluster, repoFields); err != nil {
94+
if err := setBootstrapRepoOverrides(clientset, cluster, repoFields,
95+
namespace); err != nil {
9296
return err
9397
}
9498
repoName = fmt.Sprintf(util.BackrestRepoPVCName, restoreClusterName)
@@ -114,11 +118,13 @@ func CreateRepoDeployment(clientset kubernetes.Interface, cluster *crv1.Pgcluste
114118
// if createPVC is set to true, attempt to create the PVC
115119
if createPVC {
116120
// create backrest repo PVC with same name as repoName
117-
_, err := clientset.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, repoName, metav1.GetOptions{})
121+
_, err := clientset.CoreV1().PersistentVolumeClaims(namespace).Get(ctx,
122+
repoName, metav1.GetOptions{})
118123
if err == nil {
119124
log.Debugf("pvc [%s] already present, will not recreate", repoName)
120125
} else if kerrors.IsNotFound(err) {
121-
_, err = pvc.CreatePVC(clientset, &cluster.Spec.BackrestStorage, repoName, cluster.Name, namespace)
126+
_, err = pvc.CreatePVC(clientset, &cluster.Spec.BackrestStorage, repoName,
127+
cluster.Name, namespace)
122128
if err != nil {
123129
return err
124130
}
@@ -152,7 +158,8 @@ func CreateRepoDeployment(clientset kubernetes.Interface, cluster *crv1.Pgcluste
152158
operator.SetContainerImageOverride(config.CONTAINER_IMAGE_PGO_BACKREST_REPO,
153159
&deployment.Spec.Template.Spec.Containers[0])
154160

155-
if _, err := clientset.AppsV1().Deployments(namespace).Create(ctx, &deployment, metav1.CreateOptions{}); err != nil &&
161+
if _, err := clientset.AppsV1().Deployments(namespace).Create(ctx, &deployment,
162+
metav1.CreateOptions{}); err != nil &&
156163
!kerrors.IsAlreadyExists(err) {
157164
return err
158165
}
@@ -174,18 +181,22 @@ func CreateRepoSecret(clientset kubernetes.Interface, cluster *crv1.Pgcluster) e
174181
return err
175182
}
176183

177-
// setBootstrapRepoOverrides overrides certain fields used to populate the pgBackRest repository template
178-
// as needed to support the creation of a bootstrap repository need to bootstrap a new cluster from an
179-
// existing data source.
184+
// setBootstrapRepoOverrides overrides certain fields in the pgBackRest repository template as
185+
// as needed to support the creation of a bootstrap repository for bootstrapping a new cluster from
186+
// an existing data source. The namespace provided as a parameter corresponds to the namespace
187+
// containing the cluster that will be utilized as the data source for the new pgcluster (and is
188+
// therefore utilized to obtain any required resources from that cluster, e.g. its pgBackRest
189+
// configuration). This namespace could differ from the namespace for the new pgcluster if
190+
// bootstrapping/restoring from a cluster in another namespace.
180191
func setBootstrapRepoOverrides(clientset kubernetes.Interface, cluster *crv1.Pgcluster,
181-
repoFields *RepoDeploymentTemplateFields) error {
192+
repoFields *RepoDeploymentTemplateFields, namespace string) error {
182193
ctx := context.TODO()
183194

184195
restoreClusterName := cluster.Spec.PGDataSource.RestoreFrom
185-
namespace := cluster.GetNamespace()
186196

187197
repoFields.ClusterName = restoreClusterName
188198
repoFields.BootstrapCluster = cluster.GetName()
199+
repoFields.BootstrapNamespace = cluster.GetNamespace()
189200
repoFields.Name = fmt.Sprintf(util.BackrestRepoServiceName, restoreClusterName)
190201
repoFields.SshdSecretsName = fmt.Sprintf(util.BackrestRepoSecretName, restoreClusterName)
191202

0 commit comments

Comments
 (0)