From 42968fb8e14ee0134bfc2b50e783d5e4953e37e1 Mon Sep 17 00:00:00 2001 From: decentral1se Date: Sat, 31 Jul 2021 15:50:04 +0200 Subject: [PATCH] feat: finally implement app new command --- cli/app.go | 6 +++-- client/secret.go | 20 +++++++++++++++ config/env.go | 4 +++ secret/secret.go | 64 ++++++++++++++++++++++++++++++------------------ 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/cli/app.go b/cli/app.go index 7a48b9d2..3714b617 100644 --- a/cli/app.go +++ b/cli/app.go @@ -113,7 +113,9 @@ on your $PATH. logrus.Fatal(fmt.Errorf("'%s' cannot be longer than 45 characters", sanitisedAppName)) } - config.CopyAppEnvSample(appType, AppName, Server) + if err := config.CopyAppEnvSample(appType, AppName, Server); err != nil { + logrus.Fatal(err) + } secrets := make(map[string]string) if Secrets { @@ -123,7 +125,7 @@ on your $PATH. logrus.Fatal(err) } secretEnvVars := secret.ReadSecretEnvVars(appEnv) - secrets, err = secret.GenerateSecrets(secretEnvVars, Server) + secrets, err = secret.GenerateSecrets(secretEnvVars, sanitisedAppName, Server) if err != nil { logrus.Fatal(err) } diff --git a/client/secret.go b/client/secret.go index d9bb8d13..a627b38e 100644 --- a/client/secret.go +++ b/client/secret.go @@ -1,5 +1,25 @@ package client +import ( + "context" + + "github.com/docker/docker/api/types/swarm" +) + func StoreSecret(secretName, secretValue, server string) error { + cl, err := NewClientWithContext(server) + if err != nil { + return err + } + + ctx := context.Background() + ann := swarm.Annotations{Name: secretName} + spec := swarm.SecretSpec{Annotations: ann, Data: []byte(secretValue)} + + // We don't bother with the secret IDs for now + if _, err := cl.SecretCreate(ctx, spec); err != nil { + return err + } + return nil } diff --git a/config/env.go b/config/env.go index 5d217b74..ffe313c4 100644 --- a/config/env.go +++ b/config/env.go @@ -208,6 +208,10 @@ func CopyAppEnvSample(appType, appName, server string) error { } appEnvPath := path.Join(ABRA_DIR, "servers", server, fmt.Sprintf("%s.env", appName)) + if _, err := os.Stat(appEnvPath); err == nil { + return fmt.Errorf("%s already exists?", appEnvPath) + } + err = ioutil.WriteFile(appEnvPath, envSample, 0755) if err != nil { return err diff --git a/secret/secret.go b/secret/secret.go index 24bf05cb..0c52f8a5 100644 --- a/secret/secret.go +++ b/secret/secret.go @@ -80,39 +80,55 @@ func ParseSecretEnvVarValue(secretValue string) (SecretValue, error) { if err != nil { return SecretValue{}, err } - return SecretValue{Version: values[0], Length: length}, nil + version := strings.ReplaceAll(values[0], " ", "") + return SecretValue{Version: version, Length: length}, nil } } -func GenerateSecrets(secretEnvVars map[string]string, server string) (map[string]string, error) { +func GenerateSecrets(secretEnvVars map[string]string, appName, server string) (map[string]string, error) { secrets := make(map[string]string) + ch := make(chan error, len(secretEnvVars)) for secretEnvVar := range secretEnvVars { - secretName := ParseSecretEnvVarName(secretEnvVar) - secretValue, err := ParseSecretEnvVarValue(secretEnvVars[secretEnvVar]) + go func(s string) { + secretName := ParseSecretEnvVarName(s) + secretValue, err := ParseSecretEnvVarValue(secretEnvVars[s]) + if err != nil { + ch <- err + return + } + secretRemoteName := fmt.Sprintf("%s_%s_%s", appName, secretName, secretValue.Version) + if secretValue.Length > 0 { + passwords, err := GeneratePasswords(1, uint(secretValue.Length)) + if err != nil { + ch <- err + return + } + if err := client.StoreSecret(secretRemoteName, passwords[0], server); err != nil { + ch <- err + return + } + secrets[secretName] = passwords[0] + } else { + passphrases, err := GeneratePassphrases(1) + if err != nil { + ch <- err + return + } + if err := client.StoreSecret(secretRemoteName, passphrases[0], server); err != nil { + ch <- err + } + secrets[secretName] = passphrases[0] + } + ch <- nil + }(secretEnvVar) + } + + for range secretEnvVars { + err := <-ch if err != nil { return nil, err } - - if secretValue.Length > 0 { - passwords, err := GeneratePasswords(1, uint(secretValue.Length)) - if err != nil { - return nil, err - } - secrets[secretName] = passwords[0] - if err := client.StoreSecret(secretName, passwords[0], server); err != nil { - return nil, err - } - } else { - passphrases, err := GeneratePassphrases(1) - if err != nil { - return nil, err - } - secrets[secretName] = passphrases[0] - if err := client.StoreSecret(secretName, passphrases[0], server); err != nil { - return nil, err - } - } } return secrets, nil