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

S3 assume role support #290

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.12

replace (
cloud.google.com/go => github.com/GoogleCloudPlatform/google-cloud-go v0.1.1-0.20160913182117-3b1ae45394a2
github.com/graymeta/stow => github.com/kastenhq/stow v0.1.1-kasten
github.com/graymeta/stow => github.com/kastenhq/stow v0.1.2-kasten
github.com/rook/operator-kit => github.com/kastenhq/operator-kit v0.0.0-20180316185208-859e831cc18d
)

Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kastenhq/stow v0.1.1-kasten h1:0IuykRy/KfqUttO2n6w3XTJzyFhSThXeE5UtKvstmYs=
github.com/kastenhq/stow v0.1.1-kasten/go.mod h1:ABI2whmZOX25JbmbVuHRLFuPiGnv5lxXhduCtof7UHk=
github.com/kastenhq/stow v0.1.2-kasten h1:3msAbg6woEPWzYaBPmsOY4a0V55QosWD86XMOE+gDbM=
github.com/kastenhq/stow v0.1.2-kasten/go.mod h1:ABI2whmZOX25JbmbVuHRLFuPiGnv5lxXhduCtof7UHk=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
Expand Down Expand Up @@ -200,6 +202,7 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/softlayer/softlayer-go v0.0.0-20190615201252-ba6e7f295217 h1:MFHQI+AYM6otrSP+l3dLhE2DjrSr5HXfV4mt4M6pjPs=
github.com/softlayer/softlayer-go v0.0.0-20190615201252-ba6e7f295217/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw=
Expand Down Expand Up @@ -268,6 +271,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/cr/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ type Profile struct {
Location Location `json:"location"`
Credential Credential `json:"credential"`
SkipSSLVerify bool `json:"skipSSLVerify"`
Role string `json:"role"`
}

// LocationType
Expand Down
1 change: 1 addition & 0 deletions pkg/location/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func getBucket(ctx context.Context, pType objectstore.ProviderType, profile para
Type: pType,
Endpoint: profile.Location.Endpoint,
SkipSSLVerify: profile.SkipSSLVerify,
Role: profile.Role,
}
secret, err := getOSSecret(pType, profile.Credential)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions pkg/objectstore/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
Expand All @@ -40,6 +42,29 @@ func config(region string) *aws.Config {
return c
}

type awsCreds struct {
accessKeyID string
secretAccessKey string
token string
}

// switchRole changes the role using the credentials provider.
// It returns the new set of credentials.
func switchRole(awsAccessKeyID, awsSecretAccessKey, role string) (*awsCreds, error) {
creds := credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, role)
sess := session.New(aws.NewConfig().WithCredentials(creds))
creds = stscreds.NewCredentials(sess, role)
val, err := creds.Get()
if err != nil {
return nil, errors.Wrap(err, "Failed to get role credentials")
}
return &awsCreds{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: not for this PR, but we should consider using the AWS type credential.Value

accessKeyID: val.AccessKeyID,
secretAccessKey: val.SecretAccessKey,
token: val.SessionToken,
}, nil
}

func IsBucketNotFoundError(err error) bool {
if err == nil {
return false
Expand Down
2 changes: 2 additions & 0 deletions pkg/objectstore/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type ProviderConfig struct {
// If true, disable SSL verification. If false (the default), SSL
// verification is enabled.
SkipSSLVerify bool
// If given, the object store access will be established after switching to the role.
Role string
}

// SecretAws AWS keys
Expand Down
12 changes: 12 additions & 0 deletions pkg/objectstore/objectstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ func s3Config(config ProviderConfig, secret *Secret, region string) (stowKind st
stows3.ConfigAccessKeyID: awsAccessKeyID,
stows3.ConfigSecretKey: awsSecretAccessKey,
}
if config.Role != "" {
// Switch role and replace credentials.
creds, err := switchRole(awsAccessKeyID, awsSecretAccessKey, config.Role)
if err != nil {
return "", cm, errors.New("Failed to switch role")
}
cm = stow.ConfigMap{
stows3.ConfigAccessKeyID: creds.accessKeyID,
stows3.ConfigSecretKey: creds.secretAccessKey,
stows3.ConfigToken: creds.token,
}
}
if region != "" {
cm[stows3.ConfigRegion] = region
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/objectstore/objectstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type ObjectStoreProviderSuite struct {
osType ProviderType
provider Provider
rand *rand.Rand
role string
root Bucket // root of the default test bucket
suiteDirPrefix string // directory name prefix for all tests in this suite
testDir string // directory name for a given test
Expand All @@ -48,9 +49,11 @@ type ObjectStoreProviderSuite struct {
const (
testBucketName = "kio-store-tests"
testRegionS3 = "us-west-2"
testRole = ""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to create a role for Kanister test purpose, and make it settable by environment variables.

)

var _ = Suite(&ObjectStoreProviderSuite{osType: ProviderTypeS3, region: testRegionS3})
var _ = Suite(&ObjectStoreProviderSuite{osType: ProviderTypeS3, region: testRegionS3, role: testRole})
var _ = Suite(&ObjectStoreProviderSuite{osType: ProviderTypeGCS, region: ""})
var _ = Suite(&ObjectStoreProviderSuite{osType: ProviderTypeAzure, region: ""})

Expand All @@ -72,7 +75,7 @@ func (s *ObjectStoreProviderSuite) SetUpSuite(c *C) {
ctx := context.Background()

s.rand = rand.New(rand.NewSource(time.Now().UnixNano()))
pc := ProviderConfig{Type: s.osType}
pc := ProviderConfig{Type: s.osType, Role: s.role}
secret := getSecret(c, s.osType)
s.provider, err = NewProvider(ctx, pc, secret)
c.Check(err, IsNil)
Expand Down
1 change: 1 addition & 0 deletions pkg/param/param.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type Profile struct {
Location crv1alpha1.Location
Credential Credential
SkipSSLVerify bool
Role string
}

// CredentialType
Expand Down
2 changes: 2 additions & 0 deletions pkg/validate/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ func ReadAccess(ctx context.Context, p *crv1alpha1.Profile, cli kubernetes.Inter
Type: pType,
Endpoint: p.Location.Endpoint,
SkipSSLVerify: p.SkipSSLVerify,
Role: p.Role,
}
provider, err := objectstore.NewProvider(ctx, pc, secret)
if err != nil {
Expand Down Expand Up @@ -257,6 +258,7 @@ func WriteAccess(ctx context.Context, p *crv1alpha1.Profile, cli kubernetes.Inte
Type: pType,
Endpoint: p.Location.Endpoint,
SkipSSLVerify: p.SkipSSLVerify,
Role: p.Role,
}
provider, err := objectstore.NewProvider(ctx, pc, secret)
if err != nil {
Expand Down