diff --git a/packages/cmd/dynamic_secrets.go b/packages/cmd/dynamic_secrets.go index ed32f49b..20349a88 100644 --- a/packages/cmd/dynamic_secrets.go +++ b/packages/cmd/dynamic_secrets.go @@ -31,38 +31,11 @@ var dynamicSecretCmd = &cobra.Command{ } func getDynamicSecretList(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectSlug, err := cmd.Flags().GetString("project-slug") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse path flag") - } + projectSlug := util.GetStringArgument(cmd, "project-slug", "Unable to parse flag --project-slug") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") var infisicalToken string httpClient, err := util.GetRestyClientWithCustomHeaders() @@ -70,14 +43,6 @@ func getDynamicSecretList(cmd *cobra.Command, args []string) { util.HandleError(err, "Unable to get resty client with custom headers") } - if projectId == "" && projectSlug == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project, pass in project slug with --project-slug flag, or pass in project id with --projectId flag") - } - projectId = workspaceFile.WorkspaceId - } - if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { infisicalToken = token.Token } else { @@ -111,7 +76,7 @@ func getDynamicSecretList(cmd *cobra.Command, args []string) { infisicalClient.Auth().SetAccessToken(infisicalToken) if projectSlug == "" { - projectDetails, err := api.CallGetProjectById(httpClient, projectId) + projectDetails, err := api.CallGetProjectById(httpClient, projectConfig.WorkspaceId) if err != nil { util.HandleError(err, "To fetch project details") } @@ -120,8 +85,8 @@ func getDynamicSecretList(cmd *cobra.Command, args []string) { dynamicSecretRootCredentials, err := infisicalClient.DynamicSecrets().List(infisicalSdk.ListDynamicSecretsRootCredentialsOptions{ ProjectSlug: projectSlug, - SecretPath: secretsPath, - EnvironmentSlug: environmentName, + SecretPath: projectConfig.SecretsPath, + EnvironmentSlug: projectConfig.Environment, }) if err != nil { @@ -159,48 +124,14 @@ var dynamicSecretLeaseCreateCmd = &cobra.Command{ func createDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { dynamicSecretRootCredentialName := args[0] - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectSlug, err := cmd.Flags().GetString("project-slug") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) + projectSlug := util.GetStringArgument(cmd, "project-slug", "Unable to parse flag --project-slug") - ttl, err := cmd.Flags().GetString("ttl") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + ttl := util.GetStringArgument(cmd, "ttl", "Unable to parse flag --ttl") - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse path flag") - } - - plainOutput, err := cmd.Flags().GetBool("plain") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + plainOutput := util.GetBooleanArgument(cmd, "plain", "Unable to parse flag --plain") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") var infisicalToken string httpClient, err := util.GetRestyClientWithCustomHeaders() @@ -208,14 +139,6 @@ func createDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { util.HandleError(err, "Unable to get resty client with custom headers") } - if projectId == "" && projectSlug == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project, pass in project id with --projectId flag, or pass in project slug with --project-slug flag") - } - projectId = workspaceFile.WorkspaceId - } - if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { infisicalToken = token.Token } else { @@ -248,7 +171,7 @@ func createDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { infisicalClient.Auth().SetAccessToken(infisicalToken) if projectSlug == "" { - projectDetails, err := api.CallGetProjectById(httpClient, projectId) + projectDetails, err := api.CallGetProjectById(httpClient, projectConfig.WorkspaceId) if err != nil { util.HandleError(err, "To fetch project details") } @@ -258,8 +181,8 @@ func createDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { dynamicSecretRootCredential, err := infisicalClient.DynamicSecrets().GetByName(infisicalSdk.GetDynamicSecretRootCredentialByNameOptions{ DynamicSecretName: dynamicSecretRootCredentialName, ProjectSlug: projectSlug, - SecretPath: secretsPath, - EnvironmentSlug: environmentName, + SecretPath: projectConfig.SecretsPath, + EnvironmentSlug: projectConfig.Environment, }) if err != nil { @@ -267,10 +190,7 @@ func createDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { } // for Kubernetes dynamic secrets only - kubernetesNamespace, err := cmd.Flags().GetString("kubernetes-namespace") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + kubernetesNamespace := util.GetStringArgument(cmd, "kubernetes-namespace", "Unable to parse flag --kubernetes-namespace") config := map[string]any{} if kubernetesNamespace != "" { @@ -281,8 +201,8 @@ func createDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { DynamicSecretName: dynamicSecretRootCredential.Name, ProjectSlug: projectSlug, TTL: ttl, - SecretPath: secretsPath, - EnvironmentSlug: environmentName, + SecretPath: projectConfig.SecretsPath, + EnvironmentSlug: projectConfig.Environment, Config: config, }) @@ -330,43 +250,13 @@ var dynamicSecretLeaseRenewCmd = &cobra.Command{ func renewDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { dynamicSecretLeaseId := args[0] - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectSlug, err := cmd.Flags().GetString("project-slug") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - ttl, err := cmd.Flags().GetString("ttl") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + projectSlug := util.GetStringArgument(cmd, "project-slug", "Unable to parse flag --project-slug") - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse path flag") - } + ttl := util.GetStringArgument(cmd, "ttl", "Unable to parse flag --ttl") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") var infisicalToken string httpClient, err := util.GetRestyClientWithCustomHeaders() @@ -374,14 +264,6 @@ func renewDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { util.HandleError(err, "Unable to get resty client with custom headers") } - if projectId == "" && projectSlug == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project, pass in project slug with --project-slug flag, or pass in project id with --projectId flag") - } - projectId = workspaceFile.WorkspaceId - } - if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { infisicalToken = token.Token } else { @@ -415,7 +297,7 @@ func renewDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { infisicalClient.Auth().SetAccessToken(infisicalToken) if projectSlug == "" { - projectDetails, err := api.CallGetProjectById(httpClient, projectId) + projectDetails, err := api.CallGetProjectById(httpClient, projectConfig.WorkspaceId) if err != nil { util.HandleError(err, "To fetch project details") } @@ -429,8 +311,8 @@ func renewDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { leaseDetails, err := infisicalClient.DynamicSecrets().Leases().RenewById(infisicalSdk.RenewDynamicSecretLeaseOptions{ ProjectSlug: projectSlug, TTL: ttl, - SecretPath: secretsPath, - EnvironmentSlug: environmentName, + SecretPath: projectConfig.SecretsPath, + EnvironmentSlug: projectConfig.Environment, LeaseId: dynamicSecretLeaseId, }) if err != nil { @@ -465,38 +347,11 @@ var dynamicSecretLeaseRevokeCmd = &cobra.Command{ func revokeDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { dynamicSecretLeaseId := args[0] - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectSlug, err := cmd.Flags().GetString("project-slug") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse path flag") - } + projectSlug := util.GetStringArgument(cmd, "project-slug", "Unable to parse flag --project-slug") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") var infisicalToken string httpClient, err := util.GetRestyClientWithCustomHeaders() @@ -504,14 +359,6 @@ func revokeDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { util.HandleError(err, "Unable to get resty client with custom headers") } - if projectId == "" && projectSlug == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project, pass in project slug with --project-slug flag, or pass in project id with --projectId flag") - } - projectId = workspaceFile.WorkspaceId - } - if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { infisicalToken = token.Token } else { @@ -545,7 +392,7 @@ func revokeDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { infisicalClient.Auth().SetAccessToken(infisicalToken) if projectSlug == "" { - projectDetails, err := api.CallGetProjectById(httpClient, projectId) + projectDetails, err := api.CallGetProjectById(httpClient, projectConfig.WorkspaceId) if err != nil { util.HandleError(err, "To fetch project details") } @@ -558,8 +405,8 @@ func revokeDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { leaseDetails, err := infisicalClient.DynamicSecrets().Leases().DeleteById(infisicalSdk.DeleteDynamicSecretLeaseOptions{ ProjectSlug: projectSlug, - SecretPath: secretsPath, - EnvironmentSlug: environmentName, + SecretPath: projectConfig.SecretsPath, + EnvironmentSlug: projectConfig.Environment, LeaseId: dynamicSecretLeaseId, }) if err != nil { @@ -593,38 +440,11 @@ var dynamicSecretLeaseListCmd = &cobra.Command{ func listDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { dynamicSecretRootCredentialName := args[0] - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - projectSlug, err := cmd.Flags().GetString("project-slug") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + projectSlug := util.GetStringArgument(cmd, "project-slug", "Unable to parse flag --project-slug") - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse path flag") - } - - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") var infisicalToken string httpClient, err := util.GetRestyClientWithCustomHeaders() @@ -632,14 +452,6 @@ func listDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { util.HandleError(err, "Unable to get resty client with custom headers") } - if projectId == "" && projectSlug == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project, pass in project slug with --project-slug flag, or pass in project id with --projectId flag") - } - projectId = workspaceFile.WorkspaceId - } - if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { infisicalToken = token.Token } else { @@ -672,7 +484,7 @@ func listDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { infisicalClient.Auth().SetAccessToken(infisicalToken) if projectSlug == "" { - projectDetails, err := api.CallGetProjectById(httpClient, projectId) + projectDetails, err := api.CallGetProjectById(httpClient, projectConfig.WorkspaceId) if err != nil { util.HandleError(err, "To fetch project details") } @@ -682,8 +494,8 @@ func listDynamicSecretLeaseByName(cmd *cobra.Command, args []string) { dynamicSecretLeases, err := infisicalClient.DynamicSecrets().Leases().List(infisicalSdk.ListDynamicSecretLeasesOptions{ DynamicSecretName: dynamicSecretRootCredentialName, ProjectSlug: projectSlug, - SecretPath: secretsPath, - EnvironmentSlug: environmentName, + SecretPath: projectConfig.SecretsPath, + EnvironmentSlug: projectConfig.Environment, }) if err != nil { diff --git a/packages/cmd/export.go b/packages/cmd/export.go index 33cd212c..78ed75e0 100644 --- a/packages/cmd/export.go +++ b/packages/cmd/export.go @@ -34,69 +34,25 @@ var exportCmd = &cobra.Command{ Example: "infisical export --env=prod --format=json > secrets.json\ninfisical export --env=prod --format=json --output-file=secrets.json", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - shouldExpandSecrets, err := cmd.Flags().GetBool("expand") - if err != nil { - util.HandleError(err) - } - - includeImports, err := cmd.Flags().GetBool("include-imports") - if err != nil { - util.HandleError(err) - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err) - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - format, err := cmd.Flags().GetString("format") - if err != nil { - util.HandleError(err) - } + shouldExpandSecrets := util.GetBooleanArgument(cmd, "expand", "Unable to parse flag --expand") - templatePath, err := cmd.Flags().GetString("template") - if err != nil { - util.HandleError(err) - } + includeImports := util.GetBooleanArgument(cmd, "include-imports", "Unable to parse flag --include-imports") - secretOverriding, err := cmd.Flags().GetBool("secret-overriding") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + format := util.GetStringArgument(cmd, "format", "Unable to parse flag --format") - tagSlugs, err := cmd.Flags().GetString("tags") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + templatePath := util.GetStringArgument(cmd, "template", "Unable to parse flag --template") - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + secretOverriding := util.GetBooleanArgument(cmd, "secret-overriding", "Unable to parse flag --secret-overriding") - outputFile, err := cmd.Flags().GetString("output-file") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFile := util.GetStringArgument(cmd, "output-file", "Unable to parse flag --output-file") request := models.GetAllSecretsParameters{ - Environment: environmentName, - TagSlugs: tagSlugs, - WorkspaceId: projectId, - SecretsPath: secretsPath, + Environment: projectConfig.Environment, + TagSlugs: projectConfig.TagSlugs, + WorkspaceId: projectConfig.WorkspaceId, + SecretsPath: projectConfig.SecretsPath, IncludeImport: includeImports, ExpandSecretReferences: shouldExpandSecrets, } @@ -132,7 +88,7 @@ var exportCmd = &cobra.Command{ return } - secrets, err := util.GetAllEnvironmentVariables(request, "") + secrets, err := util.GetAllEnvironmentVariables(request) if err != nil { util.HandleError(err, "Unable to fetch secrets") } @@ -144,7 +100,7 @@ var exportCmd = &cobra.Command{ } var output string - secrets = util.FilterSecretsByTag(secrets, tagSlugs) + secrets = util.FilterSecretsByTag(secrets, projectConfig.TagSlugs) secrets = util.SortSecretsByKeys(secrets) output, err = formatEnvs(secrets, format) @@ -207,7 +163,7 @@ func resolveOutputPath(outputFile, format string) (string, error) { defaultFilename := getDefaultFilename(format) return filepath.Join(absPath, defaultFilename), nil } - + // Ensure the parent directory exists parentDir := filepath.Dir(absPath) if _, err := os.Stat(parentDir); os.IsNotExist(err) { @@ -216,7 +172,7 @@ func resolveOutputPath(outputFile, format string) (string, error) { return "", fmt.Errorf("failed to create parent directory %s: %w", parentDir, err) } } - + // If no extension provided, add default extension based on format if filepath.Ext(absPath) == "" { ext := getDefaultExtension(format) @@ -357,4 +313,4 @@ func escapeNewLinesIfRequired(env models.SingleEnvironmentVariable) string { } return env.Value -} \ No newline at end of file +} diff --git a/packages/cmd/folder.go b/packages/cmd/folder.go index 809f84c2..d0ca27f4 100644 --- a/packages/cmd/folder.go +++ b/packages/cmd/folder.go @@ -24,36 +24,15 @@ var getCmd = &cobra.Command{ Use: "get", Short: "Get folders in a directory", Run: func(cmd *cobra.Command, args []string) { + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } + foldersPath := util.GetStringArgument(cmd, "path", "Unable to parse flag --path") - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - foldersPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") request := models.GetAllFoldersParameters{ - Environment: environmentName, - WorkspaceId: projectId, + Environment: projectConfig.Environment, + WorkspaceId: projectConfig.WorkspaceId, FoldersPath: foldersPath, } @@ -97,61 +76,23 @@ var createCmd = &cobra.Command{ Use: "create", Short: "Create a folder", Run: func(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + folderPath := util.GetStringArgument(cmd, "path", "Unable to parse flag --path") - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + folderName := util.GetStringArgument(cmd, "name", "Unable to parse flag --name") - folderPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - folderName, err := cmd.Flags().GetString("name") - if err != nil { - util.HandleError(err, "Unable to parse name flag") - } - - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") if folderName == "" { util.HandleError(errors.New("invalid folder name, folder name cannot be empty")) } - if err != nil { - util.HandleError(err, "Unable to get workspace file") - } - - if projectId == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - - projectId = workspaceFile.WorkspaceId - } - params := models.CreateFolderParameters{ FolderName: folderName, - Environment: environmentName, + Environment: projectConfig.Environment, FolderPath: folderPath, - WorkspaceId: projectId, + WorkspaceId: projectConfig.WorkspaceId, } if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { @@ -188,57 +129,22 @@ var deleteCmd = &cobra.Command{ Use: "delete", Short: "Delete a folder", Run: func(cmd *cobra.Command, args []string) { + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - folderPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + folderPath := util.GetStringArgument(cmd, "path", "Unable to parse flag --path") - folderName, err := cmd.Flags().GetString("name") - if err != nil { - util.HandleError(err, "Unable to parse name flag") - } + folderName := util.GetStringArgument(cmd, "name", "Unable to parse flag --name") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse flag --output") if folderName == "" { util.HandleError(errors.New("invalid folder name, folder name cannot be empty")) } - if projectId == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - - projectId = workspaceFile.WorkspaceId - } - params := models.DeleteFolderParameters{ FolderName: folderName, - WorkspaceId: projectId, - Environment: environmentName, + WorkspaceId: projectConfig.WorkspaceId, + Environment: projectConfig.Environment, FolderPath: folderPath, } @@ -246,7 +152,7 @@ var deleteCmd = &cobra.Command{ params.InfisicalToken = token.Token } - _, err = util.DeleteFolder(params) + _, err := util.DeleteFolder(params) if err != nil { util.HandleError(err, "Unable to delete folder") } diff --git a/packages/cmd/root.go b/packages/cmd/root.go index b9370ad8..cc26e7b6 100644 --- a/packages/cmd/root.go +++ b/packages/cmd/root.go @@ -41,6 +41,7 @@ func init() { rootCmd.PersistentFlags().StringP("log-level", "l", "info", "log level (trace, debug, info, warn, error, fatal)") rootCmd.PersistentFlags().Bool("telemetry", true, "Infisical collects non-sensitive telemetry data to enhance features and improve user experience. Participation is voluntary") rootCmd.PersistentFlags().StringVar(&config.INFISICAL_URL, "domain", fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_US_URL), "Point the CLI to your own backend [can also set via environment variable name: INFISICAL_API_URL]") + rootCmd.PersistentFlags().String("project-config-dir", "", "The directory where the .infisical.json resides") rootCmd.PersistentFlags().Bool("silent", false, "Disable output of tip/info messages. Useful when running in scripts or CI/CD pipelines.") rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) { silent, err := cmd.Flags().GetBool("silent") diff --git a/packages/cmd/run.go b/packages/cmd/run.go index 7f11a3f9..ff4647d6 100644 --- a/packages/cmd/run.go +++ b/packages/cmd/run.go @@ -59,42 +59,11 @@ var runCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + command := util.GetStringArgument(cmd, "command", "Unable to parse flag --command") - projectConfigDir, err := cmd.Flags().GetString("project-config-dir") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - command, err := cmd.Flags().GetString("command") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretOverriding, err := cmd.Flags().GetBool("secret-overriding") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + secretOverriding := util.GetBooleanArgument(cmd, "secret-overriding", "Unable to parse flag --secret-overriding") watchMode, err := cmd.Flags().GetBool("watch") if err != nil { @@ -116,16 +85,6 @@ var runCmd = &cobra.Command{ util.HandleError(err, "Unable to parse flag") } - tagSlugs, err := cmd.Flags().GetString("tags") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - includeImports, err := cmd.Flags().GetBool("include-imports") if err != nil { util.HandleError(err, "Unable to parse flag") @@ -137,16 +96,16 @@ var runCmd = &cobra.Command{ } request := models.GetAllSecretsParameters{ - Environment: environmentName, - WorkspaceId: projectId, - TagSlugs: tagSlugs, - SecretsPath: secretsPath, + Environment: projectConfig.Environment, + WorkspaceId: projectConfig.WorkspaceId, + TagSlugs: projectConfig.TagSlugs, + SecretsPath: projectConfig.SecretsPath, IncludeImport: includeImports, Recursive: recursive, ExpandSecretReferences: shouldExpandSecrets, } - injectableEnvironment, err := fetchAndFormatSecretsForShell(request, projectConfigDir, secretOverriding, token) + injectableEnvironment, err := fetchAndFormatSecretsForShell(request, secretOverriding, token) if err != nil { util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid") } @@ -154,7 +113,7 @@ var runCmd = &cobra.Command{ log.Debug().Msgf("injecting the following environment variables into shell: %v", injectableEnvironment.Variables) if watchMode { - executeCommandWithWatchMode(command, args, watchModeInterval, request, projectConfigDir, secretOverriding, token) + executeCommandWithWatchMode(command, args, watchModeInterval, request, secretOverriding, token) } else { if cmd.Flags().Changed("command") { command := cmd.Flag("command").Value.String() @@ -307,8 +266,7 @@ func waitForExitCommand(cmd *exec.Cmd) (int, error) { return waitStatus.ExitStatus(), nil } -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, secretOverriding bool, token *models.TokenDetails) { var cmd *exec.Cmd var err error var lastSecretsFetch time.Time @@ -423,7 +381,7 @@ func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInt watchMutex.Lock() defer watchMutex.Unlock() - newEnvironmentVariables, err := fetchAndFormatSecretsForShell(request, projectConfigDir, secretOverriding, token) + newEnvironmentVariables, err := fetchAndFormatSecretsForShell(request, secretOverriding, token) if err != nil { log.Error().Err(err).Msg("[HOT RELOAD] Failed to fetch secrets") return @@ -439,7 +397,7 @@ func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInt } } -func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) { +func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) { if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token @@ -447,7 +405,7 @@ func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, proje request.UniversalAuthAccessToken = token.Token } - secrets, err := util.GetAllEnvironmentVariables(request, projectConfigDir) + secrets, err := util.GetAllEnvironmentVariables(request) if err != nil { return models.InjectableEnvironmentResult{}, err diff --git a/packages/cmd/secrets.go b/packages/cmd/secrets.go index c3d4b9d5..5a9b690c 100644 --- a/packages/cmd/secrets.go +++ b/packages/cmd/secrets.go @@ -25,69 +25,25 @@ var secretsCmd = &cobra.Command{ DisableFlagsInUseLine: true, Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - shouldExpandSecrets, err := cmd.Flags().GetBool("expand") - if err != nil { - util.HandleError(err) - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - includeImports, err := cmd.Flags().GetBool("include-imports") - if err != nil { - util.HandleError(err) - } + shouldExpandSecrets := util.GetBooleanArgument(cmd, "expand", "Unable to parse argument --expand") - recursive, err := cmd.Flags().GetBool("recursive") - if err != nil { - util.HandleError(err) - } + includeImports := util.GetBooleanArgument(cmd, "include-imports", "Unable to parse argument --include-imports") - tagSlugs, err := cmd.Flags().GetString("tags") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + recursive := util.GetBooleanArgument(cmd, "recursive", "Unable to parse argument --recursive") - secretOverriding, err := cmd.Flags().GetBool("secret-overriding") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + secretOverriding := util.GetBooleanArgument(cmd, "secret-overriding", "Unable to parse argument --secret-overriding") - plainOutput, err := cmd.Flags().GetBool("plain") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + plainOutput := util.GetBooleanArgument(cmd, "plain", "Unable to parse argument --plain") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse argument --output") request := models.GetAllSecretsParameters{ - Environment: environmentName, - WorkspaceId: projectId, - TagSlugs: tagSlugs, - SecretsPath: secretsPath, + Environment: projectConfig.Environment, + WorkspaceId: projectConfig.WorkspaceId, + TagSlugs: projectConfig.TagSlugs, + SecretsPath: projectConfig.SecretsPath, IncludeImport: includeImports, Recursive: recursive, ExpandSecretReferences: shouldExpandSecrets, @@ -99,7 +55,7 @@ var secretsCmd = &cobra.Command{ request.UniversalAuthAccessToken = token.Token } - secrets, err := util.GetAllEnvironmentVariables(request, "") + secrets, err := util.GetAllEnvironmentVariables(request) if err != nil { util.HandleError(err) } @@ -178,47 +134,15 @@ var secretsSetCmd = &cobra.Command{ return cobra.MinimumNArgs(1)(cmd, args) }, Run: func(cmd *cobra.Command, args []string) { - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) + secretType := util.GetStringArgument(cmd, "type", "Unable to parse argument --type") + if secretType != util.SECRET_TYPE_SHARED && secretType != util.SECRET_TYPE_PERSONAL { + util.PrintErrorMessageAndExit("Invalid secret type. Valid values are 'shared' and 'personal'") } - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse argument --output") - if token == nil && projectId == "" { - _, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - } - - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretType, err := cmd.Flags().GetString("type") - if err != nil || (secretType != util.SECRET_TYPE_SHARED && secretType != util.SECRET_TYPE_PERSONAL) { - util.HandleError(err, "Unable to parse secret type") - } - - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - processedArgs := []string{} + var processedArgs []string for _, arg := range args { splitKeyValue := strings.SplitN(arg, "=", 2) if len(splitKeyValue) != 2 { @@ -242,32 +166,17 @@ var secretsSetCmd = &cobra.Command{ processedArgs = append(processedArgs, fmt.Sprintf("%s=%s", key, value)) } - file, err := cmd.Flags().GetString("file") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + file := util.GetStringArgument(cmd, "file", "Unable to parse argument --file") var secretOperations []models.SecretSetOperation if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { - if projectId == "" { - util.PrintErrorMessageAndExit("When using service tokens or machine identities, you must set the --projectId flag") - } - - secretOperations, err = util.SetRawSecrets(args, secretType, environmentName, secretsPath, projectId, token, file) + var err error + secretOperations, err = util.SetRawSecrets(args, secretType, projectConfig.Environment, projectConfig.SecretsPath, projectConfig.WorkspaceId, token, file) if err != nil { util.HandleError(err, "Unable to set secrets") } } else { - if projectId == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - - projectId = workspaceFile.WorkspaceId - } - loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true) if err != nil { util.HandleError(err, "unable to authenticate [err=%v]") @@ -277,7 +186,7 @@ var secretsSetCmd = &cobra.Command{ loggedInUserDetails = util.EstablishUserLoginSession() } - secretOperations, err = util.SetRawSecrets(processedArgs, secretType, environmentName, secretsPath, projectId, &models.TokenDetails{ + secretOperations, err = util.SetRawSecrets(processedArgs, secretType, projectConfig.Environment, projectConfig.SecretsPath, projectConfig.WorkspaceId, &models.TokenDetails{ Type: "", Token: loggedInUserDetails.UserCredentials.JTWToken, }, file) @@ -289,7 +198,7 @@ var secretsSetCmd = &cobra.Command{ // Print secret operations headers := [...]string{"SECRET NAME", "SECRET VALUE", "STATUS"} - rows := [][3]string{} + var rows [][3]string for _, secretOperation := range secretOperations { rows = append(rows, [...]string{secretOperation.SecretKey, secretOperation.SecretValue, secretOperation.SecretOperation}) } @@ -328,38 +237,11 @@ var secretsDeleteCmd = &cobra.Command{ DisableFlagsInUseLine: true, Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + secretType := util.GetStringArgument(cmd, "type", "Unable to parse argument --type") - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - secretType, err := cmd.Flags().GetString("type") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse argument --output") httpClient, err := util.GetRestyClientWithCustomHeaders() if err != nil { @@ -368,14 +250,6 @@ var secretsDeleteCmd = &cobra.Command{ httpClient.SetHeader("Accept", "application/json") - if projectId == "" { - workspaceFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - projectId = workspaceFile.WorkspaceId - } - if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { httpClient.SetAuthToken(token.Token) } else { @@ -395,11 +269,11 @@ var secretsDeleteCmd = &cobra.Command{ for _, secretName := range args { request := api.DeleteSecretV3Request{ - WorkspaceId: projectId, - Environment: environmentName, + WorkspaceId: projectConfig.WorkspaceId, + Environment: projectConfig.Environment, SecretName: secretName, Type: secretType, - SecretPath: secretsPath, + SecretPath: projectConfig.SecretsPath, } err = api.CallDeleteSecretsRawV3(httpClient, request) @@ -431,79 +305,32 @@ var secretsDeleteCmd = &cobra.Command{ } func getSecretsByNames(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - shouldExpand, err := cmd.Flags().GetBool("expand") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - tagSlugs, err := cmd.Flags().GetString("tags") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse path flag") - } + shouldExpand := util.GetBooleanArgument(cmd, "expand", "Unable to parse argument --expand") - recursive, err := cmd.Flags().GetBool("recursive") - if err != nil { - util.HandleError(err, "Unable to parse recursive flag") - } + recursive := util.GetBooleanArgument(cmd, "recursive", "Unable to parse argument --recursive") - outputFormat, err := cmd.Flags().GetString("output") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + outputFormat := util.GetStringArgument(cmd, "output", "Unable to parse argument --output") // deprecated, in favor of --plain - showOnlyValue, err := cmd.Flags().GetBool("raw-value") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + showOnlyValue := util.GetBooleanArgument(cmd, "raw-value", "Unable to parse argument --raw-value") - plainOutput, err := cmd.Flags().GetBool("plain") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + plainOutput := util.GetBooleanArgument(cmd, "plain", "Unable to parse argument --plain") if showOnlyValue { plainOutput = true } - includeImports, err := cmd.Flags().GetBool("include-imports") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + includeImports := util.GetBooleanArgument(cmd, "include-imports", "Unable to parse argument --include-imports") - secretOverriding, err := cmd.Flags().GetBool("secret-overriding") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + secretOverriding := util.GetBooleanArgument(cmd, "secret-overriding", "Unable to parse argument --secret-overriding") request := models.GetAllSecretsParameters{ - Environment: environmentName, - WorkspaceId: projectId, - TagSlugs: tagSlugs, - SecretsPath: secretsPath, + Environment: projectConfig.Environment, + WorkspaceId: projectConfig.WorkspaceId, + TagSlugs: projectConfig.TagSlugs, + SecretsPath: projectConfig.SecretsPath, IncludeImport: includeImports, Recursive: recursive, ExpandSecretReferences: shouldExpand, @@ -515,7 +342,7 @@ func getSecretsByNames(cmd *cobra.Command, args []string) { request.UniversalAuthAccessToken = token.Token } - secrets, err := util.GetAllEnvironmentVariables(request, "") + secrets, err := util.GetAllEnvironmentVariables(request) if err != nil { util.HandleError(err, "To fetch all secrets") } @@ -526,7 +353,7 @@ func getSecretsByNames(cmd *cobra.Command, args []string) { secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) } - requestedSecrets := []models.SingleEnvironmentVariable{} + var requestedSecrets []models.SingleEnvironmentVariable secretsMap := getSecretsByKeys(secrets) @@ -579,39 +406,13 @@ func getSecretsByNames(cmd *cobra.Command, args []string) { } func generateExampleEnv(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") - if !cmd.Flags().Changed("env") { - environmentFromWorkspace := util.GetEnvFromWorkspaceFile() - if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace - } - } - - secretsPath, err := cmd.Flags().GetString("path") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - token, err := util.GetInfisicalToken(cmd) - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - tagSlugs, err := cmd.Flags().GetString("tags") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + token, projectConfig := util.GetTokenAndProjectConfigFromCommand(cmd) request := models.GetAllSecretsParameters{ - Environment: environmentName, - WorkspaceId: projectId, - TagSlugs: tagSlugs, - SecretsPath: secretsPath, + Environment: projectConfig.Environment, + WorkspaceId: projectConfig.WorkspaceId, + TagSlugs: projectConfig.TagSlugs, + SecretsPath: projectConfig.SecretsPath, IncludeImport: true, } @@ -621,7 +422,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { request.UniversalAuthAccessToken = token.Token } - secrets, err := util.GetAllEnvironmentVariables(request, "") + secrets, err := util.GetAllEnvironmentVariables(request) if err != nil { util.HandleError(err, "To fetch all secrets") } @@ -629,7 +430,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { tagsHashToSecretKey := make(map[string]int) slugsToFilerBy := make(map[string]int) - for _, slug := range strings.Split(tagSlugs, ",") { + for _, slug := range strings.Split(projectConfig.TagSlugs, ",") { slugsToFilerBy[slug] = 1 } @@ -644,7 +445,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { }) for i, secret := range secrets { - filteredTag := []models.Tag{} + var filteredTag []models.Tag for _, secretTag := range secret.Tags { _, exists := slugsToFilerBy[secretTag.Slug] @@ -658,7 +459,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { } for _, secret := range secrets { - listOfTagSlugs := []string{} + var listOfTagSlugs []string for _, tag := range secret.Tags { listOfTagSlugs = append(listOfTagSlugs, tag.Slug) @@ -673,7 +474,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { finalTagHashToSecretKey := make(map[string]TagsAndSecrets) for _, secret := range secrets { - listOfTagSlugs := []string{} + var listOfTagSlugs []string for _, tag := range secret.Tags { listOfTagSlugs = append(listOfTagSlugs, tag.Slug) } @@ -709,7 +510,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { } } - // sort the fianl result by secret key fo consistent print order + // sort the final result by secret key for consistent print order listOfsecretDetails := make([]TagsAndSecrets, 0, len(finalTagHashToSecretKey)) for _, secretDetails := range finalTagHashToSecretKey { listOfsecretDetails = append(listOfsecretDetails, secretDetails) @@ -720,10 +521,10 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { return len(listOfsecretDetails[i].Tags) < len(listOfsecretDetails[j].Tags) }) - tableOfContents := []string{} - fullyGeneratedDocuments := []string{} + var tableOfContents []string + var fullyGeneratedDocuments []string for _, secretDetails := range listOfsecretDetails { - listOfKeyValue := []string{} + var listOfKeyValue []string for _, secret := range secretDetails.Secrets { re := regexp.MustCompile(`(?s)(.*)DEFAULT:(.*)`) @@ -754,7 +555,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { listOfKeyValue = append(listOfKeyValue, row) } - listOfTagNames := []string{} + var listOfTagNames []string for _, tag := range secretDetails.Tags { listOfTagNames = append(listOfTagNames, tag.Name) } @@ -769,7 +570,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) { } } - dashedList := []string{} + var dashedList []string for _, item := range tableOfContents { dashedList = append(dashedList, fmt.Sprintf("# - %s \n", item)) } @@ -821,7 +622,7 @@ func init() { secretsGetCmd.Flags().String("path", "/", "get secrets within a folder path") secretsGetCmd.Flags().Bool("plain", false, "print values without formatting, one per line") secretsGetCmd.Flags().Bool("raw-value", false, "deprecated. Returns only the value of secret, only works with one secret. Use --plain instead") - secretsGetCmd.Flags().MarkHidden("raw-value") // hide from --help output + _ = secretsGetCmd.Flags().MarkHidden("raw-value") // hide-from --help output secretsGetCmd.Flags().Bool("include-imports", true, "Imported linked secrets ") secretsGetCmd.Flags().Bool("expand", true, "Parse shell parameter expansions in your secrets, and process your referenced secrets") secretsGetCmd.Flags().Bool("recursive", false, "Fetch secrets from all sub-folders") diff --git a/packages/cmd/tokens.go b/packages/cmd/tokens.go index c610374d..362d9d65 100644 --- a/packages/cmd/tokens.go +++ b/packages/cmd/tokens.go @@ -48,38 +48,15 @@ var tokensCreateCmd = &cobra.Command{ loggedInUserDetails = util.EstablishUserLoginSession() } - tokenOnly, err := cmd.Flags().GetBool("token-only") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + tokenOnly := util.GetBooleanArgument(cmd, "token-only", "Unable to parse flag --token-only") - workspaceId, err := cmd.Flags().GetString("projectId") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + projectConfig := util.GetWorkspaceConfigFromCommandOrFile(cmd) - if workspaceId == "" { - configFile, err := util.GetWorkSpaceFromFile() - if err != nil { - util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - workspaceId = configFile.WorkspaceId - } + serviceTokenName := util.GetStringArgument(cmd, "name", "Unable to parse flag --name") - serviceTokenName, err := cmd.Flags().GetString("name") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + expireSeconds := util.GetIntArgument(cmd, "expiry-seconds", "Unable to parse flag --expiry-seconds") - expireSeconds, err := cmd.Flags().GetInt("expiry-seconds") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } - - scopes, err := cmd.Flags().GetStringSlice("scope") - if err != nil { - util.HandleError(err, "Unable to parse flag") - } + scopes := util.GetStringSliceArgument(cmd, "scope", "Unable to parse flag --scope") if len(scopes) == 0 { util.PrintErrorMessageAndExit("You must define the environments and paths your service token should have access to via the --scope flag") @@ -98,10 +75,7 @@ var tokensCreateCmd = &cobra.Command{ permissions = append(permissions, api.ScopePermission{Environment: parts[0], SecretPath: parts[1]}) } - accessLevels, err := cmd.Flags().GetStringSlice("access-level") - if err != nil { - util.HandleError(err, "Unable to parse flag accessLevels") - } + accessLevels := util.GetStringSliceArgument(cmd, "access-level", "Unable to parse flag --access-level") if len(accessLevels) == 0 { util.PrintErrorMessageAndExit("You must define whether your service token can be used to read and or write via the --access-level flag") @@ -130,7 +104,7 @@ var tokensCreateCmd = &cobra.Command{ createServiceTokenResponse, err := api.CallCreateServiceToken(httpClient, api.CreateServiceTokenRequest{ Name: serviceTokenName, - WorkspaceId: workspaceId, + WorkspaceId: projectConfig.WorkspaceId, Scopes: permissions, ExpiresIn: expireSeconds, Permissions: accessLevels, @@ -158,7 +132,7 @@ var tokensCreateCmd = &cobra.Command{ fmt.Printf("New service token created\n") fmt.Printf("Name: %v\n", serviceTokenName) - fmt.Printf("Project ID: %v\n", workspaceId) + fmt.Printf("Project ID: %v\n", projectConfig.WorkspaceId) fmt.Printf("Access type: [%v]\n", strings.Join(accessLevels, ", ")) fmt.Printf("Permission(s): %v\n", strings.Join(printablePermission, ", ")) fmt.Printf("Service Token: %v\n", serviceToken) diff --git a/packages/models/cli.go b/packages/models/cli.go index 785b3827..90ea0b36 100644 --- a/packages/models/cli.go +++ b/packages/models/cli.go @@ -95,10 +95,19 @@ type Workspace struct { type WorkspaceConfigFile struct { WorkspaceId string `json:"workspaceId"` + TagSlugs []string `json:"tags"` + SecretsPath string `json:"path"` DefaultEnvironment string `json:"defaultEnvironment"` GitBranchToEnvironmentMapping map[string]string `json:"gitBranchToEnvironmentMapping"` } +type WorkspaceConfig struct { + WorkspaceId string + TagSlugs string + SecretsPath string + Environment string +} + type SymmetricEncryptionResult struct { CipherText []byte `json:"CipherText"` Nonce []byte `json:"Nonce"` diff --git a/packages/util/config.go b/packages/util/config.go index 8d44c84d..3e35617c 100644 --- a/packages/util/config.go +++ b/packages/util/config.go @@ -5,8 +5,10 @@ import ( "encoding/json" "errors" "fmt" + "github.com/spf13/cobra" "os" "path/filepath" + "strings" "github.com/Infisical/infisical-merge/packages/config" "github.com/Infisical/infisical-merge/packages/models" @@ -96,46 +98,63 @@ func WorkspaceConfigFileExistsInCurrentPath() bool { } } -func GetWorkSpaceFromFile() (models.WorkspaceConfigFile, error) { - cfgFile, err := FindWorkspaceConfigFile() - if err != nil { - return models.WorkspaceConfigFile{}, err - } +func GetWorkspaceConfigFromCommandOrFile(cmd *cobra.Command) models.WorkspaceConfig { + var configFilePath string + if cmd.Flag("project-config-dir").Changed { + configFileDir := GetStringArgument(cmd, "project-config-dir", "Unable to parse flag --project-config-dir") + configFilePath = filepath.Join(configFileDir, ".infisical.json") - configFileAsBytes, err := os.ReadFile(cfgFile) - if err != nil { - return models.WorkspaceConfigFile{}, err + _, err := os.Stat(configFilePath) + if os.IsNotExist(err) { + // The user explicitly provided the path, it must exist + PrintErrorMessageAndExit(fmt.Sprintf("file %s does not exist", configFilePath)) + } + } else { + configFilePath, _ = FindWorkspaceConfigFile() } + workspaceConfig := models.WorkspaceConfig{} var workspaceConfigFile models.WorkspaceConfigFile - err = json.Unmarshal(configFileAsBytes, &workspaceConfigFile) - if err != nil { - return models.WorkspaceConfigFile{}, err + + if configFilePath != "" { + workspaceConfigFile = getWorkspaceConfigByPath(configFilePath) } - return workspaceConfigFile, nil -} + if cmd.Flag("projectId") != nil && cmd.Flag("projectId").Changed { + workspaceConfig.WorkspaceId = GetStringArgument(cmd, "projectId", "Unable to parse argument --projectId") + } else { + workspaceConfig.WorkspaceId = workspaceConfigFile.WorkspaceId + } -func GetWorkSpaceFromFilePath(configFileDir string) (models.WorkspaceConfigFile, error) { - configFilePath := filepath.Join(configFileDir, ".infisical.json") + if workspaceConfig.WorkspaceId == "" { + // We have no project to work with from args or the file + if configFilePath == "" { + PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") + } + PrintErrorMessageAndExit("Your project id is missing in your local config file. Please add it or run again [infisical init]") + } - _, configFileStatusError := os.Stat(configFilePath) - if os.IsNotExist(configFileStatusError) { - return models.WorkspaceConfigFile{}, fmt.Errorf("file %s does not exist", configFilePath) + if cmd.Flag("tags") != nil && cmd.Flag("tags").Changed { + workspaceConfig.TagSlugs = GetStringArgument(cmd, "tags", "Unable to parse argument --tags") + } else { + workspaceConfig.TagSlugs = strings.Join(workspaceConfigFile.TagSlugs, ",") } - configFileAsBytes, err := os.ReadFile(configFilePath) - if err != nil { - return models.WorkspaceConfigFile{}, err + if cmd.Flag("path") != nil && (cmd.Flag("path").Changed || workspaceConfigFile.SecretsPath == "") { + workspaceConfig.SecretsPath = GetStringArgument(cmd, "path", "Unable to parse argument --path") + } else { + workspaceConfig.SecretsPath = workspaceConfigFile.SecretsPath } - var workspaceConfigFile models.WorkspaceConfigFile - err = json.Unmarshal(configFileAsBytes, &workspaceConfigFile) - if err != nil { - return models.WorkspaceConfigFile{}, err + configFileBranch := getEnvelopmentBasedOnGitBranch(workspaceConfigFile) + + if cmd.Flag("env") != nil && (cmd.Flag("env").Changed || configFileBranch == "") { + workspaceConfig.Environment = GetStringArgument(cmd, "env", "Unable to parse argument --env") + } else { + workspaceConfig.Environment = configFileBranch } - return workspaceConfigFile, nil + return workspaceConfig } // FindWorkspaceConfigFile searches for a .infisical.json file in the current directory and all parent directories. @@ -181,19 +200,39 @@ func GetFullConfigFilePath() (fullPathToFile string, fullPathToDirectory string, } // Given a path to a workspace config, unmarshal workspace config -func GetWorkspaceConfigByPath(path string) (workspaceConfig models.WorkspaceConfigFile, err error) { +func getWorkspaceConfigByPath(path string) models.WorkspaceConfigFile { workspaceConfigFileAsBytes, err := os.ReadFile(path) if err != nil { - return models.WorkspaceConfigFile{}, fmt.Errorf("GetWorkspaceConfigByPath: Unable to read workspace config file because [%s]", err) + log.Debug().Msgf("GetWorkspaceConfigByPath: Unable to read workspace config file because [%s]", err) + PrintErrorMessageAndExit(fmt.Sprintf("Unable to read workspace config file %s", path)) } - var workspaceConfigFile models.WorkspaceConfigFile + 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) + log.Debug().Msgf("GetWorkspaceConfigByPath: Unable to unmarshal workspace config file because [%s]", err) + PrintErrorMessageAndExit(fmt.Sprintf("Unable to read workspace config file %s", path)) + } + + return workspaceConfigFile +} + +func getEnvelopmentBasedOnGitBranch(workspaceFile models.WorkspaceConfigFile) string { + branch, err := getCurrentBranch() + if err != nil { + log.Debug().Msgf("getEnvelopmentBasedOnGitBranch: [err=%s]", err) } - return workspaceConfigFile, nil + envBasedOnGitBranch, ok := workspaceFile.GitBranchToEnvironmentMapping[branch] + + log.Debug().Msgf("GetEnvelopmentBasedOnGitBranch: [envBasedOnGitBranch=%s] [ok=%t]", envBasedOnGitBranch, ok) + + if err == nil && ok { + return envBasedOnGitBranch + } else { + log.Debug().Msgf("getEnvelopmentBasedOnGitBranch: [err=%s]", err) + return workspaceFile.DefaultEnvironment + } } // Get the infisical config file and if it doesn't exist, return empty config model, otherwise raise error diff --git a/packages/util/config_test.go b/packages/util/config_test.go new file mode 100644 index 00000000..1dcb474b --- /dev/null +++ b/packages/util/config_test.go @@ -0,0 +1,184 @@ +package util + +import ( + "fmt" + "github.com/spf13/cobra" + "os" + "testing" +) + +func TestFindWorkspaceConfigFile(t *testing.T) { + tmp := t.TempDir() + + // Set the temp folder as the current working directory + os.Chdir(tmp) + os.WriteFile(".infisical.json", []byte("{}"), 0644) + + configFile, err := FindWorkspaceConfigFile() + if configFile == fmt.Sprintf("%s/%s", tmp, ".infisical.json") { + t.Errorf("Expected config file to be found in the current working directory, found: %s", configFile) + } + if err != nil { + t.Errorf("Expected error to be nil, got %s", err.Error()) + } +} + +func TestFindWorkspaceConfigFile_NoConfigFile(t *testing.T) { + tmp := t.TempDir() + + // Set the temp folder as the current working directory + os.Chdir(tmp) + + configFile, err := FindWorkspaceConfigFile() + if configFile != "" { + t.Errorf("Expected config file to be empty, got %s", configFile) + } + if err.Error() != "file not found: .infisical.json" { + t.Errorf("Expected error to be 'file not found: .inifisical.json', got %s", err.Error()) + } +} + +func TestGetWorkspaceConfigFromCommandOrFile_NoConfigFile_NoProjectId(t *testing.T) { + defer func() { + errorMessage := recover().(string) + expectedErrorMessage := "Please either run infisical init to connect to a project or pass in project id with --projectId flag" + if errorMessage != expectedErrorMessage { + t.Errorf("Unexpected error message: %s", errorMessage) + } + }() + + tmp := t.TempDir() + os.Chdir(tmp) + + emptyCmd := getCommandWithFullConfig() + GetWorkspaceConfigFromCommandOrFile(emptyCmd) + + t.Errorf("Expected the function to panic") +} + +func TestGetWorkspaceConfigFromCommandOrFile_ConfigFile_EmptyProjectId(t *testing.T) { + defer func() { + errorMessage := recover().(string) + expectedErrorMessage := "Your project id is missing in your local config file. Please add it or run again [infisical init]" + if errorMessage != expectedErrorMessage { + t.Errorf("Unexpected error message: %s", errorMessage) + } + }() + + tmp := t.TempDir() + os.Chdir(tmp) + + os.WriteFile(".infisical.json", []byte(`{"workspaceId": ""}`), 0644) + + emptyCmd := getCommandWithFullConfig() + GetWorkspaceConfigFromCommandOrFile(emptyCmd) + + t.Errorf("Expected the function to panic") +} + +func TestGetWorkspaceConfigFromCommandOrFile_OverrideConfigFile(t *testing.T) { + tmp := t.TempDir() + os.Chdir(tmp) + + os.WriteFile(".infisical.json", []byte(`{"workspaceId": "default-project", "defaultEnvironment": "default-env"}`), 0644) + + overrideDir := t.TempDir() + os.WriteFile(fmt.Sprintf("%s/.infisical.json", overrideDir), []byte(`{"workspaceId": "override-project", "defaultEnvironment": "override-env"}`), 0644) + + cmd := getCommandWithFullConfig() + cmd.Flags().Set("project-config-dir", overrideDir) + projectConfig := GetWorkspaceConfigFromCommandOrFile(cmd) + + if projectConfig.WorkspaceId != "override-project" { + t.Errorf("Expected project id to be 'override-project', got %s", projectConfig.WorkspaceId) + } +} + +func TestGetWorkspaceConfigFromCommandOrFile_ReadFromCommand(t *testing.T) { + tmp := t.TempDir() + os.Chdir(tmp) + + os.WriteFile(".infisical.json", []byte(`{"workspaceId": "default-project", "defaultEnvironment": "default-env", "tags": ["file", "tags"], "path": "/override"}`), 0644) + + cmd := getCommandWithFullConfig() + cmd.Flags().Set("projectId", "cmd-project") + cmd.Flags().Set("env", "cmd-env") + cmd.Flags().Set("tags", "cmd,tags") + cmd.Flags().Set("path", "/cmd") + projectConfig := GetWorkspaceConfigFromCommandOrFile(cmd) + + if projectConfig.WorkspaceId != "cmd-project" { + t.Errorf("Expected project id to be 'cmd-project', got %s", projectConfig.WorkspaceId) + } + if projectConfig.TagSlugs != "cmd,tags" { + t.Errorf("Expected tags to be 'cmd,tags', got %s", projectConfig.TagSlugs) + } + if projectConfig.SecretsPath != "/cmd" { + t.Errorf("Expected secrets path to be '/cmd', got %s", projectConfig.SecretsPath) + } + if projectConfig.Environment != "cmd-env" { + t.Errorf("Expected environment to be 'cmd-env', got %s", projectConfig.Environment) + } +} + +func TestGetWorkspaceConfigFromCommandOrFile_ReadFromFile(t *testing.T) { + tmp := t.TempDir() + os.Chdir(tmp) + + os.WriteFile(".infisical.json", []byte(`{"workspaceId": "default-project", "defaultEnvironment": "default-env", "tags": ["file", "tags"], "path": "/override"}`), 0644) + + emptyCmd := getCommandWithFullConfig() + projectConfig := GetWorkspaceConfigFromCommandOrFile(emptyCmd) + + if projectConfig.WorkspaceId != "default-project" { + t.Errorf("Expected project id to be 'override-project', got %s", projectConfig.WorkspaceId) + } + if projectConfig.TagSlugs != "file,tags" { + t.Errorf("Expected tags to be 'file,tags', got %s", projectConfig.TagSlugs) + } + if projectConfig.SecretsPath != "/override" { + t.Errorf("Expected secrets path to be '/override', got %s", projectConfig.SecretsPath) + } + if projectConfig.Environment != "default-env" { + t.Errorf("Expected environment to be 'default-env', got %s", projectConfig.Environment) + } +} + +func TestGetWorkspaceConfigFromCommandOrFile_Defaults(t *testing.T) { + tmp := t.TempDir() + os.Chdir(tmp) + + os.WriteFile(".infisical.json", []byte(`{"workspaceId": "default-project"}`), 0644) + + emptyCmd := getCommandWithFullConfig() + projectConfig := GetWorkspaceConfigFromCommandOrFile(emptyCmd) + + if projectConfig.WorkspaceId != "default-project" { + t.Errorf("Expected project id to be 'override-project', got %s", projectConfig.WorkspaceId) + } + if projectConfig.SecretsPath != "/" { + t.Errorf("Expected secrets path to be default value '/', got %s", projectConfig.SecretsPath) + } + if projectConfig.Environment != "default" { + t.Errorf("Expected environment to be default value 'default', got %s", projectConfig.Environment) + } +} + +func getCommandWithProjectAndEnv() *cobra.Command { + cmd := &cobra.Command{ + Use: "test", + Run: func(cmd *cobra.Command, args []string) { + }, + } + cmd.Flags().String("project-config-dir", "", "The directory .infisical.json is stored in. Defaults to the current working directory.") + cmd.Flags().String("projectId", "", "Project name") + cmd.Flags().String("env", "default", "Environment name") + return cmd +} + +func getCommandWithFullConfig() *cobra.Command { + cmd := getCommandWithProjectAndEnv() + cmd.Flags().String("path", "/", "Secrets path") + cmd.Flags().String("tags", "", "Comma separated list of tags") + return cmd +} diff --git a/packages/util/folders.go b/packages/util/folders.go index fb4f2a32..edf0e1c3 100644 --- a/packages/util/folders.go +++ b/packages/util/folders.go @@ -27,14 +27,6 @@ func GetAllFolders(params models.GetAllFoldersParameters) ([]models.SingleFolder loggedInUserDetails = EstablishUserLoginSession() } - if params.WorkspaceId == "" { - workspaceFile, err := GetWorkSpaceFromFile() - if err != nil { - PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - params.WorkspaceId = workspaceFile.WorkspaceId - } - folders, err := GetFoldersViaJTW(loggedInUserDetails.UserCredentials.JTWToken, params.WorkspaceId, params.Environment, params.FoldersPath) folderErr = err foldersToReturn = folders diff --git a/packages/util/helper.go b/packages/util/helper.go index ccf1df4a..a995168d 100644 --- a/packages/util/helper.go +++ b/packages/util/helper.go @@ -383,33 +383,6 @@ func RequireServiceToken() { } } -func RequireLocalWorkspaceFile() { - workspaceFilePath, _ := FindWorkspaceConfigFile() - if workspaceFilePath == "" { - PrintErrorMessageAndExit("It looks you have not yet connected this project to Infisical", "To do so, run [infisical init] then run your command again") - } - - workspaceFile, err := GetWorkSpaceFromFile() - if err != nil { - HandleError(err, "Unable to read your project configuration, please try initializing this project again.", "Run [infisical init]") - } - - if workspaceFile.WorkspaceId == "" { - PrintErrorMessageAndExit("Your project id is missing in your local config file. Please add it or run again [infisical init]") - } -} - -func ValidateWorkspaceFile(projectConfigFilePath string) { - workspaceFilePath, err := GetWorkSpaceFromFilePath(projectConfigFilePath) - if err != nil { - PrintErrorMessageAndExit(fmt.Sprintf("error reading your project config %v", err)) - } - - if workspaceFilePath.WorkspaceId == "" { - PrintErrorMessageAndExit("Your project id is missing in your local config file. Please add it or run again [infisical init]") - } -} - func GetHashFromStringList(list []string) string { hash := sha256.New() @@ -545,3 +518,39 @@ func GenerateETagFromSecrets(secrets []models.SingleEnvironmentVariable) string hash := sha256.Sum256(content) return fmt.Sprintf(`"%s"`, hex.EncodeToString(hash[:])) } + +func GetStringArgument(cmd *cobra.Command, argument string, errorMessage string) string { + value, flagsErr := cmd.Flags().GetString(argument) + if flagsErr != nil { + HandleError(flagsErr, errorMessage) + } + + return value +} + +func GetBooleanArgument(cmd *cobra.Command, argument string, errorMessage string) bool { + value, flagsErr := cmd.Flags().GetBool(argument) + if flagsErr != nil { + HandleError(flagsErr, errorMessage) + } + + return value +} + +func GetIntArgument(cmd *cobra.Command, argument string, errorMessage string) int { + value, flagsErr := cmd.Flags().GetInt(argument) + if flagsErr != nil { + HandleError(flagsErr, errorMessage) + } + + return value +} + +func GetStringSliceArgument(cmd *cobra.Command, argument string, errorMessage string) []string { + value, flagsErr := cmd.Flags().GetStringSlice(argument) + if flagsErr != nil { + HandleError(flagsErr, errorMessage) + } + + return value +} diff --git a/packages/util/log.go b/packages/util/log.go index f5b40533..09ec9807 100644 --- a/packages/util/log.go +++ b/packages/util/log.go @@ -2,6 +2,7 @@ package util import ( "encoding/json" + "flag" "fmt" "net/http" "os" @@ -16,6 +17,10 @@ func HandleError(err error, messages ...string) { PrintErrorAndExit(1, err, messages...) } +func IsTestRun() bool { + return flag.Lookup("test.v") != nil +} + func PrintErrorAndExit(exitCode int, err error, messages ...string) { // Check if it's an API error for special formatting if apiErr, ok := err.(*api.APIError); ok { @@ -36,6 +41,10 @@ func PrintErrorAndExit(exitCode int, err error, messages ...string) { } + if IsTestRun() { + // Panic to allow for recovery and assertion in tests + panic(messages[0]) + } os.Exit(exitCode) } @@ -54,6 +63,10 @@ func PrintErrorMessageAndExit(messages ...string) { } } + if IsTestRun() { + // Panic to allow for recovery and assertion in tests + panic(messages[0]) + } os.Exit(1) } diff --git a/packages/util/secrets.go b/packages/util/secrets.go index ab592e53..b077c652 100644 --- a/packages/util/secrets.go +++ b/packages/util/secrets.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/spf13/cobra" "os" "strings" "unicode" @@ -245,23 +246,12 @@ func FilterSecretsByTag(plainTextSecrets []models.SingleEnvironmentVariable, tag return filteredSecrets } -func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) { +func GetAllEnvironmentVariables(params models.GetAllSecretsParameters) ([]models.SingleEnvironmentVariable, error) { var secretsToReturn []models.SingleEnvironmentVariable // var serviceTokenDetails api.GetServiceTokenDetailsResponse var errorToReturn error if params.InfisicalToken == "" && params.UniversalAuthAccessToken == "" { - if params.WorkspaceId == "" { - if projectConfigFilePath == "" { - _, err := GetWorkSpaceFromFile() - if err != nil { - PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - } else { - ValidateWorkspaceFile(projectConfigFilePath) - } - } - RequireLogin() log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") @@ -281,27 +271,6 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo loggedInUserDetails = EstablishUserLoginSession() } - if params.WorkspaceId == "" { - var infisicalDotJson models.WorkspaceConfigFile - - if projectConfigFilePath == "" { - projectConfig, err := GetWorkSpaceFromFile() - if err != nil { - PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --projectId flag") - } - - infisicalDotJson = projectConfig - } else { - projectConfig, err := GetWorkSpaceFromFilePath(projectConfigFilePath) - if err != nil { - return nil, err - } - - infisicalDotJson = projectConfig - } - params.WorkspaceId = infisicalDotJson.WorkspaceId - } - res, err := GetPlainTextSecretsV3(loggedInUserDetails.UserCredentials.JTWToken, params.WorkspaceId, params.Environment, params.SecretsPath, params.IncludeImport, params.Recursive, params.TagSlugs, true) log.Debug().Msgf("GetAllEnvironmentVariables: Trying to fetch secrets JTW token [err=%s]", err) @@ -510,38 +479,6 @@ func DeleteBackupSecrets() error { return os.RemoveAll(fullPathToSecretsBackupFolder) } -func GetEnvFromWorkspaceFile() string { - workspaceFile, err := GetWorkSpaceFromFile() - if err != nil { - log.Debug().Msgf("getEnvFromWorkspaceFile: [err=%s]", err) - return "" - } - - if env := GetEnvelopmentBasedOnGitBranch(workspaceFile); env != "" { - return env - } - - return workspaceFile.DefaultEnvironment -} - -func GetEnvelopmentBasedOnGitBranch(workspaceFile models.WorkspaceConfigFile) string { - branch, err := getCurrentBranch() - if err != nil { - log.Debug().Msgf("getEnvelopmentBasedOnGitBranch: [err=%s]", err) - } - - envBasedOnGitBranch, ok := workspaceFile.GitBranchToEnvironmentMapping[branch] - - log.Debug().Msgf("GetEnvelopmentBasedOnGitBranch: [envBasedOnGitBranch=%s] [ok=%t]", envBasedOnGitBranch, ok) - - if err == nil && ok { - return envBasedOnGitBranch - } else { - log.Debug().Msgf("getEnvelopmentBasedOnGitBranch: [err=%s]", err) - return "" - } -} - func parseSecrets(fileName string, content string) (map[string]string, error) { secrets := make(map[string]string) @@ -657,7 +594,7 @@ func SetRawSecrets(secretArgs []string, secretType string, environmentName strin httpClient.SetHeader("Accept", "application/json") // pull current secrets - secrets, err := GetAllEnvironmentVariables(getAllEnvironmentVariablesRequest, "") + secrets, err := GetAllEnvironmentVariables(getAllEnvironmentVariablesRequest) if err != nil { return nil, fmt.Errorf("unable to retrieve secrets [err=%v]", err) } @@ -775,5 +712,21 @@ func SetRawSecrets(secretArgs []string, secretType string, environmentName strin } return secretOperations, nil +} + +func GetTokenAndProjectConfigFromCommand(cmd *cobra.Command) (*models.TokenDetails, *models.WorkspaceConfig) { + token, tokenErr := GetInfisicalToken(cmd) + if tokenErr != nil { + HandleError(tokenErr, "Unable to parse flag --token") + } + + projectId := GetStringArgument(cmd, "projectId", "Unable to parse argument --projectId") + + if projectId == "" && token != nil && (token.Type == SERVICE_TOKEN_IDENTIFIER || token.Type == UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { + PrintErrorMessageAndExit("When using service tokens or machine identities, you must set the --projectId flag") + } + + projectConfig := GetWorkspaceConfigFromCommandOrFile(cmd) + return token, &projectConfig }