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