Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/cmd/agent_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ infisical secrets agent-proxy connect -- claude`,

agentProxyConnectCmd.Flags().String("proxy", "", "address of the agent proxy as host:port (falls back to INFISICAL_AGENT_PROXY_ADDRESS)")
agentProxyConnectCmd.Flags().StringP("env", "e", "", "environment slug to fetch proxied services and secrets from (falls back to INFISICAL_ENVIRONMENT, then .infisical.yaml or a legacy .infisical.json)")
agentProxyConnectCmd.Flags().String("path", "/", "secret path (folder) scope (falls back to INFISICAL_SECRET_PATH, then secrets-management.default-secret-path in .infisical.yaml or defaultSecretPath in a legacy .infisical.json)")
agentProxyConnectCmd.Flags().String("path", "/", "secret path (folder) scope (falls back to INFISICAL_SECRET_PATH, then secrets-management.secret-path in .infisical.yaml or defaultSecretPath in a legacy .infisical.json)")
agentProxyConnectCmd.Flags().String("projectId", "", "project id (falls back to INFISICAL_PROJECT_ID, then .infisical.yaml or a legacy .infisical.json)")
agentProxyConnectCmd.Flags().String("client-id", "", "universal auth client id for the agent machine identity")
agentProxyConnectCmd.Flags().String("client-secret", "", "universal auth client secret for the agent machine identity")
Expand Down Expand Up @@ -169,7 +169,7 @@ func runAgentProxyConnect(cmd *cobra.Command, args []string) {

environment := util.ResolveEnvironmentName(cmd)
if environment == "" {
util.HandleError(fmt.Errorf("the environment is required; pass --env, set INFISICAL_ENVIRONMENT, or set secrets-management.default-environment in .infisical.yaml (or defaultEnvironment in a legacy .infisical.json)"))
util.HandleError(fmt.Errorf("the environment is required; pass --env, set INFISICAL_ENVIRONMENT, or set secrets-management.environment in .infisical.yaml (or defaultEnvironment in a legacy .infisical.json)"))
}

secretPath := util.ResolveSecretPath(cmd)
Expand Down
4 changes: 2 additions & 2 deletions packages/cmd/agent_proxy_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func buildAgentProxyRunCmd() *cobra.Command {
}

agentProxyRunCmd.Flags().StringP("env", "e", "", "environment slug to fetch proxied services and secrets from (falls back to INFISICAL_ENVIRONMENT, then .infisical.yaml or a legacy .infisical.json)")
agentProxyRunCmd.Flags().String("path", "/", "secret path (folder) to fetch from (falls back to INFISICAL_SECRET_PATH, then secrets-management.default-secret-path in .infisical.yaml or defaultSecretPath in a legacy .infisical.json)")
agentProxyRunCmd.Flags().String("path", "/", "secret path (folder) to fetch from (falls back to INFISICAL_SECRET_PATH, then secrets-management.secret-path in .infisical.yaml or defaultSecretPath in a legacy .infisical.json)")
agentProxyRunCmd.Flags().String("projectId", "", "project id (falls back to INFISICAL_PROJECT_ID, then .infisical.yaml or a legacy .infisical.json)")
agentProxyRunCmd.Flags().String("token", "", "run using this token instead of your logged-in session")
agentProxyRunCmd.Flags().Bool("sandbox", true, "run the agent inside the OS sandbox")
Expand Down Expand Up @@ -78,7 +78,7 @@ func runAgentProxyRun(cmd *cobra.Command, args []string) {
// Same resolution order as `connect`: flag, then env var, then .infisical.yaml.
environment := util.ResolveEnvironmentName(cmd)
if environment == "" {
util.HandleError(fmt.Errorf("the environment is required; pass --env, set INFISICAL_ENVIRONMENT, or set secrets-management.default-environment in .infisical.yaml (or defaultEnvironment in a legacy .infisical.json)"))
util.HandleError(fmt.Errorf("the environment is required; pass --env, set INFISICAL_ENVIRONMENT, or set secrets-management.environment in .infisical.yaml (or defaultEnvironment in a legacy .infisical.json)"))
}

secretPath := util.ResolveSecretPath(cmd)
Expand Down
14 changes: 9 additions & 5 deletions packages/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ infisical init --project-id <project-id>`,
},
Run: func(cmd *cobra.Command, args []string) {
projectID, _ := cmd.Flags().GetString("project-id")
silent, _ := cmd.Flags().GetBool("silent")
showMessages := !silent && !isStructuredOutputRequested(cmd)

if util.WorkspaceConfigFileExistsInCurrentPath() {
if !isatty.IsTerminal(os.Stdin.Fd()) {
Expand Down Expand Up @@ -77,7 +79,7 @@ infisical init --project-id <project-id>`,
if userCreds.OrganizationID != "" {
rejectTransientOrgOverride(userCreds)
}
if err := writeWorkspaceFile(models.Workspace{ID: projectID}); err != nil {
if err := writeWorkspaceFile(models.Workspace{ID: projectID}, showMessages); err != nil {
util.HandleError(err)
}
hintDirectoryProfileBinding(userCreds)
Expand Down Expand Up @@ -167,7 +169,7 @@ infisical init --project-id <project-id>`,
util.HandleError(err)
}

err = writeWorkspaceFile(filteredWorkspaces[index])
err = writeWorkspaceFile(filteredWorkspaces[index], showMessages)
if err != nil {
util.HandleError(err)
}
Expand Down Expand Up @@ -335,7 +337,7 @@ func pickOrganization(httpClient *resty.Client, label string, username string) (
return subItems[subIndex].ID, &selectedSubOrgName, nil
}

func writeWorkspaceFile(selectedWorkspace models.Workspace) error {
func writeWorkspaceFile(selectedWorkspace models.Workspace, showMessages bool) error {
workspaceFileToSave := models.WorkspaceConfigFileYaml{
Version: util.INFISICAL_WORKSPACE_CONFIG_YAML_VERSION,
SecretsManagement: models.SecretsManagementConfigSection{
Expand All @@ -348,13 +350,15 @@ func writeWorkspaceFile(selectedWorkspace models.Workspace) error {
return err
}

err = util.WriteFileAtomic(util.INFISICAL_NEW_WORKSPACE_CONFIG_FILE_NAME, marshalledWorkspaceFile, 0o600)
err = util.WriteFileAtomic(util.INFISICAL_WORKSPACE_CONFIG_FILE_NAME, marshalledWorkspaceFile, 0o600)
if err != nil {
return err
}

// the legacy file is left in place; .infisical.yaml takes precedence over it from now on
util.RemindToRemoveLegacyWorkspaceConfig(".")
if _, err := os.Stat(util.LEGACY_INFISICAL_WORKSPACE_CONFIG_FILE_NAME); err == nil && showMessages {
util.PrintWarning(fmt.Sprintf("The legacy %s in this directory is no longer used because %s takes precedence. You can delete it.", util.LEGACY_INFISICAL_WORKSPACE_CONFIG_FILE_NAME, util.INFISICAL_WORKSPACE_CONFIG_FILE_NAME))
}

return nil
}
Expand Down
39 changes: 33 additions & 6 deletions packages/cmd/init_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package cmd

import (
"bytes"
"io"
"os"
"path/filepath"
"runtime"
"strings"
"testing"

"github.com/Infisical/infisical-merge/packages/models"
Expand All @@ -23,11 +26,11 @@ func TestWriteWorkspaceFile(t *testing.T) {
t.Run("fresh directory gets only a yaml config", func(t *testing.T) {
dir := isolateWorkspaceDir(t)

if err := writeWorkspaceFile(models.Workspace{ID: "proj-new"}); err != nil {
if err := writeWorkspaceFile(models.Workspace{ID: "proj-new"}, true); err != nil {
t.Fatalf("writeWorkspaceFile: %v", err)
}

yamlPath := filepath.Join(dir, util.INFISICAL_NEW_WORKSPACE_CONFIG_FILE_NAME)
yamlPath := filepath.Join(dir, util.INFISICAL_WORKSPACE_CONFIG_FILE_NAME)
raw, err := os.ReadFile(yamlPath)
if err != nil {
t.Fatalf("read %s: %v", yamlPath, err)
Expand Down Expand Up @@ -64,19 +67,19 @@ func TestWriteWorkspaceFile(t *testing.T) {
if err != nil {
t.Fatalf("read dir: %v", err)
}
if len(entries) != 1 || entries[0].Name() != util.INFISICAL_NEW_WORKSPACE_CONFIG_FILE_NAME {
t.Errorf("expected only %s in dir, got %v", util.INFISICAL_NEW_WORKSPACE_CONFIG_FILE_NAME, entries)
if len(entries) != 1 || entries[0].Name() != util.INFISICAL_WORKSPACE_CONFIG_FILE_NAME {
t.Errorf("expected only %s in dir, got %v", util.INFISICAL_WORKSPACE_CONFIG_FILE_NAME, entries)
}
})

t.Run("leaves a legacy json config in place", func(t *testing.T) {
dir := isolateWorkspaceDir(t)
jsonPath := filepath.Join(dir, util.INFISICAL_WORKSPACE_CONFIG_FILE_NAME)
jsonPath := filepath.Join(dir, util.LEGACY_INFISICAL_WORKSPACE_CONFIG_FILE_NAME)
if err := os.WriteFile(jsonPath, []byte(`{"workspaceId":"proj-old"}`), 0o600); err != nil {
t.Fatalf("write json: %v", err)
}

if err := writeWorkspaceFile(models.Workspace{ID: "proj-new"}); err != nil {
if err := writeWorkspaceFile(models.Workspace{ID: "proj-new"}, true); err != nil {
t.Fatalf("writeWorkspaceFile: %v", err)
}

Expand All @@ -97,4 +100,28 @@ func TestWriteWorkspaceFile(t *testing.T) {
t.Errorf("WorkspaceId = %q, want proj-new", cfg.WorkspaceId)
}
})

t.Run("legacy json warning is shown only when messages are enabled", func(t *testing.T) {
var stderr bytes.Buffer
originalStderrWriter := util.GetStderrWriter
util.GetStderrWriter = func() io.Writer { return &stderr }
t.Cleanup(func() { util.GetStderrWriter = originalStderrWriter })

for _, showMessages := range []bool{false, true} {
stderr.Reset()
dir := isolateWorkspaceDir(t)
if err := os.WriteFile(filepath.Join(dir, util.LEGACY_INFISICAL_WORKSPACE_CONFIG_FILE_NAME), []byte(`{"workspaceId":"proj-old"}`), 0o600); err != nil {
t.Fatalf("write json: %v", err)
}

if err := writeWorkspaceFile(models.Workspace{ID: "proj-new"}, showMessages); err != nil {
t.Fatalf("writeWorkspaceFile: %v", err)
}

warned := strings.Contains(stderr.String(), util.LEGACY_INFISICAL_WORKSPACE_CONFIG_FILE_NAME)
if warned != showMessages {
t.Errorf("showMessages=%t: warned = %t, stderr:\n%s", showMessages, warned, stderr.String())
}
}
})
}
8 changes: 0 additions & 8 deletions packages/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,6 @@ func init() {
if err != nil {
util.HandleError(err)
}
if !silent && !isStructuredOutputRequested(cmd) {
util.EnableWorkspaceConfigMessages()
}

profileFlag, err := cmd.Flags().GetString("profile")
if err != nil {
Expand Down Expand Up @@ -197,11 +194,6 @@ func init() {

if !util.IsRunningInDocker() && !silent && !isStructuredOutputRequested(cmd) {
util.CheckForUpdateWithWriter(cmd.ErrOrStderr())
projectConfigDir := ""
if f := cmd.Flags().Lookup("project-config-dir"); f != nil {
projectConfigDir = f.Value.String()
}
util.DisplayWorkspaceConfigMigrationNoticeWithWriter(silent, projectConfigDir, cmd.ErrOrStderr())
}

loggedInDetails, err := util.GetCurrentLoggedInUserDetails(false)
Expand Down
28 changes: 22 additions & 6 deletions packages/models/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,29 @@ type GeneralConfigSection struct {
Domain string `yaml:"domain,omitempty"`
}

// GitBranchEnvironmentOverride is one entry of the secrets-management.overrides.git-branch list.
type GitBranchEnvironmentOverride struct {
Branch string `yaml:"branch"`
Environment string `yaml:"environment"`
}

type OverridesConfigSection struct {
GitBranch []GitBranchEnvironmentOverride `yaml:"git-branch,omitempty"`
}

type SecretsManagementConfigSection struct {
ProjectID string `yaml:"project-id"`
DefaultEnvironment string `yaml:"default-environment"`
DefaultSecretPath string `yaml:"default-secret-path,omitempty"`
Mappings struct {
GitBranchToEnvironment map[string]string `yaml:"git-branch-to-environment"`
} `yaml:"mappings"`
ProjectID string `yaml:"project-id"`
Environment string `yaml:"environment,omitempty"`
SecretPath string `yaml:"secret-path,omitempty"`
Overrides OverridesConfigSection `yaml:"overrides,omitempty"`
// Deprecated: superseded by Environment; still read until support for it is removed.
DefaultEnvironment string `yaml:"default-environment,omitempty"`
// Deprecated: superseded by SecretPath; still read until support for it is removed.
DefaultSecretPath string `yaml:"default-secret-path,omitempty"`
// Deprecated: superseded by Overrides.GitBranch; still read until support for it is removed.
Mappings struct {
GitBranchToEnvironment map[string]string `yaml:"git-branch-to-environment,omitempty"`
} `yaml:"mappings,omitempty"`
}

type WorkspaceConfigFileYaml struct {
Expand Down
Loading
Loading