145 lines
3.6 KiB
Go
145 lines
3.6 KiB
Go
package aws
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"fmt"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
"github.com/aws/aws-sdk-go/service/iam"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
)
|
|
|
|
func resourceAwsIamAccessKey() *schema.Resource {
|
|
return &schema.Resource{
|
|
Create: resourceAwsIamAccessKeyCreate,
|
|
Read: resourceAwsIamAccessKeyRead,
|
|
Delete: resourceAwsIamAccessKeyDelete,
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
"user": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
},
|
|
"status": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
// this could be settable, but goamz does not support the
|
|
// UpdateAccessKey API yet.
|
|
Computed: true,
|
|
},
|
|
"secret": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"ses_smtp_password": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func resourceAwsIamAccessKeyCreate(d *schema.ResourceData, meta interface{}) error {
|
|
iamconn := meta.(*AWSClient).iamconn
|
|
|
|
request := &iam.CreateAccessKeyInput{
|
|
UserName: aws.String(d.Get("user").(string)),
|
|
}
|
|
|
|
createResp, err := iamconn.CreateAccessKey(request)
|
|
if err != nil {
|
|
return fmt.Errorf(
|
|
"Error creating access key for user %s: %s",
|
|
*request.UserName,
|
|
err,
|
|
)
|
|
}
|
|
|
|
if err := d.Set("secret", createResp.AccessKey.SecretAccessKey); err != nil {
|
|
return err
|
|
}
|
|
|
|
d.Set("ses_smtp_password",
|
|
sesSmtpPasswordFromSecretKey(createResp.AccessKey.SecretAccessKey))
|
|
|
|
return resourceAwsIamAccessKeyReadResult(d, &iam.AccessKeyMetadata{
|
|
AccessKeyId: createResp.AccessKey.AccessKeyId,
|
|
CreateDate: createResp.AccessKey.CreateDate,
|
|
Status: createResp.AccessKey.Status,
|
|
UserName: createResp.AccessKey.UserName,
|
|
})
|
|
}
|
|
|
|
func resourceAwsIamAccessKeyRead(d *schema.ResourceData, meta interface{}) error {
|
|
iamconn := meta.(*AWSClient).iamconn
|
|
|
|
request := &iam.ListAccessKeysInput{
|
|
UserName: aws.String(d.Get("user").(string)),
|
|
}
|
|
|
|
getResp, err := iamconn.ListAccessKeys(request)
|
|
if err != nil {
|
|
if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX TEST ME
|
|
// the user does not exist, so the key can't exist.
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
return fmt.Errorf("Error reading IAM acces key: %s", err)
|
|
}
|
|
|
|
for _, key := range getResp.AccessKeyMetadata {
|
|
if key.AccessKeyId != nil && *key.AccessKeyId == d.Id() {
|
|
return resourceAwsIamAccessKeyReadResult(d, key)
|
|
}
|
|
}
|
|
|
|
// Guess the key isn't around anymore.
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
|
|
func resourceAwsIamAccessKeyReadResult(d *schema.ResourceData, key *iam.AccessKeyMetadata) error {
|
|
d.SetId(*key.AccessKeyId)
|
|
if err := d.Set("user", key.UserName); err != nil {
|
|
return err
|
|
}
|
|
if err := d.Set("status", key.Status); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func resourceAwsIamAccessKeyDelete(d *schema.ResourceData, meta interface{}) error {
|
|
iamconn := meta.(*AWSClient).iamconn
|
|
|
|
request := &iam.DeleteAccessKeyInput{
|
|
AccessKeyId: aws.String(d.Id()),
|
|
UserName: aws.String(d.Get("user").(string)),
|
|
}
|
|
|
|
if _, err := iamconn.DeleteAccessKey(request); err != nil {
|
|
return fmt.Errorf("Error deleting access key %s: %s", d.Id(), err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sesSmtpPasswordFromSecretKey(key *string) string {
|
|
if key == nil {
|
|
return ""
|
|
}
|
|
version := byte(0x02)
|
|
message := []byte("SendRawEmail")
|
|
hmacKey := []byte(*key)
|
|
h := hmac.New(sha256.New, hmacKey)
|
|
h.Write(message)
|
|
rawSig := h.Sum(nil)
|
|
versionedSig := make([]byte, 0, len(rawSig)+1)
|
|
versionedSig = append(versionedSig, version)
|
|
versionedSig = append(versionedSig, rawSig...)
|
|
return base64.StdEncoding.EncodeToString(versionedSig)
|
|
}
|