Skip to content

Commit c5c6644

Browse files
authored
Add support for Let's Encrypt Certificates. (#165)
* Add support for Let's Encrypt Certificates. * Update CHANGELOG with applied changes. * Update changelog
1 parent e6249e5 commit c5c6644

File tree

3 files changed

+137
-45
lines changed

3 files changed

+137
-45
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Change Log
22

3+
## [v1.2.0] - 2018-05-08
4+
5+
- #166 Remove support for Go 1.6 - @iheanyi
6+
- #165 Add support for Let's Encrypt Certificates - @viola
7+
38
## [v1.1.3] - 2018-03-07
49

510
- #156 Handle non-json errors from the API - @aknuds1

certificates.go

+14-9
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,24 @@ type CertificatesService interface {
1919

2020
// Certificate represents a DigitalOcean certificate configuration.
2121
type Certificate struct {
22-
ID string `json:"id,omitempty"`
23-
Name string `json:"name,omitempty"`
24-
NotAfter string `json:"not_after,omitempty"`
25-
SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"`
26-
Created string `json:"created_at,omitempty"`
22+
ID string `json:"id,omitempty"`
23+
Name string `json:"name,omitempty"`
24+
DNSNames []string `json:"dns_names,omitempty"`
25+
NotAfter string `json:"not_after,omitempty"`
26+
SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"`
27+
Created string `json:"created_at,omitempty"`
28+
State string `json:"state,omitempty"`
29+
Type string `json:"type,omitempty"`
2730
}
2831

2932
// CertificateRequest represents configuration for a new certificate.
3033
type CertificateRequest struct {
31-
Name string `json:"name,omitempty"`
32-
PrivateKey string `json:"private_key,omitempty"`
33-
LeafCertificate string `json:"leaf_certificate,omitempty"`
34-
CertificateChain string `json:"certificate_chain,omitempty"`
34+
Name string `json:"name,omitempty"`
35+
DNSNames []string `json:"dns_names,omitempty"`
36+
PrivateKey string `json:"private_key,omitempty"`
37+
LeafCertificate string `json:"leaf_certificate,omitempty"`
38+
CertificateChain string `json:"certificate_chain,omitempty"`
39+
Type string `json:"type,omitempty"`
3540
}
3641

3742
type certificateRoot struct {

certificates_test.go

+118-36
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@ var certJSONResponse = `
1515
"certificate": {
1616
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
1717
"name": "web-cert-01",
18+
"dns_names": [
19+
"somedomain.com",
20+
"api.somedomain.com"
21+
],
1822
"not_after": "2017-02-22T00:23:00Z",
1923
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
20-
"created_at": "2017-02-08T16:02:37Z"
24+
"created_at": "2017-02-08T16:02:37Z",
25+
"state": "verified",
26+
"type": "custom"
2127
}
2228
}
2329
`
@@ -27,17 +33,26 @@ var certsJSONResponse = `
2733
"certificates": [
2834
{
2935
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
30-
"name": "web-cert-01",
36+
"name": "web-cert-01",
37+
"dns_names": [
38+
"somedomain.com",
39+
"api.somedomain.com"
40+
],
3141
"not_after": "2017-02-22T00:23:00Z",
3242
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
33-
"created_at": "2017-02-08T16:02:37Z"
43+
"created_at": "2017-02-08T16:02:37Z",
44+
"state": "verified",
45+
"type": "custom"
3446
},
3547
{
3648
"id": "992071a0-bb95-49bc-8021-3afd67a210bf",
37-
"name": "web-cert-02",
49+
"name": "web-cert-02",
50+
"dns_names":["example.com"],
3851
"not_after": "2017-02-22T00:23:00Z",
3952
"sha1_fingerprint": "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
40-
"created_at": "2017-02-08T16:02:37Z"
53+
"created_at": "2017-02-08T16:02:37Z",
54+
"state": "pending",
55+
"type": "lets_encrypt"
4156
}
4257
],
4358
"links": {},
@@ -67,9 +82,12 @@ func TestCertificates_Get(t *testing.T) {
6782
expected := &Certificate{
6883
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
6984
Name: "web-cert-01",
85+
DNSNames: []string{"somedomain.com", "api.somedomain.com"},
7086
NotAfter: "2017-02-22T00:23:00Z",
7187
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
7288
Created: "2017-02-08T16:02:37Z",
89+
State: "verified",
90+
Type: "custom",
7391
}
7492

7593
assert.Equal(t, expected, certificate)
@@ -95,61 +113,125 @@ func TestCertificates_List(t *testing.T) {
95113
{
96114
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
97115
Name: "web-cert-01",
116+
DNSNames: []string{"somedomain.com", "api.somedomain.com"},
98117
NotAfter: "2017-02-22T00:23:00Z",
99118
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
100119
Created: "2017-02-08T16:02:37Z",
120+
State: "verified",
121+
Type: "custom",
101122
},
102123
{
103124
ID: "992071a0-bb95-49bc-8021-3afd67a210bf",
104125
Name: "web-cert-02",
126+
DNSNames: []string{"example.com"},
105127
NotAfter: "2017-02-22T00:23:00Z",
106128
SHA1Fingerprint: "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
107129
Created: "2017-02-08T16:02:37Z",
130+
State: "pending",
131+
Type: "lets_encrypt",
108132
},
109133
}
110134

111135
assert.Equal(t, expected, certificates)
112136
}
113137

114138
func TestCertificates_Create(t *testing.T) {
115-
setup()
116-
defer teardown()
117-
118-
createRequest := &CertificateRequest{
119-
Name: "web-cert-01",
120-
PrivateKey: "-----BEGIN PRIVATE KEY-----",
121-
LeafCertificate: "-----BEGIN CERTIFICATE-----",
122-
CertificateChain: "-----BEGIN CERTIFICATE-----",
139+
tests := []struct {
140+
desc string
141+
createRequest *CertificateRequest
142+
certJSONResponse string
143+
expectedCertificate *Certificate
144+
}{
145+
{
146+
desc: "creates custom certificate",
147+
createRequest: &CertificateRequest{
148+
Name: "web-cert-01",
149+
PrivateKey: "-----BEGIN PRIVATE KEY-----",
150+
LeafCertificate: "-----BEGIN CERTIFICATE-----",
151+
CertificateChain: "-----BEGIN CERTIFICATE-----",
152+
},
153+
certJSONResponse: `{
154+
"certificate": {
155+
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
156+
"name": "custom-cert",
157+
"dns_names":[],
158+
"not_after": "2017-02-22T00:23:00Z",
159+
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
160+
"created_at": "2017-02-08T16:02:37Z",
161+
"state": "verified",
162+
"type": "custom"
163+
}
164+
}`,
165+
expectedCertificate: &Certificate{
166+
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
167+
Name: "custom-cert",
168+
DNSNames: []string{},
169+
NotAfter: "2017-02-22T00:23:00Z",
170+
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
171+
Created: "2017-02-08T16:02:37Z",
172+
State: "verified",
173+
Type: "custom",
174+
},
175+
},
176+
{
177+
desc: "creates let's encrypt certificate",
178+
createRequest: &CertificateRequest{
179+
Name: "lets-encrypt-cert",
180+
DNSNames: []string{"example.com", "api.example.com"},
181+
Type: "lets_encrypt",
182+
},
183+
certJSONResponse: `{
184+
"certificate": {
185+
"id": "91bce928-a983-4c97-a5ee-78c585bf798d",
186+
"name": "lets-encrypt-cert",
187+
"dns_names":["example.com", "api.example.com"],
188+
"not_after": "2022-01-26T15:50:00Z",
189+
"sha1_fingerprint": "2e3c2ba8016faf80f431700ff2865ef6dba30a81",
190+
"created_at": "2017-08-23T20:42:46Z",
191+
"state": "pending",
192+
"type": "lets_encrypt"
193+
}
194+
}`,
195+
expectedCertificate: &Certificate{
196+
ID: "91bce928-a983-4c97-a5ee-78c585bf798d",
197+
Name: "lets-encrypt-cert",
198+
DNSNames: []string{"example.com", "api.example.com"},
199+
NotAfter: "2022-01-26T15:50:00Z",
200+
SHA1Fingerprint: "2e3c2ba8016faf80f431700ff2865ef6dba30a81",
201+
Created: "2017-08-23T20:42:46Z",
202+
State: "pending",
203+
Type: "lets_encrypt",
204+
},
205+
},
123206
}
124207

125-
urlStr := "/v2/certificates"
126-
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
127-
v := new(CertificateRequest)
128-
err := json.NewDecoder(r.Body).Decode(v)
129-
if err != nil {
130-
t.Fatal(err)
131-
}
208+
for _, test := range tests {
209+
t.Run(test.desc, func(t *testing.T) {
210+
setup()
211+
defer teardown()
132212

133-
testMethod(t, r, http.MethodPost)
134-
assert.Equal(t, createRequest, v)
213+
urlStr := "/v2/certificates"
214+
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
215+
v := new(CertificateRequest)
216+
err := json.NewDecoder(r.Body).Decode(v)
217+
if err != nil {
218+
t.Fatal(err)
219+
}
135220

136-
fmt.Fprint(w, certJSONResponse)
137-
})
221+
testMethod(t, r, http.MethodPost)
222+
assert.Equal(t, test.createRequest, v)
138223

139-
certificate, _, err := client.Certificates.Create(ctx, createRequest)
140-
if err != nil {
141-
t.Errorf("Certificates.Create returned error: %v", err)
142-
}
224+
fmt.Fprint(w, test.certJSONResponse)
225+
})
143226

144-
expected := &Certificate{
145-
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
146-
Name: "web-cert-01",
147-
NotAfter: "2017-02-22T00:23:00Z",
148-
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
149-
Created: "2017-02-08T16:02:37Z",
150-
}
227+
certificate, _, err := client.Certificates.Create(ctx, test.createRequest)
228+
if err != nil {
229+
t.Errorf("Certificates.Create returned error: %v", err)
230+
}
151231

152-
assert.Equal(t, expected, certificate)
232+
assert.Equal(t, test.expectedCertificate, certificate)
233+
})
234+
}
153235
}
154236

155237
func TestCertificates_Delete(t *testing.T) {

0 commit comments

Comments
 (0)