fix: duplicate certificate projections (#331)

When referring to the same ObjectStore with custom TLS certificates
multiple times, the plugin was adding the same volume projection two
times. This lead to a wrong Job definition.

This patch makes the plugin add a sidecar to replica cluster Pods that
are using the plugin to get WALs, even if the plugin itself is not used
for WAL archiving.

Closes: #329

Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
This commit is contained in:
Leonardo Cecchi 2025-05-09 14:27:20 +02:00 committed by GitHub
parent 3fee90befd
commit 8c20e4fe85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 42 additions and 33 deletions

View File

@ -0,0 +1,22 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-replica
spec:
instances: 3
bootstrap:
recovery:
source: source
replica:
enabled: true
source: source
externalClusters:
- name: source
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: minio-store
serverName: cluster-example
storage:
size: 1Gi

View File

@ -5,6 +5,7 @@ import (
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/decoder"
"github.com/cloudnative-pg/machinery/pkg/stringset"
"k8s.io/apimachinery/pkg/types"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
@ -85,16 +86,23 @@ func (config *PluginConfiguration) GetReplicaSourceBarmanObjectKey() types.Names
// GetReferredBarmanObjectsKey gets the list of barman objects referred by this
// plugin configuration
func (config *PluginConfiguration) GetReferredBarmanObjectsKey() []types.NamespacedName {
result := make([]types.NamespacedName, 0, 3)
objectNames := stringset.New()
if len(config.BarmanObjectName) > 0 {
result = append(result, config.GetBarmanObjectKey())
objectNames.Put(config.BarmanObjectName)
}
if len(config.RecoveryBarmanObjectName) > 0 {
result = append(result, config.GetRecoveryBarmanObjectKey())
objectNames.Put(config.RecoveryBarmanObjectName)
}
if len(config.ReplicaSourceBarmanObjectName) > 0 {
result = append(result, config.GetReplicaSourceBarmanObjectKey())
objectNames.Put(config.ReplicaSourceBarmanObjectName)
}
result := make([]types.NamespacedName, 0, 3)
for _, name := range objectNames.ToSortedList() {
result = append(result, types.NamespacedName{
Name: name,
Namespace: config.Cluster.Namespace,
})
}
return result

View File

@ -118,7 +118,7 @@ func (impl LifecycleImplementation) reconcileJob(
return nil, err
}
certificates, err := impl.collectAdditionalCertificates(ctx, cluster.Namespace, pluginConfiguration)
certificates, err := impl.collectAdditionalCertificates(ctx, pluginConfiguration)
if err != nil {
return nil, err
}
@ -197,7 +197,7 @@ func (impl LifecycleImplementation) reconcilePod(
return nil, err
}
certificates, err := impl.collectAdditionalCertificates(ctx, cluster.Namespace, pluginConfiguration)
certificates, err := impl.collectAdditionalCertificates(ctx, pluginConfiguration)
if err != nil {
return nil, err
}
@ -223,7 +223,8 @@ func reconcilePod(
mutatedPod := pod.DeepCopy()
if len(pluginConfiguration.BarmanObjectName) != 0 {
if len(pluginConfiguration.BarmanObjectName) != 0 ||
len(pluginConfiguration.ReplicaSourceBarmanObjectName) != 0 {
if err := reconcilePodSpec(
cluster,
&mutatedPod.Spec,

View File

@ -18,38 +18,16 @@ 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,
},
)
for _, barmanObjectKey := range pluginConfiguration.GetReferredBarmanObjectsKey() {
certs, err := impl.collectObjectStoreCertificates(ctx, barmanObjectKey)
if err != nil {
return nil, err
}
result = append(result, envs...)
}
if len(pluginConfiguration.RecoveryBarmanObjectName) > 0 &&
pluginConfiguration.RecoveryBarmanObjectName != pluginConfiguration.BarmanObjectName {
envs, err := impl.collectObjectStoreCertificates(
ctx,
types.NamespacedName{
Name: pluginConfiguration.RecoveryBarmanObjectName,
Namespace: namespace,
},
)
if err != nil {
return nil, err
}
result = append(result, envs...)
result = append(result, certs...)
}
return result, nil