mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add substitute flag for run
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user