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
}
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")
@@ -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)
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

View File

@@ -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, "${")
@@ -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
}
@@ -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
}
@@ -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,

View File

@@ -7,61 +7,61 @@ import (
)
// 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 {
// 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}"},
// }
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,
// }
for _, test := range tests {
secret := models.SingleEnvironmentVariable{
Key: test.Key,
Value: test.Value,
}
// secrets := []models.SingleEnvironmentVariable{secret}
// result := SubstituteSecrets(secrets)
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)
// }
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) {
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}"},
// }
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,
// }
for _, test := range tests {
secret := models.SingleEnvironmentVariable{
Key: test.Key,
Value: test.Value,
}
// secrets := []models.SingleEnvironmentVariable{secret}
// result := SubstituteSecrets(secrets)
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)
// }
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) {
@@ -71,14 +71,9 @@ func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *t
ExpectedValue string
}{
{
Key: "A",
Value: "*${A}* ${X}",
ExpectedValue: "*${A}*",
},
{
Key: "H",
Value: "${X} >>>",
ExpectedValue: "*${A}*",
Key: "O",
Value: "${P} ==$$ ${X} ${UNKNOWN} ${A}",
ExpectedValue: "DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A}",
},
{
Key: "X",
@@ -86,25 +81,30 @@ func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *t
ExpectedValue: "DOMAIN",
},
{
Key: "P",
Value: "${X} === ${A} ${H}",
ExpectedValue: "DOMAIN",
Key: "A",
Value: "*${A}* ${X}",
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{}
@@ -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})
}
SubstituteSecrets(secrets)
results := 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)
// }
// 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)
}
}
}
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)
}
}
}