Skip to content

Commit

Permalink
Add substitute flag for run
Browse files Browse the repository at this point in the history
  • Loading branch information
maidul98 committed Nov 26, 2022
1 parent 7d289d5 commit 746ded9
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 92 deletions.
16 changes: 15 additions & 1 deletion cli/packages/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ var runCmd = &cobra.Command{
return
}

substitute, err := cmd.Flags().GetBool("substitute")
if err != nil {
log.Errorln("Unable to parse the substitute flag")
log.Debugln(err)
return
}

projectId, err := cmd.Flags().GetString("projectId")
if err != nil {
log.Errorln("Unable to parse the project id flag")
Expand Down Expand Up @@ -82,14 +89,21 @@ var runCmd = &cobra.Command{
}
}

execCmd(args[0], args[1:], envsFromApi)
if substitute {
substitutions := util.SubstituteSecrets(envsFromApi)
execCmd(args[0], args[1:], substitutions)
} else {
execCmd(args[0], args[1:], envsFromApi)
}

},
}

func init() {
rootCmd.AddCommand(runCmd)
runCmd.Flags().StringP("env", "e", "dev", "Set the environment (dev, prod, etc.) from which your secrets should be pulled from")
runCmd.Flags().String("projectId", "", "The project ID from which your secrets should be pulled from")
runCmd.Flags().Bool("substitute", true, "Parse shell variable substitutions in your secrets")
}

// Credit: inspired by AWS Valut
Expand Down
14 changes: 6 additions & 8 deletions cli/packages/util/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,7 @@ func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variable
return secret.Value
}

fullyReplacedValue := secret.Value
fmt.Println("variablesToPopulate", variablesToPopulate)
valueToEdit := secret.Value
for _, variableWithSign := range variablesToPopulate {
variableWithoutSign := strings.Trim(variableWithSign, "}")
variableWithoutSign = strings.Trim(variableWithoutSign, "${")
Expand All @@ -236,10 +235,8 @@ func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variable
var expandedVariableValue string

if preComputedVariable, found := hashMapOfCompleteVariables[variableWithoutSign]; found {
fmt.Println("precompute for varable: ", variableWithoutSign)
expandedVariableValue = preComputedVariable
} else {
fmt.Println("compute for varable: ", variableWithoutSign)
expandedVariableValue = getExpandedEnvVariable(secrets, variableWithoutSign, hashMapOfCompleteVariables, hashMapOfSelfRefs)
hashMapOfCompleteVariables[variableWithoutSign] = expandedVariableValue
}
Expand All @@ -248,12 +245,13 @@ func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variable
if _, found := hashMapOfSelfRefs[variableWithoutSign]; found {
continue
} else {
fullyReplacedValue = strings.ReplaceAll(fullyReplacedValue, variableWithSign, expandedVariableValue)
valueToEdit = strings.ReplaceAll(valueToEdit, variableWithSign, expandedVariableValue)
}
}

return fullyReplacedValue
}

return valueToEdit

} else {
continue
}
Expand All @@ -266,9 +264,9 @@ func SubstituteSecrets(secrets []models.SingleEnvironmentVariable) []models.Sing
hashMapOfCompleteVariables := make(map[string]string)
hashMapOfSelfRefs := make(map[string]string)
expandedSecrets := []models.SingleEnvironmentVariable{}

