api: Add NewWithCredentials()#646
Conversation
61a6d51 to
7357588
Compare
7357588 to
47bede5
Compare
47bede5 to
ca93984
Compare
| } | ||
| filename = filepath.Join(homeDir, ".mc", "config.json") | ||
| if runtime.GOOS == "windows" { | ||
| filepath.Join(homeDir, "mc", "config.json") |
ca93984 to
cf59834
Compare
| if endpoint == "" { | ||
| // IAM Roles for Amazon EC2 | ||
| // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html | ||
| endpoint = "http://169.254.169.254" |
There was a problem hiding this comment.
Nope it is only accessible from inside EC2 instance.
| if err != nil { | ||
| return nil, err | ||
| } | ||
| resp, err := client.Do(req) |
| } | ||
|
|
||
| if err := s.Err(); err != nil { | ||
| return nil, errors.New("Failed to read from IAM metadata service") |
There was a problem hiding this comment.
I think it is bettter to append s.Err() to the returned error here.
| if err != nil { | ||
| return ec2RoleCredRespBody{}, err | ||
| } | ||
| u.Path = path.Join(iamSecurityCredsPath, credsName) |
There was a problem hiding this comment.
Shouldn't we encode credsName here ?
There was a problem hiding this comment.
actually its not needed.. u.String() encodes it.
| return ec2RoleCredRespBody{}, err | ||
| } | ||
|
|
||
| resp, err := client.Do(req) |
| if e.CurrentTime == nil { | ||
| e.CurrentTime = time.Now | ||
| } | ||
| return e.expiration.Before(e.CurrentTime()) |
There was a problem hiding this comment.
No Before is correct. Read it as expiration time is before current time.
There was a problem hiding this comment.
oh yes sorry, probably it is easier to read e.CurrentTime().After(e.expiration)
There was a problem hiding this comment.
But usually it is better to use on the left side what you are validating against. Otherwise it would look like currentTime() is what we are validating not expiration.
| } | ||
|
|
||
| // isExpired helper method wrapping the definition of expired credentials. | ||
| func (c *Info) isExpired() bool { |
There was a problem hiding this comment.
This function doesn't seem to be useful, you can merge it in IsExpired()
There was a problem hiding this comment.
isExpired() is used at two places one in Get() and another is IsExpired()
There was a problem hiding this comment.
isExpired() is used at two places one in Get() and another is IsExpired()
yes, right.
|
Some missing LICENCES in some files |
Yeah will add license at the end. |
cf59834 to
7c477e9
Compare
|
@harshavardhana - is this ready for merge? |
Not yet waiting on Mattermost. |
| // NewIAM returns a pointer to a new Credentials object wrapping | ||
| // the IAM. Takes a ConfigProvider to create a EC2Metadata client. | ||
| // The ConfigProvider is satisfied by the session.Session type. | ||
| func NewIAM(endpoint string) *Info { |
There was a problem hiding this comment.
I think this API needs to accept a role name as a parameter, not only endpoint. The application needs to get credentials from the right role name before performing the needed action which is only authorized by that role.
There was a problem hiding this comment.
RoleName is not needed since the IAM RoleName is attached to the EC2 instance where the GET originates. So you are bound to be under the RoleName already.
Why do you think it is necessary?
There was a problem hiding this comment.
Yes, you are right. I thought we can attach multiple IAM roles to one instance but we can only set one. (which is weird by the way and looks painful for the users)
I found this here, http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
You *cannot* attach multiple IAM roles to a single instance, but you can attach a single IAM role to multiple instances. For more information about creating and using IAM roles,
8c3242f to
7a6ce85
Compare
0eb4826 to
8deedd1
Compare
| // Different types of supported signatures - default is Latest i.e SignatureV4. | ||
| const ( | ||
| Latest SignatureType = iota | ||
| // Default signature is always V4. |
There was a problem hiding this comment.
comment on exported const SignatureDefault should be of the form "SignatureDefault ..."
fdadb5b to
46c196c
Compare
|
Unblocking and ready for review @vadmeste |
46c196c to
d008c7d
Compare
| signerType = parseSignatureType(value.SignatureType) | ||
| } | ||
|
|
||
| // FIXME: Session token should be supported. |
There was a problem hiding this comment.
This can't be fixed in this PR ?
There was a problem hiding this comment.
Spec is little vague on post policy about this. Will need to explore more.
| // ask for anything specific signature style.. Check if the | ||
| // credentials set returned the type of signature that should | ||
| // be used, if not proceed to use default. | ||
| if signerType == SignatureDefault && value.SignatureType != "" { |
There was a problem hiding this comment.
I think that the signature type that comes from config, if it exists, should override the one specified in the application code. That way, we can give users more power to configure.
There was a problem hiding this comment.
Actually no. We have methods to override that see NewV4 and NewV2. We need to honor that. Since they don't take dynamic credentials.
| c.secretAccessKey, location, metadata.contentLength, time.Now().UTC()) | ||
| req = s3signer.SignV2(*req, accessKeyID, secretAccessKey) | ||
| case signerType.isStreamingV4() && method == "PUT": | ||
| req = s3signer.StreamingSignV4(req, accessKeyID, |
There was a problem hiding this comment.
Need to figure it out .. not sure right now.
|
|
||
| // IsExpired returns if the credentials have been retrieved. | ||
| func (e *EnvAWS) IsExpired() bool { | ||
| return !e.retrieved |
There was a problem hiding this comment.
This probably should always return true. A user can change his environment variables inside his application (who knows), and also it is no harm if we fetch from the environment each time Retrieve() is called.
There was a problem hiding this comment.
That we already do.. it is to indicate if envs can ever be expired. They cannot be. It is not correct to call it not expired.. basically envs are similar to static creds in their behavior.
|
|
||
| import "fmt" | ||
|
|
||
| // A Chain will search for a provider which returns credentials |
There was a problem hiding this comment.
This is well thought, I wasn't able to criticize this.
d008c7d to
9c88e6d
Compare
90f7686 to
f43530b
Compare
| return nil, nil, err | ||
| } | ||
|
|
||
| if sessionToken != "" { |
b0ba992 to
64743cc
Compare
|
|
||
| // NewStatic returns a pointer to a new Credentials object | ||
| // wrapping a static credentials value provider. | ||
| func NewStatic(id, secret, token, signerType string) *Credentials { |
There was a problem hiding this comment.
Isn't better to create a new exported signature data type and use it instead of string ? that way the user would be less prone to error since any typo will make this module uses anonymous.
There was a problem hiding this comment.
Actually it can be simplified..
64743cc to
414b641
Compare
|
|
||
| // NewFileAWSCredentials returns a pointer to a new Credentials object | ||
| // wrapping the Profile file provider. | ||
| func NewFileAWSCredentials(filename string, profile string) (*Credentials, error) { |
There was a problem hiding this comment.
NewFileAWSCredentials and NewFileMinioClient are always returnig nil, shall we remove the returned error ? if we do, it will be like other New() primitive for static, IAM and envs.
There was a problem hiding this comment.
Yes looks like older problem. Will fix
This PR adds a new API
- NewWithCredentials()
Internally NewWithCredentials is now used with
all APIs such as New(), NewV4(), NewV2() and NewWithRegion.
Also brings a new package called `credentials` to manage
various credentials type, currently the credentials
package supports
- Reading file from `.aws/credentials`, `.mc/config.json`
- Reading env variables for AWS*, MINIO*
- Fetching from IAM roles assigned to an EC2 instance.
- Static credentials which is the current default behavior.
Example code using IAM.
```go
iam := credentials.NewIAM("")
s3Client, err := minio.NewWithCredentials("s3.amazonaws.com", iam, true, "")
if err != nil {
log.Fatalln(err)
}
buckets, err := s3Client.ListBuckets()
if err != nil {
log.Fatalln(err)
}
for _, bucket := range buckets {
log.Println(bucket)
}
```
Fixes minio#643
414b641 to
56cfb04
Compare
This PR adds a new API
Internally NewWithCredentials is now used with
all APIs such as New(), NewV4(), NewV2() and NewWithRegion.
Also brings a new package called
credentialsto managevarious credentials type, currently the credentials
package supports
.aws/credentials,.mc/config.jsonExample code using IAM.
Fixes #643