Skip to content
Draft

TBD #19539

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions pkg/storage/chunk/client/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/pkg/errors"
)

// DynamoConfigFromURL returns AWS config from given URL. It expects escaped
Expand Down Expand Up @@ -73,15 +72,17 @@ func DynamoConfigFromURL(awsURL *url.URL) (*dynamodb.Options, error) {
return &config, nil
}

func CredentialsFromURL(awsURL *url.URL) (key, secret, session string, err error) {
func CredentialsFromURL(awsURL *url.URL) (key, secret, session string) {
if awsURL.User != nil {
username := awsURL.User.Username()
password, _ := awsURL.User.Password()

// We request at least the username or password being set to enable the static credentials.
if username != "" || password != "" {
return username, password, "", nil
return username, password, ""
}
}
return "", "", "", errors.New("Unable to build AWS credentials from URL")
// Return empty credentials instead of error to allow AWS SDK to use default credential chain
// (environment variables, IAM roles, etc.)
return "", "", ""
}
59 changes: 59 additions & 0 deletions pkg/storage/chunk/client/aws/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package aws

import (
"net/url"
"testing"

"github.com/stretchr/testify/require"
)

func TestCredentialsFromURL(t *testing.T) {
tests := []struct {
name string
urlStr string
expectedKey string
expectedSecret string
expectedSession string
}{
{
name: "URL with username and password",
urlStr: "s3://mykey:mysecret@us-east-1",
expectedKey: "mykey",
expectedSecret: "mysecret",
expectedSession: "",
},
{
name: "URL with only username",
urlStr: "s3://mykey@us-east-1",
expectedKey: "mykey",
expectedSecret: "",
expectedSession: "",
},
{
name: "URL without credentials (should not error)",
urlStr: "s3://us-east-1",
expectedKey: "",
expectedSecret: "",
expectedSession: "",
},
{
name: "URL with endpoint without credentials",
urlStr: "s3://s3.amazonaws.com",
expectedKey: "",
expectedSecret: "",
expectedSession: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
u, err := url.Parse(tt.urlStr)
require.NoError(t, err)

key, secret, session := CredentialsFromURL(u)
require.Equal(t, tt.expectedKey, key)
require.Equal(t, tt.expectedSecret, secret)
require.Equal(t, tt.expectedSession, session)
})
}
}
10 changes: 6 additions & 4 deletions pkg/storage/chunk/client/aws/s3_storage_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,13 @@ func buildS3Client(cfg S3Config, hedgingCfg hedging.Config, hedging bool) (*s3.C

// if an s3 url is passed use it to initialize the s3Config and then override with any additional params
if cfg.S3.URL != nil {
key, secret, session, err := CredentialsFromURL(cfg.S3.URL)
if err != nil {
return nil, err
key, secret, session := CredentialsFromURL(cfg.S3.URL)

// Only set credentials if they were provided in the URL
// Otherwise, let AWS SDK use the default credential chain
if key != "" || secret != "" {
s3Options.Credentials = credentials.NewStaticCredentialsProvider(key, secret, session)
}
s3Options.Credentials = credentials.NewStaticCredentialsProvider(key, secret, session)
} else {
s3Options.Region = "dummy"
}
Expand Down
Loading