From d57039357e8734c5a7f3859b51f8c953cd8bd54a Mon Sep 17 00:00:00 2001 From: Andrew Suderman Date: Fri, 1 Apr 2022 13:01:51 -0600 Subject: [PATCH] Allow escaping $ in environment variable interpolation (#560) * Add test for escaped dollar signs * Check for 2663 and return it rather than an error in env parsing * Consolidate the parEnv and envMapper functions --- .../course_files/03_test_env_var.yml | 6 ++ pkg/course/course.go | 19 ++++--- pkg/course/course_test.go | 56 +++++++++++++++++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/end_to_end_testing/course_files/03_test_env_var.yml b/end_to_end_testing/course_files/03_test_env_var.yml index 3ca6ae1a..4432d4f3 100644 --- a/end_to_end_testing/course_files/03_test_env_var.yml +++ b/end_to_end_testing/course_files/03_test_env_var.yml @@ -15,3 +15,9 @@ charts: comment-problem-detector: # This is a comment "${this_var_should_not_be_parsed}" - test-value + escape-values: + repository: fairwinds-incubator + chart: basic-demo + namespace: 03-infra + values: + non-used: "A string that needs a $$ in it" diff --git a/pkg/course/course.go b/pkg/course/course.go index f37eba56..f2054fca 100644 --- a/pkg/course/course.go +++ b/pkg/course/course.go @@ -625,21 +625,22 @@ func parseSecrets(courseData []byte) error { } func parseEnv(data string) (string, error) { - dataWithEnv := os.Expand(data, envMapper) + dataWithEnv := os.Expand(data, func(key string) string { + if key == "$" { + return "$$" + } + if value, ok := os.LookupEnv(key); ok { + return value + } + color.Red("ERROR: environment variable %s is not set", key) + return "_ENV_NOT_SET_" + }) if strings.Contains(dataWithEnv, "_ENV_NOT_SET_") { return data, fmt.Errorf("course has env variables that are not properly set") } return dataWithEnv, nil } -func envMapper(key string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - color.Red("ERROR: environment variable %s is not set", key) - return "_ENV_NOT_SET_" -} - func boolPtr(b bool) *bool { return &b } diff --git a/pkg/course/course_test.go b/pkg/course/course_test.go index aa2f1130..57cfe84c 100644 --- a/pkg/course/course_test.go +++ b/pkg/course/course_test.go @@ -15,6 +15,7 @@ package course import ( + "os" "testing" "github.com/stretchr/testify/assert" @@ -221,3 +222,58 @@ func TestFileV2_populateDefaultRepository(t *testing.T) { }) } } + +func Test_parseEnv(t *testing.T) { + + tests := []struct { + name string + data string + want string + envMap map[string]string + wantErr bool + }{ + { + name: "basic error check", + data: "$this-is-certainly-not-a-valid-env-var", + wantErr: true, + }, + { + name: "basic test", + data: "$TEST_ENV_KEY", + want: "test-env-value", + envMap: map[string]string{ + "TEST_ENV_KEY": "test-env-value", + }, + wantErr: false, + }, + { + name: "escaping test", + data: "$$TEST_ENV_KEY", + want: "$$TEST_ENV_KEY", + envMap: map[string]string{ + "TEST_ENV_KEY": "test-env-value", + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for k, v := range tt.envMap { + os.Setenv(k, v) + } + + got, err := parseEnv(tt.data) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.EqualValues(t, tt.want, got) + } + }) + } +} + +func Test_boolPtr(t *testing.T) { + testBool := true + assert.EqualValues(t, &testBool, boolPtr(testBool)) +}