github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_iam_server_certificate.go (about)

     1  package aws
     2  
     3  import (
     4  	"crypto/sha1"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"log"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/aws/aws-sdk-go/aws"
    12  	"github.com/aws/aws-sdk-go/aws/awserr"
    13  	"github.com/aws/aws-sdk-go/service/iam"
    14  	"github.com/hashicorp/terraform/helper/resource"
    15  	"github.com/hashicorp/terraform/helper/schema"
    16  )
    17  
    18  func resourceAwsIAMServerCertificate() *schema.Resource {
    19  	return &schema.Resource{
    20  		Create: resourceAwsIAMServerCertificateCreate,
    21  		Read:   resourceAwsIAMServerCertificateRead,
    22  		Delete: resourceAwsIAMServerCertificateDelete,
    23  
    24  		Schema: map[string]*schema.Schema{
    25  			"certificate_body": &schema.Schema{
    26  				Type:      schema.TypeString,
    27  				Required:  true,
    28  				ForceNew:  true,
    29  				StateFunc: normalizeCert,
    30  			},
    31  
    32  			"certificate_chain": &schema.Schema{
    33  				Type:      schema.TypeString,
    34  				Optional:  true,
    35  				ForceNew:  true,
    36  				StateFunc: normalizeCert,
    37  			},
    38  
    39  			"path": &schema.Schema{
    40  				Type:     schema.TypeString,
    41  				Optional: true,
    42  				Default:  "/",
    43  				ForceNew: true,
    44  			},
    45  
    46  			"private_key": &schema.Schema{
    47  				Type:      schema.TypeString,
    48  				Required:  true,
    49  				ForceNew:  true,
    50  				StateFunc: normalizeCert,
    51  			},
    52  
    53  			"name": &schema.Schema{
    54  				Type:     schema.TypeString,
    55  				Required: true,
    56  				ForceNew: true,
    57  			},
    58  
    59  			"arn": &schema.Schema{
    60  				Type:     schema.TypeString,
    61  				Optional: true,
    62  				Computed: true,
    63  			},
    64  		},
    65  	}
    66  }
    67  
    68  func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interface{}) error {
    69  	conn := meta.(*AWSClient).iamconn
    70  
    71  	createOpts := &iam.UploadServerCertificateInput{
    72  		CertificateBody:       aws.String(d.Get("certificate_body").(string)),
    73  		PrivateKey:            aws.String(d.Get("private_key").(string)),
    74  		ServerCertificateName: aws.String(d.Get("name").(string)),
    75  	}
    76  
    77  	if v, ok := d.GetOk("certificate_chain"); ok {
    78  		createOpts.CertificateChain = aws.String(v.(string))
    79  	}
    80  
    81  	if v, ok := d.GetOk("path"); ok {
    82  		createOpts.Path = aws.String(v.(string))
    83  	}
    84  
    85  	log.Printf("[DEBUG] Creating IAM Server Certificate with opts: %s", createOpts)
    86  	resp, err := conn.UploadServerCertificate(createOpts)
    87  	if err != nil {
    88  		if awsErr, ok := err.(awserr.Error); ok {
    89  			return fmt.Errorf("[WARN] Error uploading server certificate, error: %s: %s", awsErr.Code(), awsErr.Message())
    90  		}
    91  		return fmt.Errorf("[WARN] Error uploading server certificate, error: %s", err)
    92  	}
    93  
    94  	d.SetId(*resp.ServerCertificateMetadata.ServerCertificateId)
    95  
    96  	return resourceAwsIAMServerCertificateRead(d, meta)
    97  }
    98  
    99  func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{}) error {
   100  	conn := meta.(*AWSClient).iamconn
   101  	resp, err := conn.GetServerCertificate(&iam.GetServerCertificateInput{
   102  		ServerCertificateName: aws.String(d.Get("name").(string)),
   103  	})
   104  
   105  	if err != nil {
   106  		if awsErr, ok := err.(awserr.Error); ok {
   107  			return fmt.Errorf("[WARN] Error reading IAM Server Certificate: %s: %s", awsErr.Code(), awsErr.Message())
   108  		}
   109  		return fmt.Errorf("[WARN] Error reading IAM Server Certificate: %s", err)
   110  	}
   111  
   112  	// these values should always be present, and have a default if not set in
   113  	// configuration, and so safe to reference with nil checks
   114  	d.Set("certificate_body", normalizeCert(resp.ServerCertificate.CertificateBody))
   115  
   116  	c := normalizeCert(resp.ServerCertificate.CertificateChain)
   117  	if c != "" {
   118  		d.Set("certificate_chain", c)
   119  	}
   120  
   121  	d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path)
   122  	d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.Arn)
   123  
   124  	return nil
   125  }
   126  
   127  func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interface{}) error {
   128  	conn := meta.(*AWSClient).iamconn
   129  	log.Printf("[INFO] Deleting IAM Server Certificate: %s", d.Id())
   130  	err := resource.Retry(1*time.Minute, func() error {
   131  		_, err := conn.DeleteServerCertificate(&iam.DeleteServerCertificateInput{
   132  			ServerCertificateName: aws.String(d.Get("name").(string)),
   133  		})
   134  
   135  		if err != nil {
   136  			if awsErr, ok := err.(awserr.Error); ok {
   137  				if awsErr.Code() == "DeleteConflict" && strings.Contains(awsErr.Message(), "currently in use by arn") {
   138  					return fmt.Errorf("[WARN] Conflict deleting server certificate: %s, retrying", awsErr.Message())
   139  				}
   140  			}
   141  			return resource.RetryError{Err: err}
   142  		}
   143  		return nil
   144  	})
   145  
   146  	if err != nil {
   147  		return err
   148  	}
   149  
   150  	d.SetId("")
   151  	return nil
   152  }
   153  
   154  func normalizeCert(cert interface{}) string {
   155  	if cert == nil || cert == (*string)(nil) {
   156  		return ""
   157  	}
   158  
   159  	switch cert.(type) {
   160  	case string:
   161  		hash := sha1.Sum([]byte(strings.TrimSpace(cert.(string))))
   162  		return hex.EncodeToString(hash[:])
   163  	case *string:
   164  		hash := sha1.Sum([]byte(strings.TrimSpace(*cert.(*string))))
   165  		return hex.EncodeToString(hash[:])
   166  	default:
   167  		return ""
   168  	}
   169  }