diff --git a/docs/examples/minio-store.yaml b/docs/examples/minio-store.yaml index 0193713..78d0833 100644 --- a/docs/examples/minio-store.yaml +++ b/docs/examples/minio-store.yaml @@ -4,8 +4,11 @@ metadata: name: minio-store spec: configuration: + endpointCA: + name: minio-server-tls + key: tls.crt destinationPath: s3://backups/ - endpointURL: http://minio:9000 + endpointURL: https://minio:9000 s3Credentials: accessKeyId: name: minio diff --git a/go.mod b/go.mod index 3211de9..f99838c 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,12 @@ toolchain go1.24.1 require ( github.com/cert-manager/cert-manager v1.17.1 github.com/cloudnative-pg/api v1.25.1 - github.com/cloudnative-pg/barman-cloud v0.1.0 + github.com/cloudnative-pg/barman-cloud v0.2.0 github.com/cloudnative-pg/cloudnative-pg v1.25.1 github.com/cloudnative-pg/cnpg-i v0.1.0 github.com/cloudnative-pg/cnpg-i-machinery v0.1.2 github.com/cloudnative-pg/machinery v0.1.0 - github.com/onsi/ginkgo/v2 v2.22.2 + github.com/onsi/ginkgo/v2 v2.23.0 github.com/onsi/gomega v1.36.2 github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.19.0 @@ -118,7 +118,7 @@ require ( golang.org/x/term v0.29.0 // indirect golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.9.0 // indirect - golang.org/x/tools v0.28.0 // indirect + golang.org/x/tools v0.30.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect diff --git a/go.sum b/go.sum index 9c132b0..5bfb28f 100644 --- a/go.sum +++ b/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/cloudnative-pg/api v1.25.1 h1:uNjKiB0MIspUeH9l651SnFDcuflr1crB3t6LjxUCafQ= github.com/cloudnative-pg/api v1.25.1/go.mod h1:fwF5g4XkuNZqYXIeRR3AJvUfWlqWig+r2DXc5bEmw6U= -github.com/cloudnative-pg/barman-cloud v0.1.0 h1:e/z52CehMBIh1LjZqNBJnncWJbS+1JYvRMBR8Js6Uiw= -github.com/cloudnative-pg/barman-cloud v0.1.0/go.mod h1:rJUJO/f1yNckLZiVxHAyRmKY+4EPJkYRJsGbTZRJQSY= +github.com/cloudnative-pg/barman-cloud v0.2.0 h1:KMwJPKjytDqljNNOounBGojsGTXiowztH0WQrVB8/DQ= +github.com/cloudnative-pg/barman-cloud v0.2.0/go.mod h1:kNIUU+fpnYjkr25YwHnteROLhbs6rqpjDiB8XW1+sug= github.com/cloudnative-pg/cloudnative-pg v1.25.1 h1:Yc6T7ikQ1AiWXBQht+6C3DoihrIpUN2OkM1dIwqadTo= github.com/cloudnative-pg/cloudnative-pg v1.25.1/go.mod h1:96b9bRFLSr3uFWHjhytPdcvKIKwy9H6AG7cH0O6jefs= github.com/cloudnative-pg/cnpg-i v0.1.0 h1:QH2xTsrODMhEEc6B25GbOYe7ZIttDmSkYvXotfU5dfs= @@ -137,8 +137,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= -github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/ginkgo/v2 v2.23.0 h1:FA1xjp8ieYDzlgS5ABTpdUDB7wtngggONc8a7ku2NqQ= +github.com/onsi/ginkgo/v2 v2.23.0/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= @@ -271,8 +271,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/cnpgi/common/common.go b/internal/cnpgi/common/common.go index 8d99482..d09d2a2 100644 --- a/internal/cnpgi/common/common.go +++ b/internal/cnpgi/common/common.go @@ -2,9 +2,12 @@ package common import ( "fmt" + "path" "strings" barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api" + + "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata" ) // TODO: refactor. @@ -70,3 +73,8 @@ func MergeEnv(env []string, incomingEnv []string) []string { return result } + +// BuildCertificateFilePath builds the path to the barman objectStore certificate +func BuildCertificateFilePath(objectStoreName string) string { + return path.Join(metadata.BarmanCertificatesPath, objectStoreName, metadata.BarmanCertificatesFileName) +} diff --git a/internal/cnpgi/common/wal.go b/internal/cnpgi/common/wal.go index 7d4dcd8..586991d 100644 --- a/internal/cnpgi/common/wal.go +++ b/internal/cnpgi/common/wal.go @@ -77,12 +77,14 @@ func (w WALServiceImplementation) Archive( return nil, err } - envArchive, err := barmanCredentials.EnvSetBackupCloudCredentials( + envArchive, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates( ctx, w.Client, objectStore.Namespace, &objectStore.Spec.Configuration, - os.Environ()) + os.Environ(), + BuildCertificateFilePath(objectStore.Name), + ) if err != nil { if apierrors.IsForbidden(err) { return nil, errors.New("backup credentials don't yet have access permissions. Will retry reconciliation loop") @@ -191,12 +193,13 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore( barmanConfiguration := &objectStore.Spec.Configuration env := GetRestoreCABundleEnv(barmanConfiguration) - credentialsEnv, err := barmanCredentials.EnvSetBackupCloudCredentials( + credentialsEnv, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates( ctx, w.Client, objectStore.Namespace, &objectStore.Spec.Configuration, os.Environ(), + BuildCertificateFilePath(objectStore.Name), ) if err != nil { return fmt.Errorf("while getting recover credentials: %w", err) diff --git a/internal/cnpgi/instance/backup.go b/internal/cnpgi/instance/backup.go index 207550a..687cae7 100644 --- a/internal/cnpgi/instance/backup.go +++ b/internal/cnpgi/instance/backup.go @@ -98,12 +98,14 @@ func (b BackupServiceImplementation) Backup( // PGHOST (and the like) to be available osEnvironment := os.Environ() caBundleEnvironment := common.GetRestoreCABundleEnv(&objectStore.Spec.Configuration) - env, err := barmanCredentials.EnvSetBackupCloudCredentials( + env, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates( ctx, b.Client, objectStore.Namespace, &objectStore.Spec.Configuration, - common.MergeEnv(osEnvironment, caBundleEnvironment)) + common.MergeEnv(osEnvironment, caBundleEnvironment), + common.BuildCertificateFilePath(objectStore.Name), + ) if err != nil { contextLogger.Error(err, "while setting backup cloud credentials") return nil, err diff --git a/internal/cnpgi/metadata/constants.go b/internal/cnpgi/metadata/constants.go index f799c34..698e3a3 100644 --- a/internal/cnpgi/metadata/constants.go +++ b/internal/cnpgi/metadata/constants.go @@ -11,6 +11,14 @@ const ( // if present, requires the WAL archiver to check that the backup object // store is empty. CheckEmptyWalArchiveFile = ".check-empty-wal-archive" + + // BarmanCertificatesPath is the path where the Barman + // certificates will be installed + BarmanCertificatesPath = "/barman-certificates" + + // BarmanCertificatesFileName is the path where the Barman + // certificates will be used + BarmanCertificatesFileName = "barman-ca.crt" ) // Data is the metadata of this plugin. diff --git a/internal/cnpgi/operator/lifecycle.go b/internal/cnpgi/operator/lifecycle.go index a706dbd..040048c 100644 --- a/internal/cnpgi/operator/lifecycle.go +++ b/internal/cnpgi/operator/lifecycle.go @@ -14,11 +14,9 @@ import ( "github.com/spf13/viper" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" - barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config" ) @@ -107,56 +105,6 @@ func (impl LifecycleImplementation) LifecycleHook( } } -func (impl LifecycleImplementation) collectAdditionalEnvs( - ctx context.Context, - namespace string, - pluginConfiguration *config.PluginConfiguration, -) ([]corev1.EnvVar, error) { - var result []corev1.EnvVar - - if len(pluginConfiguration.BarmanObjectName) > 0 { - envs, err := impl.collectObjectStoreEnvs( - ctx, - types.NamespacedName{ - Name: pluginConfiguration.BarmanObjectName, - Namespace: namespace, - }, - ) - if err != nil { - return nil, err - } - result = append(result, envs...) - } - - if len(pluginConfiguration.RecoveryBarmanObjectName) > 0 { - envs, err := impl.collectObjectStoreEnvs( - ctx, - types.NamespacedName{ - Name: pluginConfiguration.RecoveryBarmanObjectName, - Namespace: namespace, - }, - ) - if err != nil { - return nil, err - } - result = append(result, envs...) - } - - return result, nil -} - -func (impl LifecycleImplementation) collectObjectStoreEnvs( - ctx context.Context, - barmanObjectKey types.NamespacedName, -) ([]corev1.EnvVar, error) { - var objectStore barmancloudv1.ObjectStore - if err := impl.Client.Get(ctx, barmanObjectKey, &objectStore); err != nil { - return nil, err - } - - return objectStore.Spec.InstanceSidecarConfiguration.Env, nil -} - func (impl LifecycleImplementation) reconcileJob( ctx context.Context, cluster *cnpgv1.Cluster, @@ -165,10 +113,15 @@ func (impl LifecycleImplementation) reconcileJob( ) (*lifecycle.OperatorLifecycleResponse, error) { env, err := impl.collectAdditionalEnvs(ctx, cluster.Namespace, pluginConfiguration) if err != nil { - return nil, nil + return nil, err } - return reconcileJob(ctx, cluster, request, env) + certificates, err := impl.collectAdditionalCertificates(ctx, cluster.Namespace, pluginConfiguration) + if err != nil { + return nil, err + } + + return reconcileJob(ctx, cluster, request, env, certificates) } func reconcileJob( @@ -176,6 +129,7 @@ func reconcileJob( cluster *cnpgv1.Cluster, request *lifecycle.OperatorLifecycleRequest, env []corev1.EnvVar, + certificates []corev1.VolumeProjection, ) (*lifecycle.OperatorLifecycleResponse, error) { contextLogger := log.FromContext(ctx).WithName("lifecycle") if pluginConfig := cluster.GetRecoverySourcePlugin(); pluginConfig == nil || pluginConfig.Name != metadata.PluginName { @@ -212,6 +166,7 @@ func reconcileJob( Args: []string{"restore"}, }, env, + certificates, ); err != nil { return nil, fmt.Errorf("while reconciling pod spec for job: %w", err) } @@ -235,10 +190,15 @@ func (impl LifecycleImplementation) reconcilePod( ) (*lifecycle.OperatorLifecycleResponse, error) { env, err := impl.collectAdditionalEnvs(ctx, cluster.Namespace, pluginConfiguration) if err != nil { - return nil, nil + return nil, err } - return reconcilePod(ctx, cluster, request, pluginConfiguration, env) + certificates, err := impl.collectAdditionalCertificates(ctx, cluster.Namespace, pluginConfiguration) + if err != nil { + return nil, err + } + + return reconcilePod(ctx, cluster, request, pluginConfiguration, env, certificates) } func reconcilePod( @@ -247,6 +207,7 @@ func reconcilePod( request *lifecycle.OperatorLifecycleRequest, pluginConfiguration *config.PluginConfiguration, env []corev1.EnvVar, + certificates []corev1.VolumeProjection, ) (*lifecycle.OperatorLifecycleResponse, error) { pod, err := decoder.DecodePodJSON(request.GetObjectDefinition()) if err != nil { @@ -267,6 +228,7 @@ func reconcilePod( Args: []string{"instance"}, }, env, + certificates, ); err != nil { return nil, fmt.Errorf("while reconciling pod spec for pod: %w", err) } @@ -291,6 +253,7 @@ func reconcilePodSpec( mainContainerName string, sidecarConfig corev1.Container, additionalEnvs []corev1.EnvVar, + certificates []corev1.VolumeProjection, ) error { envs := []corev1.EnvVar{ { @@ -360,10 +323,22 @@ func reconcilePodSpec( } } - if err := InjectPluginSidecarPodSpec(spec, &sidecarConfig, mainContainerName, true); err != nil { + if err := injectPluginSidecarPodSpec(spec, &sidecarConfig, mainContainerName); err != nil { return err } + // inject the volume containing the certificates if needed + if !volumeListHasVolume(spec.Volumes, barmanCertificatesVolumeName) { + spec.Volumes = append(spec.Volumes, corev1.Volume{ + Name: barmanCertificatesVolumeName, + VolumeSource: corev1.VolumeSource{ + Projected: &corev1.ProjectedVolumeSource{ + Sources: certificates, + }, + }, + }) + } + return nil } @@ -407,16 +382,15 @@ func InjectPluginVolumePodSpec(spec *corev1.PodSpec, mainContainerName string) { } } -// InjectPluginSidecarPodSpec injects a plugin sidecar into a CNPG Pod spec. +// injectPluginSidecarPodSpec injects a plugin sidecar into a CNPG Pod spec. // // If the "injectMainContainerVolumes" flag is true, this will append all the volume // mounts that are used in the instance manager Pod to the passed sidecar // container, granting it superuser access to the PostgreSQL instance. -func InjectPluginSidecarPodSpec( +func injectPluginSidecarPodSpec( spec *corev1.PodSpec, sidecar *corev1.Container, mainContainerName string, - injectMainContainerVolumes bool, ) error { sidecar = sidecar.DeepCopy() InjectPluginVolumePodSpec(spec, mainContainerName) @@ -447,11 +421,27 @@ func InjectPluginSidecarPodSpec( } // Do not modify the passed sidecar definition - if injectMainContainerVolumes { - sidecar.VolumeMounts = append(sidecar.VolumeMounts, volumeMounts...) - } + sidecar.VolumeMounts = append( + sidecar.VolumeMounts, + corev1.VolumeMount{ + Name: barmanCertificatesVolumeName, + MountPath: metadata.BarmanCertificatesPath, + }) + sidecar.VolumeMounts = append(sidecar.VolumeMounts, volumeMounts...) sidecar.RestartPolicy = ptr.To(corev1.ContainerRestartPolicyAlways) spec.InitContainers = append(spec.InitContainers, *sidecar) return nil } + +// volumeListHasVolume check if a volume with a known name exists +// in the volume list +func volumeListHasVolume(volumes []corev1.Volume, name string) bool { + for i := range volumes { + if volumes[i].Name == name { + return true + } + } + + return false +} diff --git a/internal/cnpgi/operator/lifecycle_certificates.go b/internal/cnpgi/operator/lifecycle_certificates.go new file mode 100644 index 0000000..0888212 --- /dev/null +++ b/internal/cnpgi/operator/lifecycle_certificates.go @@ -0,0 +1,89 @@ +package operator + +import ( + "context" + "path" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + + barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" + "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata" + "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config" +) + +// barmanCertificatesVolumeName is the name of the volume that hosts +// the barman certificates to be used +const barmanCertificatesVolumeName = "barman-certificates" + +func (impl LifecycleImplementation) collectAdditionalCertificates( + ctx context.Context, + namespace string, + pluginConfiguration *config.PluginConfiguration, +) ([]corev1.VolumeProjection, error) { + var result []corev1.VolumeProjection + + if len(pluginConfiguration.BarmanObjectName) > 0 { + envs, err := impl.collectObjectStoreCertificates( + ctx, + types.NamespacedName{ + Name: pluginConfiguration.BarmanObjectName, + Namespace: namespace, + }, + ) + if err != nil { + return nil, err + } + result = append(result, envs...) + } + + if len(pluginConfiguration.RecoveryBarmanObjectName) > 0 { + envs, err := impl.collectObjectStoreCertificates( + ctx, + types.NamespacedName{ + Name: pluginConfiguration.RecoveryBarmanObjectName, + Namespace: namespace, + }, + ) + if err != nil { + return nil, err + } + result = append(result, envs...) + } + + return result, nil +} + +func (impl LifecycleImplementation) collectObjectStoreCertificates( + ctx context.Context, + barmanObjectKey types.NamespacedName, +) ([]corev1.VolumeProjection, error) { + var objectStore barmancloudv1.ObjectStore + if err := impl.Client.Get(ctx, barmanObjectKey, &objectStore); err != nil { + return nil, err + } + + endpointCA := objectStore.Spec.Configuration.EndpointCA + if endpointCA == nil { + return nil, nil + } + + return []corev1.VolumeProjection{ + { + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: endpointCA.Name, + }, + Items: []corev1.KeyToPath{ + { + Key: endpointCA.Key, + Path: path.Join( + barmanObjectKey.Name, + metadata.BarmanCertificatesFileName, + ), + }, + }, + }, + }, + }, nil +} diff --git a/internal/cnpgi/operator/lifecycle_envs.go b/internal/cnpgi/operator/lifecycle_envs.go new file mode 100644 index 0000000..bfb5b22 --- /dev/null +++ b/internal/cnpgi/operator/lifecycle_envs.go @@ -0,0 +1,61 @@ +package operator + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + + barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" + "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config" +) + +func (impl LifecycleImplementation) collectAdditionalEnvs( + ctx context.Context, + namespace string, + pluginConfiguration *config.PluginConfiguration, +) ([]corev1.EnvVar, error) { + var result []corev1.EnvVar + + if len(pluginConfiguration.BarmanObjectName) > 0 { + envs, err := impl.collectObjectStoreEnvs( + ctx, + types.NamespacedName{ + Name: pluginConfiguration.BarmanObjectName, + Namespace: namespace, + }, + ) + if err != nil { + return nil, err + } + result = append(result, envs...) + } + + if len(pluginConfiguration.RecoveryBarmanObjectName) > 0 { + envs, err := impl.collectObjectStoreEnvs( + ctx, + types.NamespacedName{ + Name: pluginConfiguration.RecoveryBarmanObjectName, + Namespace: namespace, + }, + ) + if err != nil { + return nil, err + } + result = append(result, envs...) + } + + return result, nil +} + +func (impl LifecycleImplementation) collectObjectStoreEnvs( + ctx context.Context, + barmanObjectKey types.NamespacedName, +) ([]corev1.EnvVar, error) { + var objectStore barmancloudv1.ObjectStore + if err := impl.Client.Get(ctx, barmanObjectKey, &objectStore); err != nil { + return nil, err + } + + return objectStore.Spec.InstanceSidecarConfiguration.Env, nil +} diff --git a/internal/cnpgi/operator/lifecycle_test.go b/internal/cnpgi/operator/lifecycle_test.go index 4c52280..1e63b6f 100644 --- a/internal/cnpgi/operator/lifecycle_test.go +++ b/internal/cnpgi/operator/lifecycle_test.go @@ -107,7 +107,7 @@ var _ = Describe("LifecycleImplementation", func() { ObjectDefinition: jobJSON, } - response, err := reconcileJob(ctx, cluster, request, nil) + response, err := reconcileJob(ctx, cluster, request, nil, nil) Expect(err).NotTo(HaveOccurred()) Expect(response).NotTo(BeNil()) Expect(response.JsonPatch).NotTo(BeEmpty()) @@ -128,7 +128,7 @@ var _ = Describe("LifecycleImplementation", func() { ObjectDefinition: jobJSON, } - response, err := reconcileJob(ctx, cluster, request, nil) + response, err := reconcileJob(ctx, cluster, request, nil, nil) Expect(err).NotTo(HaveOccurred()) Expect(response).To(BeNil()) }) @@ -138,7 +138,7 @@ var _ = Describe("LifecycleImplementation", func() { ObjectDefinition: []byte("invalid-json"), } - response, err := reconcileJob(ctx, cluster, request, nil) + response, err := reconcileJob(ctx, cluster, request, nil, nil) Expect(err).To(HaveOccurred()) Expect(response).To(BeNil()) }) @@ -165,7 +165,7 @@ var _ = Describe("LifecycleImplementation", func() { ObjectDefinition: jobJSON, } - response, err := reconcileJob(ctx, cluster, request, nil) + response, err := reconcileJob(ctx, cluster, request, nil, nil) Expect(err).NotTo(HaveOccurred()) Expect(response).To(BeNil()) }) @@ -185,7 +185,7 @@ var _ = Describe("LifecycleImplementation", func() { ObjectDefinition: podJSON, } - response, err := reconcilePod(ctx, cluster, request, pluginConfiguration, nil) + response, err := reconcilePod(ctx, cluster, request, pluginConfiguration, nil, nil) Expect(err).NotTo(HaveOccurred()) Expect(response).NotTo(BeNil()) Expect(response.JsonPatch).NotTo(BeEmpty()) @@ -203,7 +203,7 @@ var _ = Describe("LifecycleImplementation", func() { ObjectDefinition: []byte("invalid-json"), } - response, err := reconcilePod(ctx, cluster, request, pluginConfiguration, nil) + response, err := reconcilePod(ctx, cluster, request, pluginConfiguration, nil, nil) Expect(err).To(HaveOccurred()) Expect(response).To(BeNil()) }) diff --git a/internal/cnpgi/restore/restore.go b/internal/cnpgi/restore/restore.go index 5ecf463..1f0cb93 100644 --- a/internal/cnpgi/restore/restore.go +++ b/internal/cnpgi/restore/restore.go @@ -26,6 +26,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" + "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config" ) @@ -87,7 +88,12 @@ func (impl JobHookImpl) Restore( return nil, err } - if err := impl.checkBackupDestination(ctx, configuration.Cluster, &targetObjectStore.Spec.Configuration); err != nil { + if err := impl.checkBackupDestination( + ctx, + configuration.Cluster, + &targetObjectStore.Spec.Configuration, + targetObjectStore.Name, + ); err != nil { return nil, err } } @@ -98,6 +104,7 @@ func (impl JobHookImpl) Restore( impl.Client, configuration.Cluster, &recoveryObjectStore.Spec.Configuration, + recoveryObjectStore.Name, configuration.RecoveryServerName, ) if err != nil { @@ -220,13 +227,16 @@ func (impl *JobHookImpl) checkBackupDestination( ctx context.Context, cluster *cnpgv1.Cluster, barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration, + objectStoreName string, ) error { // Get environment from cache - env, err := barmanCredentials.EnvSetRestoreCloudCredentials(ctx, + env, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates(ctx, impl.Client, cluster.Namespace, barmanConfiguration, - os.Environ()) + os.Environ(), + common.BuildCertificateFilePath(objectStoreName), + ) if err != nil { return fmt.Errorf("can't get credentials for cluster %v: %w", cluster.Name, err) } @@ -329,6 +339,7 @@ func loadBackupObjectFromExternalCluster( typedClient client.Client, cluster *cnpgv1.Cluster, recoveryObjectStore *api.BarmanObjectStoreConfiguration, + recoveryObjectStoreName string, serverName string, ) (*cnpgv1.Backup, []string, error) { contextLogger := log.FromContext(ctx) @@ -337,12 +348,13 @@ func loadBackupObjectFromExternalCluster( "serverName", serverName, "objectStore", recoveryObjectStore) - env, err := barmanCredentials.EnvSetRestoreCloudCredentials( + env, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates( ctx, typedClient, cluster.Namespace, recoveryObjectStore, - os.Environ()) + os.Environ(), + common.BuildCertificateFilePath(recoveryObjectStoreName)) if err != nil { return nil, nil, err }