mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-07-09 19:22:21 +02:00
Compare commits
4 Commits
1ae9d01f49
...
5de7885218
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5de7885218 | ||
|
|
e30154b938 | ||
|
|
2a12a52211 | ||
|
|
2a70f54ef8 |
@ -15,6 +15,7 @@ DigitalOcean
|
|||||||
Docusaurus
|
Docusaurus
|
||||||
EDB
|
EDB
|
||||||
EKS
|
EKS
|
||||||
|
EnterpriseDB
|
||||||
Enum
|
Enum
|
||||||
EnvVar
|
EnvVar
|
||||||
GCP
|
GCP
|
||||||
@ -76,6 +77,7 @@ backends
|
|||||||
barmanObjectName
|
barmanObjectName
|
||||||
barmanObjectStore
|
barmanObjectStore
|
||||||
barmancloud
|
barmancloud
|
||||||
|
benchmarked
|
||||||
boto
|
boto
|
||||||
bzip
|
bzip
|
||||||
cd
|
cd
|
||||||
|
|||||||
@ -144,10 +144,11 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
Compress a backup file (a tar file per tablespace) while streaming it
|
Compress a backup file (a tar file per tablespace) while streaming it
|
||||||
to the object store. Available options are empty string (no
|
to the object store. Available options are empty string (no
|
||||||
compression, default), `gzip`, `bzip2`, and `snappy`.
|
compression, default), `gzip`, `bzip2`, `lz4`, and `snappy`.
|
||||||
enum:
|
enum:
|
||||||
- bzip2
|
- bzip2
|
||||||
- gzip
|
- gzip
|
||||||
|
- lz4
|
||||||
- snappy
|
- snappy
|
||||||
type: string
|
type: string
|
||||||
encryption:
|
encryption:
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -7,7 +7,7 @@ toolchain go1.26.2
|
|||||||
require (
|
require (
|
||||||
github.com/cert-manager/cert-manager v1.20.2
|
github.com/cert-manager/cert-manager v1.20.2
|
||||||
github.com/cloudnative-pg/api v1.29.0
|
github.com/cloudnative-pg/api v1.29.0
|
||||||
github.com/cloudnative-pg/barman-cloud v0.5.0
|
github.com/cloudnative-pg/barman-cloud v0.5.1
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.29.0
|
github.com/cloudnative-pg/cloudnative-pg v1.29.0
|
||||||
github.com/cloudnative-pg/cnpg-i v0.5.0
|
github.com/cloudnative-pg/cnpg-i v0.5.0
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -20,8 +20,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cloudnative-pg/api v1.29.0 h1:mNx6yJ5qi+Xrjs0NYrUy6V4MlXBkVJxGKwvTJZIuTX4=
|
github.com/cloudnative-pg/api v1.29.0 h1:mNx6yJ5qi+Xrjs0NYrUy6V4MlXBkVJxGKwvTJZIuTX4=
|
||||||
github.com/cloudnative-pg/api v1.29.0/go.mod h1:bF3HI8UVVcllZ7M8CfBufnb+Us8FyQArhD+4qtX0qhM=
|
github.com/cloudnative-pg/api v1.29.0/go.mod h1:bF3HI8UVVcllZ7M8CfBufnb+Us8FyQArhD+4qtX0qhM=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.5.0 h1:DykSaX4o7ee2vyu5FQoG1RJsntHd+EIttIKZbJPlB1Q=
|
github.com/cloudnative-pg/barman-cloud v0.5.1 h1:vjkXrrxo2DQXHT9u9usqhtaHiPZ/lTfDVs/pIWYTepQ=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.5.0/go.mod h1:SO2HzLa+GWlSIpGyxnISoJAFPIcaa/qDa33Bb3jefac=
|
github.com/cloudnative-pg/barman-cloud v0.5.1/go.mod h1:XPc5IUFP1y4cZX1sg+Pd8j9V4tmUEVnv3BGCpfQOOg8=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.29.0 h1:49Dm8+y4va7RODspJjeaK8uMWP3OGAD0gMsxhjm16Mo=
|
github.com/cloudnative-pg/cloudnative-pg v1.29.0 h1:49Dm8+y4va7RODspJjeaK8uMWP3OGAD0gMsxhjm16Mo=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.29.0/go.mod h1:0Sgb/50VyaCnQm3IbWqgnhQG8Kb6mgqo8Jo1J+KtkSI=
|
github.com/cloudnative-pg/cloudnative-pg v1.29.0/go.mod h1:0Sgb/50VyaCnQm3IbWqgnhQG8Kb6mgqo8Jo1J+KtkSI=
|
||||||
github.com/cloudnative-pg/cnpg-i v0.5.0 h1:/TOzpNT6cwNgrpftTtrnLKdoHgMwd+88vZgXjlVgXeE=
|
github.com/cloudnative-pg/cnpg-i v0.5.0 h1:/TOzpNT6cwNgrpftTtrnLKdoHgMwd+88vZgXjlVgXeE=
|
||||||
|
|||||||
@ -145,10 +145,16 @@ func (impl LifecycleImplementation) reconcileJob(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useAzureWorkloadIdentity, err := impl.collectAzureWorkloadIdentityUsage(ctx, pluginConfiguration)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return reconcileJob(ctx, cluster, request, sidecarConfiguration{
|
return reconcileJob(ctx, cluster, request, sidecarConfiguration{
|
||||||
env: env,
|
env: env,
|
||||||
certificates: certificates,
|
certificates: certificates,
|
||||||
resources: resources,
|
resources: resources,
|
||||||
|
useAzureWorkloadIdentity: useAzureWorkloadIdentity,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +163,7 @@ type sidecarConfiguration struct {
|
|||||||
certificates []corev1.VolumeProjection
|
certificates []corev1.VolumeProjection
|
||||||
resources corev1.ResourceRequirements
|
resources corev1.ResourceRequirements
|
||||||
additionalArgs []string
|
additionalArgs []string
|
||||||
|
useAzureWorkloadIdentity bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func reconcileJob(
|
func reconcileJob(
|
||||||
@ -243,11 +250,17 @@ func (impl LifecycleImplementation) reconcilePod(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useAzureWorkloadIdentity, err := impl.collectAzureWorkloadIdentityUsage(ctx, pluginConfiguration)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return reconcileInstancePod(ctx, cluster, request, pluginConfiguration, sidecarConfiguration{
|
return reconcileInstancePod(ctx, cluster, request, pluginConfiguration, sidecarConfiguration{
|
||||||
env: env,
|
env: env,
|
||||||
certificates: certificates,
|
certificates: certificates,
|
||||||
resources: resources,
|
resources: resources,
|
||||||
additionalArgs: additionalArgs,
|
additionalArgs: additionalArgs,
|
||||||
|
useAzureWorkloadIdentity: useAzureWorkloadIdentity,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +314,25 @@ func (impl LifecycleImplementation) collectAdditionalInstanceArgs(
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (impl LifecycleImplementation) collectAzureWorkloadIdentityUsage(
|
||||||
|
ctx context.Context,
|
||||||
|
pluginConfiguration *config.PluginConfiguration,
|
||||||
|
) (bool, error) {
|
||||||
|
for _, objectKey := range pluginConfiguration.GetReferredBarmanObjectsKey() {
|
||||||
|
var objectStore barmancloudv1.ObjectStore
|
||||||
|
if err := impl.Client.Get(ctx, objectKey, &objectStore); err != nil {
|
||||||
|
return false, fmt.Errorf("while getting object store %s: %w", objectKey.String(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if objectStore.Spec.Configuration.Azure != nil &&
|
||||||
|
objectStore.Spec.Configuration.Azure.UseDefaultAzureCredentials {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
func reconcileInstancePod(
|
func reconcileInstancePod(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
cluster *cnpgv1.Cluster,
|
cluster *cnpgv1.Cluster,
|
||||||
@ -379,6 +411,13 @@ func reconcilePodSpec(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if config.useAzureWorkloadIdentity {
|
||||||
|
envs = append(envs, corev1.EnvVar{
|
||||||
|
Name: "AZURE_FEDERATED_TOKEN_FILE",
|
||||||
|
Value: azureFederatedTokenFilePath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
envs = append(envs, config.env...)
|
envs = append(envs, config.env...)
|
||||||
|
|
||||||
baseProbe := &corev1.Probe{
|
baseProbe := &corev1.Probe{
|
||||||
@ -466,6 +505,34 @@ func reconcilePodSpec(
|
|||||||
spec.Volumes = removeVolume(spec.Volumes, barmanCertificatesVolumeName)
|
spec.Volumes = removeVolume(spec.Volumes, barmanCertificatesVolumeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.useAzureWorkloadIdentity {
|
||||||
|
sidecarTemplate.VolumeMounts = ensureVolumeMount(
|
||||||
|
sidecarTemplate.VolumeMounts,
|
||||||
|
corev1.VolumeMount{
|
||||||
|
Name: azureFederatedTokenVolumeName,
|
||||||
|
MountPath: azureFederatedTokenMountPath,
|
||||||
|
ReadOnly: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
spec.Volumes = ensureVolume(spec.Volumes, corev1.Volume{
|
||||||
|
Name: azureFederatedTokenVolumeName,
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
Projected: &corev1.ProjectedVolumeSource{
|
||||||
|
Sources: []corev1.VolumeProjection{
|
||||||
|
{
|
||||||
|
ServiceAccountToken: &corev1.ServiceAccountTokenProjection{
|
||||||
|
Path: azureFederatedTokenFileName,
|
||||||
|
Audience: azureFederatedTokenAudience,
|
||||||
|
ExpirationSeconds: ptr.To[int64](azureFederatedTokenExpirationSeconds),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if err := injectPluginSidecarPodSpec(spec, &sidecarTemplate, mainContainerName); err != nil {
|
if err := injectPluginSidecarPodSpec(spec, &sidecarTemplate, mainContainerName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -473,6 +540,15 @@ func reconcilePodSpec(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
azureFederatedTokenVolumeName = "azure-identity-token"
|
||||||
|
azureFederatedTokenMountPath = "/var/run/secrets/azure/tokens"
|
||||||
|
azureFederatedTokenFileName = "azure-identity-token"
|
||||||
|
azureFederatedTokenFilePath = azureFederatedTokenMountPath + "/" + azureFederatedTokenFileName
|
||||||
|
azureFederatedTokenAudience = "api://AzureADTokenExchange"
|
||||||
|
azureFederatedTokenExpirationSeconds = 3600
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: move to machinery once the logic is finalized
|
// TODO: move to machinery once the logic is finalized
|
||||||
|
|
||||||
// InjectPluginVolumePodSpec injects the plugin volume into a CNPG Pod spec.
|
// InjectPluginVolumePodSpec injects the plugin volume into a CNPG Pod spec.
|
||||||
|
|||||||
@ -22,6 +22,7 @@ package operator
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
"github.com/cloudnative-pg/cloudnative-pg/pkg/utils"
|
"github.com/cloudnative-pg/cloudnative-pg/pkg/utils"
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/lifecycle"
|
"github.com/cloudnative-pg/cnpg-i/pkg/lifecycle"
|
||||||
@ -387,6 +388,134 @@ var _ = Describe("LifecycleImplementation", func() {
|
|||||||
Expect(args).To(Equal([]string{"--log-level=info"}))
|
Expect(args).To(Equal([]string{"--log-level=info"}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("collectAzureWorkloadIdentityUsage", func() {
|
||||||
|
It("returns true when any referred object store uses default Azure credentials", func(ctx SpecContext) {
|
||||||
|
ns := "test-ns"
|
||||||
|
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
|
||||||
|
pc := &config.PluginConfiguration{
|
||||||
|
Cluster: cluster,
|
||||||
|
BarmanObjectName: "primary-store",
|
||||||
|
RecoveryBarmanObjectName: "recovery-store",
|
||||||
|
}
|
||||||
|
primaryStore := &barmancloudv1.ObjectStore{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: pc.BarmanObjectName, Namespace: ns},
|
||||||
|
Spec: barmancloudv1.ObjectStoreSpec{
|
||||||
|
Configuration: barmanapi.BarmanObjectStoreConfiguration{
|
||||||
|
BarmanCredentials: barmanapi.BarmanCredentials{
|
||||||
|
Azure: &barmanapi.AzureCredentials{UseDefaultAzureCredentials: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
recoveryStore := &barmancloudv1.ObjectStore{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: pc.RecoveryBarmanObjectName, Namespace: ns},
|
||||||
|
}
|
||||||
|
cli := buildClientFunc(primaryStore, recoveryStore).Build()
|
||||||
|
|
||||||
|
impl := LifecycleImplementation{Client: cli}
|
||||||
|
useWorkloadIdentity, err := impl.collectAzureWorkloadIdentityUsage(ctx, pc)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(useWorkloadIdentity).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns false when none of the referred object stores use default Azure credentials", func(ctx SpecContext) {
|
||||||
|
ns := "test-ns"
|
||||||
|
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
|
||||||
|
pc := &config.PluginConfiguration{
|
||||||
|
Cluster: cluster,
|
||||||
|
BarmanObjectName: "primary-store",
|
||||||
|
}
|
||||||
|
primaryStore := &barmancloudv1.ObjectStore{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: pc.BarmanObjectName, Namespace: ns},
|
||||||
|
Spec: barmancloudv1.ObjectStoreSpec{
|
||||||
|
Configuration: barmanapi.BarmanObjectStoreConfiguration{
|
||||||
|
BarmanCredentials: barmanapi.BarmanCredentials{
|
||||||
|
Azure: &barmanapi.AzureCredentials{InheritFromAzureAD: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cli := buildClientFunc(primaryStore).Build()
|
||||||
|
|
||||||
|
impl := LifecycleImplementation{Client: cli}
|
||||||
|
useWorkloadIdentity, err := impl.collectAzureWorkloadIdentityUsage(ctx, pc)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(useWorkloadIdentity).To(BeFalse())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var _ = Describe("reconcilePodSpec", func() {
|
||||||
|
It("injects the Azure federated token volume and env when workload identity is enabled", func() {
|
||||||
|
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "cluster-1", Namespace: "ns-1"}}
|
||||||
|
spec := &corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Name: "postgres",
|
||||||
|
Env: []corev1.EnvVar{
|
||||||
|
{Name: "AZURE_CLIENT_ID", Value: "client-id"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := reconcilePodSpec(
|
||||||
|
cluster,
|
||||||
|
spec,
|
||||||
|
"postgres",
|
||||||
|
corev1.Container{Args: []string{"instance"}},
|
||||||
|
sidecarConfiguration{useAzureWorkloadIdentity: true},
|
||||||
|
)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(spec.Volumes).To(ContainElement(HaveField("Name", azureFederatedTokenVolumeName)))
|
||||||
|
Expect(spec.InitContainers).To(HaveLen(1))
|
||||||
|
Expect(spec.InitContainers[0].Env).To(ContainElement(corev1.EnvVar{
|
||||||
|
Name: "AZURE_FEDERATED_TOKEN_FILE",
|
||||||
|
Value: azureFederatedTokenFilePath,
|
||||||
|
}))
|
||||||
|
Expect(spec.InitContainers[0].Env).To(ContainElement(corev1.EnvVar{
|
||||||
|
Name: "AZURE_CLIENT_ID",
|
||||||
|
Value: "client-id",
|
||||||
|
}))
|
||||||
|
Expect(spec.InitContainers[0].VolumeMounts).To(ContainElement(corev1.VolumeMount{
|
||||||
|
Name: azureFederatedTokenVolumeName,
|
||||||
|
MountPath: azureFederatedTokenMountPath,
|
||||||
|
ReadOnly: true,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("does not override an existing federated token file env", func() {
|
||||||
|
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "cluster-1", Namespace: "ns-1"}}
|
||||||
|
spec := &corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Name: "postgres",
|
||||||
|
Env: []corev1.EnvVar{
|
||||||
|
{Name: "AZURE_FEDERATED_TOKEN_FILE", Value: "/custom/token"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := reconcilePodSpec(
|
||||||
|
cluster,
|
||||||
|
spec,
|
||||||
|
"postgres",
|
||||||
|
corev1.Container{Args: []string{"instance"}},
|
||||||
|
sidecarConfiguration{useAzureWorkloadIdentity: true},
|
||||||
|
)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(spec.InitContainers).To(HaveLen(1))
|
||||||
|
Expect(spec.InitContainers[0].Env).To(ContainElement(corev1.EnvVar{
|
||||||
|
Name: "AZURE_FEDERATED_TOKEN_FILE",
|
||||||
|
Value: "/custom/token",
|
||||||
|
}))
|
||||||
|
Expect(spec.InitContainers[0].Env).NotTo(ContainElement(corev1.EnvVar{
|
||||||
|
Name: "AZURE_FEDERATED_TOKEN_FILE",
|
||||||
|
Value: azureFederatedTokenFilePath,
|
||||||
|
}))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
var _ = Describe("Volume utilities", func() {
|
var _ = Describe("Volume utilities", func() {
|
||||||
|
|||||||
@ -143,10 +143,11 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
Compress a backup file (a tar file per tablespace) while streaming it
|
Compress a backup file (a tar file per tablespace) while streaming it
|
||||||
to the object store. Available options are empty string (no
|
to the object store. Available options are empty string (no
|
||||||
compression, default), `gzip`, `bzip2`, and `snappy`.
|
compression, default), `gzip`, `bzip2`, `lz4`, and `snappy`.
|
||||||
enum:
|
enum:
|
||||||
- bzip2
|
- bzip2
|
||||||
- gzip
|
- gzip
|
||||||
|
- lz4
|
||||||
- snappy
|
- snappy
|
||||||
type: string
|
type: string
|
||||||
encryption:
|
encryption:
|
||||||
|
|||||||
@ -15,7 +15,7 @@ for space, speed, or a balance of both.
|
|||||||
|
|
||||||
- `bzip2`
|
- `bzip2`
|
||||||
- `gzip`
|
- `gzip`
|
||||||
- `lz4` (WAL only)
|
- `lz4`
|
||||||
- `snappy`
|
- `snappy`
|
||||||
- `xz` (WAL only)
|
- `xz` (WAL only)
|
||||||
- `zstd` (WAL only)
|
- `zstd` (WAL only)
|
||||||
@ -41,3 +41,5 @@ network throughput.
|
|||||||
| bzip2 | 25,404 | 13,886 | 395 | 67 | 5.9:1 |
|
| bzip2 | 25,404 | 13,886 | 395 | 67 | 5.9:1 |
|
||||||
| gzip | 116,281 | 3,077 | 395 | 91 | 4.3:1 |
|
| gzip | 116,281 | 3,077 | 395 | 91 | 4.3:1 |
|
||||||
| snappy | 8,134 | 8,341 | 395 | 166 | 2.4:1 |
|
| snappy | 8,134 | 8,341 | 395 | 166 | 2.4:1 |
|
||||||
|
|
||||||
|
Numbers come from a 2021 Barman proof of concept ([EnterpriseDB/barman#344](https://github.com/EnterpriseDB/barman/issues/344#issuecomment-992547396)), which predates `lz4` support for base backups. `lz4` is not yet benchmarked.
|
||||||
|
|||||||
@ -272,9 +272,10 @@ flow, which uses [`DefaultAzureCredential`](https://learn.microsoft.com/en-us/py
|
|||||||
to automatically discover and use available credentials in the following order:
|
to automatically discover and use available credentials in the following order:
|
||||||
|
|
||||||
1. **Environment Variables** — `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, and `AZURE_TENANT_ID` for Service Principal authentication
|
1. **Environment Variables** — `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, and `AZURE_TENANT_ID` for Service Principal authentication
|
||||||
2. **Managed Identity** — Uses the managed identity assigned to the pod
|
2. **Workload Identity** — Uses `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, and a federated service account token
|
||||||
3. **Azure CLI** — Uses credentials from the Azure CLI if available
|
3. **Managed Identity** — Uses the managed identity assigned to the pod
|
||||||
4. **Azure PowerShell** — Uses credentials from Azure PowerShell if available
|
4. **Azure CLI** — Uses credentials from the Azure CLI if available
|
||||||
|
5. **Azure PowerShell** — Uses credentials from Azure PowerShell if available
|
||||||
|
|
||||||
This approach is particularly useful for getting started with development and testing; it allows
|
This approach is particularly useful for getting started with development and testing; it allows
|
||||||
the SDK to attempt multiple authentication mechanisms seamlessly across different environments.
|
the SDK to attempt multiple authentication mechanisms seamlessly across different environments.
|
||||||
@ -295,6 +296,30 @@ spec:
|
|||||||
[...]
|
[...]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
When `useDefaultAzureCredentials: true` is set, the plugin sidecar projects a
|
||||||
|
service account token with the Azure workload identity audience and exposes it
|
||||||
|
as `AZURE_FEDERATED_TOKEN_FILE`. If your platform does not already inject
|
||||||
|
`AZURE_CLIENT_ID` and `AZURE_TENANT_ID`, you can provide them through
|
||||||
|
`.spec.instanceSidecarConfiguration.env`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: barmancloud.cnpg.io/v1
|
||||||
|
kind: ObjectStore
|
||||||
|
metadata:
|
||||||
|
name: azure-store
|
||||||
|
spec:
|
||||||
|
configuration:
|
||||||
|
destinationPath: "<destination path here>"
|
||||||
|
azureCredentials:
|
||||||
|
useDefaultAzureCredentials: true
|
||||||
|
instanceSidecarConfiguration:
|
||||||
|
env:
|
||||||
|
- name: AZURE_CLIENT_ID
|
||||||
|
value: "<managed-identity-client-id>"
|
||||||
|
- name: AZURE_TENANT_ID
|
||||||
|
value: "<tenant-id>"
|
||||||
|
```
|
||||||
|
|
||||||
### Access Key, SAS Token, or Connection String
|
### Access Key, SAS Token, or Connection String
|
||||||
|
|
||||||
Store credentials in a Kubernetes secret:
|
Store credentials in a Kubernetes secret:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user