Skip to content

Commit a75e93a

Browse files
committed
Use current region to find bucket region
1 parent 67c4e22 commit a75e93a

File tree

3 files changed

+50
-23
lines changed

3 files changed

+50
-23
lines changed

s3secrets-helper/main.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ const (
1616
envPipeline = "BUILDKITE_PIPELINE_SLUG"
1717
envRepo = "BUILDKITE_REPO"
1818
envCredHelper = "BUILDKITE_PLUGIN_S3_SECRETS_CREDHELPER"
19-
20-
envDefaultRegion = "AWS_DEFAULT_REGION"
21-
defaultRegion = "us-east-1"
2219
)
2320

2421
func main() {
@@ -42,11 +39,7 @@ func mainWithError(log *log.Logger) error {
4239
return fmt.Errorf("%s or %s required", envPrefix, envPipeline)
4340
}
4441

45-
region := os.Getenv(envDefaultRegion)
46-
if region == "" {
47-
region = defaultRegion
48-
}
49-
client, err := s3.New(region)
42+
client, err := s3.New(bucket)
5043
if err != nil {
5144
return err
5245
}

s3secrets-helper/s3/s3.go

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,70 @@ package s3
22

33
import (
44
"io/ioutil"
5+
"os"
56

67
"github.com/aws/aws-sdk-go/aws"
78
"github.com/aws/aws-sdk-go/aws/awserr"
9+
"github.com/aws/aws-sdk-go/aws/ec2metadata"
810
"github.com/aws/aws-sdk-go/aws/session"
911
"github.com/aws/aws-sdk-go/service/s3"
12+
"github.com/aws/aws-sdk-go/service/s3/s3manager"
1013
"github.com/buildkite/elastic-ci-stack-s3-secrets-hooks/s3secrets-helper/v2/sentinel"
1114
)
1215

16+
const envDefaultRegion = "AWS_DEFAULT_REGION"
17+
1318
type Client struct {
1419
s3 *s3.S3
20+
bucket string
1521
}
1622

17-
func New(region string) (*Client, error) {
18-
sess, err := session.NewSession(&aws.Config{
19-
Region: &region,
23+
func New(bucket string) (*Client, error) {
24+
sess, err := session.NewSession()
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
currentRegion := os.Getenv(envDefaultRegion)
30+
// Discover our executing region using the IMDS
31+
if currentRegion == "" {
32+
idms := ec2metadata.New(sess)
33+
currentRegion, _ = idms.Region()
34+
}
35+
// Fall back to us-east-1 :(
36+
if currentRegion == "" {
37+
currentRegion = "us-east-1"
38+
}
39+
40+
// Using the current region (or a guess) find where the bucket lives
41+
bucketRegion, err := s3manager.GetBucketRegion(aws.BackgroundContext(), sess, bucket, currentRegion)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
sess, err = session.NewSession(&aws.Config{
47+
Region: &bucketRegion,
2048
})
2149
if err != nil {
2250
return nil, err
2351
}
2452
return &Client{
2553
s3: s3.New(sess),
54+
bucket: bucket,
2655
}, nil
2756
}
2857

58+
func (c *Client) Bucket() (string) {
59+
return c.bucket
60+
}
61+
2962
// Get downloads an object from S3.
3063
// Intended for small files; object is fully read into memory.
3164
// sentinel.ErrNotFound and sentinel.ErrForbidden are returned for those cases.
3265
// Other errors are returned verbatim.
33-
func (c *Client) Get(bucket, key string) ([]byte, error) {
66+
func (c *Client) Get(key string) ([]byte, error) {
3467
out, err := c.s3.GetObject(&s3.GetObjectInput{
35-
Bucket: &bucket,
68+
Bucket: &c.bucket,
3669
Key: &key,
3770
})
3871
if err != nil {
@@ -59,8 +92,8 @@ func (c *Client) Get(bucket, key string) ([]byte, error) {
5992
// 200 OK returns true without error.
6093
// 404 Not Found and 403 Forbidden return false without error.
6194
// Other errors result in false with an error.
62-
func (c *Client) BucketExists(bucket string) (bool, error) {
63-
if _, err := c.s3.HeadBucket(&s3.HeadBucketInput{Bucket: &bucket}); err != nil {
95+
func (c *Client) BucketExists() (bool, error) {
96+
if _, err := c.s3.HeadBucket(&s3.HeadBucketInput{Bucket: &c.bucket}); err != nil {
6497
if aerr, ok := err.(awserr.Error); ok {
6598
switch aerr.Code() {
6699
// https://github.com/aws/aws-sdk-go/issues/2593#issuecomment-491436818

s3secrets-helper/secrets/secrets.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import (
1212

1313
// Client represents interaction with AWS S3
1414
type Client interface {
15-
Get(bucket, key string) ([]byte, error)
16-
BucketExists(bucket string) (bool, error)
15+
Bucket() (string)
16+
Get(key string) ([]byte, error)
17+
BucketExists() (bool, error)
1718
}
1819

1920
// Agent represents interaction with an ssh-agent process
@@ -56,12 +57,12 @@ type Config struct {
5657
// functionality; secrets are downloaded from S3, and loaded into ssh-agent
5758
// etc.
5859
func Run(conf Config) error {
59-
bucket := conf.Bucket
60+
bucket := conf.Client.Bucket()
6061
log := conf.Logger
6162

6263
log.Printf("~~~ Downloading secrets from :s3: %s", bucket)
6364

64-
if ok, err := conf.Client.BucketExists(bucket); !ok {
65+
if ok, err := conf.Client.BucketExists(); !ok {
6566
if err != nil {
6667
log.Printf("+++ :warning: Bucket %q not found: %v", bucket, err)
6768
} else {
@@ -102,7 +103,7 @@ func getSSHKeys(conf Config, results chan<- getResult) {
102103
for _, k := range keys {
103104
conf.Logger.Printf("- %s", k)
104105
}
105-
go GetAll(conf.Client, conf.Bucket, keys, results)
106+
go GetAll(conf.Client, conf.Client.Bucket(), keys, results)
106107
}
107108

108109
func getEnvs(conf Config, results chan<- getResult) {
@@ -116,7 +117,7 @@ func getEnvs(conf Config, results chan<- getResult) {
116117
for _, k := range keys {
117118
conf.Logger.Printf("- %s", k)
118119
}
119-
go GetAll(conf.Client, conf.Bucket, keys, results)
120+
go GetAll(conf.Client, conf.Client.Bucket(), keys, results)
120121
}
121122

122123
func getGitCredentials(conf Config, results chan<- getResult) {
@@ -128,7 +129,7 @@ func getGitCredentials(conf Config, results chan<- getResult) {
128129
for _, k := range keys {
129130
conf.Logger.Printf("- %s", k)
130131
}
131-
go GetAll(conf.Client, conf.Bucket, keys, results)
132+
go GetAll(conf.Client, conf.Client.Bucket(), keys, results)
132133
}
133134

134135
func handleSSHKeys(conf Config, results <-chan getResult) error {
@@ -241,7 +242,7 @@ func GetAll(c Client, bucket string, keys []string, results chan<- getResult) {
241242
// goroutine immediately fetches from S3, then waits for its turn to send
242243
// to the results channel; concurrent fetch, ordered results.
243244
go func(k string, link <-chan chan<- getResult, nextLink chan<- chan<- getResult) {
244-
data, err := c.Get(bucket, k)
245+
data, err := c.Get(k)
245246
results := <-link // wait for results channel from previous goroutine
246247
results <- getResult{bucket: bucket, key: k, data: data, err: err}
247248
nextLink <- results // send results channel to the next goroutine

0 commit comments

Comments
 (0)