Skip to content

Commit

Permalink
Export in a variety of formats
Browse files Browse the repository at this point in the history
  • Loading branch information
mtibben committed Feb 16, 2023
1 parent d6cfad2 commit 756d2ac
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 24 deletions.
19 changes: 14 additions & 5 deletions cli/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
})
Expand Down
66 changes: 47 additions & 19 deletions cli/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -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').
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -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
}

0 comments on commit 756d2ac

Please sign in to comment.