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