Skip to content

Commit 32fa686

Browse files
Merge pull request #3238 from Infisical/feat/ENG-2320-echo-environment-being-used-in-cli
feat: confirm environment exists when running `run` command
2 parents de7e92c + b4faef7 commit 32fa686

File tree

6 files changed

+89
-14
lines changed

6 files changed

+89
-14
lines changed

.gitignore

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.direnv/
2+
13
# backend
24
node_modules
35
.env
@@ -26,8 +28,6 @@ node_modules
2628
/.pnp
2729
.pnp.js
2830

29-
.env
30-
3131
# testing
3232
coverage
3333
reports
@@ -63,10 +63,12 @@ yarn-error.log*
6363

6464
# Editor specific
6565
.vscode/*
66-
.idea/*
66+
**/.idea/*
6767

6868
frontend-build
6969

70+
# cli
71+
.go/
7072
*.tgz
7173
cli/infisical-merge
7274
cli/test/infisical-merge

cli/packages/api/model.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ package api
22

33
import "time"
44

5+
type Environment struct {
6+
Name string `json:"name"`
7+
Slug string `json:"slug"`
8+
ID string `json:"id"`
9+
}
10+
511
// Stores info for login one
612
type LoginOneRequest struct {
713
Email string `json:"email"`
@@ -14,7 +20,6 @@ type LoginOneResponse struct {
1420
}
1521

1622
// Stores info for login two
17-
1823
type LoginTwoRequest struct {
1924
Email string `json:"email"`
2025
ClientProof string `json:"clientProof"`
@@ -168,9 +173,10 @@ type Secret struct {
168173
}
169174

170175
type Project struct {
171-
ID string `json:"id"`
172-
Name string `json:"name"`
173-
Slug string `json:"slug"`
176+
ID string `json:"id"`
177+
Name string `json:"name"`
178+
Slug string `json:"slug"`
179+
Environments []Environment `json:"environments"`
174180
}
175181

176182
type RawSecret struct {

cli/packages/cmd/run.go

+64-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import (
1515
"syscall"
1616
"time"
1717

18+
"github.com/Infisical/infisical-merge/packages/api"
19+
"github.com/go-resty/resty/v2"
20+
1821
"github.com/Infisical/infisical-merge/packages/models"
1922
"github.com/Infisical/infisical-merge/packages/util"
2023
"github.com/fatih/color"
@@ -59,11 +62,11 @@ var runCmd = &cobra.Command{
5962
return nil
6063
},
6164
Run: func(cmd *cobra.Command, args []string) {
62-
environmentName, _ := cmd.Flags().GetString("env")
65+
environmentSlug, _ := cmd.Flags().GetString("env")
6366
if !cmd.Flags().Changed("env") {
6467
environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
6568
if environmentFromWorkspace != "" {
66-
environmentName = environmentFromWorkspace
69+
environmentSlug = environmentFromWorkspace
6770
}
6871
}
6972

@@ -136,8 +139,20 @@ var runCmd = &cobra.Command{
136139
util.HandleError(err, "Unable to parse flag")
137140
}
138141

142+
log.Debug().Msgf("Confirming selected environment is valid: %s", environmentSlug)
143+
144+
hasEnvironment, err := confirmProjectHasEnvironment(environmentSlug, projectId, token)
145+
if err != nil {
146+
util.HandleError(err, "Could not confirm project has environment")
147+
}
148+
if !hasEnvironment {
149+
util.HandleError(fmt.Errorf("project does not have environment '%s'", environmentSlug))
150+
}
151+
152+
log.Debug().Msgf("Project '%s' has environment '%s'", projectId, environmentSlug)
153+
139154
request := models.GetAllSecretsParameters{
140-
Environment: environmentName,
155+
Environment: environmentSlug,
141156
WorkspaceId: projectId,
142157
TagSlugs: tagSlugs,
143158
SecretsPath: secretsPath,
@@ -308,7 +323,6 @@ func waitForExitCommand(cmd *exec.Cmd) (int, error) {
308323
}
309324

310325
func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInterval int, request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) {
311-
312326
var cmd *exec.Cmd
313327
var err error
314328
var lastSecretsFetch time.Time
@@ -439,8 +453,53 @@ func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInt
439453
}
440454
}
441455

442-
func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) {
456+
func confirmProjectHasEnvironment(environmentSlug, projectId string, token *models.TokenDetails) (bool, error) {
457+
var accessToken string
458+
459+
if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) {
460+
accessToken = token.Token
461+
} else {
462+
util.RequireLogin()
463+
util.RequireLocalWorkspaceFile()
464+
465+
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
466+
if err != nil {
467+
util.HandleError(err, "Unable to authenticate")
468+
}
443469

470+
if loggedInUserDetails.LoginExpired {
471+
util.PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
472+
}
473+
accessToken = loggedInUserDetails.UserCredentials.JTWToken
474+
}
475+
476+
if projectId == "" {
477+
workspaceFile, err := util.GetWorkSpaceFromFile()
478+
if err != nil {
479+
util.HandleError(err, "Unable to get local project details")
480+
}
481+
482+
projectId = workspaceFile.WorkspaceId
483+
}
484+
485+
httpClient := resty.New()
486+
httpClient.SetAuthToken(accessToken).
487+
SetHeader("Accept", "application/json")
488+
489+
project, err := api.CallGetProjectById(httpClient, projectId)
490+
if err != nil {
491+
return false, err
492+
}
493+
494+
for _, env := range project.Environments {
495+
if env.Slug == environmentSlug {
496+
return true, nil
497+
}
498+
}
499+
return false, nil
500+
}
501+
502+
func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) {
444503
if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER {
445504
request.InfisicalToken = token.Token
446505
} else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER {

cli/packages/util/secrets.go

-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,6 @@ func FilterSecretsByTag(plainTextSecrets []models.SingleEnvironmentVariable, tag
232232

233233
func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) {
234234
var secretsToReturn []models.SingleEnvironmentVariable
235-
// var serviceTokenDetails api.GetServiceTokenDetailsResponse
236235
var errorToReturn error
237236

238237
if params.InfisicalToken == "" && params.UniversalAuthAccessToken == "" {

cli/test/secrets_test.go

-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) {
7676
if err != nil {
7777
t.Fatalf("snapshot failed: %v", err)
7878
}
79-
8079
}
8180

8281
func TestUserAuth_SecretsGetAll(t *testing.T) {

flake.nix

+10
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,21 @@
1414
git
1515
lazygit
1616

17+
go
1718
python312Full
1819
nodejs_20
1920
nodePackages.prettier
2021
infisical
2122
];
23+
24+
env = {
25+
GOROOT = "${pkgs.go}/share/go";
26+
};
27+
28+
shellHook = ''
29+
export GOPATH="$(pwd)/.go"
30+
mkdir -p "$GOPATH"
31+
'';
2232
};
2333
};
2434
}

0 commit comments

Comments
 (0)