fix: guard against concurrent write errors

This commit is contained in:
decentral1se 2022-03-12 16:59:45 +01:00
parent b31cb6b866
commit 262009701e
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
1 changed files with 19 additions and 0 deletions

View File

@ -8,6 +8,7 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"sync"
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
@ -119,23 +120,32 @@ func ParseSecretEnvVarValue(secret string) (secretValue, error) {
func GenerateSecrets(secretEnvVars map[string]string, appName, server string) (map[string]string, error) { func GenerateSecrets(secretEnvVars map[string]string, appName, server string) (map[string]string, error) {
secrets := make(map[string]string) secrets := make(map[string]string)
var mutex sync.Mutex
var wg sync.WaitGroup
ch := make(chan error, len(secretEnvVars)) ch := make(chan error, len(secretEnvVars))
for secretEnvVar := range secretEnvVars { for secretEnvVar := range secretEnvVars {
wg.Add(1)
go func(s string) { go func(s string) {
defer wg.Done()
secretName := ParseSecretEnvVarName(s) secretName := ParseSecretEnvVarName(s)
secretValue, err := ParseSecretEnvVarValue(secretEnvVars[s]) secretValue, err := ParseSecretEnvVarValue(secretEnvVars[s])
if err != nil { if err != nil {
ch <- err ch <- err
return return
} }
secretRemoteName := fmt.Sprintf("%s_%s_%s", appName, secretName, secretValue.Version) secretRemoteName := fmt.Sprintf("%s_%s_%s", appName, secretName, secretValue.Version)
logrus.Debugf("attempting to generate and store %s on %s", secretRemoteName, server) logrus.Debugf("attempting to generate and store %s on %s", secretRemoteName, server)
if secretValue.Length > 0 { if secretValue.Length > 0 {
passwords, err := GeneratePasswords(1, uint(secretValue.Length)) passwords, err := GeneratePasswords(1, uint(secretValue.Length))
if err != nil { if err != nil {
ch <- err ch <- err
return return
} }
if err := client.StoreSecret(secretRemoteName, passwords[0], server); err != nil { if err := client.StoreSecret(secretRemoteName, passwords[0], server); err != nil {
if strings.Contains(err.Error(), "AlreadyExists") { if strings.Contains(err.Error(), "AlreadyExists") {
logrus.Warnf("%s already exists, moving on...", secretRemoteName) logrus.Warnf("%s already exists, moving on...", secretRemoteName)
@ -145,6 +155,9 @@ func GenerateSecrets(secretEnvVars map[string]string, appName, server string) (m
} }
return return
} }
mutex.Lock()
defer mutex.Unlock()
secrets[secretName] = passwords[0] secrets[secretName] = passwords[0]
} else { } else {
passphrases, err := GeneratePassphrases(1) passphrases, err := GeneratePassphrases(1)
@ -152,6 +165,7 @@ func GenerateSecrets(secretEnvVars map[string]string, appName, server string) (m
ch <- err ch <- err
return return
} }
if err := client.StoreSecret(secretRemoteName, passphrases[0], server); err != nil { if err := client.StoreSecret(secretRemoteName, passphrases[0], server); err != nil {
if strings.Contains(err.Error(), "AlreadyExists") { if strings.Contains(err.Error(), "AlreadyExists") {
logrus.Warnf("%s already exists, moving on...", secretRemoteName) logrus.Warnf("%s already exists, moving on...", secretRemoteName)
@ -161,12 +175,17 @@ func GenerateSecrets(secretEnvVars map[string]string, appName, server string) (m
} }
return return
} }
mutex.Lock()
defer mutex.Unlock()
secrets[secretName] = passphrases[0] secrets[secretName] = passphrases[0]
} }
ch <- nil ch <- nil
}(secretEnvVar) }(secretEnvVar)
} }
wg.Wait()
for range secretEnvVars { for range secretEnvVars {
err := <-ch err := <-ch
if err != nil { if err != nil {