From 1c3dd8558fd2c11c4409d09b68ec1bfba5f6d867 Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Thu, 13 Nov 2025 18:06:00 +0100 Subject: [PATCH 1/6] feat(auth): add support for DefaultAzureCredential Signed-off-by: Gabriele Fedi --- internal/cnpgi/common/common.go | 15 +++++++++++++++ internal/cnpgi/common/wal.go | 2 ++ internal/cnpgi/instance/backup.go | 2 ++ internal/cnpgi/instance/retention.go | 2 ++ internal/cnpgi/restore/restore.go | 4 +++- pkg/metadata/doc.go | 2 ++ pkg/metadata/labels_annotations.go | 15 +++++++++++++++ 7 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 pkg/metadata/doc.go create mode 100644 pkg/metadata/labels_annotations.go diff --git a/internal/cnpgi/common/common.go b/internal/cnpgi/common/common.go index 9526d7e2..5a21c1e3 100644 --- a/internal/cnpgi/common/common.go +++ b/internal/cnpgi/common/common.go @@ -20,13 +20,17 @@ SPDX-License-Identifier: Apache-2.0 package common import ( + "context" "fmt" "path" "strings" barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api" + "github.com/cloudnative-pg/barman-cloud/pkg/command" + barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata" + pluginmetadata "github.com/cloudnative-pg/plugin-barman-cloud/pkg/metadata" ) // TODO: refactor. @@ -97,3 +101,14 @@ func MergeEnv(env []string, incomingEnv []string) []string { func BuildCertificateFilePath(objectStoreName string) string { return path.Join(metadata.BarmanCertificatesPath, objectStoreName, metadata.BarmanCertificatesFileName) } + +// ContextWithProviderOptions enriches the context with cloud service provider specific options +// based on the ObjectStore resource +func ContextWithProviderOptions(ctx context.Context, objectStore barmancloudv1.ObjectStore) context.Context { + if objectStore.GetAnnotations()[pluginmetadata.UseDefaultAzureCredentialsAnnotationName] == + pluginmetadata.UseDefaultAzureCredentialsTrueValue { + return command.ContextWithDefaultAzureCredentials(ctx, true) + } + + return ctx +} diff --git a/internal/cnpgi/common/wal.go b/internal/cnpgi/common/wal.go index 8e58cb42..c9b286bc 100644 --- a/internal/cnpgi/common/wal.go +++ b/internal/cnpgi/common/wal.go @@ -127,6 +127,8 @@ func (w WALServiceImplementation) Archive( return nil, err } + ctx = ContextWithProviderOptions(ctx, objectStore) + envArchive, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates( ctx, w.Client, diff --git a/internal/cnpgi/instance/backup.go b/internal/cnpgi/instance/backup.go index ebf166c4..0b90edea 100644 --- a/internal/cnpgi/instance/backup.go +++ b/internal/cnpgi/instance/backup.go @@ -87,6 +87,8 @@ func (b BackupServiceImplementation) Backup( return nil, err } + ctx = common.ContextWithProviderOptions(ctx, objectStore) + if err := fileutils.EnsureDirectoryExists(postgres.BackupTemporaryDirectory); err != nil { contextLogger.Error(err, "Cannot create backup temporary directory", "err", err) return nil, err diff --git a/internal/cnpgi/instance/retention.go b/internal/cnpgi/instance/retention.go index 372d50ee..ec4becb6 100644 --- a/internal/cnpgi/instance/retention.go +++ b/internal/cnpgi/instance/retention.go @@ -93,6 +93,8 @@ func (c *CatalogMaintenanceRunnable) cycle(ctx context.Context) (time.Duration, return 0, err } + ctx = common.ContextWithProviderOptions(ctx, barmanObjectStore) + if err := c.maintenance(ctx, &cluster, &barmanObjectStore); err != nil { return 0, err } diff --git a/internal/cnpgi/restore/restore.go b/internal/cnpgi/restore/restore.go index 187143ee..42d8f623 100644 --- a/internal/cnpgi/restore/restore.go +++ b/internal/cnpgi/restore/restore.go @@ -109,7 +109,7 @@ func (impl JobHookImpl) Restore( } if err := impl.checkBackupDestination( - ctx, + common.ContextWithProviderOptions(ctx, targetObjectStore), configuration.Cluster, &targetObjectStore.Spec.Configuration, targetObjectStore.Name, @@ -118,6 +118,8 @@ func (impl JobHookImpl) Restore( } } + ctx = common.ContextWithProviderOptions(ctx, recoveryObjectStore) + // Detect the backup to recover backup, env, err := loadBackupObjectFromExternalCluster( ctx, diff --git a/pkg/metadata/doc.go b/pkg/metadata/doc.go new file mode 100644 index 00000000..5d2f6890 --- /dev/null +++ b/pkg/metadata/doc.go @@ -0,0 +1,2 @@ +// Package metadata provides metadata utilities for the Barman Cloud plugin +package metadata diff --git a/pkg/metadata/labels_annotations.go b/pkg/metadata/labels_annotations.go new file mode 100644 index 00000000..5dae9b69 --- /dev/null +++ b/pkg/metadata/labels_annotations.go @@ -0,0 +1,15 @@ +package metadata + +// MetadataNamespace is the namespace used for the Barman Cloud plugin metadata +const MetadataNamespace = "barmancloud.cnpg.io" + +const ( + // UseDefaultAzureCredentialsAnnotationName is an annotation that can be set + // on an ObjectStore resource to enable the use DefaultAzureCredentials + // to authenticate to Azure. This is meant to be used with inheritFromAzureAD enabled. + UseDefaultAzureCredentialsAnnotationName = MetadataNamespace + "/useDefaultAzureCredentials" + + // UseDefaultAzureCredentialsTrueValue is the value for the annotation + // barmancloud.cnpg.io/useDefaultAzureCredentials to enable the use of DefaultAzureCredentials + UseDefaultAzureCredentialsTrueValue = "true" +) From c811749c328cc7b795b146377a64d89f68f1eddc Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Fri, 14 Nov 2025 16:54:50 +0100 Subject: [PATCH 2/6] docs: default azure credentials Signed-off-by: Gabriele Fedi --- web/docs/object_stores.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/web/docs/object_stores.md b/web/docs/object_stores.md index f1714c93..ed5d2030 100644 --- a/web/docs/object_stores.md +++ b/web/docs/object_stores.md @@ -233,6 +233,7 @@ Barman Cloud supports the following authentication methods: - Storage Account Name + [Access Key](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage) - Storage Account Name + [SAS Token](https://learn.microsoft.com/en-us/azure/storage/blobs/sas-service-create) - [Azure AD Workload Identity](https://azure.github.io/azure-workload-identity/docs/introduction.html) +- [Azure Default Credentials](https://learn.microsoft.com/en-us/azure/developer/go/sdk/authentication/credential-chains#defaultazurecredential-overview) ### Azure AD Workload Identity @@ -252,6 +253,26 @@ spec: [...] ``` +### Azure Default Credentials + +To authenticate using Azure Default Credentials, set the annotation +`barmancloud.cnpg.io/useDefaultAzureCredentials="true"` on the ObjectStore: + +```yaml +apiVersion: barmancloud.cnpg.io/v1 +kind: ObjectStore +metadata: + name: azure-store + annotations: + barmancloud.cnpg.io/useDefaultAzureCredentials: "true" +spec: + configuration: + destinationPath: "" + azureCredentials: + inheritFromAzureAD: true + [...] +``` + ### Access Key, SAS Token, or Connection String Store credentials in a Kubernetes secret: From 80dfe727ed10a7a5cb850f72ded2a52b9ef04670 Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Mon, 17 Nov 2025 10:17:48 +0100 Subject: [PATCH 3/6] style(lint): imports Signed-off-by: Gabriele Fedi --- internal/cnpgi/common/common.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cnpgi/common/common.go b/internal/cnpgi/common/common.go index 5a21c1e3..b9d4280f 100644 --- a/internal/cnpgi/common/common.go +++ b/internal/cnpgi/common/common.go @@ -28,7 +28,7 @@ import ( barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api" "github.com/cloudnative-pg/barman-cloud/pkg/command" - barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" + apiv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata" pluginmetadata "github.com/cloudnative-pg/plugin-barman-cloud/pkg/metadata" ) @@ -104,7 +104,7 @@ func BuildCertificateFilePath(objectStoreName string) string { // ContextWithProviderOptions enriches the context with cloud service provider specific options // based on the ObjectStore resource -func ContextWithProviderOptions(ctx context.Context, objectStore barmancloudv1.ObjectStore) context.Context { +func ContextWithProviderOptions(ctx context.Context, objectStore apiv1.ObjectStore) context.Context { if objectStore.GetAnnotations()[pluginmetadata.UseDefaultAzureCredentialsAnnotationName] == pluginmetadata.UseDefaultAzureCredentialsTrueValue { return command.ContextWithDefaultAzureCredentials(ctx, true) From 6d2d3eb925fd1ac6da51e329f849336e8ad9371c Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Mon, 17 Nov 2025 10:18:22 +0100 Subject: [PATCH 4/6] chore(dockerfile): add pkg folder to containers Signed-off-by: Gabriele Fedi --- containers/Dockerfile.plugin | 1 + containers/Dockerfile.sidecar | 1 + 2 files changed, 2 insertions(+) diff --git a/containers/Dockerfile.plugin b/containers/Dockerfile.plugin index 5777125c..f090e3b1 100644 --- a/containers/Dockerfile.plugin +++ b/containers/Dockerfile.plugin @@ -15,6 +15,7 @@ RUN go mod download COPY ../cmd/manager/main.go cmd/manager/main.go COPY ../api/ api/ COPY ../internal/ internal/ +COPY ../pkg/ pkg/ ENV GOCACHE=/root/.cache/go-build ENV GOMODCACHE=/go/pkg/mod diff --git a/containers/Dockerfile.sidecar b/containers/Dockerfile.sidecar index 828fcff5..a43b8d04 100644 --- a/containers/Dockerfile.sidecar +++ b/containers/Dockerfile.sidecar @@ -24,6 +24,7 @@ ENV GOMODCACHE=/go/pkg/mod COPY ../cmd/manager/main.go cmd/manager/main.go COPY ../api/ api/ COPY ../internal/ internal/ +COPY ../pkg/ pkg/ # Build # the GOARCH has not a default value to allow the binary be built according to the host where the command From cdb893a70dadedc2dd7bbe7ad808b794477c94a8 Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Mon, 17 Nov 2025 10:50:16 +0100 Subject: [PATCH 5/6] docs: minor fixes Signed-off-by: Gabriele Fedi --- pkg/metadata/labels_annotations.go | 6 +++--- web/docs/object_stores.md | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/metadata/labels_annotations.go b/pkg/metadata/labels_annotations.go index 5dae9b69..cf6ec560 100644 --- a/pkg/metadata/labels_annotations.go +++ b/pkg/metadata/labels_annotations.go @@ -5,11 +5,11 @@ const MetadataNamespace = "barmancloud.cnpg.io" const ( // UseDefaultAzureCredentialsAnnotationName is an annotation that can be set - // on an ObjectStore resource to enable the use DefaultAzureCredentials - // to authenticate to Azure. This is meant to be used with inheritFromAzureAD enabled. + // on an ObjectStore resource to enable the authentication to Azure via DefaultAzureCredentials. + // This is meant to be used with inheritFromAzureAD enabled. UseDefaultAzureCredentialsAnnotationName = MetadataNamespace + "/useDefaultAzureCredentials" // UseDefaultAzureCredentialsTrueValue is the value for the annotation - // barmancloud.cnpg.io/useDefaultAzureCredentials to enable the use of DefaultAzureCredentials + // barmancloud.cnpg.io/useDefaultAzureCredentials to enable the DefaultAzureCredentials auth mechanism. UseDefaultAzureCredentialsTrueValue = "true" ) diff --git a/web/docs/object_stores.md b/web/docs/object_stores.md index ed5d2030..ea4f9425 100644 --- a/web/docs/object_stores.md +++ b/web/docs/object_stores.md @@ -233,7 +233,7 @@ Barman Cloud supports the following authentication methods: - Storage Account Name + [Access Key](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage) - Storage Account Name + [SAS Token](https://learn.microsoft.com/en-us/azure/storage/blobs/sas-service-create) - [Azure AD Workload Identity](https://azure.github.io/azure-workload-identity/docs/introduction.html) -- [Azure Default Credentials](https://learn.microsoft.com/en-us/azure/developer/go/sdk/authentication/credential-chains#defaultazurecredential-overview) +- [DefaultAzureCredential](https://learn.microsoft.com/en-us/azure/developer/go/sdk/authentication/credential-chains#defaultazurecredential-overview) ### Azure AD Workload Identity @@ -253,10 +253,11 @@ spec: [...] ``` -### Azure Default Credentials +### DefaultAzureCredential -To authenticate using Azure Default Credentials, set the annotation -`barmancloud.cnpg.io/useDefaultAzureCredentials="true"` on the ObjectStore: +To authenticate using `DefaultAzureCredential`, set the annotation +`barmancloud.cnpg.io/useDefaultAzureCredential="true"` on the ObjectStore in +conjunction with the `.spec.configuration.inheritFromAzureAD` option: ```yaml apiVersion: barmancloud.cnpg.io/v1 @@ -264,7 +265,7 @@ kind: ObjectStore metadata: name: azure-store annotations: - barmancloud.cnpg.io/useDefaultAzureCredentials: "true" + barmancloud.cnpg.io/useDefaultAzureCredential: "true" spec: configuration: destinationPath: "" From 2cb76ef62225f0094f4c7f06ac30bdb71ebabf17 Mon Sep 17 00:00:00 2001 From: Gabriele Fedi Date: Tue, 18 Nov 2025 09:28:11 +0100 Subject: [PATCH 6/6] refactor: mispelled auth method naming Signed-off-by: Gabriele Fedi --- internal/cnpgi/common/common.go | 4 ++-- pkg/metadata/labels_annotations.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/cnpgi/common/common.go b/internal/cnpgi/common/common.go index b9d4280f..7fa0674c 100644 --- a/internal/cnpgi/common/common.go +++ b/internal/cnpgi/common/common.go @@ -105,8 +105,8 @@ func BuildCertificateFilePath(objectStoreName string) string { // ContextWithProviderOptions enriches the context with cloud service provider specific options // based on the ObjectStore resource func ContextWithProviderOptions(ctx context.Context, objectStore apiv1.ObjectStore) context.Context { - if objectStore.GetAnnotations()[pluginmetadata.UseDefaultAzureCredentialsAnnotationName] == - pluginmetadata.UseDefaultAzureCredentialsTrueValue { + if objectStore.GetAnnotations()[pluginmetadata.UseDefaultAzureCredentialAnnotationName] == + pluginmetadata.UseDefaultAzureCredentialTrueValue { return command.ContextWithDefaultAzureCredentials(ctx, true) } diff --git a/pkg/metadata/labels_annotations.go b/pkg/metadata/labels_annotations.go index cf6ec560..e277a237 100644 --- a/pkg/metadata/labels_annotations.go +++ b/pkg/metadata/labels_annotations.go @@ -4,12 +4,12 @@ package metadata const MetadataNamespace = "barmancloud.cnpg.io" const ( - // UseDefaultAzureCredentialsAnnotationName is an annotation that can be set - // on an ObjectStore resource to enable the authentication to Azure via DefaultAzureCredentials. + // UseDefaultAzureCredentialAnnotationName is an annotation that can be set + // on an ObjectStore resource to enable the authentication to Azure via DefaultAzureCredential. // This is meant to be used with inheritFromAzureAD enabled. - UseDefaultAzureCredentialsAnnotationName = MetadataNamespace + "/useDefaultAzureCredentials" + UseDefaultAzureCredentialAnnotationName = MetadataNamespace + "/useDefaultAzureCredential" - // UseDefaultAzureCredentialsTrueValue is the value for the annotation - // barmancloud.cnpg.io/useDefaultAzureCredentials to enable the DefaultAzureCredentials auth mechanism. - UseDefaultAzureCredentialsTrueValue = "true" + // UseDefaultAzureCredentialTrueValue is the value for the annotation + // barmancloud.cnpg.io/useDefaultAzureCredential to enable the DefaultAzureCredentials auth mechanism. + UseDefaultAzureCredentialTrueValue = "true" )