diff --git a/go.mod b/go.mod index a6f2e69c..153b3525 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/cloudnative-pg/barman-cloud +module github.com/davidchandra95/barman-cloud go 1.26.0 diff --git a/pkg/api/config.go b/pkg/api/config.go index 0e731081..350cc140 100644 --- a/pkg/api/config.go +++ b/pkg/api/config.go @@ -165,6 +165,20 @@ type GoogleCredentials struct { GKEEnvironment bool `json:"gkeEnvironment,omitempty"` } +// S3AddressingStyle controls how Barman Cloud addresses S3 buckets. +type S3AddressingStyle string + +const ( + // S3AddressingStyleAuto lets Barman Cloud choose the addressing style. + S3AddressingStyleAuto S3AddressingStyle = "auto" + + // S3AddressingStyleVirtual addresses buckets as subdomains of the endpoint. + S3AddressingStyleVirtual S3AddressingStyle = "virtual" + + // S3AddressingStylePath addresses buckets as a path below the endpoint. + S3AddressingStylePath S3AddressingStyle = "path" +) + // BarmanObjectStoreConfiguration contains the backup configuration // using Barman against an S3-compatible object storage type BarmanObjectStoreConfiguration struct { @@ -176,6 +190,12 @@ type BarmanObjectStoreConfiguration struct { // +optional EndpointURL string `json:"endpointURL,omitempty"` + // S3AddressingStyle controls how Barman Cloud addresses S3 buckets. It is + // applied to every Barman Cloud command that uses this object store. + // +kubebuilder:validation:Enum=auto;virtual;path + // +optional + S3AddressingStyle S3AddressingStyle `json:"s3AddressingStyle,omitempty"` + // 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 diff --git a/pkg/api/webhooks/config.go b/pkg/api/webhooks/config.go index 7300e63f..a633206d 100644 --- a/pkg/api/webhooks/config.go +++ b/pkg/api/webhooks/config.go @@ -22,8 +22,8 @@ package webhooks import ( "k8s.io/apimachinery/pkg/util/validation/field" - "github.com/cloudnative-pg/barman-cloud/pkg/api" - "github.com/cloudnative-pg/barman-cloud/pkg/utils" + "github.com/davidchandra95/barman-cloud/pkg/api" + "github.com/davidchandra95/barman-cloud/pkg/utils" ) // ValidateBackupConfiguration validates the backup configuration diff --git a/pkg/api/webhooks/config_test.go b/pkg/api/webhooks/config_test.go index edf5e25c..68e0137a 100644 --- a/pkg/api/webhooks/config_test.go +++ b/pkg/api/webhooks/config_test.go @@ -22,7 +22,7 @@ package webhooks import ( "k8s.io/apimachinery/pkg/util/validation/field" - api "github.com/cloudnative-pg/barman-cloud/pkg/api" + api "github.com/davidchandra95/barman-cloud/pkg/api" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/pkg/archiver/archiver.go b/pkg/archiver/archiver.go index 18e48155..2f99976a 100644 --- a/pkg/archiver/archiver.go +++ b/pkg/archiver/archiver.go @@ -27,10 +27,10 @@ import ( "github.com/cloudnative-pg/machinery/pkg/log" - "github.com/cloudnative-pg/barman-cloud/pkg/api" - "github.com/cloudnative-pg/barman-cloud/pkg/command" - "github.com/cloudnative-pg/barman-cloud/pkg/spool" - "github.com/cloudnative-pg/barman-cloud/pkg/walarchive" + "github.com/davidchandra95/barman-cloud/pkg/api" + "github.com/davidchandra95/barman-cloud/pkg/command" + "github.com/davidchandra95/barman-cloud/pkg/spool" + "github.com/davidchandra95/barman-cloud/pkg/walarchive" ) // WALArchiver is a structure containing every info need to archive a set of WAL files diff --git a/pkg/archiver/command.go b/pkg/archiver/command.go index 92be4e9e..83090087 100644 --- a/pkg/archiver/command.go +++ b/pkg/archiver/command.go @@ -23,9 +23,9 @@ import ( "context" "fmt" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" - barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command" - "github.com/cloudnative-pg/barman-cloud/pkg/utils" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" + barmanCommand "github.com/davidchandra95/barman-cloud/pkg/command" + "github.com/davidchandra95/barman-cloud/pkg/utils" ) // BarmanCloudWalArchiveOptions calculates the set of options to be diff --git a/pkg/archiver/command_test.go b/pkg/archiver/command_test.go index d8df9c33..82ccab77 100644 --- a/pkg/archiver/command_test.go +++ b/pkg/archiver/command_test.go @@ -23,7 +23,7 @@ import ( "os" "strings" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/pkg/backup/backup.go b/pkg/backup/backup.go index 74a08075..72df4aac 100644 --- a/pkg/backup/backup.go +++ b/pkg/backup/backup.go @@ -29,10 +29,10 @@ import ( "github.com/cloudnative-pg/machinery/pkg/execlog" "github.com/cloudnative-pg/machinery/pkg/log" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" - barmanCatalog "github.com/cloudnative-pg/barman-cloud/pkg/catalog" - barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command" - "github.com/cloudnative-pg/barman-cloud/pkg/utils" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" + barmanCatalog "github.com/davidchandra95/barman-cloud/pkg/catalog" + barmanCommand "github.com/davidchandra95/barman-cloud/pkg/command" + "github.com/davidchandra95/barman-cloud/pkg/utils" ) // Command represents a barman backup command diff --git a/pkg/backup/backup_test.go b/pkg/backup/backup_test.go index 7d7586f6..5d534787 100644 --- a/pkg/backup/backup_test.go +++ b/pkg/backup/backup_test.go @@ -24,7 +24,7 @@ import ( "k8s.io/utils/ptr" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -130,4 +130,23 @@ var _ = Describe("GetBarmanCloudBackupOptions", func() { "s3://bucket-name/ test-cluster", )) }) + + It("should apply the configured S3 addressing style over additional arguments", func(ctx SpecContext) { + backupCommand.configuration.BarmanCredentials = barmanApi.BarmanCredentials{ + AWS: &barmanApi.S3Credentials{InheritFromIAMRole: true}, + } + backupCommand.configuration.S3AddressingStyle = barmanApi.S3AddressingStyleVirtual + backupCommand.configuration.Data.AdditionalCommandArgs = []string{ + "--addressing-style", "path", + } + + options, err := backupCommand.GetBarmanCloudBackupOptions(ctx, "test-backup", "test-cluster") + Expect(err).ToNot(HaveOccurred()) + Expect(strings.Join(options, " ")).To(Equal( + "--user postgres --name test-backup " + + "--gzip --encryption aes256 --immediate-checkpoint --jobs 4 " + + "--cloud-provider aws-s3 --addressing-style virtual " + + "s3://bucket-name/ test-cluster", + )) + }) }) diff --git a/pkg/command/backupdelete.go b/pkg/command/backupdelete.go index 7fbff495..6f6f3d66 100644 --- a/pkg/command/backupdelete.go +++ b/pkg/command/backupdelete.go @@ -26,8 +26,8 @@ import ( "github.com/cloudnative-pg/machinery/pkg/log" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" - barmanUtils "github.com/cloudnative-pg/barman-cloud/pkg/utils" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" + barmanUtils "github.com/davidchandra95/barman-cloud/pkg/utils" ) // DeleteBackupsByPolicy executes a command that deletes backups, given the Barman object store configuration, diff --git a/pkg/command/backuplist.go b/pkg/command/backuplist.go index 4dc1e19d..6b548cbd 100644 --- a/pkg/command/backuplist.go +++ b/pkg/command/backuplist.go @@ -51,9 +51,9 @@ import ( "github.com/cloudnative-pg/machinery/pkg/log" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" - "github.com/cloudnative-pg/barman-cloud/pkg/catalog" - "github.com/cloudnative-pg/barman-cloud/pkg/utils" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" + "github.com/davidchandra95/barman-cloud/pkg/catalog" + "github.com/davidchandra95/barman-cloud/pkg/utils" ) func executeQueryCommand( diff --git a/pkg/command/commandbuilder.go b/pkg/command/commandbuilder.go index 70260b0b..36e3677c 100644 --- a/pkg/command/commandbuilder.go +++ b/pkg/command/commandbuilder.go @@ -21,8 +21,10 @@ package command import ( "context" + "fmt" + "strings" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" ) // CloudWalRestoreOptions returns the options needed to execute the barman command successfully @@ -62,7 +64,27 @@ func AppendCloudProviderOptionsFromConfiguration( options []string, barmanConfiguration *barmanApi.BarmanObjectStoreConfiguration, ) ([]string, error) { - return appendCloudProviderOptions(ctx, options, barmanConfiguration.BarmanCredentials) + if barmanConfiguration.S3AddressingStyle != "" { + if barmanConfiguration.AWS == nil { + return nil, fmt.Errorf("s3AddressingStyle requires s3Credentials") + } + + options = withoutOption(options, "--addressing-style") + } + + options, err := appendCloudProviderOptions(ctx, options, barmanConfiguration.BarmanCredentials) + if err != nil { + return nil, err + } + + if barmanConfiguration.S3AddressingStyle != "" { + options = append(options, + "--addressing-style", + string(barmanConfiguration.S3AddressingStyle), + ) + } + + return options, nil } // AppendCloudProviderOptionsFromBackup takes an options array and adds the cloud provider specified @@ -127,6 +149,28 @@ func appendCloudProviderOptions( return options, nil } +// withoutOption removes a command-line option and its value from options. +// The configured ObjectStore value must take precedence over a command-specific +// additional argument so every Barman command uses the same addressing style. +func withoutOption(options []string, option string) []string { + result := make([]string, 0, len(options)) + for index := 0; index < len(options); index++ { + current := options[index] + switch { + case current == option: + if index+1 < len(options) { + index++ + } + case strings.HasPrefix(current, option+"="): + continue + default: + result = append(result, current) + } + } + + return result +} + type contextKey string // contextKeyUseDefaultAzureCredentials contains a bool indicating if the default azure credentials should be used diff --git a/pkg/command/commandbuilder_test.go b/pkg/command/commandbuilder_test.go index bb2d1a0d..b3a6320d 100644 --- a/pkg/command/commandbuilder_test.go +++ b/pkg/command/commandbuilder_test.go @@ -25,7 +25,7 @@ import ( machineryapi "github.com/cloudnative-pg/machinery/pkg/api" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -62,6 +62,21 @@ var _ = Describe("barmanCloudWalRestoreOptions", func() { "s3://bucket-name/ test-cluster --read-timeout=60 -vv", )) }) + + It("should apply the configured S3 addressing style", func(ctx SpecContext) { + storageConf.BarmanCredentials = barmanApi.BarmanCredentials{ + AWS: &barmanApi.S3Credentials{InheritFromIAMRole: true}, + } + storageConf.S3AddressingStyle = barmanApi.S3AddressingStyleVirtual + + options, err := CloudWalRestoreOptions(ctx, storageConf, "test-cluster") + Expect(err).ToNot(HaveOccurred()) + Expect(options).To(Equal([]string{ + "--cloud-provider", "aws-s3", + "--addressing-style", "virtual", + "s3://bucket-name/", "test-cluster", + })) + }) }) var _ = Describe("useDefaultAzureCredentials", func() { @@ -172,3 +187,33 @@ var _ = Describe("AppendCloudProviderOptions with Azure credentials", func() { )) }) }) + +var _ = Describe("AppendCloudProviderOptionsFromConfiguration with S3 addressing", func() { + It("should replace an addressing style from command-specific arguments", func(ctx SpecContext) { + configuration := &barmanApi.BarmanObjectStoreConfiguration{ + BarmanCredentials: barmanApi.BarmanCredentials{ + AWS: &barmanApi.S3Credentials{InheritFromIAMRole: true}, + }, + S3AddressingStyle: barmanApi.S3AddressingStyleVirtual, + } + + options, err := AppendCloudProviderOptionsFromConfiguration(ctx, []string{ + "--addressing-style", "path", "--read-timeout=60", + }, configuration) + Expect(err).ToNot(HaveOccurred()) + Expect(options).To(Equal([]string{ + "--read-timeout=60", + "--cloud-provider", "aws-s3", + "--addressing-style", "virtual", + })) + }) + + It("should reject an addressing style without S3 credentials", func(ctx SpecContext) { + configuration := &barmanApi.BarmanObjectStoreConfiguration{ + S3AddressingStyle: barmanApi.S3AddressingStyleVirtual, + } + + _, err := AppendCloudProviderOptionsFromConfiguration(ctx, nil, configuration) + Expect(err).To(MatchError("s3AddressingStyle requires s3Credentials")) + }) +}) diff --git a/pkg/credentials/env.go b/pkg/credentials/env.go index d7810288..8860a540 100644 --- a/pkg/credentials/env.go +++ b/pkg/credentials/env.go @@ -28,7 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - barmanApi "github.com/cloudnative-pg/barman-cloud/pkg/api" + barmanApi "github.com/davidchandra95/barman-cloud/pkg/api" ) const ( diff --git a/pkg/restorer/restorer.go b/pkg/restorer/restorer.go index 46f17a7b..3e7db2ad 100644 --- a/pkg/restorer/restorer.go +++ b/pkg/restorer/restorer.go @@ -31,8 +31,8 @@ import ( "github.com/cloudnative-pg/machinery/pkg/execlog" "github.com/cloudnative-pg/machinery/pkg/log" - "github.com/cloudnative-pg/barman-cloud/pkg/spool" - "github.com/cloudnative-pg/barman-cloud/pkg/utils" + "github.com/davidchandra95/barman-cloud/pkg/spool" + "github.com/davidchandra95/barman-cloud/pkg/utils" ) const ( diff --git a/pkg/walarchive/cmd.go b/pkg/walarchive/cmd.go index f8db8eb5..831b6177 100644 --- a/pkg/walarchive/cmd.go +++ b/pkg/walarchive/cmd.go @@ -31,7 +31,7 @@ import ( "github.com/cloudnative-pg/machinery/pkg/fileutils" "github.com/cloudnative-pg/machinery/pkg/log" - "github.com/cloudnative-pg/barman-cloud/pkg/utils" + "github.com/davidchandra95/barman-cloud/pkg/utils" ) // BarmanArchiver implements a WAL archiver based