for _, secret := range secrets {
expandedVariable := getExpandedEnvVariable(secrets, secret.Key, hashMapOfCompleteVariables, hashMapOfSelfRefs)
fmt.Println(secret.Key, "=", expandedVariable)
expandedSecrets = append(expandedSecrets, models.SingleEnvironmentVariable{
Key: secret.Key,
Value: expandedVariable,
Expand Down
204 changes: 121 additions & 83 deletions cli/packages/util/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,61 @@ import (
)

// References to self should return the value unaltered
// func Test_SubstituteSecrets_When_ReferenceToSelf(t *testing.T) {

// var tests = []struct {
// Key string
// Value string
// ExpectedValue string
// }{
// {Key: "A", Value: "${A}", ExpectedValue: "${A}"},
// {Key: "A", Value: "${A} ${A}", ExpectedValue: "${A} ${A}"},
// {Key: "A", Value: "${A}${A}", ExpectedValue: "${A}${A}"},
// }

// for _, test := range tests {
// secret := models.SingleEnvironmentVariable{
// Key: test.Key,
// Value: test.Value,
// }

// secrets := []models.SingleEnvironmentVariable{secret}
// result := SubstituteSecrets(secrets)

// if result[0].Value != test.ExpectedValue {
// t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
// }

// }
// }

// func Test_SubstituteSecrets_When_ReferenceDoesNotExist(t *testing.T) {

// var tests = []struct {
// Key string
// Value string
// ExpectedValue string
// }{
// {Key: "A", Value: "${X}", ExpectedValue: "${X}"},
// {Key: "A", Value: "${H}HELLO", ExpectedValue: "${H}HELLO"},
// {Key: "A", Value: "${L}${S}", ExpectedValue: "${L}${S}"},
// }

// for _, test := range tests {
// secret := models.SingleEnvironmentVariable{
// Key: test.Key,
// Value: test.Value,
// }

// secrets := []models.SingleEnvironmentVariable{secret}
// result := SubstituteSecrets(secrets)

// if result[0].Value != test.ExpectedValue {
// t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
// }

// }
// }
func Test_SubstituteSecrets_When_ReferenceToSelf(t *testing.T) {

var tests = []struct {
Key string
Value string
ExpectedValue string
}{
{Key: "A", Value: "${A}", ExpectedValue: "${A}"},
{Key: "A", Value: "${A} ${A}", ExpectedValue: "${A} ${A}"},
{Key: "A", Value: "${A}${A}", ExpectedValue: "${A}${A}"},
}

for _, test := range tests {
secret := models.SingleEnvironmentVariable{
Key: test.Key,
Value: test.Value,
}

secrets := []models.SingleEnvironmentVariable{secret}
result := SubstituteSecrets(secrets)

if result[0].Value != test.ExpectedValue {
t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
}

}
}

func Test_SubstituteSecrets_When_ReferenceDoesNotExist(t *testing.T) {

var tests = []struct {
Key string
Value string
ExpectedValue string
}{
{Key: "A", Value: "${X}", ExpectedValue: "${X}"},
{Key: "A", Value: "${H}HELLO", ExpectedValue: "${H}HELLO"},
{Key: "A", Value: "${L}${S}", ExpectedValue: "${L}${S}"},
}

for _, test := range tests {
secret := models.SingleEnvironmentVariable{
Key: test.Key,
Value: test.Value,
}

secrets := []models.SingleEnvironmentVariable{secret}
result := SubstituteSecrets(secrets)

if result[0].Value != test.ExpectedValue {
t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
}

}
}

func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *testing.T) {

Expand All @@ -70,53 +70,91 @@ func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *t
Value string
ExpectedValue string
}{
{
Key: "O",
Value: "${P} ==$$ ${X} ${UNKNOWN} ${A}",
ExpectedValue: "DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A}",
},
{
Key: "X",
Value: "DOMAIN",
ExpectedValue: "DOMAIN",
},
{
Key: "A",
Value: "*${A}* ${X}",
ExpectedValue: "*${A}*",
ExpectedValue: "*${A}* DOMAIN",
},
{
Key: "H",
Value: "${X} >>>",
ExpectedValue: "*${A}*",
ExpectedValue: "DOMAIN >>>",
},
{
Key: "X",
Value: "DOMAIN",
ExpectedValue: "DOMAIN",
Key: "P",
Value: "DOMAIN === ${A} ${H}",
ExpectedValue: "DOMAIN === ${A} DOMAIN >>>",
},
{
Key: "P",
Value: "${X} === ${A} ${H}",
ExpectedValue: "DOMAIN",
Key: "T",
Value: "${P} ==$$ ${X} ${UNKNOWN} ${A} ${P} ==$$ ${X} ${UNKNOWN} ${A}",
ExpectedValue: "DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A} DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A}",
},
{
Key: "S",
Value: "${ SSS$$ ${HEY}",
ExpectedValue: "${ SSS$$ ${HEY}",
},
// {
// Key: "B",
// Value: "*${A}*TOKEN*${X}*",
// ExpectedValue: "*${A}*TOKEN*DOMAIN*",
// },
// {
// Key: "C",
// Value: "*${A}* *${X}* *${B}* *${UNKNOWN}*",
// ExpectedValue: "*${A}* *DOMAIN* **${A}*TOKEN*DOMAIN** *${UNKNOWN}*",
// },
// {
// Key: "W",
// Value: "*${W}* ${LOL $JK} *${C}* *${C}*",
// ExpectedValue: "*${W}* ${LOL $JK} **${A}* *DOMAIN* **${A}*TOKEN*DOMAIN** *${UNKNOWN}** **${A}* *DOMAIN* **${A}*TOKEN*DOMAIN** *${UNKNOWN}**",
// },
}

secrets := []models.SingleEnvironmentVariable{}
for _, test := range tests {
secrets = append(secrets, models.SingleEnvironmentVariable{Key: test.Key, Value: test.Value})
}

SubstituteSecrets(secrets)
results := SubstituteSecrets(secrets)

for index, expanded := range results {
if expanded.Value != tests[index].ExpectedValue {
t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected [%s] but got [%s] for input [%s]", tests[index].ExpectedValue, expanded.Value, tests[index].Value)
}
}
}

func Test_SubstituteSecrets_When_No_SubstituteNeeded(t *testing.T) {

tests := []struct {
Key string
Value string
ExpectedValue string
}{
{
Key: "DOMAIN",
Value: "infisical.com",
ExpectedValue: "infisical.com",
},
{
Key: "API_KEY",
Value: "hdgsvjshcgkdckhevdkd",
ExpectedValue: "hdgsvjshcgkdckhevdkd",
},
{
Key: "ENV",
Value: "PROD",
ExpectedValue: "PROD",
},
}

secrets := []models.SingleEnvironmentVariable{}
for _, test := range tests {
secrets = append(secrets, models.SingleEnvironmentVariable{Key: test.Key, Value: test.Value})
}

// if result[0].Value != test.ExpectedValue {
// t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
// }
results := SubstituteSecrets(secrets)

// fmt.Println(result)
for index, expanded := range results {
if expanded.Value != tests[index].ExpectedValue {
t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected [%s] but got [%s] for input [%s]", tests[index].ExpectedValue, expanded.Value, tests[index].Value)
}
}
}

0 comments on commit 746ded9

Please sign in to comment.