Skip to content

Commit

Permalink
adding functionality to parse json in multivalue secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
aircraft-cerier committed Feb 18, 2021
1 parent 01efe84 commit 387e660
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
13 changes: 12 additions & 1 deletion environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package environment

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -106,7 +107,17 @@ func (m *Manager) Populate() error {
}

if found {
env[name] = secret
secretMap := make(map[string]string)
err = json.Unmarshal([]byte(secret), &secretMap)
// if the json Unmarshal errors that means the secret is not a json and we set the original env variable to the secret
if err != nil {
env[name] = secret
} else {
// if the secret is a json we want to set the key-value pairs within the json to the env variables
for keySecret, valueSecret := range secretMap {
env[keySecret] = valueSecret
}
}
}
}

Expand Down
59 changes: 42 additions & 17 deletions environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ import (
func TestMain(t *testing.T) {
tests := []struct {
description string
key string
value string
envKey string
secretKey string
envValue string
secretValue string
expect string
json bool
callsSM bool
smOutput *secretsmanager.GetSecretValueOutput
callsSSM bool
Expand All @@ -29,14 +32,14 @@ func TestMain(t *testing.T) {
}{
{
description: "does not have sideffects for the regular environment",
key: "TEST",
value: "somevalue",
envKey: "TEST",
envValue: "somevalue",
expect: "somevalue",
},
{
description: "allows empty strings as secrets",
key: "TEST",
value: "sm://<secret-path>",
envKey: "TEST",
envValue: "sm://<secret-path>",
expect: "",
callsSM: true,
smOutput: &secretsmanager.GetSecretValueOutput{
Expand All @@ -45,8 +48,8 @@ func TestMain(t *testing.T) {
},
{
description: "picks up sm secrets",
key: "TEST",
value: "sm://<secret-path>",
envKey: "TEST",
envValue: "sm://<secret-path>",
expect: "secret",
callsSM: true,
smOutput: &secretsmanager.GetSecretValueOutput{
Expand All @@ -55,8 +58,8 @@ func TestMain(t *testing.T) {
},
{
description: "picks up ssm secrets",
key: "TEST",
value: "ssm://<parameter-path>",
envKey: "TEST",
envValue: "ssm://<parameter-path>",
expect: "secret",
callsSSM: true,
ssmOutput: &ssm.GetParameterOutput{
Expand All @@ -67,14 +70,27 @@ func TestMain(t *testing.T) {
},
{
description: "picks up kms secrets",
key: "TEST",
value: "kms://" + base64.StdEncoding.EncodeToString([]byte("<encrypted>")),
envKey: "TEST",
envValue: "kms://" + base64.StdEncoding.EncodeToString([]byte("<encrypted>")),
expect: "secret",
callsKMS: true,
kmsOutput: &kms.DecryptOutput{
Plaintext: []byte("secret"),
},
},
{
description: "test multi key-value secret within json",
envKey: "TEST",
envValue: "sm://<secret-path>",
expect: "sm://<secret-path>",
secretKey: "password",
secretValue: "secret",
json: true,
callsSM: true,
smOutput: &secretsmanager.GetSecretValueOutput{
SecretString: aws.String("{\"password\": \"secret\"}"),
},
},
}

for _, tc := range tests {
Expand All @@ -96,13 +112,13 @@ func TestMain(t *testing.T) {
}

// Set environment
old := os.Getenv(tc.key)
if err := os.Setenv(tc.key, tc.value); err != nil {
old := os.Getenv(tc.envKey)
if err := os.Setenv(tc.envKey, tc.envValue); err != nil {
t.Fatalf("failed to set environment variable: %s", err)
}
// Set the old value before exiting
defer func() {
if err := os.Setenv(tc.key, old); err != nil {
if err := os.Setenv(tc.envKey, old); err != nil {
t.Fatalf("failed to set environment variable: %s", err)
}
}()
Expand All @@ -112,8 +128,17 @@ func TestMain(t *testing.T) {
if err := env.Populate(); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if got, want := os.Getenv(tc.key), tc.expect; got != want {
t.Errorf("\ngot: %s\nwanted: %s", got, want)
if tc.json != true {
if got, want := os.Getenv(tc.envKey), tc.expect; got != want {
t.Errorf("\ngot: %s\nwanted: %s", got, want)
}
} else {
if got, want := os.Getenv(tc.envKey), tc.expect; got != want {
t.Errorf("\ngot: %s\nwanted: %s", got, want)
}
if got, want := os.Getenv(tc.secretKey), tc.secretValue; got != want {
t.Errorf("\ngot: %s\nwanted: %s", got, want)
}
}
})
}
Expand Down

0 comments on commit 387e660

Please sign in to comment.