github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/builtin/providers/aws/resource_aws_iam_access_key.go (about)

     1  package aws
     2  
     3  import (
     4  	"crypto/hmac"
     5  	"crypto/sha256"
     6  	"encoding/base64"
     7  	"fmt"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/iam"
    12  
    13  	"github.com/hashicorp/terraform/helper/encryption"
    14  	"github.com/hashicorp/terraform/helper/schema"
    15  )
    16  
    17  func resourceAwsIamAccessKey() *schema.Resource {
    18  	return &schema.Resource{
    19  		Create: resourceAwsIamAccessKeyCreate,
    20  		Read:   resourceAwsIamAccessKeyRead,
    21  		Delete: resourceAwsIamAccessKeyDelete,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"user": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: true,
    28  			},
    29  			"status": &schema.Schema{
    30  				Type:     schema.TypeString,
    31  				Computed: true,
    32  			},
    33  			"secret": &schema.Schema{
    34  				Type:       schema.TypeString,
    35  				Computed:   true,
    36  				Deprecated: "Please use a PGP key to encrypt",
    37  			},
    38  			"ses_smtp_password": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Computed: true,
    41  			},
    42  			"pgp_key": {
    43  				Type:     schema.TypeString,
    44  				ForceNew: true,
    45  				Optional: true,
    46  			},
    47  			"key_fingerprint": {
    48  				Type:     schema.TypeString,
    49  				Computed: true,
    50  			},
    51  			"encrypted_secret": {
    52  				Type:     schema.TypeString,
    53  				Computed: true,
    54  			},
    55  		},
    56  	}
    57  }
    58  
    59  func resourceAwsIamAccessKeyCreate(d *schema.ResourceData, meta interface{}) error {
    60  	iamconn := meta.(*AWSClient).iamconn
    61  
    62  	request := &iam.CreateAccessKeyInput{
    63  		UserName: aws.String(d.Get("user").(string)),
    64  	}
    65  
    66  	createResp, err := iamconn.CreateAccessKey(request)
    67  	if err != nil {
    68  		return fmt.Errorf(
    69  			"Error creating access key for user %s: %s",
    70  			*request.UserName,
    71  			err,
    72  		)
    73  	}
    74  
    75  	d.SetId(*createResp.AccessKey.AccessKeyId)
    76  
    77  	if createResp.AccessKey == nil || createResp.AccessKey.SecretAccessKey == nil {
    78  		return fmt.Errorf("[ERR] CreateAccessKey response did not contain a Secret Access Key as expected")
    79  	}
    80  
    81  	if v, ok := d.GetOk("pgp_key"); ok {
    82  		pgpKey := v.(string)
    83  		encryptionKey, err := encryption.RetrieveGPGKey(pgpKey)
    84  		if err != nil {
    85  			return err
    86  		}
    87  		fingerprint, encrypted, err := encryption.EncryptValue(encryptionKey, *createResp.AccessKey.SecretAccessKey, "IAM Access Key Secret")
    88  		if err != nil {
    89  			return err
    90  		}
    91  
    92  		d.Set("key_fingerprint", fingerprint)
    93  		d.Set("encrypted_secret", encrypted)
    94  	} else {
    95  		if err := d.Set("secret", createResp.AccessKey.SecretAccessKey); err != nil {
    96  			return err
    97  		}
    98  	}
    99  
   100  	d.Set("ses_smtp_password",
   101  		sesSmtpPasswordFromSecretKey(createResp.AccessKey.SecretAccessKey))
   102  
   103  	return resourceAwsIamAccessKeyReadResult(d, &iam.AccessKeyMetadata{
   104  		AccessKeyId: createResp.AccessKey.AccessKeyId,
   105  		CreateDate:  createResp.AccessKey.CreateDate,
   106  		Status:      createResp.AccessKey.Status,
   107  		UserName:    createResp.AccessKey.UserName,
   108  	})
   109  }
   110  
   111  func resourceAwsIamAccessKeyRead(d *schema.ResourceData, meta interface{}) error {
   112  	iamconn := meta.(*AWSClient).iamconn
   113  
   114  	request := &iam.ListAccessKeysInput{
   115  		UserName: aws.String(d.Get("user").(string)),
   116  	}
   117  
   118  	getResp, err := iamconn.ListAccessKeys(request)
   119  	if err != nil {
   120  		if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX TEST ME
   121  			// the user does not exist, so the key can't exist.
   122  			d.SetId("")
   123  			return nil
   124  		}
   125  		return fmt.Errorf("Error reading IAM acces key: %s", err)
   126  	}
   127  
   128  	for _, key := range getResp.AccessKeyMetadata {
   129  		if key.AccessKeyId != nil && *key.AccessKeyId == d.Id() {
   130  			return resourceAwsIamAccessKeyReadResult(d, key)
   131  		}
   132  	}
   133  
   134  	// Guess the key isn't around anymore.
   135  	d.SetId("")
   136  	return nil
   137  }
   138  
   139  func resourceAwsIamAccessKeyReadResult(d *schema.ResourceData, key *iam.AccessKeyMetadata) error {
   140  	d.SetId(*key.AccessKeyId)
   141  	if err := d.Set("user", key.UserName); err != nil {
   142  		return err
   143  	}
   144  	if err := d.Set("status", key.Status); err != nil {
   145  		return err
   146  	}
   147  	return nil
   148  }
   149  
   150  func resourceAwsIamAccessKeyDelete(d *schema.ResourceData, meta interface{}) error {
   151  	iamconn := meta.(*AWSClient).iamconn
   152  
   153  	request := &iam.DeleteAccessKeyInput{
   154  		AccessKeyId: aws.String(d.Id()),
   155  		UserName:    aws.String(d.Get("user").(string)),
   156  	}
   157  
   158  	if _, err := iamconn.DeleteAccessKey(request); err != nil {
   159  		return fmt.Errorf("Error deleting access key %s: %s", d.Id(), err)
   160  	}
   161  	return nil
   162  }
   163  
   164  func sesSmtpPasswordFromSecretKey(key *string) string {
   165  	if key == nil {
   166  		return ""
   167  	}
   168  	version := byte(0x02)
   169  	message := []byte("SendRawEmail")
   170  	hmacKey := []byte(*key)
   171  	h := hmac.New(sha256.New, hmacKey)
   172  	h.Write(message)
   173  	rawSig := h.Sum(nil)
   174  	versionedSig := make([]byte, 0, len(rawSig)+1)
   175  	versionedSig = append(versionedSig, version)
   176  	versionedSig = append(versionedSig, rawSig...)
   177  	return base64.StdEncoding.EncodeToString(versionedSig)
   178  }