Merge remote-tracking branch 'upsteam/main' into insecrt-secret-from-stdin
This commit is contained in:
@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -17,6 +18,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/secret"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/docker/docker/api/types"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/spf13/cobra"
|
||||
@ -143,7 +145,7 @@ var AppSecretGenerateCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
var AppSecretInsertCommand = &cobra.Command{
|
||||
Use: i18n.G("insert <domain> <secret> <version> <data> [flags]"),
|
||||
Use: i18n.G("insert <domain> <secret> <version> [<data>] [flags]"),
|
||||
Aliases: []string{i18n.G("i")},
|
||||
Short: i18n.G("Insert secret"),
|
||||
Long: i18n.G(`This command inserts a secret into an app environment.
|
||||
@ -184,40 +186,20 @@ environment. Typically, you can let Abra generate them for you on app creation
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
app := internal.ValidateApp(args)
|
||||
|
||||
if err := app.Recipe.Ensure(internal.GetEnsureContext()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// if err := app.Recipe.Ensure(internal.GetEnsureContext()); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// cl, err := client.New(app.Server)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
name := args[1]
|
||||
version := args[2]
|
||||
var data string
|
||||
if len(args) == 4 {
|
||||
data = args[3]
|
||||
} else if len(args) == 3 {
|
||||
if insertFromFile {
|
||||
log.Fatal("can not insert from file and read from stdin")
|
||||
}
|
||||
|
||||
fi, err := os.Stdin.Stat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if fi.Mode()&os.ModeNamedPipe == 0 {
|
||||
log.Fatal("need to provide secret data or stdin stream")
|
||||
}
|
||||
|
||||
log.Debug("reading secret data from stdin")
|
||||
bytes, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("reading data from stdin: %s", err)
|
||||
}
|
||||
|
||||
data = string(bytes)
|
||||
// version := args[2]
|
||||
data, err := readSecretData(args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
||||
@ -240,7 +222,7 @@ environment. Typically, you can let Abra generate them for you on app creation
|
||||
log.Fatal(i18n.G("no secret %s available for recipe %s?", name, app.Recipe.Name))
|
||||
}
|
||||
|
||||
if insertFromFile && len(args) == 4 {
|
||||
if insertFromFile {
|
||||
raw, err := os.ReadFile(data)
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("reading secret from file: %s", err))
|
||||
@ -252,21 +234,70 @@ environment. Typically, you can let Abra generate them for you on app creation
|
||||
data = strings.TrimSpace(data)
|
||||
}
|
||||
|
||||
secretName := fmt.Sprintf("%s_%s_%s", app.StackName(), name, version)
|
||||
if err := client.StoreSecret(cl, secretName, data, app.Server); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// secretName := fmt.Sprintf("%s_%s_%s", app.StackName(), name, version)
|
||||
// if err := client.StoreSecret(cl, secretName, dbats -Tp tests/integration/app_check.batsata, app.Server); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
log.Info(i18n.G("%s successfully stored on server", secretName))
|
||||
// log.Info(i18n.G("%s successfully stored on server", secretName))
|
||||
|
||||
if storeInPass {
|
||||
if err := secret.PassInsertSecret(data, name, app.Name, app.Server); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
// if storeInPass {
|
||||
// if err := secret.PassInsertSecret(data, name, app.Name, app.Server); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// }
|
||||
},
|
||||
}
|
||||
|
||||
func readSecretData(args []string) (string, error) {
|
||||
if len(args) == 4 {
|
||||
return args[3], nil
|
||||
}
|
||||
|
||||
if len(args) != 3 {
|
||||
return "", errors.New(i18n.G("need 3 or 4 arguments"))
|
||||
}
|
||||
// First check if data is provided by stdin
|
||||
fi, err := os.Stdin.Stat()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if fi.Mode()&os.ModeNamedPipe != 0 {
|
||||
// Can't insert from stdin and read from file
|
||||
if insertFromFile {
|
||||
return "", errors.New(i18n.G("can not insert from file and read from stdin"))
|
||||
}
|
||||
|
||||
log.Debug(i18n.G("reading secret data from stdin"))
|
||||
bytes, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return "", errors.New(i18n.G("reading data from stdin: %s", err))
|
||||
}
|
||||
|
||||
return string(bytes), nil
|
||||
}
|
||||
if internal.NoInput {
|
||||
return "", errors.New(i18n.G("must provide <data> argument if --no-input is passed"))
|
||||
}
|
||||
|
||||
log.Debug(i18n.G("secret data not provided on command-line or stdin, prompting"))
|
||||
var prompt survey.Prompt
|
||||
if !insertFromFile {
|
||||
prompt = &survey.Password{
|
||||
Message: i18n.G("specify secret value"),
|
||||
}
|
||||
} else {
|
||||
prompt = &survey.Input{
|
||||
Message: i18n.G("specify secret file"),
|
||||
}
|
||||
}
|
||||
var data string
|
||||
if err := survey.AskOne(prompt, &data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// secretRm removes a secret.
|
||||
func secretRm(cl *dockerClient.Client, app appPkg.App, secretName, parsed string) error {
|
||||
if err := cl.SecretRemove(context.Background(), secretName); err != nil {
|
||||
|
Reference in New Issue
Block a user