Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage: add profile flag #453

Merged
merged 17 commits into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from 7 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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## not released yet

#### Features
- Added `--profile` flag to allow users to specify a [named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html). ([#353](https://github.com/peak/s5cmd/issues/353))


## v2.0.0 - 4 Jul 2022

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ s5cmd --use-list-objects-v1 ls s3://bucket/

`s5cmd` uses official AWS SDK to access S3. SDK requires credentials to sign
requests to AWS. Credentials can be provided in a variety of ways:

- Command line options `--profile` to use a [named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) and `--no-sign-request` to send requests anonymously
- Environment variables
- AWS credentials file, including profile selection via `AWS_PROFILE` environment
variable
Expand Down
10 changes: 10 additions & 0 deletions command/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ var app = &cli.App{
Name: "request-payer",
Usage: "who pays for request (access requester pays buckets)",
},
&cli.StringFlag{
Name: "profile",
Usage: "use the specified profile from the credential file",
},
},
Before: func(c *cli.Context) error {
retryCount := c.Int("retry-count")
Expand All @@ -97,6 +101,11 @@ var app = &cli.App{
printError(commandFromContext(c), c.Command.Name, err)
return err
}
if c.Bool("no-sign-request") && c.String("profile") != "" {
err := fmt.Errorf(`"no-sign-request" and "profile" flags cannot be used together`)
printError(commandFromContext(c), c.Command.Name, err)
return err
}

if isStat {
stat.InitStat()
Expand Down Expand Up @@ -162,6 +171,7 @@ func NewStorageOpts(c *cli.Context) storage.Options {
NoVerifySSL: c.Bool("no-verify-ssl"),
RequestPayer: c.String("request-payer"),
UseListObjectsV1: c.Bool("use-list-objects-v1"),
Profile: c.String("profile"),
}
}

Expand Down
4 changes: 3 additions & 1 deletion storage/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,9 @@ func (sc *SessionCache) newSession(ctx context.Context, opts Options) (*session.

if opts.NoSignRequest {
// do not sign requests when making service API calls
awsCfg.Credentials = credentials.AnonymousCredentials
awsCfg = awsCfg.WithCredentials(credentials.AnonymousCredentials)
} else if opts.Profile != "" { // if they provided a profile
seruman marked this conversation as resolved.
Show resolved Hide resolved
awsCfg = awsCfg.WithCredentials(credentials.NewSharedCredentials("", opts.Profile))
}

endpointURL, err := parseEndpoint(opts.Endpoint)
Expand Down
18 changes: 18 additions & 0 deletions storage/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,24 @@ func TestNewSessionWithNoSignRequest(t *testing.T) {
}
}

func TestNewSessionWithProfile(t *testing.T) {
globalSessionCache.clear()
profileName := "default"
igungor marked this conversation as resolved.
Show resolved Hide resolved
sess, err := globalSessionCache.newSession(context.Background(), Options{
Profile: profileName,
})
if err != nil {
t.Fatal(err)
}

got, _ := sess.Config.Credentials.Get()
expected, _ := credentials.NewSharedCredentials("", profileName).Get()

if expected != got {
t.Error("expected profile credentials does not match the credential we got!")
}
}

func TestS3ListURL(t *testing.T) {
url, err := url.New("s3://bucket/key")
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func NewRemoteClient(ctx context.Context, url *url.URL, opts Options) (*S3, erro
NoSignRequest: opts.NoSignRequest,
UseListObjectsV1: opts.UseListObjectsV1,
RequestPayer: opts.RequestPayer,
Profile: opts.Profile,
bucket: url.Bucket,
region: opts.region,
}
Expand All @@ -77,6 +78,7 @@ type Options struct {
NoSignRequest bool
UseListObjectsV1 bool
RequestPayer string
Profile string
bucket string
region string
}
Expand Down