github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/tls/resource_cert_request.go (about)

     1  package tls
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/x509"
     6  	"encoding/pem"
     7  	"fmt"
     8  	"net"
     9  
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  )
    12  
    13  const pemCertReqType = "CERTIFICATE REQUEST"
    14  
    15  func resourceCertRequest() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: CreateCertRequest,
    18  		Delete: DeleteCertRequest,
    19  		Read:   ReadCertRequest,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  
    23  			"dns_names": &schema.Schema{
    24  				Type:        schema.TypeList,
    25  				Optional:    true,
    26  				Description: "List of DNS names to use as subjects of the certificate",
    27  				ForceNew:    true,
    28  				Elem: &schema.Schema{
    29  					Type: schema.TypeString,
    30  				},
    31  			},
    32  
    33  			"ip_addresses": &schema.Schema{
    34  				Type:        schema.TypeList,
    35  				Optional:    true,
    36  				Description: "List of IP addresses to use as subjects of the certificate",
    37  				ForceNew:    true,
    38  				Elem: &schema.Schema{
    39  					Type: schema.TypeString,
    40  				},
    41  			},
    42  
    43  			"key_algorithm": &schema.Schema{
    44  				Type:        schema.TypeString,
    45  				Required:    true,
    46  				Description: "Name of the algorithm to use to generate the certificate's private key",
    47  				ForceNew:    true,
    48  			},
    49  
    50  			"private_key_pem": &schema.Schema{
    51  				Type:        schema.TypeString,
    52  				Required:    true,
    53  				Description: "PEM-encoded private key that the certificate will belong to",
    54  				ForceNew:    true,
    55  				StateFunc: func(v interface{}) string {
    56  					return hashForState(v.(string))
    57  				},
    58  			},
    59  
    60  			"subject": &schema.Schema{
    61  				Type:     schema.TypeList,
    62  				Required: true,
    63  				Elem:     nameSchema,
    64  				ForceNew: true,
    65  			},
    66  
    67  			"cert_request_pem": &schema.Schema{
    68  				Type:     schema.TypeString,
    69  				Computed: true,
    70  			},
    71  		},
    72  	}
    73  }
    74  
    75  func CreateCertRequest(d *schema.ResourceData, meta interface{}) error {
    76  	key, err := parsePrivateKey(d, "private_key_pem", "key_algorithm")
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	subjectConfs := d.Get("subject").([]interface{})
    82  	if len(subjectConfs) != 1 {
    83  		return fmt.Errorf("must have exactly one 'subject' block")
    84  	}
    85  	subjectConf := subjectConfs[0].(map[string]interface{})
    86  	subject, err := nameFromResourceData(subjectConf)
    87  	if err != nil {
    88  		return fmt.Errorf("invalid subject block: %s", err)
    89  	}
    90  
    91  	certReq := x509.CertificateRequest{
    92  		Subject: *subject,
    93  	}
    94  
    95  	dnsNamesI := d.Get("dns_names").([]interface{})
    96  	for _, nameI := range dnsNamesI {
    97  		certReq.DNSNames = append(certReq.DNSNames, nameI.(string))
    98  	}
    99  	ipAddressesI := d.Get("ip_addresses").([]interface{})
   100  	for _, ipStrI := range ipAddressesI {
   101  		ip := net.ParseIP(ipStrI.(string))
   102  		if ip == nil {
   103  			return fmt.Errorf("invalid IP address %#v", ipStrI.(string))
   104  		}
   105  		certReq.IPAddresses = append(certReq.IPAddresses, ip)
   106  	}
   107  
   108  	certReqBytes, err := x509.CreateCertificateRequest(rand.Reader, &certReq, key)
   109  	if err != nil {
   110  		return fmt.Errorf("Error creating certificate request: %s", err)
   111  	}
   112  	certReqPem := string(pem.EncodeToMemory(&pem.Block{Type: pemCertReqType, Bytes: certReqBytes}))
   113  
   114  	d.SetId(hashForState(string(certReqBytes)))
   115  	d.Set("cert_request_pem", certReqPem)
   116  
   117  	return nil
   118  }
   119  
   120  func DeleteCertRequest(d *schema.ResourceData, meta interface{}) error {
   121  	d.SetId("")
   122  	return nil
   123  }
   124  
   125  func ReadCertRequest(d *schema.ResourceData, meta interface{}) error {
   126  	return nil
   127  }