diff --git a/cli/exec.go b/cli/exec.go index 2ccd26aa9..68d184f6b 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -109,10 +109,6 @@ func ConfigureExecCommand(app *kingpin.Application, a *AwsVault) { StringsVar(&input.Args) cmd.Action(func(c *kingpin.ParseContext) (err error) { - if input.JSONDeprecated { - return fmt.Errorf("The --json option has been removed, use `aws-vault export --json` instead") - } - input.Config.MfaPromptMethod = a.PromptDriver input.Config.NonChainedGetSessionTokenDuration = input.SessionDuration input.Config.AssumeRoleDuration = input.SessionDuration @@ -127,7 +123,20 @@ func ConfigureExecCommand(app *kingpin.Application, a *AwsVault) { return err } - err = ExecCommand(input, f, keyring) + if input.JSONDeprecated { + exportCommandInput := ExportCommandInput{ + ProfileName: input.ProfileName, + Format: "json", + Config: input.Config, + SessionDuration: input.SessionDuration, + NoSession: input.NoSession, + } + + err = ExportCommand(exportCommandInput, f, keyring) + } else { + err = ExecCommand(input, f, keyring) + } + app.FatalIfError(err, "exec") return nil }) diff --git a/cli/export.go b/cli/export.go index 20bd6cd65..a03b0d222 100644 --- a/cli/export.go +++ b/cli/export.go @@ -16,17 +16,24 @@ import ( type ExportCommandInput struct { ProfileName string - JSON bool + Format string Config vault.Config SessionDuration time.Duration NoSession bool UseStdout bool } +var ( + FormatTypeEnv = "env" + FormatTypeExportEnv = "export-env" + FormatTypeExportJSON = "json" + FormatTypeExportINI = "ini" +) + func ConfigureExportCommand(app *kingpin.Application, a *AwsVault) { input := ExportCommandInput{} - cmd := app.Command("export", "Export AWS credentials") + cmd := app.Command("export", "Export AWS credentials in env, export-env, json or ini format") cmd.Flag("duration", "Duration of the temporary or assume-role session. Defaults to 1h"). Short('d'). @@ -43,9 +50,9 @@ func ConfigureExportCommand(app *kingpin.Application, a *AwsVault) { Short('t'). StringVar(&input.Config.MfaToken) - cmd.Flag("json", "Output credentials in JSON that can be used by credential_process"). - Short('j'). - BoolVar(&input.JSON) + cmd.Flag("format", fmt.Sprintf("Format to output credentials. Valid values are %s, %s and %s", FormatTypeEnv, FormatTypeExportEnv, FormatTypeExportJSON)). + Default(FormatTypeEnv). + EnumVar(&input.Format, FormatTypeEnv, FormatTypeExportEnv, FormatTypeExportJSON, FormatTypeExportINI) cmd.Flag("stdout", "Print the SSO link to the terminal without automatically opening the browser"). BoolVar(&input.UseStdout) @@ -99,14 +106,18 @@ func ExportCommand(input ExportCommandInput, f *vault.ConfigFile, keyring keyrin return fmt.Errorf("Error getting temporary credentials: %w", err) } - if input.JSON { - return exportJSON(input, credsProvider) + if input.Format == FormatTypeExportJSON { + return printJSON(input, credsProvider) + } else if input.Format == FormatTypeExportINI { + return printINI(input, credsProvider) + } else if input.Format == FormatTypeExportEnv { + return printEnv(input, credsProvider, "export ") + } else { + return printEnv(input, credsProvider, "") } - - return exportEnv(input, credsProvider) } -func exportJSON(input ExportCommandInput, credsProvider aws.CredentialsProvider) error { +func printJSON(input ExportCommandInput, credsProvider aws.CredentialsProvider) error { // AwsCredentialHelperData is metadata for AWS CLI credential process // See https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#sourcing-credentials-from-external-processes type AwsCredentialHelperData struct { @@ -133,32 +144,49 @@ func exportJSON(input ExportCommandInput, credsProvider aws.CredentialsProvider) credentialData.Expiration = iso8601.Format(creds.Expires) } - json, err := json.Marshal(&credentialData) + json, err := json.MarshalIndent(&credentialData, "", " ") if err != nil { return fmt.Errorf("Error creating credential json: %w", err) } - fmt.Print(string(json)) + fmt.Print(string(json) + "\n") + + return nil +} + +func printINI(input ExportCommandInput, credsProvider aws.CredentialsProvider) error { + creds, err := credsProvider.Retrieve(context.TODO()) + if err != nil { + return fmt.Errorf("Failed to get credentials for %s: %w", input.ProfileName, err) + } + + fmt.Printf("[%s]\n", input.ProfileName) + fmt.Printf("aws_access_key_id=%s\n", creds.AccessKeyID) + fmt.Printf("aws_secret_access_key=%s\n", creds.SecretAccessKey) + if creds.SessionToken != "" { + fmt.Printf("aws_session_token=%s\n", creds.SessionToken) + } + if creds.CanExpire { + fmt.Printf(";aws_credential_expiration=%s\n", iso8601.Format(creds.Expires)) + } return nil } -func exportEnv(input ExportCommandInput, credsProvider aws.CredentialsProvider) error { +func printEnv(input ExportCommandInput, credsProvider aws.CredentialsProvider, prefix string) error { creds, err := credsProvider.Retrieve(context.TODO()) if err != nil { return fmt.Errorf("Failed to get credentials for %s: %w", input.ProfileName, err) } - fmt.Printf("AWS_ACCESS_KEY_ID=%s\n", creds.AccessKeyID) - fmt.Printf("AWS_SECRET_ACCESS_KEY=%s\n", creds.SecretAccessKey) + fmt.Printf("%sAWS_ACCESS_KEY_ID=%s\n", prefix, creds.AccessKeyID) + fmt.Printf("%sAWS_SECRET_ACCESS_KEY=%s\n", prefix, creds.SecretAccessKey) if creds.SessionToken != "" { - fmt.Printf("AWS_SESSION_TOKEN=%s\n", creds.SessionToken) - fmt.Printf("AWS_SECURITY_TOKEN=%s\n", creds.SessionToken) + fmt.Printf("%sAWS_SESSION_TOKEN=%s\n", prefix, creds.SessionToken) } if creds.CanExpire { - fmt.Printf("AWS_CREDENTIAL_EXPIRATION=%s\n", iso8601.Format(creds.Expires)) - fmt.Printf("AWS_SESSION_EXPIRATION=%s\n", iso8601.Format(creds.Expires)) + fmt.Printf("%sAWS_CREDENTIAL_EXPIRATION=%s\n", prefix, iso8601.Format(creds.Expires)) } return nil }