From f99734a7dcb99ac73e7072f3cd3c78610d78a641 Mon Sep 17 00:00:00 2001 From: Simon Engmann Date: Fri, 2 Aug 2024 13:58:05 +0200 Subject: [PATCH] `sops_decrypt_file()`: resolve path argument relative to `terragrunt.hcl` (#2752) * Fix relative paths with sops_decrypt_file() sops_decrypt_file() computed the file path relative to the working directory instead of relative to the Terragrunt configuration. This generally worked with individual `terragrunt apply` operations but failed for `terragrunt run-all apply`, as it would look for the file in the parent directory. Fixes #1319. * Add test case for sops_decrypt_file() + run-all Verify that sops_decrypt_file() behaves as expected in combination with run-all. --- config/config_helpers.go | 4 ++-- test/integration_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/config/config_helpers.go b/config/config_helpers.go index 4f79cf1ec..da8894b6d 100644 --- a/config/config_helpers.go +++ b/config/config_helpers.go @@ -746,7 +746,7 @@ func sopsDecryptFile(ctx *ParsingContext, params []string) (string, error) { if err != nil { return "", errors.WithStackTrace(err) } - canonicalSourceFile, err := util.CanonicalPath(sourceFile, ctx.TerragruntOptions.WorkingDir) + canonicalSourceFile, err := util.CanonicalPath(sourceFile, filepath.Dir(ctx.TerragruntOptions.TerragruntConfigPath)) if err != nil { return "", errors.WithStackTrace(err) } @@ -755,7 +755,7 @@ func sopsDecryptFile(ctx *ParsingContext, params []string) (string, error) { return val, nil } - rawData, err := decrypt.File(sourceFile, format) + rawData, err := decrypt.File(canonicalSourceFile, format) if err != nil { return "", errors.WithStackTrace(extractSopsErrors(err)) } diff --git a/test/integration_test.go b/test/integration_test.go index 75e46448c..1e80b5a17 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -5098,6 +5098,39 @@ func TestSopsDecryptedCorrectly(t *testing.T) { assert.Contains(t, outputs["ini_value"].Value, "password = potato") } +func TestSopsDecryptedCorrectlyRunAll(t *testing.T) { + t.Parallel() + + cleanupTerraformFolder(t, TEST_FIXTURE_SOPS) + tmpEnvPath := copyEnvironment(t, TEST_FIXTURE_SOPS) + rootPath := util.JoinPath(tmpEnvPath, TEST_FIXTURE_SOPS) + + runTerragrunt(t, fmt.Sprintf("terragrunt run-all apply -auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s/.. --terragrunt-include-dir %s", rootPath, TEST_FIXTURE_SOPS)) + + stdout := bytes.Buffer{} + stderr := bytes.Buffer{} + + err := runTerragruntCommand(t, fmt.Sprintf("terragrunt run-all output -no-color -json --terragrunt-non-interactive --terragrunt-working-dir %s/.. --terragrunt-include-dir %s", rootPath, TEST_FIXTURE_SOPS), &stdout, &stderr) + require.NoError(t, err) + + outputs := map[string]TerraformOutput{} + require.NoError(t, json.Unmarshal(stdout.Bytes(), &outputs)) + + assert.Equal(t, outputs["json_bool_array"].Value, []interface{}{true, false}) + assert.Equal(t, outputs["json_string_array"].Value, []interface{}{"example_value1", "example_value2"}) + assert.Equal(t, outputs["json_number"].Value, 1234.56789) + assert.Equal(t, outputs["json_string"].Value, "example_value") + assert.Equal(t, outputs["json_hello"].Value, "Welcome to SOPS! Edit this file as you please!") + assert.Equal(t, outputs["yaml_bool_array"].Value, []interface{}{true, false}) + assert.Equal(t, outputs["yaml_string_array"].Value, []interface{}{"example_value1", "example_value2"}) + assert.Equal(t, outputs["yaml_number"].Value, 1234.5679) + assert.Equal(t, outputs["yaml_string"].Value, "example_value") + assert.Equal(t, outputs["yaml_hello"].Value, "Welcome to SOPS! Edit this file as you please!") + assert.Equal(t, outputs["text_value"].Value, "Raw Secret Example") + assert.Contains(t, outputs["env_value"].Value, "DB_PASSWORD=tomato") + assert.Contains(t, outputs["ini_value"].Value, "password = potato") +} + func TestTerragruntRunAllCommandPrompt(t *testing.T) { t.Parallel()