Skip to content

Commit eb9b042

Browse files
authored
Allow for a S3 bucket name to be edited after cluster creation
This allows for the name of a S3 bucket to be edited after a cluster is created, i.e. through the custom resource. Should this action be taken, the following occurs: - The pgBackRest report Pod is redeployed - The PostgreSQL cluster is redeployed using a rolling update - Once the above two actions complete, a new stanza is created and an initial backup in that stanza is created. A create stanza must be attempted as the new bucket may be entirely empty. Issue: [ch11061]
1 parent 04cd81d commit eb9b042

File tree

5 files changed

+101
-13
lines changed

5 files changed

+101
-13
lines changed

docs/content/architecture/high-availability/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,5 +443,6 @@ modification to the custom resource:
443443
- Custom annotation changes
444444
- Enabling/disabling the monitoring sidecar on a PostgreSQL cluster (`--metrics`)
445445
- Enabling/disabling the pgBadger sidecar on a PostgreSQL cluster (`--pgbadger`)
446+
- S3 bucket name updates
446447
- Tablespace additions
447448
- Toleration modifications

docs/content/custom-resources/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ make changes, as described below.
726726
| backrestLimits | `create`, `update` | Specify the container resource limits that the pgBackRest repository should use. Follows the [Kubernetes definitions of resource limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-requests-and-limits-of-pod-and-container). |
727727
| backrestRepoPath | `create` | Optional reference to the location of the pgBackRest repository. |
728728
| BackrestResources | `create`, `update` | Specify the container resource requests that the pgBackRest repository should use. Follows the [Kubernetes definitions of resource requests](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-requests-and-limits-of-pod-and-container). |
729-
| backrestS3Bucket | `create` | An optional parameter that specifies a S3 bucket that pgBackRest should use. |
729+
| backrestS3Bucket | `create`, `update` | An optional parameter that specifies a S3 bucket that pgBackRest should use. If the name is updated, the Postgres Operator will create a new stanza and take an initial backup in the new bucket. |
730730
| backrestS3Endpoint | `create` | An optional parameter that specifies the S3 endpoint pgBackRest should use. |
731731
| backrestS3Region | `create` | An optional parameter that specifies a cloud region that pgBackRest should use. |
732732
| backrestS3URIStyle | `create` | An optional parameter that specifies if pgBackRest should use the `path` or `host` S3 URI style. |

