mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-09-04 14:12:21 +02:00
feat: let a Cluster declare the object stores a Backup may request
The Role bound to the instance service account is built from the object stores the Cluster refers to, so a Backup naming any other store fails with a forbidden error on objectstores. The object store selection of a Backup is therefore unusable on its own. Add the additionalBarmanObjectNames parameter, a comma separated list of stores that take part in the RBAC and in the certificates of the instances while nothing is routed to them, so that a Backup can name one of them. Closes #611 Assisted-by: Claude Opus 5 Signed-off-by: Ildar Gilyazev <horiganmikle@gmail.com>
This commit is contained in:
parent
ec238c4d42
commit
946c704bee
@ -76,6 +76,12 @@ type PluginConfiguration struct {
|
||||
|
||||
ReplicaSourceBarmanObjectName string
|
||||
ReplicaSourceServerName string
|
||||
|
||||
// AdditionalBarmanObjectNames lists the object stores that a Backup
|
||||
// resource is allowed to request on top of the ones used by the cluster
|
||||
// itself. Nothing is written to them unless a Backup asks for one, but
|
||||
// they take part in the RBAC and in the certificates of the instances.
|
||||
AdditionalBarmanObjectNames []string
|
||||
}
|
||||
|
||||
// GetBarmanObjectKey gets the namespaced name of the barman object
|
||||
@ -133,8 +139,11 @@ func (config *PluginConfiguration) GetReferredBarmanObjectsKey() []types.Namespa
|
||||
if len(config.ReplicaSourceBarmanObjectName) > 0 {
|
||||
objectNames.Put(config.ReplicaSourceBarmanObjectName)
|
||||
}
|
||||
for _, name := range config.AdditionalBarmanObjectNames {
|
||||
objectNames.Put(name)
|
||||
}
|
||||
|
||||
result := make([]types.NamespacedName, 0, 3)
|
||||
result := make([]types.NamespacedName, 0, 4)
|
||||
for _, name := range objectNames.ToSortedList() {
|
||||
result = append(result, types.NamespacedName{
|
||||
Name: name,
|
||||
@ -197,6 +206,8 @@ func NewFromCluster(cluster *cnpgv1.Cluster) *PluginConfiguration {
|
||||
// used for the backup/archive
|
||||
BarmanObjectName: helper.Parameters["barmanObjectName"],
|
||||
ServerName: serverName,
|
||||
// reachable by a Backup resource requesting them explicitly
|
||||
AdditionalBarmanObjectNames: parseObjectNameList(helper.Parameters["additionalBarmanObjectNames"]),
|
||||
// used for restore and wal_restore during backup recovery
|
||||
RecoveryServerName: recoveryServerName,
|
||||
RecoveryBarmanObjectName: recoveryBarmanObjectName,
|
||||
@ -208,6 +219,23 @@ func NewFromCluster(cluster *cnpgv1.Cluster) *PluginConfiguration {
|
||||
return result
|
||||
}
|
||||
|
||||
// parseObjectNameList splits a comma separated list of object store names,
|
||||
// dropping the empty entries
|
||||
func parseObjectNameList(value string) []string {
|
||||
if len(value) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result []string
|
||||
for _, name := range strings.Split(value, ",") {
|
||||
if name = strings.TrimSpace(name); len(name) > 0 {
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func getRecoveryParameters(cluster *cnpgv1.Cluster) map[string]string {
|
||||
recoveryPluginConfiguration := getRecoverySourcePlugin(cluster)
|
||||
if recoveryPluginConfiguration == nil {
|
||||
|
||||
@ -163,3 +163,40 @@ var _ = Describe("PluginConfiguration.ApplyBackupParameters", func() {
|
||||
Expect(cfg.ServerName).To(Equal("cluster-example"))
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("Additional object stores", 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("are referred to, so that they are covered by RBAC and certificates", func() {
|
||||
cfg := newConfiguration(map[string]string{
|
||||
"barmanObjectName": "minio-store",
|
||||
"additionalBarmanObjectNames": "archive-store, monthly-store ,",
|
||||
})
|
||||
|
||||
names := make([]string, 0, 3)
|
||||
for _, key := range cfg.GetReferredBarmanObjectsKey() {
|
||||
Expect(key.Namespace).To(Equal("test-ns"))
|
||||
names = append(names, key.Name)
|
||||
}
|
||||
|
||||
Expect(names).To(ConsistOf("minio-store", "archive-store", "monthly-store"))
|
||||
})
|
||||
|
||||
It("do not receive anything on their own", func() {
|
||||
cfg := newConfiguration(map[string]string{
|
||||
"barmanObjectName": "minio-store",
|
||||
"additionalBarmanObjectNames": "archive-store",
|
||||
})
|
||||
|
||||
Expect(cfg.GetBarmanObjectKey().Name).To(Equal("minio-store"))
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user