Skip to content

Commit

Permalink
Assume IAM role for EBS provider (#239)
Browse files Browse the repository at this point in the history
* Adds support for assume role in EBS provider code.
  • Loading branch information
Hakan Memisoglu committed Sep 10, 2019
1 parent b2c48f0 commit 3022763
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
33 changes: 21 additions & 12 deletions pkg/blockstorage/awsebs/awsebs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
Expand All @@ -42,6 +44,7 @@ var _ zone.Mapper = (*ebsStorage)(nil)

type ebsStorage struct {
ec2Cli *EC2
role string
}

// EC2 is kasten's wrapper around ec2.EC2 structs
Expand All @@ -60,26 +63,32 @@ func (s *ebsStorage) Type() blockstorage.Type {

// NewProvider returns a provider for the EBS storage type in the specified region
func NewProvider(config map[string]string) (blockstorage.Provider, error) {
awsConfig, region, _, err := awsconfig.GetConfig(config)
awsConfig, region, role, err := awsconfig.GetConfig(config)
if err != nil {
return nil, err
}
ec2Cli, err := newEC2Client(region, awsConfig)
ec2Cli, err := newEC2Client(region, awsConfig, role)
if err != nil {
return nil, errors.Wrapf(err, "Could not get EC2 client")
}
return &ebsStorage{ec2Cli: ec2Cli}, nil
return &ebsStorage{ec2Cli: ec2Cli, role: role}, nil
}

// newEC2Client returns ec2 client struct.
func newEC2Client(awsRegion string, config *aws.Config) (*EC2, error) {
httpClient := &http.Client{Transport: http.DefaultTransport}
func newEC2Client(awsRegion string, config *aws.Config, role string) (*EC2, error) {
s, err := session.NewSession(config)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "Failed to create session for EFS")
}
var creds *credentials.Credentials
if config != nil {
creds = config.Credentials
}
if role != "" {
creds = stscreds.NewCredentials(s, role)
}
return &EC2{EC2: ec2.New(s, &aws.Config{MaxRetries: aws.Int(maxRetries),
Region: aws.String(awsRegion), HTTPClient: httpClient})}, nil
conf := config.WithMaxRetries(maxRetries).WithRegion(awsRegion).WithCredentials(creds)
return &EC2{EC2: ec2.New(s, conf)}, nil
}

func (s *ebsStorage) VolumeCreate(ctx context.Context, volume blockstorage.Volume) (*blockstorage.Volume, error) {
Expand Down Expand Up @@ -221,15 +230,15 @@ func (s *ebsStorage) SnapshotCopy(ctx context.Context, from, to blockstorage.Sna
return nil, errors.Errorf("Snapshot %v destination ID must be empty", to)
}
// Copy operation must be initiated from the destination region.
ec2Cli, err := newEC2Client(to.Region, nil)
ec2Cli, err := newEC2Client(to.Region, nil, s.role)
if err != nil {
return nil, errors.Wrapf(err, "Could not get EC2 client")
}
// Include a presigned URL when the regions are different. Include it
// independent of whether or not the snapshot is encrypted.
var presignedURL *string
if to.Region != from.Region {
fromCli, err2 := newEC2Client(from.Region, nil)
fromCli, err2 := newEC2Client(from.Region, nil, s.role)
if err2 != nil {
return nil, errors.Wrap(err2, "Could not create client to presign URL for snapshot copy request")
}
Expand Down Expand Up @@ -590,8 +599,8 @@ func (s *ebsStorage) FromRegion(ctx context.Context, region string) ([]string, e
return staticRegionToZones(region)
}

func queryRegionToZones(ctx context.Context, region string) ([]string, error) {
ec2Cli, err := newEC2Client(region, nil)
func (s *ebsStorage) queryRegionToZones(ctx context.Context, region string) ([]string, error) {
ec2Cli, err := newEC2Client(region, nil, s.role)
if err != nil {
return nil, errors.Wrapf(err, "Could not get EC2 client")
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/blockstorage/awsebs/awsebs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ func (s AWSEBSSuite) TestQueryRegionToZones(c *C) {
c.Skip("Only works on AWS")
ctx := context.Background()
region := "us-east-1"
zs, err := queryRegionToZones(ctx, region)
ec2Cli, err := newEC2Client(region, nil, "")
c.Assert(err, IsNil)
provider := &ebsStorage{ec2Cli: ec2Cli}
zs, err := provider.queryRegionToZones(ctx, region)
c.Assert(err, IsNil)
c.Assert(zs, DeepEquals, []string{"us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e", "us-east-1f"})
}

0 comments on commit 3022763

Please sign in to comment.