logical/aws: refactor access key create to the secret file
This commit is contained in:
parent
665cbaa3e4
commit
05246433bb
|
@ -2,8 +2,6 @@ package aws
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/aws-sdk-go/aws"
|
||||
"github.com/hashicorp/aws-sdk-go/gen/iam"
|
||||
|
@ -30,79 +28,21 @@ func pathUser(b *backend) *framework.Path {
|
|||
|
||||
func (b *backend) pathUserRead(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
client, err := clientIAM(req.Storage)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(err.Error()), nil
|
||||
}
|
||||
policyName := d.Get("name").(string)
|
||||
|
||||
// Read the policy
|
||||
policy, err := req.Storage.Get("policy/" + d.Get("name").(string))
|
||||
policy, err := req.Storage.Get("policy/" + policyName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving policy: %s", err)
|
||||
}
|
||||
if policy == nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Policy '%s' not found", d.Get("name").(string))), nil
|
||||
"Policy '%s' not found", policyName)), nil
|
||||
}
|
||||
|
||||
// Generate a random username. We don't put the policy names in the
|
||||
// username because the AWS console makes it pretty easy to see that.
|
||||
username := fmt.Sprintf("vault-%d-%d", time.Now().Unix(), rand.Int31n(10000))
|
||||
|
||||
// Write to the WAL that this user will be created. We do this before
|
||||
// the user is created because if switch the order then the WAL put
|
||||
// can fail, which would put us in an awkward position: we have a user
|
||||
// we need to rollback but can't put the WAL entry to do the rollback.
|
||||
walId, err := framework.PutWAL(req.Storage, "user", &walUser{
|
||||
UserName: username,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error writing WAL entry: %s", err)
|
||||
}
|
||||
|
||||
// Create the user
|
||||
_, err = client.CreateUser(&iam.CreateUserRequest{
|
||||
UserName: aws.String(username),
|
||||
})
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Error creating IAM user: %s", err)), nil
|
||||
}
|
||||
|
||||
// Add the user to all the groups
|
||||
err = client.PutUserPolicy(&iam.PutUserPolicyRequest{
|
||||
UserName: aws.String(username),
|
||||
PolicyName: aws.String(d.Get("name").(string)),
|
||||
PolicyDocument: aws.String(string(policy.Value)),
|
||||
})
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Error adding user to group: %s", err)), nil
|
||||
}
|
||||
|
||||
// Create the keys
|
||||
keyResp, err := client.CreateAccessKey(&iam.CreateAccessKeyRequest{
|
||||
UserName: aws.String(username),
|
||||
})
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Error creating access keys: %s", err)), nil
|
||||
}
|
||||
|
||||
// Remove the WAL entry, we succeeded! If we fail, we don't return
|
||||
// the secret because it'll get rolled back anyways, so we have to return
|
||||
// an error here.
|
||||
if err := framework.DeleteWAL(req.Storage, walId); err != nil {
|
||||
return nil, fmt.Errorf("Failed to commit WAL entry: %s", err)
|
||||
}
|
||||
|
||||
// Return the info!
|
||||
return b.Secret(SecretAccessKeyType).Response(map[string]interface{}{
|
||||
"access_key": *keyResp.AccessKey.AccessKeyID,
|
||||
"secret_key": *keyResp.AccessKey.SecretAccessKey,
|
||||
}, map[string]interface{}{
|
||||
"username": username,
|
||||
}), nil
|
||||
// Use the helper to create the secret
|
||||
return b.secretAccessKeysCreate(
|
||||
req.Storage, policyName, string(policy.Value))
|
||||
}
|
||||
|
||||
func pathUserRollback(req *logical.Request, _kind string, data interface{}) error {
|
||||
|
|
|
@ -2,7 +2,11 @@ package aws
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/aws-sdk-go/aws"
|
||||
"github.com/hashicorp/aws-sdk-go/gen/iam"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
)
|
||||
|
@ -28,6 +32,75 @@ func secretAccessKeys() *framework.Secret {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *backend) secretAccessKeysCreate(
|
||||
s logical.Storage,
|
||||
policyName string, policy string) (*logical.Response, error) {
|
||||
client, err := clientIAM(s)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(err.Error()), nil
|
||||
}
|
||||
|
||||
// Generate a random username. We don't put the policy names in the
|
||||
// username because the AWS console makes it pretty easy to see that.
|
||||
username := fmt.Sprintf("vault-%d-%d", time.Now().Unix(), rand.Int31n(10000))
|
||||
|
||||
// Write to the WAL that this user will be created. We do this before
|
||||
// the user is created because if switch the order then the WAL put
|
||||
// can fail, which would put us in an awkward position: we have a user
|
||||
// we need to rollback but can't put the WAL entry to do the rollback.
|
||||
walId, err := framework.PutWAL(s, "user", &walUser{
|
||||
UserName: username,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error writing WAL entry: %s", err)
|
||||
}
|
||||
|
||||
// Create the user
|
||||
_, err = client.CreateUser(&iam.CreateUserRequest{
|
||||
UserName: aws.String(username),
|
||||
})
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Error creating IAM user: %s", err)), nil
|
||||
}
|
||||
|
||||
// Add the user to all the groups
|
||||
err = client.PutUserPolicy(&iam.PutUserPolicyRequest{
|
||||
UserName: aws.String(username),
|
||||
PolicyName: aws.String(policyName),
|
||||
PolicyDocument: aws.String(policy),
|
||||
})
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Error adding user to group: %s", err)), nil
|
||||
}
|
||||
|
||||
// Create the keys
|
||||
keyResp, err := client.CreateAccessKey(&iam.CreateAccessKeyRequest{
|
||||
UserName: aws.String(username),
|
||||
})
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"Error creating access keys: %s", err)), nil
|
||||
}
|
||||
|
||||
// Remove the WAL entry, we succeeded! If we fail, we don't return
|
||||
// the secret because it'll get rolled back anyways, so we have to return
|
||||
// an error here.
|
||||
if err := framework.DeleteWAL(s, walId); err != nil {
|
||||
return nil, fmt.Errorf("Failed to commit WAL entry: %s", err)
|
||||
}
|
||||
|
||||
// Return the info!
|
||||
return b.Secret(SecretAccessKeyType).Response(map[string]interface{}{
|
||||
"access_key": *keyResp.AccessKey.AccessKeyID,
|
||||
"secret_key": *keyResp.AccessKey.SecretAccessKey,
|
||||
}, map[string]interface{}{
|
||||
"username": username,
|
||||
"policy": policy,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func secretAccessKeysRevoke(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
// Get the username from the internal data
|
||||
|
|
Loading…
Reference in New Issue