Add support for Let's Encrypt Certificates. (#165)

* Add support for Let's Encrypt Certificates.

* Update CHANGELOG with applied changes.

* Update changelog
This commit is contained in:
Wioletta Holownia 2018-05-08 16:40:21 -04:00 committed by GitHub
parent e6249e5059
commit c5c6644acf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 46 deletions

View File

@ -1,5 +1,10 @@
# Change Log
## [v1.2.0] - 2018-05-08
- #166 Remove support for Go 1.6 - @iheanyi
- #165 Add support for Let's Encrypt Certificates - @viola
## [v1.1.3] - 2018-03-07
- #156 Handle non-json errors from the API - @aknuds1

View File

@ -19,19 +19,24 @@ type CertificatesService interface {
// Certificate represents a DigitalOcean certificate configuration.
type Certificate struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
NotAfter string `json:"not_after,omitempty"`
SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"`
Created string `json:"created_at,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
DNSNames []string `json:"dns_names,omitempty"`
NotAfter string `json:"not_after,omitempty"`
SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"`
Created string `json:"created_at,omitempty"`
State string `json:"state,omitempty"`
Type string `json:"type,omitempty"`
}
// CertificateRequest represents configuration for a new certificate.
type CertificateRequest struct {
Name string `json:"name,omitempty"`
PrivateKey string `json:"private_key,omitempty"`
LeafCertificate string `json:"leaf_certificate,omitempty"`
CertificateChain string `json:"certificate_chain,omitempty"`
Name string `json:"name,omitempty"`
DNSNames []string `json:"dns_names,omitempty"`
PrivateKey string `json:"private_key,omitempty"`
LeafCertificate string `json:"leaf_certificate,omitempty"`
CertificateChain string `json:"certificate_chain,omitempty"`
Type string `json:"type,omitempty"`
}
type certificateRoot struct {

View File

@ -15,9 +15,15 @@ var certJSONResponse = `
"certificate": {
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
"name": "web-cert-01",
"dns_names": [
"somedomain.com",
"api.somedomain.com"
],
"not_after": "2017-02-22T00:23:00Z",
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
"created_at": "2017-02-08T16:02:37Z"
"created_at": "2017-02-08T16:02:37Z",
"state": "verified",
"type": "custom"
}
}
`
@ -27,17 +33,26 @@ var certsJSONResponse = `
"certificates": [
{
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
"name": "web-cert-01",
"name": "web-cert-01",
"dns_names": [
"somedomain.com",
"api.somedomain.com"
],
"not_after": "2017-02-22T00:23:00Z",
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
"created_at": "2017-02-08T16:02:37Z"
"created_at": "2017-02-08T16:02:37Z",
"state": "verified",
"type": "custom"
},
{
"id": "992071a0-bb95-49bc-8021-3afd67a210bf",
"name": "web-cert-02",
"name": "web-cert-02",
"dns_names":["example.com"],
"not_after": "2017-02-22T00:23:00Z",
"sha1_fingerprint": "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
"created_at": "2017-02-08T16:02:37Z"
"created_at": "2017-02-08T16:02:37Z",
"state": "pending",
"type": "lets_encrypt"
}
],
"links": {},
@ -67,9 +82,12 @@ func TestCertificates_Get(t *testing.T) {
expected := &Certificate{
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
Name: "web-cert-01",
DNSNames: []string{"somedomain.com", "api.somedomain.com"},
NotAfter: "2017-02-22T00:23:00Z",
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
Created: "2017-02-08T16:02:37Z",
State: "verified",
Type: "custom",
}
assert.Equal(t, expected, certificate)
@ -95,16 +113,22 @@ func TestCertificates_List(t *testing.T) {
{
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
Name: "web-cert-01",
DNSNames: []string{"somedomain.com", "api.somedomain.com"},
NotAfter: "2017-02-22T00:23:00Z",
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
Created: "2017-02-08T16:02:37Z",
State: "verified",
Type: "custom",
},
{
ID: "992071a0-bb95-49bc-8021-3afd67a210bf",
Name: "web-cert-02",
DNSNames: []string{"example.com"},
NotAfter: "2017-02-22T00:23:00Z",
SHA1Fingerprint: "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
Created: "2017-02-08T16:02:37Z",
State: "pending",
Type: "lets_encrypt",
},
}
@ -112,44 +136,102 @@ func TestCertificates_List(t *testing.T) {
}
func TestCertificates_Create(t *testing.T) {
setup()
defer teardown()
createRequest := &CertificateRequest{
Name: "web-cert-01",
PrivateKey: "-----BEGIN PRIVATE KEY-----",
LeafCertificate: "-----BEGIN CERTIFICATE-----",
CertificateChain: "-----BEGIN CERTIFICATE-----",
tests := []struct {
desc string
createRequest *CertificateRequest
certJSONResponse string
expectedCertificate *Certificate
}{
{
desc: "creates custom certificate",
createRequest: &CertificateRequest{
Name: "web-cert-01",
PrivateKey: "-----BEGIN PRIVATE KEY-----",
LeafCertificate: "-----BEGIN CERTIFICATE-----",
CertificateChain: "-----BEGIN CERTIFICATE-----",
},
certJSONResponse: `{
"certificate": {
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
"name": "custom-cert",
"dns_names":[],
"not_after": "2017-02-22T00:23:00Z",
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
"created_at": "2017-02-08T16:02:37Z",
"state": "verified",
"type": "custom"
}
}`,
expectedCertificate: &Certificate{
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
Name: "custom-cert",
DNSNames: []string{},
NotAfter: "2017-02-22T00:23:00Z",
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
Created: "2017-02-08T16:02:37Z",
State: "verified",
Type: "custom",
},
},
{
desc: "creates let's encrypt certificate",
createRequest: &CertificateRequest{
Name: "lets-encrypt-cert",
DNSNames: []string{"example.com", "api.example.com"},
Type: "lets_encrypt",
},
certJSONResponse: `{
"certificate": {
"id": "91bce928-a983-4c97-a5ee-78c585bf798d",
"name": "lets-encrypt-cert",
"dns_names":["example.com", "api.example.com"],
"not_after": "2022-01-26T15:50:00Z",
"sha1_fingerprint": "2e3c2ba8016faf80f431700ff2865ef6dba30a81",
"created_at": "2017-08-23T20:42:46Z",
"state": "pending",
"type": "lets_encrypt"
}
}`,
expectedCertificate: &Certificate{
ID: "91bce928-a983-4c97-a5ee-78c585bf798d",
Name: "lets-encrypt-cert",
DNSNames: []string{"example.com", "api.example.com"},
NotAfter: "2022-01-26T15:50:00Z",
SHA1Fingerprint: "2e3c2ba8016faf80f431700ff2865ef6dba30a81",
Created: "2017-08-23T20:42:46Z",
State: "pending",
Type: "lets_encrypt",
},
},
}
urlStr := "/v2/certificates"
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
v := new(CertificateRequest)
err := json.NewDecoder(r.Body).Decode(v)
if err != nil {
t.Fatal(err)
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
setup()
defer teardown()
testMethod(t, r, http.MethodPost)
assert.Equal(t, createRequest, v)
urlStr := "/v2/certificates"
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
v := new(CertificateRequest)
err := json.NewDecoder(r.Body).Decode(v)
if err != nil {
t.Fatal(err)
}
fmt.Fprint(w, certJSONResponse)
})
testMethod(t, r, http.MethodPost)
assert.Equal(t, test.createRequest, v)
certificate, _, err := client.Certificates.Create(ctx, createRequest)
if err != nil {
t.Errorf("Certificates.Create returned error: %v", err)
fmt.Fprint(w, test.certJSONResponse)
})
certificate, _, err := client.Certificates.Create(ctx, test.createRequest)
if err != nil {
t.Errorf("Certificates.Create returned error: %v", err)
}
assert.Equal(t, test.expectedCertificate, certificate)
})
}
expected := &Certificate{
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
Name: "web-cert-01",
NotAfter: "2017-02-22T00:23:00Z",
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
Created: "2017-02-08T16:02:37Z",
}
assert.Equal(t, expected, certificate)
}
func TestCertificates_Delete(t *testing.T) {