Add substitute flag for run

This commit is contained in:
Maidul Islam
2022-11-26 16:54:36 -05:00
parent 7d289d5180
commit 746ded9a53
3 changed files with 135 additions and 85 deletions

View File

@@ -33,6 +33,13 @@ var runCmd = &cobra.Command{
return 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") projectId, err := cmd.Flags().GetString("projectId")
if err != nil { if err != nil {
log.Errorln("Unable to parse the project id flag") log.Errorln("Unable to parse the project id flag")
@@ -82,7 +89,13 @@ 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)
}
}, },
} }
@@ -90,6 +103,7 @@ func init() {
rootCmd.AddCommand(runCmd) 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().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().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 // Credit: inspired by AWS Valut

View File

@@ -222,8 +222,7 @@ func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variable
return secret.Value return secret.Value
} }
fullyReplacedValue := secret.Value valueToEdit := secret.Value
fmt.Println("variablesToPopulate", variablesToPopulate)
for _, variableWithSign := range variablesToPopulate { for _, variableWithSign := range variablesToPopulate {
variableWithoutSign := strings.Trim(variableWithSign, "}") variableWithoutSign := strings.Trim(variableWithSign, "}")
variableWithoutSign = strings.Trim(variableWithoutSign, "${") variableWithoutSign = strings.Trim(variableWithoutSign, "${")
@@ -236,10 +235,8 @@ func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variable
var expandedVariableValue string var expandedVariableValue string
if preComputedVariable, found := hashMapOfCompleteVariables[variableWithoutSign]; found { if preComputedVariable, found := hashMapOfCompleteVariables[variableWithoutSign]; found {
fmt.Println("precompute for varable: ", variableWithoutSign)
expandedVariableValue = preComputedVariable expandedVariableValue = preComputedVariable
} else { } else {
fmt.Println("compute for varable: ", variableWithoutSign)
expandedVariableValue = getExpandedEnvVariable(secrets, variableWithoutSign, hashMapOfCompleteVariables, hashMapOfSelfRefs) expandedVariableValue = getExpandedEnvVariable(secrets, variableWithoutSign, hashMapOfCompleteVariables, hashMapOfSelfRefs)
hashMapOfCompleteVariables[variableWithoutSign] = expandedVariableValue hashMapOfCompleteVariables[variableWithoutSign] = expandedVariableValue
} }
@@ -248,12 +245,13 @@ func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variable
if _, found := hashMapOfSelfRefs[variableWithoutSign]; found { if _, found := hashMapOfSelfRefs[variableWithoutSign]; found {
continue continue
} else { } else {
fullyReplacedValue = strings.ReplaceAll(fullyReplacedValue, variableWithSign, expandedVariableValue) valueToEdit = strings.ReplaceAll(valueToEdit, variableWithSign, expandedVariableValue)
} }
} }
return fullyReplacedValue
} }
return valueToEdit
} else { } else {
continue continue
} }
@@ -266,9 +264,9 @@ func SubstituteSecrets(secrets []models.SingleEnvironmentVariable) []models.Sing
hashMapOfCompleteVariables := make(map[string]string) hashMapOfCompleteVariables := make(map[string]string)
hashMapOfSelfRefs := make(map[string]string) hashMapOfSelfRefs := make(map[string]string)
expandedSecrets := []models.SingleEnvironmentVariable{} expandedSecrets := []models.SingleEnvironmentVariable{}
for _, secret := range secrets { for _, secret := range secrets {
expandedVariable := getExpandedEnvVariable(secrets, secret.Key, hashMapOfCompleteVariables, hashMapOfSelfRefs) expandedVariable := getExpandedEnvVariable(secrets, secret.Key, hashMapOfCompleteVariables, hashMapOfSelfRefs)
fmt.Println(secret.Key, "=", expandedVariable)
expandedSecrets = append(expandedSecrets, models.SingleEnvironmentVariable{ expandedSecrets = append(expandedSecrets, models.SingleEnvironmentVariable{
Key: secret.Key, Key: secret.Key,
Value: expandedVariable, Value: expandedVariable,

View File

@@ -7,61 +7,61 @@ import (
) )
// References to self should return the value unaltered // References to self should return the value unaltered
// func Test_SubstituteSecrets_When_ReferenceToSelf(t *testing.T) { func Test_SubstituteSecrets_When_ReferenceToSelf(t *testing.T) {
// var tests = []struct { var tests = []struct {
// Key string Key string
// Value string Value string
// ExpectedValue string ExpectedValue string
// }{ }{
// {Key: "A", Value: "${A}", ExpectedValue: "${A}"}, {Key: "A", Value: "${A}", ExpectedValue: "${A}"},
// {Key: "A", Value: "${A} ${A}", ExpectedValue: "${A} ${A}"}, {Key: "A", Value: "${A} ${A}", ExpectedValue: "${A} ${A}"},
// {Key: "A", Value: "${A}${A}", ExpectedValue: "${A}${A}"}, {Key: "A", Value: "${A}${A}", ExpectedValue: "${A}${A}"},
// } }
// for _, test := range tests { for _, test := range tests {
// secret := models.SingleEnvironmentVariable{ secret := models.SingleEnvironmentVariable{
// Key: test.Key, Key: test.Key,
// Value: test.Value, Value: test.Value,
// } }
// secrets := []models.SingleEnvironmentVariable{secret} secrets := []models.SingleEnvironmentVariable{secret}
// result := SubstituteSecrets(secrets) result := SubstituteSecrets(secrets)
// if result[0].Value != test.ExpectedValue { 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) 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) { func Test_SubstituteSecrets_When_ReferenceDoesNotExist(t *testing.T) {
// var tests = []struct { var tests = []struct {
// Key string Key string
// Value string Value string
// ExpectedValue string ExpectedValue string
// }{ }{
// {Key: "A", Value: "${X}", ExpectedValue: "${X}"}, {Key: "A", Value: "${X}", ExpectedValue: "${X}"},
// {Key: "A", Value: "${H}HELLO", ExpectedValue: "${H}HELLO"}, {Key: "A", Value: "${H}HELLO", ExpectedValue: "${H}HELLO"},
// {Key: "A", Value: "${L}${S}", ExpectedValue: "${L}${S}"}, {Key: "A", Value: "${L}${S}", ExpectedValue: "${L}${S}"},
// } }
// for _, test := range tests { for _, test := range tests {
// secret := models.SingleEnvironmentVariable{ secret := models.SingleEnvironmentVariable{
// Key: test.Key, Key: test.Key,
// Value: test.Value, Value: test.Value,
// } }
// secrets := []models.SingleEnvironmentVariable{secret} secrets := []models.SingleEnvironmentVariable{secret}
// result := SubstituteSecrets(secrets) result := SubstituteSecrets(secrets)
// if result[0].Value != test.ExpectedValue { 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) 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) { func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *testing.T) {
@@ -71,14 +71,9 @@ func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *t
ExpectedValue string ExpectedValue string
}{ }{
{ {
Key: "A", Key: "O",
Value: "*${A}* ${X}", Value: "${P} ==$$ ${X} ${UNKNOWN} ${A}",
ExpectedValue: "*${A}*", ExpectedValue: "DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A}",
},
{
Key: "H",
Value: "${X} >>>",
ExpectedValue: "*${A}*",
}, },
{ {
Key: "X", Key: "X",
@@ -86,25 +81,30 @@ func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *t
ExpectedValue: "DOMAIN", ExpectedValue: "DOMAIN",
}, },
{ {
Key: "P", Key: "A",
Value: "${X} === ${A} ${H}", Value: "*${A}* ${X}",
ExpectedValue: "DOMAIN", ExpectedValue: "*${A}* DOMAIN",
},
{
Key: "H",
Value: "${X} >>>",
ExpectedValue: "DOMAIN >>>",
},
{
Key: "P",
Value: "DOMAIN === ${A} ${H}",
ExpectedValue: "DOMAIN === ${A} 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{} secrets := []models.SingleEnvironmentVariable{}
@@ -112,11 +112,49 @@ func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *t
secrets = append(secrets, models.SingleEnvironmentVariable{Key: test.Key, Value: test.Value}) secrets = append(secrets, models.SingleEnvironmentVariable{Key: test.Key, Value: test.Value})
} }
SubstituteSecrets(secrets) results := SubstituteSecrets(secrets)
// if result[0].Value != test.ExpectedValue { for index, expanded := range results {
// t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value) 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)
}
// fmt.Println(result) }
}
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})
}
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)
}
}
} }