fix: honour the object store requested by a Backup resource

The operator relays the parameters of a Backup resource to the plugin in
the BackupRequest, but the plugin builds its configuration from the
Cluster alone. A Backup asking for a different object store is therefore
written to the cluster one, and it completes without any warning, so the
mistake surfaces only when the archive turns out to be empty.

Apply the parameters of the Backup on top of the configuration derived
from the Cluster, so that barmanObjectName and serverName select the
destination of that single backup.

Closes #611

Assisted-by: Claude Opus 5
Signed-off-by: Ildar Gilyazev <horiganmikle@gmail.com>
This commit is contained in:
Ildar Gilyazev 2026-08-26 10:32:05 +03:00
parent 77118ed413
commit ec238c4d42
3 changed files with 59 additions and 0 deletions

View File

@ -81,6 +81,8 @@ func (b BackupServiceImplementation) Backup(
return nil, err
}
configuration.ApplyBackupParameters(request.GetParameters())
var objectStore barmancloudv1.ObjectStore
if err := b.Client.Get(ctx, configuration.GetBarmanObjectKey(), &objectStore); err != nil {
contextLogger.Error(err, "while getting object store", "key", configuration.GetRecoveryBarmanObjectKey())

View File

@ -86,6 +86,24 @@ func (config *PluginConfiguration) GetBarmanObjectKey() types.NamespacedName {
}
}
// ApplyBackupParameters overrides the object store selection with the
// parameters of the Backup resource. The operator relays them in the
// BackupRequest, and without this a Backup asking for a different object
// store is silently written to the cluster one.
func (config *PluginConfiguration) ApplyBackupParameters(parameters map[string]string) {
if len(parameters) == 0 {
return
}
if value := parameters["barmanObjectName"]; len(value) > 0 {
config.BarmanObjectName = value
}
if value := parameters["serverName"]; len(value) > 0 {
config.ServerName = value
}
}
// GetRecoveryBarmanObjectKey gets the namespaced name of the recovery barman object
func (config *PluginConfiguration) GetRecoveryBarmanObjectKey() types.NamespacedName {
return types.NamespacedName{

View File

@ -124,3 +124,42 @@ var _ = Describe("NewFromCluster", func() {
Expect(cfg.Validate()).NotTo(Succeed())
})
})
var _ = Describe("PluginConfiguration.ApplyBackupParameters", func() {
newConfiguration := func(parameters map[string]string) *PluginConfiguration {
return NewFromCluster(&cnpgv1.Cluster{
ObjectMeta: metav1.ObjectMeta{Name: "cluster-example", Namespace: "test-ns"},
Spec: cnpgv1.ClusterSpec{
Plugins: []cnpgv1.PluginConfiguration{
{Name: metadata.PluginName, Parameters: parameters},
},
},
})
}
It("sends the backup to the object store requested by the Backup resource", func() {
cfg := newConfiguration(map[string]string{"barmanObjectName": "minio-store"})
cfg.ApplyBackupParameters(map[string]string{"barmanObjectName": "archive-store"})
Expect(cfg.GetBarmanObjectKey().Name).To(Equal("archive-store"))
})
It("overrides the server name too", func() {
cfg := newConfiguration(map[string]string{"barmanObjectName": "minio-store"})
cfg.ApplyBackupParameters(map[string]string{"serverName": "another-name"})
Expect(cfg.ServerName).To(Equal("another-name"))
Expect(cfg.GetBarmanObjectKey().Name).To(Equal("minio-store"))
})
It("keeps the cluster object store when the Backup carries no parameters", func() {
cfg := newConfiguration(map[string]string{"barmanObjectName": "minio-store"})
cfg.ApplyBackupParameters(nil)
Expect(cfg.GetBarmanObjectKey().Name).To(Equal("minio-store"))
Expect(cfg.ServerName).To(Equal("cluster-example"))
})
})