internal/apiserver/backrestservice/backrestimpl.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -424,21 +424,19 @@ func ShowBackrest(name, selector, ns string) msgs.ShowBackrestResponse {
424424

425425
// get the pgBackRest info using this legacy function
426426
info, err := getInfo(storageType, podname, ns, verifyTLS)
427+
427428
// see if the function returned successfully, and if so, unmarshal the JSON
429+
// if there was an error getting the info, log that the error occurred in
430+
// the API server logs and have the response added to the list.
428431
if err != nil {
429432
log.Error(err)
430-
response.Status.Code = msgs.Error
431-
response.Status.Msg = err.Error()
432-
433-
return response
434-
}
435-
436-
if err := json.Unmarshal([]byte(info), &detail.Info); err != nil {
437-
log.Error(err)
438-
response.Status.Code = msgs.Error
439-
response.Status.Msg = err.Error()
440-
441-
return response
433+
} else {
434+
if err := json.Unmarshal([]byte(info), &detail.Info); err != nil {
435+
log.Error(err)
436+
response.Status.Code = msgs.Error
437+
response.Status.Msg = err.Error()
438+
return response
439+
}
442440
}
443441

444442
// append the details to the list of items

internal/controller/pgcluster/pgclustercontroller.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
import (
1919
"context"
2020
"encoding/json"
21+
"fmt"
2122
"reflect"
2223
"strings"
2324

@@ -332,6 +333,20 @@ func (c *Controller) onUpdate(oldObj, newObj interface{}) {
332333
rollingUpdateFuncs = append(rollingUpdateFuncs, clusteroperator.UpdateTolerations)
333334
}
334335

336+
// check to see if the S3 bucket name has changed. If it has, this requires
337+
// both updating the Postgres + pgBackRest Deployments AND reruning the stanza
338+
// create Job
339+
if oldcluster.Spec.BackrestS3Bucket != newcluster.Spec.BackrestS3Bucket {
340+
// first, update the pgBackRest repository
341+
if err := updateBackrestS3(c, newcluster); err != nil {
342+
log.Errorf("not updating pgBackrest S3 settings: %s", err.Error())
343+
} else {
344+
// if that is successful, add updating the pgBackRest S3 settings to the
345+
// rolling update changes
346+
rollingUpdateFuncs = append(rollingUpdateFuncs, clusteroperator.UpdateBackrestS3)
347+
}
348+
}
349+
335350
// if there is no need to perform a rolling update, exit here
336351
if len(rollingUpdateFuncs) == 0 {
337352
return
@@ -351,6 +366,12 @@ func (c *Controller) onUpdate(oldObj, newObj interface{}) {
351366
log.Error(err)
352367
return
353368
}
369+
370+
// one follow-up post rolling update: if the S3 bucket changed, issue a
371+
// "create stanza" job
372+
if oldcluster.Spec.BackrestS3Bucket != newcluster.Spec.BackrestS3Bucket {
373+
backrestoperator.StanzaCreate(newcluster.Namespace, newcluster.Name, c.Client)
374+
}
354375
}
355376

356377
// onDelete is called when a pgcluster is deleted
@@ -508,6 +529,54 @@ func updateAnnotations(c *Controller, oldCluster *crv1.Pgcluster, newCluster *cr
508529
return len(annotationsPostgres) != 0, nil
509530
}
510531

532+
// updateBackrestS3 makes updates to the pgBackRest repo Deployment if any of
533+
// the S3 specific settings have changed. Presently, this is just the S3 bucket
534+
// name
535+
func updateBackrestS3(c *Controller, cluster *crv1.Pgcluster) error {
536+
ctx := context.TODO()
537+
538+
// get the pgBackRest deployment
539+
backrestDeploymentName := fmt.Sprintf(util.BackrestRepoDeploymentName, cluster.Name)
540+
backrestDeployment, err := c.Client.AppsV1().Deployments(cluster.Namespace).Get(ctx,
541+
backrestDeploymentName, metav1.GetOptions{})
542+
543+
if err != nil {
544+
return err
545+
}
546+
547+
// update the environmental variable(s) in the container that is aptly(?)
548+
// named database
549+
for i, container := range backrestDeployment.Spec.Template.Spec.Containers {
550+
if container.Name != "database" {
551+
continue
552+
}
553+
554+
for j, envVar := range backrestDeployment.Spec.Template.Spec.Containers[i].Env {
555+
if envVar.Name == "PGBACKREST_REPO1_S3_BUCKET" {
556+
backrestDeployment.Spec.Template.Spec.Containers[i].Env[j].Value = cluster.Spec.BackrestS3Bucket
557+
}
558+
}
559+
}
560+
561+
if _, err := c.Client.AppsV1().Deployments(cluster.Namespace).Update(ctx,
562+
backrestDeployment, metav1.UpdateOptions{}); err != nil {
563+
return err
564+
}
565+
566+
// update the annotation on the pgBackRest Secret too
567+
secretName := fmt.Sprintf(util.BackrestRepoSecretName, cluster.Name)
568+
patch, _ := kubeapi.NewMergePatch().Add("metadata", "annotations")(map[string]string{
569+
config.ANNOTATION_S3_BUCKET: cluster.Spec.BackrestS3Bucket,
570+
}).Bytes()
571+
572+
if _, err := c.Client.CoreV1().Secrets(cluster.Namespace).Patch(ctx,
573+
secretName, types.MergePatchType, patch, metav1.PatchOptions{}); err != nil {
574+
return err
575+
}
576+
577+
return nil
578+
}
579+
511580
// updatePgBouncer updates the pgBouncer Deployment to reflect any changes that
512581
// may be made, which include:
513582
// - enabling a pgBouncer Deployment :)

internal/operator/cluster/cluster.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,26 @@ func UpdateAnnotations(clientset kubeapi.Interface, cluster *crv1.Pgcluster, dep
485485
return nil
486486
}
487487

488+
// UpdateBackrestS3 updates any pgBackRest settings that may have been updated.
489+
// Presently this is just the bucket name.
490+
func UpdateBackrestS3(clientset kubeapi.Interface, cluster *crv1.Pgcluster, deployment *apps_v1.Deployment) error {
491+
// go through the environmetnal variables on the "database" container and edit
492+
// the appropriate S3 related ones
493+
for i, container := range deployment.Spec.Template.Spec.Containers {
494+
if container.Name != "database" {
495+
continue
496+
}
497+
498+
for j, envVar := range deployment.Spec.Template.Spec.Containers[i].Env {
499+
if envVar.Name == "PGBACKREST_REPO1_S3_BUCKET" {
500+
deployment.Spec.Template.Spec.Containers[i].Env[j].Value = cluster.Spec.BackrestS3Bucket
501+
}
502+
}
503+
}
504+
505+
return nil
506+
}
507+
488508
// UpdateResources updates the PostgreSQL instance Deployments to reflect the
489509
// update resources (i.e. CPU, memory)
490510
func UpdateResources(clientset kubeapi.Interface, cluster *crv1.Pgcluster, deployment *apps_v1.Deployment) error {

0 commit comments

Comments
 (0)