mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 03:26:27 +00:00
add mono repo support
This commit is contained in:
@@ -36,7 +36,7 @@ var initCmd = &cobra.Command{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if util.WorkspaceConfigFileExists() {
|
if util.WorkspaceConfigFileExistsInCurrentPath() {
|
||||||
shouldOverride, err := shouldOverrideWorkspacePrompt()
|
shouldOverride, err := shouldOverrideWorkspacePrompt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("Unable to parse your answer")
|
log.Errorln("Unable to parse your answer")
|
||||||
|
|||||||
@@ -47,18 +47,17 @@ var runCmd = &cobra.Command{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
envsFromApi, err := util.GetAllEnvironmentVariables(projectId, envName)
|
secrets, err := util.GetAllEnvironmentVariables(projectId, envName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("Something went wrong when pulling secrets using your Infisical token. Double check the token, project id or environment name (dev, prod, ect.)")
|
|
||||||
log.Debugln(err)
|
log.Debugln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if shouldExpandSecrets {
|
if shouldExpandSecrets {
|
||||||
substitutions := util.SubstituteSecrets(envsFromApi)
|
secretsWithSubstitutions := util.SubstituteSecrets(secrets)
|
||||||
execCmd(args[0], args[1:], substitutions)
|
execCmd(args[0], args[1:], secretsWithSubstitutions)
|
||||||
} else {
|
} else {
|
||||||
execCmd(args[0], args[1:], envsFromApi)
|
execCmd(args[0], args[1:], secrets)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@@ -73,9 +72,12 @@ func init() {
|
|||||||
|
|
||||||
// Credit: inspired by AWS Valut
|
// Credit: inspired by AWS Valut
|
||||||
func execCmd(command string, args []string, envs []models.SingleEnvironmentVariable) error {
|
func execCmd(command string, args []string, envs []models.SingleEnvironmentVariable) error {
|
||||||
log.Infof("\x1b[%dm%s\x1b[0m", 32, "\u2713 Injected Infisical secrets into your application process successfully")
|
numberOfSecretsInjected := fmt.Sprintf("\u2713 Injected %v Infisical secrets into your application process successfully", len(envs))
|
||||||
log.Debugln("Secrets to inject:", envs)
|
|
||||||
|
log.Infof("\x1b[%dm%s\x1b[0m", 32, numberOfSecretsInjected)
|
||||||
log.Debugf("executing command: %s %s \n", command, strings.Join(args, " "))
|
log.Debugf("executing command: %s %s \n", command, strings.Join(args, " "))
|
||||||
|
log.Debugln("Secrets injected:", envs)
|
||||||
|
|
||||||
cmd := exec.Command(command, args...)
|
cmd := exec.Command(command, args...)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func ConfigFileExists() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WorkspaceConfigFileExists() bool {
|
func WorkspaceConfigFileExistsInCurrentPath() bool {
|
||||||
if _, err := os.Stat(INFISICAL_WORKSPACE_CONFIG_FILE_NAME); err == nil {
|
if _, err := os.Stat(INFISICAL_WORKSPACE_CONFIG_FILE_NAME); err == nil {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@@ -90,3 +90,65 @@ func GetFullConfigFilePath() (fullPathToFile string, fullPathToDirectory string,
|
|||||||
fullDirPath := fmt.Sprintf("%s/%s", homeDir, CONFIG_FOLDER_NAME)
|
fullDirPath := fmt.Sprintf("%s/%s", homeDir, CONFIG_FOLDER_NAME)
|
||||||
return fullPath, fullDirPath, err
|
return fullPath, fullDirPath, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given a path to a workspace config, unmarshal workspace config
|
||||||
|
func GetWorkspaceConfigByPath(path string) (workspaceConfig models.WorkspaceConfigFile, err error) {
|
||||||
|
workspaceConfigFileAsBytes, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return models.WorkspaceConfigFile{}, fmt.Errorf("GetWorkspaceConfigByPath: Unable to read workspace config file because [%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var workspaceConfigFile models.WorkspaceConfigFile
|
||||||
|
err = json.Unmarshal(workspaceConfigFileAsBytes, &workspaceConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return models.WorkspaceConfigFile{}, fmt.Errorf("GetWorkspaceConfigByPath: Unable to unmarshal workspace config file because [%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceConfigFile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will get the list of .infisical.json files that are located
|
||||||
|
// within the root of each sub folder from where the CLI is ran from
|
||||||
|
func GetAllWorkSpaceConfigsStartingFromCurrentPath() (workspaces []models.WorkspaceConfigFile, err error) {
|
||||||
|
currentDir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllProjectConfigs: unable to get the current directory because [%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := os.ReadDir(currentDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllProjectConfigs: unable to read the contents of the current directory because [%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
listOfWorkSpaceConfigs := []models.WorkspaceConfigFile{}
|
||||||
|
for _, file := range files {
|
||||||
|
if !file.IsDir() && file.Name() == INFISICAL_WORKSPACE_CONFIG_FILE_NAME {
|
||||||
|
pathToWorkspaceConfigFile := currentDir + "/" + INFISICAL_WORKSPACE_CONFIG_FILE_NAME
|
||||||
|
|
||||||
|
workspaceConfig, err := GetWorkspaceConfigByPath(pathToWorkspaceConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllProjectConfigs: Unable to get config file because [%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
listOfWorkSpaceConfigs = append(listOfWorkSpaceConfigs, workspaceConfig)
|
||||||
|
|
||||||
|
} else if file.IsDir() {
|
||||||
|
pathToSubFolder := currentDir + "/" + file.Name()
|
||||||
|
pathToMaybeWorkspaceConfigFile := pathToSubFolder + "/" + INFISICAL_WORKSPACE_CONFIG_FILE_NAME
|
||||||
|
|
||||||
|
_, err := os.Stat(pathToMaybeWorkspaceConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
continue // workspace config file doesn't exist
|
||||||
|
}
|
||||||
|
|
||||||
|
workspaceConfig, err := GetWorkspaceConfigByPath(pathToMaybeWorkspaceConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetAllProjectConfigs: Unable to get config file because [%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
listOfWorkSpaceConfigs = append(listOfWorkSpaceConfigs, workspaceConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOfWorkSpaceConfigs, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,9 @@ package util
|
|||||||
import (
|
import (
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func DecryptSymmetric(key []byte, encryptedPrivateKey []byte, tag []byte, IV []byte) ([]byte, error) {
|
func DecryptSymmetric(key []byte, encryptedPrivateKey []byte, tag []byte, IV []byte) ([]byte, error) {
|
||||||
log.Debugln("Key:", key, "encryptedPrivateKey", encryptedPrivateKey, "tag", tag, "IV", IV)
|
|
||||||
block, err := aes.NewCipher(key)
|
block, err := aes.NewCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -14,19 +14,7 @@ import (
|
|||||||
"golang.org/x/crypto/nacl/box"
|
"golang.org/x/crypto/nacl/box"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetSecretsFromAPIUsingCurrentLoggedInUser(envName string, userCreds models.UserCredentials) ([]models.SingleEnvironmentVariable, error) {
|
func getSecretsByWorkspaceIdAndEnvName(httpClient resty.Client, envName string, workspace models.WorkspaceConfigFile, userCreds models.UserCredentials) (listOfSecrets []models.SingleEnvironmentVariable, err error) {
|
||||||
log.Debugln("envName", envName, "userCreds", userCreds)
|
|
||||||
// check if user has configured a workspace
|
|
||||||
workspace, err := GetWorkSpaceFromFile()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Unable to read workspace file:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create http client
|
|
||||||
httpClient := resty.New().
|
|
||||||
SetAuthToken(userCreds.JTWToken).
|
|
||||||
SetHeader("Accept", "application/json")
|
|
||||||
|
|
||||||
var pullSecretsRequestResponse models.PullSecretsResponse
|
var pullSecretsRequestResponse models.PullSecretsResponse
|
||||||
response, err := httpClient.
|
response, err := httpClient.
|
||||||
R().
|
R().
|
||||||
@@ -35,14 +23,11 @@ func GetSecretsFromAPIUsingCurrentLoggedInUser(envName string, userCreds models.
|
|||||||
SetResult(&pullSecretsRequestResponse).
|
SetResult(&pullSecretsRequestResponse).
|
||||||
Get(fmt.Sprintf("%v/v1/secret/%v", INFISICAL_URL, workspace.WorkspaceId)) // need to change workspace id
|
Get(fmt.Sprintf("%v/v1/secret/%v", INFISICAL_URL, workspace.WorkspaceId)) // need to change workspace id
|
||||||
|
|
||||||
log.Debugln("Response from get secrets:", response)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if response.StatusCode() > 299 {
|
if response.StatusCode() > 299 {
|
||||||
log.Debugln(response)
|
|
||||||
return nil, fmt.Errorf(response.Status())
|
return nil, fmt.Errorf(response.Status())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +52,7 @@ func GetSecretsFromAPIUsingCurrentLoggedInUser(envName string, userCreds models.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugln("workspaceKey", workspaceKey, "nonce", nonce, "senderPublicKey", senderPublicKey, "currentUsersPrivateKey", currentUsersPrivateKey)
|
// log.Debugln("workspaceKey", workspaceKey, "nonce", nonce, "senderPublicKey", senderPublicKey, "currentUsersPrivateKey", currentUsersPrivateKey)
|
||||||
workspaceKeyInBytes, _ := box.Open(nil, workspaceKey, (*[24]byte)(nonce), (*[32]byte)(senderPublicKey), (*[32]byte)(currentUsersPrivateKey))
|
workspaceKeyInBytes, _ := box.Open(nil, workspaceKey, (*[24]byte)(nonce), (*[32]byte)(senderPublicKey), (*[32]byte)(currentUsersPrivateKey))
|
||||||
var listOfEnv []models.SingleEnvironmentVariable
|
var listOfEnv []models.SingleEnvironmentVariable
|
||||||
|
|
||||||
@@ -101,6 +86,32 @@ func GetSecretsFromAPIUsingCurrentLoggedInUser(envName string, userCreds models.
|
|||||||
return listOfEnv, nil
|
return listOfEnv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSecretsFromAPIUsingCurrentLoggedInUser(envName string, userCreds models.UserCredentials) ([]models.SingleEnvironmentVariable, error) {
|
||||||
|
log.Debugln("GetSecretsFromAPIUsingCurrentLoggedInUser", "envName", envName, "userCreds", userCreds)
|
||||||
|
// check if user has configured a workspace
|
||||||
|
workspaces, err := GetAllWorkSpaceConfigsStartingFromCurrentPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to read workspace file(s):", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create http client
|
||||||
|
httpClient := resty.New().
|
||||||
|
SetAuthToken(userCreds.JTWToken).
|
||||||
|
SetHeader("Accept", "application/json")
|
||||||
|
|
||||||
|
secrets := []models.SingleEnvironmentVariable{}
|
||||||
|
for _, workspace := range workspaces {
|
||||||
|
secretsFromAPI, err := getSecretsByWorkspaceIdAndEnvName(*httpClient, envName, workspace, userCreds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetSecretsFromAPIUsingCurrentLoggedInUser: Unable to get secrets by workspace id and env name")
|
||||||
|
}
|
||||||
|
|
||||||
|
secrets = append(secrets, secretsFromAPI...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return secrets, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string, projectId string) ([]models.SingleEnvironmentVariable, error) {
|
func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string, projectId string) ([]models.SingleEnvironmentVariable, error) {
|
||||||
if infisicalToken == "" || projectId == "" || envName == "" {
|
if infisicalToken == "" || projectId == "" || envName == "" {
|
||||||
return nil, errors.New("infisical token, project id and or environment name cannot be empty")
|
return nil, errors.New("infisical token, project id and or environment name cannot be empty")
|
||||||
@@ -127,7 +138,6 @@ func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if response.StatusCode() > 299 {
|
if response.StatusCode() > 299 {
|
||||||
log.Debugln(response)
|
|
||||||
return nil, fmt.Errorf(response.Status())
|
return nil, fmt.Errorf(response.Status())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +198,7 @@ func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string,
|
|||||||
func GetAllEnvironmentVariables(projectId string, envName string) ([]models.SingleEnvironmentVariable, error) {
|
func GetAllEnvironmentVariables(projectId string, envName string) ([]models.SingleEnvironmentVariable, error) {
|
||||||
var envsFromApi []models.SingleEnvironmentVariable
|
var envsFromApi []models.SingleEnvironmentVariable
|
||||||
infisicalToken := os.Getenv(INFISICAL_TOKEN_NAME)
|
infisicalToken := os.Getenv(INFISICAL_TOKEN_NAME)
|
||||||
|
|
||||||
if infisicalToken == "" {
|
if infisicalToken == "" {
|
||||||
hasUserLoggedInbefore, loggedInUserEmail, err := IsUserLoggedIn()
|
hasUserLoggedInbefore, loggedInUserEmail, err := IsUserLoggedIn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -208,8 +219,13 @@ func GetAllEnvironmentVariables(projectId string, envName string) ([]models.Sing
|
|||||||
return envsFromApi, err
|
return envsFromApi, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !WorkspaceConfigFileExists() {
|
workspaceConfigs, err := GetAllWorkSpaceConfigsStartingFromCurrentPath()
|
||||||
log.Infoln("Your project is not connected to a project yet. Run command [infisical init]")
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to check if you have a %s file in your current directory", INFISICAL_WORKSPACE_CONFIG_FILE_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(workspaceConfigs) == 0 {
|
||||||
|
log.Infoln("Your local project is not connected to a Infisical project yet. Run command [infisical init]")
|
||||||
return envsFromApi, fmt.Errorf("project not initialized")
|
return envsFromApi, fmt.Errorf("project not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user