Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions config/crd/bases/pgbackrest.cnpg.opera.com_archives.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,13 @@ spec:
- name
type: object
uriStyle:
description: S3 Repository URI style, either "host"
(default) or "path".
description: |-
S3 Repository URI style. Use "path" for S3-compatible stores (e.g. MinIO) at
internal endpoints that cannot resolve virtual-hosted-style DNS names.
Defaults to pgbackrest's own default ("host") when unset.
enum:
- host
- path
type: string
type: object
required:
Expand Down
20 changes: 17 additions & 3 deletions internal/pgbackrest/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ const (
KeyTypeWebID = KeyType("web-id")
)

// URIStyleType is the URI addressing style for S3-compatible repositories
type URIStyleType string

const (
// URIStyleHost uses virtual-hosted-style URIs (default): <bucket>.<endpoint>/key
URIStyleHost = URIStyleType("host")
// URIStylePath uses path-style URIs: <endpoint>/<bucket>/key
// Required for S3-compatible stores (e.g. MinIO) hosted at internal cluster endpoints
// that do not resolve virtual-hosted-style DNS names.
URIStylePath = URIStyleType("path")
)

// S3Credentials is the type for the credentials to be used to upload
// files to S3. It can be provided in two alternative ways:
//
Expand All @@ -96,10 +108,12 @@ type S3Credentials struct {
// +kubebuilder:validation:MinLength=1
Region string `json:"region,omitempty"`

// S3 Repository URI style, either "host" (default) or "path".
// TODO: Enforce values via Enum like iin compression.
// S3 Repository URI style. Use "path" for S3-compatible stores (e.g. MinIO) at
// internal endpoints that cannot resolve virtual-hosted-style DNS names.
// Defaults to pgbackrest's own default ("host") when unset.
// +kubebuilder:validation:Enum=host;path
// +optional
URIStyle string `json:"uriStyle,omitempty"`
URIStyle URIStyleType `json:"uriStyle,omitempty"`
}

// PgbackrestCredentials an object containing the potential credentials for each cloud provider
Expand Down
2 changes: 1 addition & 1 deletion internal/pgbackrest/command/commandbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func appendCloudProviderOptions(
options = append(
options,
utils.FormatRepoFlag(repoIndex, "s3-uri-style"),
repository.AWS.URIStyle)
string(repository.AWS.URIStyle))
}
}
return options, nil
Expand Down
57 changes: 57 additions & 0 deletions internal/pgbackrest/command/commandbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,63 @@ var _ = Describe("pgbackrestWalRestoreOptions", func() {
})
})

var _ = Describe("appendCloudProviderOptions", func() {
It("should include s3-uri-style flag when URIStyle is set to path", func(ctx SpecContext) {
conf := &pgbackrestApi.PgbackrestConfiguration{
Repositories: []pgbackrestApi.PgbackrestRepository{
{
Bucket: "my-bucket",
DestinationPath: "/",
PgbackrestCredentials: pgbackrestApi.PgbackrestCredentials{
AWS: &pgbackrestApi.S3Credentials{
URIStyle: pgbackrestApi.URIStylePath,
},
},
},
},
}
var empty []string
options, err := AppendCloudProviderOptionsFromConfiguration(ctx, empty, conf)
Expect(err).ToNot(HaveOccurred())
Expect(strings.Join(options, " ")).To(ContainSubstring("--repo1-s3-uri-style path"))
})

It("should include s3-uri-style flag when URIStyle is set to host", func(ctx SpecContext) {
conf := &pgbackrestApi.PgbackrestConfiguration{
Repositories: []pgbackrestApi.PgbackrestRepository{
{
Bucket: "my-bucket",
DestinationPath: "/",
PgbackrestCredentials: pgbackrestApi.PgbackrestCredentials{
AWS: &pgbackrestApi.S3Credentials{
URIStyle: pgbackrestApi.URIStyleHost,
},
},
},
},
}
var empty []string
options, err := AppendCloudProviderOptionsFromConfiguration(ctx, empty, conf)
Expect(err).ToNot(HaveOccurred())
Expect(strings.Join(options, " ")).To(ContainSubstring("--repo1-s3-uri-style host"))
})

It("should omit s3-uri-style flag when URIStyle is empty", func(ctx SpecContext) {
conf := &pgbackrestApi.PgbackrestConfiguration{
Repositories: []pgbackrestApi.PgbackrestRepository{
{
Bucket: "my-bucket",
DestinationPath: "/",
},
},
}
var empty []string
options, err := AppendCloudProviderOptionsFromConfiguration(ctx, empty, conf)
Expect(err).ToNot(HaveOccurred())
Expect(strings.Join(options, " ")).NotTo(ContainSubstring("s3-uri-style"))
})
})

var _ = Describe("PgbackrestRetention", func() {
var config *pgbackrestApi.PgbackrestConfiguration
var history int32 = 8
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/internal/objectstore/minio.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ func NewMinioArchive(namespace, name, minioOSName string, maxParallel int) *plug
Region: "dummy",
// There is no ingress that would provide domain-based
// routing.
URIStyle: "path",
URIStyle: pgbackrestApi.URIStylePath,
},
},
EndpointURL: net.JoinHostPort(minioOSName, "9000"),
Expand Down