Merge pull request #3238 from Infisical/feat/ENG-2320-echo-environment-being-used-in-cli

feat: confirm environment exists when running `run` command
This commit is contained in:
Daniel Hougaard
2025-03-14 03:58:05 +04:00
committed by GitHub
6 changed files with 89 additions and 14 deletions
+5 -3
View File
@@ -1,3 +1,5 @@
.direnv/
# backend # backend
node_modules node_modules
.env .env
@@ -26,8 +28,6 @@ node_modules
/.pnp /.pnp
.pnp.js .pnp.js
.env
# testing # testing
coverage coverage
reports reports
@@ -63,10 +63,12 @@ yarn-error.log*
# Editor specific # Editor specific
.vscode/* .vscode/*
.idea/* **/.idea/*
frontend-build frontend-build
# cli
.go/
*.tgz *.tgz
cli/infisical-merge cli/infisical-merge
cli/test/infisical-merge cli/test/infisical-merge
+10 -4
View File
@@ -2,6 +2,12 @@ package api
import "time" import "time"
type Environment struct {
Name string `json:"name"`
Slug string `json:"slug"`
ID string `json:"id"`
}
// Stores info for login one // Stores info for login one
type LoginOneRequest struct { type LoginOneRequest struct {
Email string `json:"email"` Email string `json:"email"`
@@ -14,7 +20,6 @@ type LoginOneResponse struct {
} }
// Stores info for login two // Stores info for login two
type LoginTwoRequest struct { type LoginTwoRequest struct {
Email string `json:"email"` Email string `json:"email"`
ClientProof string `json:"clientProof"` ClientProof string `json:"clientProof"`
@@ -168,9 +173,10 @@ type Secret struct {
} }
type Project struct { type Project struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Slug string `json:"slug"` Slug string `json:"slug"`
Environments []Environment `json:"environments"`
} }
type RawSecret struct { type RawSecret struct {
+64 -5
View File
@@ -15,6 +15,9 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/Infisical/infisical-merge/packages/api"
"github.com/go-resty/resty/v2"
"github.com/Infisical/infisical-merge/packages/models" "github.com/Infisical/infisical-merge/packages/models"
"github.com/Infisical/infisical-merge/packages/util" "github.com/Infisical/infisical-merge/packages/util"
"github.com/fatih/color" "github.com/fatih/color"
@@ -59,11 +62,11 @@ var runCmd = &cobra.Command{
return nil return nil
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
environmentName, _ := cmd.Flags().GetString("env") environmentSlug, _ := cmd.Flags().GetString("env")
if !cmd.Flags().Changed("env") { if !cmd.Flags().Changed("env") {
environmentFromWorkspace := util.GetEnvFromWorkspaceFile() environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
if environmentFromWorkspace != "" { if environmentFromWorkspace != "" {
environmentName = environmentFromWorkspace environmentSlug = environmentFromWorkspace
} }
} }
@@ -136,8 +139,20 @@ var runCmd = &cobra.Command{
util.HandleError(err, "Unable to parse flag") util.HandleError(err, "Unable to parse flag")
} }
log.Debug().Msgf("Confirming selected environment is valid: %s", environmentSlug)
hasEnvironment, err := confirmProjectHasEnvironment(environmentSlug, projectId, token)
if err != nil {
util.HandleError(err, "Could not confirm project has environment")
}
if !hasEnvironment {
util.HandleError(fmt.Errorf("project does not have environment '%s'", environmentSlug))
}
log.Debug().Msgf("Project '%s' has environment '%s'", projectId, environmentSlug)
request := models.GetAllSecretsParameters{ request := models.GetAllSecretsParameters{
Environment: environmentName, Environment: environmentSlug,
WorkspaceId: projectId, WorkspaceId: projectId,
TagSlugs: tagSlugs, TagSlugs: tagSlugs,
SecretsPath: secretsPath, SecretsPath: secretsPath,
@@ -308,7 +323,6 @@ func waitForExitCommand(cmd *exec.Cmd) (int, error) {
} }
func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInterval int, request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) { func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInterval int, request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) {
var cmd *exec.Cmd var cmd *exec.Cmd
var err error var err error
var lastSecretsFetch time.Time var lastSecretsFetch time.Time
@@ -439,8 +453,53 @@ func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInt
} }
} }
func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) { func confirmProjectHasEnvironment(environmentSlug, projectId string, token *models.TokenDetails) (bool, error) {
var accessToken string
if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) {
accessToken = token.Token
} else {
util.RequireLogin()
util.RequireLocalWorkspaceFile()
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
if err != nil {
util.HandleError(err, "Unable to authenticate")
}
if loggedInUserDetails.LoginExpired {
util.PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
}
accessToken = loggedInUserDetails.UserCredentials.JTWToken
}
if projectId == "" {
workspaceFile, err := util.GetWorkSpaceFromFile()
if err != nil {
util.HandleError(err, "Unable to get local project details")
}
projectId = workspaceFile.WorkspaceId
}
httpClient := resty.New()
httpClient.SetAuthToken(accessToken).
SetHeader("Accept", "application/json")
project, err := api.CallGetProjectById(httpClient, projectId)
if err != nil {
return false, err
}
for _, env := range project.Environments {
if env.Slug == environmentSlug {
return true, nil
}
}
return false, nil
}
func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) {
if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER {
request.InfisicalToken = token.Token request.InfisicalToken = token.Token
} else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER {
-1
View File
@@ -232,7 +232,6 @@ func FilterSecretsByTag(plainTextSecrets []models.SingleEnvironmentVariable, tag
func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) { func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) {
var secretsToReturn []models.SingleEnvironmentVariable var secretsToReturn []models.SingleEnvironmentVariable
// var serviceTokenDetails api.GetServiceTokenDetailsResponse
var errorToReturn error var errorToReturn error
if params.InfisicalToken == "" && params.UniversalAuthAccessToken == "" { if params.InfisicalToken == "" && params.UniversalAuthAccessToken == "" {
-1
View File
@@ -76,7 +76,6 @@ func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("snapshot failed: %v", err) t.Fatalf("snapshot failed: %v", err)
} }
} }
func TestUserAuth_SecretsGetAll(t *testing.T) { func TestUserAuth_SecretsGetAll(t *testing.T) {
+10
View File
@@ -14,11 +14,21 @@
git git
lazygit lazygit
go
python312Full python312Full
nodejs_20 nodejs_20
nodePackages.prettier nodePackages.prettier
infisical infisical
]; ];
env = {
GOROOT = "${pkgs.go}/share/go";
};
shellHook = ''
export GOPATH="$(pwd)/.go"
mkdir -p "$GOPATH"
'';
}; };
}; };
} }