terraform/builtin/providers/aws/resource_aws_iam_server_cer...

158 lines
4.2 KiB
Go

package aws
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"log"
"strings"
"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 resourceAwsIAMServerCertificate() *schema.Resource {
return &schema.Resource{
Create: resourceAwsIAMServerCertificateCreate,
Read: resourceAwsIAMServerCertificateRead,
Delete: resourceAwsIAMServerCertificateDelete,
Schema: map[string]*schema.Schema{
"certificate_body": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: normalizeCert,
},
"certificate_chain": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
StateFunc: normalizeCert,
},
"path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "/",
ForceNew: true,
},
"private_key": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: normalizeCert,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"arn": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}
func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iamconn
createOpts := &iam.UploadServerCertificateInput{
CertificateBody: aws.String(d.Get("certificate_body").(string)),
PrivateKey: aws.String(d.Get("private_key").(string)),
ServerCertificateName: aws.String(d.Get("name").(string)),
}
if v, ok := d.GetOk("certificate_chain"); ok {
createOpts.CertificateChain = aws.String(v.(string))
}
if v, ok := d.GetOk("path"); ok {
createOpts.Path = aws.String(v.(string))
}
log.Printf("[DEBUG] Creating IAM Server Certificate with opts: %s", createOpts)
resp, err := conn.UploadServerCertificate(createOpts)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
return fmt.Errorf("[WARN] Error uploading server certificate, error: %s: %s", awsErr.Code(), awsErr.Message())
}
return fmt.Errorf("[WARN] Error uploading server certificate, error: %s", err)
}
d.SetId(*resp.ServerCertificateMetadata.ServerCertificateId)
return resourceAwsIAMServerCertificateRead(d, meta)
}
func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iamconn
resp, err := conn.GetServerCertificate(&iam.GetServerCertificateInput{
ServerCertificateName: aws.String(d.Get("name").(string)),
})
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
return fmt.Errorf("[WARN] Error reading IAM Server Certificate: %s: %s", awsErr.Code(), awsErr.Message())
}
return fmt.Errorf("[WARN] Error reading IAM Server Certificate: %s", err)
}
// these values should always be present, and have a default if not set in
// configuration, and so safe to reference with nil checks
d.Set("certificate_body", normalizeCert(resp.ServerCertificate.CertificateBody))
c := normalizeCert(resp.ServerCertificate.CertificateChain)
if c != "" {
d.Set("certificate_chain", c)
}
d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path)
d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.Arn)
return nil
}
func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iamconn
_, err := conn.DeleteServerCertificate(&iam.DeleteServerCertificateInput{
ServerCertificateName: aws.String(d.Get("name").(string)),
})
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
return fmt.Errorf("[WARN] Error deleting server certificate: %s: %s", awsErr.Code(), awsErr.Message())
}
return err
}
d.SetId("")
return nil
}
func normalizeCert(cert interface{}) string {
if cert == nil || cert == (*string)(nil) {
return ""
}
switch cert.(type) {
case string:
hash := sha1.Sum([]byte(strings.TrimSpace(cert.(string))))
return hex.EncodeToString(hash[:])
case *string:
hash := sha1.Sum([]byte(strings.TrimSpace(*cert.(*string))))
return hex.EncodeToString(hash[:])
default:
return ""
}
}