diff --git a/pkg/envfile/envfile.go b/pkg/envfile/envfile.go index f10359cf..0e3bd80f 100644 --- a/pkg/envfile/envfile.go +++ b/pkg/envfile/envfile.go @@ -11,11 +11,6 @@ import ( "git.coopcloud.tech/toolshed/godotenv" ) -// envVarModifiers is a list of env var modifier strings. These are added to -// env vars as comments and modify their processing by Abra, e.g. determining -// how long secrets should be. -var envVarModifiers = []string{"length"} - // AppEnv is a map of the values in an apps env config type AppEnv = map[string]string diff --git a/pkg/secret/secret.go b/pkg/secret/secret.go index 2d03772f..f8366c7b 100644 --- a/pkg/secret/secret.go +++ b/pkg/secret/secret.go @@ -37,6 +37,9 @@ type Secret struct { // variable. For Example: // SECRET_FOO=v1 # charset=default,special Charset string + // Whether or not to skip generation of the secret or not + // For example: SECRET_FOO=v1 # generate=false + SkipGenerate bool // RemoteName is the name of the secret on the server. For example: // name: ${STACK_NAME}_test_pass_two_${SECRET_TEST_PASS_TWO_VERSION} // With the following: @@ -49,11 +52,7 @@ type Secret struct { // GeneratePassword generates passwords. func GeneratePassword(length uint, charset string) (string, error) { - passwords, err := passgen.GeneratePasswords( - 1, - length, - charset, - ) + passwords, err := passgen.GeneratePasswords(1, length, charset) if err != nil { return "", err } @@ -91,6 +90,7 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin if err != nil { return nil, err } + // Set the STACK_NAME to be able to generate the remote name correctly. appEnv["STACK_NAME"] = stackName @@ -99,6 +99,7 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin if err != nil { return nil, err } + // Read the compose files without injecting environment variables. configWithoutEnv, err := loader.LoadComposefile(opts, map[string]string{}, loader.SkipInterpolation) if err != nil { @@ -146,6 +147,7 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin if !strings.Contains(configWithoutEnv.Secrets[secretId].Name, envName) { continue } + lengthRaw, ok := modifierValues["length"] if ok { length, err := strconv.Atoi(lengthRaw) @@ -155,6 +157,13 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin value.Length = length } + generateRaw, ok := modifierValues["generate"] + if ok { + if generateRaw == "false" { + value.SkipGenerate = true + } + } + value.Charset = resolveCharset(modifierValues["charset"]) break } @@ -192,6 +201,12 @@ func GenerateSecrets(cl *dockerClient.Client, secrets map[string]Secret, server go func(secretName string, secret Secret) { defer wg.Done() + if secret.SkipGenerate { + log.Debugf("skipping generation of %s (generate=false)", secretName) + ch <- nil + return + } + log.Debugf("attempting to generate and store %s on %s", secret.RemoteName, server) if secret.Length > 0 { diff --git a/tests/integration/app_secret.bats b/tests/integration/app_secret.bats index fe3cf5c2..11151c9a 100644 --- a/tests/integration/app_secret.bats +++ b/tests/integration/app_secret.bats @@ -182,6 +182,20 @@ teardown(){ assert_output --partial '10' # NOTE(d1): hardcoded # length=10 in recipe config } +@test "generate: skip if generate=false" { + run sed -i 's/COMPOSE_FILE="compose.yml"/COMPOSE_FILE="compose.yml:compose.skip_pass.yml"/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run sed -i 's/#SECRET_TEST_SKIP_PASS_VERSION=v1/SECRET_TEST_SKIP_PASS_VERSION=v1/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app secret generate "$TEST_APP_DOMAIN" --all + assert_success + refute_output --partial 'test_skip_pass' +} + @test "insert: validate arguments" { run $ABRA app secret insert assert_failure