0
0
forked from toolshed/abra

feat(secrets): Inserting secret data from stdin

This can be usefull for scripting and gives a lot of flexibility
This commit is contained in:
2025-08-25 12:52:52 +02:00
parent 0c708f6592
commit e92ff6e013
2 changed files with 56 additions and 8 deletions

View File

@ -3,6 +3,7 @@ package app
import (
"context"
"fmt"
"io"
"os"
"strconv"
"strings"
@ -28,7 +29,8 @@ var AppSecretGenerateCommand = &cobra.Command{
ValidArgsFunction: func(
cmd *cobra.Command,
args []string,
toComplete string) ([]string, cobra.ShellCompDirective) {
toComplete string,
) ([]string, cobra.ShellCompDirective) {
switch l := len(args); l {
case 0:
return autocomplete.AppNameComplete()
@ -155,12 +157,16 @@ environment. Typically, you can let Abra generate them for you on app creation
abra app secret insert 1312.net my_secret v1 mySuperSecret
# insert secret as file
abra app secret insert 1312.net my_secret v1 secret.txt -f`),
Args: cobra.MinimumNArgs(4),
abra app secret insert 1312.net my_secret v1 secret.txt -f
# insert secret from stdin
echo "mmySuperSecret" | abra app secret insert 1312.net my_secret v1`),
Args: cobra.MinimumNArgs(3),
ValidArgsFunction: func(
cmd *cobra.Command,
args []string,
toComplete string) ([]string, cobra.ShellCompDirective) {
toComplete string,
) ([]string, cobra.ShellCompDirective) {
switch l := len(args); l {
case 0:
return autocomplete.AppNameComplete()
@ -188,7 +194,30 @@ environment. Typically, you can let Abra generate them for you on app creation
name := args[1]
version := args[2]
data := args[3]
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)
}
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
if err != nil {
@ -210,7 +239,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 {
if insertFromFile && len(args) == 4 {
raw, err := os.ReadFile(data)
if err != nil {
log.Fatal(i18n.G("reading secret from file: %s", err))
@ -269,7 +298,8 @@ match those configured in the recipe beforehand.`),
ValidArgsFunction: func(
cmd *cobra.Command,
args []string,
toComplete string) ([]string, cobra.ShellCompDirective) {
toComplete string,
) ([]string, cobra.ShellCompDirective) {
switch l := len(args); l {
case 0:
return autocomplete.AppNameComplete()
@ -376,7 +406,8 @@ var AppSecretLsCommand = &cobra.Command{
ValidArgsFunction: func(
cmd *cobra.Command,
args []string,
toComplete string) ([]string, cobra.ShellCompDirective) {
toComplete string,
) ([]string, cobra.ShellCompDirective) {
return autocomplete.AppNameComplete()
},
Run: func(cmd *cobra.Command, args []string) {

View File

@ -208,6 +208,9 @@ teardown(){
run $ABRA app secret insert "$TEST_APP_DOMAIN" bar baz
assert_failure
run bash -c "echo foo | $ABRA app secret insert $TEST_APP_DOMAIN bar baz -f"
assert_failure
}
@test "insert: cannot insert unknown secret" {
@ -248,6 +251,20 @@ teardown(){
assert_output --partial 'true'
}
@test "insert: create secret from stdin" {
run $ABRA app secret ls "$TEST_APP_DOMAIN"
assert_success
assert_output --partial 'false'
run bash -c "echo foo | $ABRA app secret insert $TEST_APP_DOMAIN test_pass_one v1"
assert_success
assert_output --partial 'successfully stored on server'
run $ABRA app secret ls "$TEST_APP_DOMAIN"
assert_success
assert_output --partial 'true'
}
@test "rm: validate arguments" {
run $ABRA app secret rm
assert_failure