fix: fix: trim comments that are not modifers
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

See coop-cloud/organising#505
This commit is contained in:
decentral1se 2023-10-09 14:37:20 +02:00
parent be693e9df0
commit c249c6ae9c
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
11 changed files with 71 additions and 22 deletions

View File

@ -2,6 +2,7 @@ package app
import ( import (
"fmt" "fmt"
"path"
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
@ -96,7 +97,7 @@ var appNewCommand = cli.Command{
var secrets AppSecrets var secrets AppSecrets
var secretTable *jsontable.JSONTable var secretTable *jsontable.JSONTable
if internal.Secrets { if internal.Secrets {
sampleEnv, err := recipe.SampleEnv() sampleEnv, err := recipe.SampleEnv(config.ReadEnvOptions{})
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -106,7 +107,8 @@ var appNewCommand = cli.Command{
logrus.Fatal(err) logrus.Fatal(err)
} }
secretsConfig, err := secret.ReadSecretsConfig(sampleEnv, composeFiles, recipe.Name) envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample")
secretsConfig, err := secret.ReadSecretsConfig(envSamplePath, composeFiles, recipe.Name)
if err != nil { if err != nil {
return err return err
} }

View File

@ -87,7 +87,7 @@ var appSecretGenerateCommand = cli.Command{
logrus.Fatal(err) logrus.Fatal(err)
} }
secretsConfig, err := secret.ReadSecretsConfig(app.Env, composeFiles, app.Recipe) secretsConfig, err := secret.ReadSecretsConfig(app.Path, composeFiles, app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -276,7 +276,7 @@ Example:
logrus.Fatal(err) logrus.Fatal(err)
} }
secretsConfig, err := secret.ReadSecretsConfig(app.Env, composeFiles, app.Recipe) secretsConfig, err := secret.ReadSecretsConfig(app.Path, composeFiles, app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -29,7 +29,7 @@ func UpdateTag(pattern, image, tag, recipeName string) (bool, error) {
opts := stack.Deploy{Composefiles: []string{composeFile}} opts := stack.Deploy{Composefiles: []string{composeFile}}
envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample")
sampleEnv, err := config.ReadEnv(envSamplePath) sampleEnv, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
return false, err return false, err
} }
@ -97,7 +97,7 @@ func UpdateLabel(pattern, serviceName, label, recipeName string) error {
opts := stack.Deploy{Composefiles: []string{composeFile}} opts := stack.Deploy{Composefiles: []string{composeFile}}
envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample")
sampleEnv, err := config.ReadEnv(envSamplePath) sampleEnv, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
return err return err
} }

View File

@ -150,7 +150,7 @@ func (a ByName) Less(i, j int) bool {
} }
func ReadAppEnvFile(appFile AppFile, name AppName) (App, error) { func ReadAppEnvFile(appFile AppFile, name AppName) (App, error) {
env, err := ReadEnv(appFile.Path) env, err := ReadEnv(appFile.Path, ReadEnvOptions{})
if err != nil { if err != nil {
return App{}, fmt.Errorf("env file for %s couldn't be read: %s", name, err.Error()) return App{}, fmt.Errorf("env file for %s couldn't be read: %s", name, err.Error())
} }

View File

@ -55,6 +55,11 @@ func GetServers() ([]string, error) {
return servers, nil return servers, nil
} }
// ReadEnvOptions modifies the ReadEnv processing of env vars.
type ReadEnvOptions struct {
IncludeModifiers bool
}
// ContainsEnvVarModifier determines if an env var contains a modifier. // ContainsEnvVarModifier determines if an env var contains a modifier.
func ContainsEnvVarModifier(envVar string) bool { func ContainsEnvVarModifier(envVar string) bool {
for _, mod := range envVarModifiers { for _, mod := range envVarModifiers {
@ -66,7 +71,7 @@ func ContainsEnvVarModifier(envVar string) bool {
} }
// ReadEnv loads an app envivornment into a map. // ReadEnv loads an app envivornment into a map.
func ReadEnv(filePath string) (AppEnv, error) { func ReadEnv(filePath string, opts ReadEnvOptions) (AppEnv, error) {
var envVars AppEnv var envVars AppEnv
envVars, err := godotenv.Read(filePath) envVars, err := godotenv.Read(filePath)
@ -76,7 +81,7 @@ func ReadEnv(filePath string) (AppEnv, error) {
for idx, envVar := range envVars { for idx, envVar := range envVars {
if strings.Contains(envVar, "#") { if strings.Contains(envVar, "#") {
if ContainsEnvVarModifier(envVar) { if opts.IncludeModifiers && ContainsEnvVarModifier(envVar) {
continue continue
} }
vals := strings.Split(envVar, "#") vals := strings.Split(envVar, "#")
@ -222,7 +227,7 @@ func CheckEnv(app App) ([]EnvVar, error) {
return envVars, err return envVars, err
} }
envSample, err := ReadEnv(envSamplePath) envSample, err := ReadEnv(envSamplePath, ReadEnvOptions{})
if err != nil { if err != nil {
return envVars, err return envVars, err
} }

View File

@ -70,7 +70,7 @@ func TestGetAllFilesInDirectory(t *testing.T) {
} }
func TestReadEnv(t *testing.T) { func TestReadEnv(t *testing.T) {
env, err := config.ReadEnv(ExpectedAppFile.Path) env, err := config.ReadEnv(ExpectedAppFile.Path, config.ReadEnvOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -123,7 +123,7 @@ func TestCheckEnv(t *testing.T) {
} }
envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample")
envSample, err := config.ReadEnv(envSamplePath) envSample, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -157,7 +157,7 @@ func TestCheckEnvError(t *testing.T) {
} }
envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample")
envSample, err := config.ReadEnv(envSamplePath) envSample, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -203,7 +203,7 @@ func TestEnvVarCommentsRemoved(t *testing.T) {
} }
envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample")
envSample, err := config.ReadEnv(envSamplePath) envSample, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -216,4 +216,31 @@ func TestEnvVarCommentsRemoved(t *testing.T) {
if strings.Contains(envVar, "should be removed") { if strings.Contains(envVar, "should be removed") {
t.Fatalf("comment from '%s' should be removed", envVar) t.Fatalf("comment from '%s' should be removed", envVar)
} }
envVar, exists = envSample["SECRET_TEST_PASS_TWO_VERSION"]
if !exists {
t.Fatal("WITH_COMMENT env var should be present in .env.sample")
}
if strings.Contains(envVar, "length") {
t.Fatal("comment from env var SECRET_TEST_PASS_TWO_VERSION should have been removed")
}
}
func TestEnvVarModifiersIncluded(t *testing.T) {
offline := true
r, err := recipe.Get("abra-test-recipe", offline)
if err != nil {
t.Fatal(err)
}
envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample")
envSample, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{IncludeModifiers: true})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(envSample["SECRET_TEST_PASS_TWO_VERSION"], "length") {
t.Fatal("comment from env var SECRET_TEST_PASS_TWO_VERSION should not be removed")
}
} }

View File

@ -227,7 +227,7 @@ func LintAppService(recipe recipe.Recipe) (bool, error) {
// therefore no matching traefik deploy label will be present. // therefore no matching traefik deploy label will be present.
func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) { func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) {
envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample")
sampleEnv, err := config.ReadEnv(envSamplePath) sampleEnv, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
return false, fmt.Errorf("Unable to discover .env.sample for %s", recipe.Name) return false, fmt.Errorf("Unable to discover .env.sample for %s", recipe.Name)
} }

View File

@ -221,7 +221,7 @@ func Get(recipeName string, offline bool) (Recipe, error) {
} }
envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, recipeName, ".env.sample")
sampleEnv, err := config.ReadEnv(envSamplePath) sampleEnv, err := config.ReadEnv(envSamplePath, config.ReadEnvOptions{})
if err != nil { if err != nil {
return Recipe{}, err return Recipe{}, err
} }
@ -249,9 +249,9 @@ func Get(recipeName string, offline bool) (Recipe, error) {
}, nil }, nil
} }
func (r Recipe) SampleEnv() (map[string]string, error) { func (r Recipe) SampleEnv(opts config.ReadEnvOptions) (map[string]string, error) {
envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, r.Name, ".env.sample")
sampleEnv, err := config.ReadEnv(envSamplePath) sampleEnv, err := config.ReadEnv(envSamplePath, opts)
if err != nil { if err != nil {
return sampleEnv, fmt.Errorf("unable to discover .env.sample for %s", r.Name) return sampleEnv, fmt.Errorf("unable to discover .env.sample for %s", r.Name)
} }

View File

@ -69,9 +69,14 @@ func GeneratePassphrases(count uint) ([]string, error) {
// and some times you don't (as the caller). We need to be able to handle the // and some times you don't (as the caller). We need to be able to handle the
// "app new" case where we pass in the .env.sample and the "secret generate" // "app new" case where we pass in the .env.sample and the "secret generate"
// case where the app is created. // case where the app is created.
func ReadSecretsConfig(appEnv map[string]string, composeFiles []string, recipeName string) (map[string]string, error) { func ReadSecretsConfig(appEnvPath string, composeFiles []string, recipeName string) (map[string]string, error) {
secretConfigs := make(map[string]string) secretConfigs := make(map[string]string)
appEnv, err := config.ReadEnv(appEnvPath, config.ReadEnvOptions{IncludeModifiers: true})
if err != nil {
return secretConfigs, err
}
opts := stack.Deploy{Composefiles: composeFiles} opts := stack.Deploy{Composefiles: composeFiles}
config, err := loader.LoadComposefile(opts, appEnv) config, err := loader.LoadComposefile(opts, appEnv)
if err != nil { if err != nil {
@ -232,7 +237,7 @@ func PollSecretsStatus(cl *dockerClient.Client, app config.App) (secretStatuses,
return secStats, err return secStats, err
} }
secretsConfig, err := ReadSecretsConfig(app.Env, composeFiles, app.Recipe) secretsConfig, err := ReadSecretsConfig(app.Path, composeFiles, app.Recipe)
if err != nil { if err != nil {
return secStats, err return secStats, err
} }

View File

@ -18,13 +18,14 @@ func TestReadSecretsConfig(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
sampleEnv, err := recipe.SampleEnv() sampleEnv, err := recipe.SampleEnv(config.ReadEnvOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
composeFiles := []string{path.Join(config.RECIPES_DIR, recipe.Name, "compose.yml")} composeFiles := []string{path.Join(config.RECIPES_DIR, recipe.Name, "compose.yml")}
secretsFromConfig, err := ReadSecretsConfig(sampleEnv, composeFiles, recipe.Name) envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample")
secretsFromConfig, err := ReadSecretsConfig(envSamplePath, composeFiles, recipe.Name)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -344,3 +344,12 @@ teardown(){
_reset_app _reset_app
} }
@test "recipe config comments not present in values" {
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input
assert_success
run $ABRA app run "$TEST_APP_DOMAIN" app env
assert_success
refute_output --partial 'should be removed'
}