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:
parent
e6249e5059
commit
c5c6644acf
|
@ -1,5 +1,10 @@
|
||||||
# Change Log
|
# 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
|
## [v1.1.3] - 2018-03-07
|
||||||
|
|
||||||
- #156 Handle non-json errors from the API - @aknuds1
|
- #156 Handle non-json errors from the API - @aknuds1
|
||||||
|
|
|
@ -19,19 +19,24 @@ type CertificatesService interface {
|
||||||
|
|
||||||
// Certificate represents a DigitalOcean certificate configuration.
|
// Certificate represents a DigitalOcean certificate configuration.
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
NotAfter string `json:"not_after,omitempty"`
|
DNSNames []string `json:"dns_names,omitempty"`
|
||||||
SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"`
|
NotAfter string `json:"not_after,omitempty"`
|
||||||
Created string `json:"created_at,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.
|
// CertificateRequest represents configuration for a new certificate.
|
||||||
type CertificateRequest struct {
|
type CertificateRequest struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
PrivateKey string `json:"private_key,omitempty"`
|
DNSNames []string `json:"dns_names,omitempty"`
|
||||||
LeafCertificate string `json:"leaf_certificate,omitempty"`
|
PrivateKey string `json:"private_key,omitempty"`
|
||||||
CertificateChain string `json:"certificate_chain,omitempty"`
|
LeafCertificate string `json:"leaf_certificate,omitempty"`
|
||||||
|
CertificateChain string `json:"certificate_chain,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type certificateRoot struct {
|
type certificateRoot struct {
|
||||||
|
|
|
@ -15,9 +15,15 @@ var certJSONResponse = `
|
||||||
"certificate": {
|
"certificate": {
|
||||||
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
|
"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",
|
"not_after": "2017-02-22T00:23:00Z",
|
||||||
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
"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": [
|
"certificates": [
|
||||||
{
|
{
|
||||||
"id": "892071a0-bb95-49bc-8021-3afd67a210bf",
|
"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",
|
"not_after": "2017-02-22T00:23:00Z",
|
||||||
"sha1_fingerprint": "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
"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",
|
"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",
|
"not_after": "2017-02-22T00:23:00Z",
|
||||||
"sha1_fingerprint": "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
"sha1_fingerprint": "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
||||||
"created_at": "2017-02-08T16:02:37Z"
|
"created_at": "2017-02-08T16:02:37Z",
|
||||||
|
"state": "pending",
|
||||||
|
"type": "lets_encrypt"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": {},
|
"links": {},
|
||||||
|
@ -67,9 +82,12 @@ func TestCertificates_Get(t *testing.T) {
|
||||||
expected := &Certificate{
|
expected := &Certificate{
|
||||||
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
|
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
|
||||||
Name: "web-cert-01",
|
Name: "web-cert-01",
|
||||||
|
DNSNames: []string{"somedomain.com", "api.somedomain.com"},
|
||||||
NotAfter: "2017-02-22T00:23:00Z",
|
NotAfter: "2017-02-22T00:23:00Z",
|
||||||
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
||||||
Created: "2017-02-08T16:02:37Z",
|
Created: "2017-02-08T16:02:37Z",
|
||||||
|
State: "verified",
|
||||||
|
Type: "custom",
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, expected, certificate)
|
assert.Equal(t, expected, certificate)
|
||||||
|
@ -95,16 +113,22 @@ func TestCertificates_List(t *testing.T) {
|
||||||
{
|
{
|
||||||
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
|
ID: "892071a0-bb95-49bc-8021-3afd67a210bf",
|
||||||
Name: "web-cert-01",
|
Name: "web-cert-01",
|
||||||
|
DNSNames: []string{"somedomain.com", "api.somedomain.com"},
|
||||||
NotAfter: "2017-02-22T00:23:00Z",
|
NotAfter: "2017-02-22T00:23:00Z",
|
||||||
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
SHA1Fingerprint: "dfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
||||||
Created: "2017-02-08T16:02:37Z",
|
Created: "2017-02-08T16:02:37Z",
|
||||||
|
State: "verified",
|
||||||
|
Type: "custom",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "992071a0-bb95-49bc-8021-3afd67a210bf",
|
ID: "992071a0-bb95-49bc-8021-3afd67a210bf",
|
||||||
Name: "web-cert-02",
|
Name: "web-cert-02",
|
||||||
|
DNSNames: []string{"example.com"},
|
||||||
NotAfter: "2017-02-22T00:23:00Z",
|
NotAfter: "2017-02-22T00:23:00Z",
|
||||||
SHA1Fingerprint: "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
SHA1Fingerprint: "cfcc9f57d86bf58e321c2c6c31c7a971be244ac7",
|
||||||
Created: "2017-02-08T16:02:37Z",
|
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) {
|
func TestCertificates_Create(t *testing.T) {
|
||||||
setup()
|
tests := []struct {
|
||||||
defer teardown()
|
desc string
|
||||||
|
createRequest *CertificateRequest
|
||||||
createRequest := &CertificateRequest{
|
certJSONResponse string
|
||||||
Name: "web-cert-01",
|
expectedCertificate *Certificate
|
||||||
PrivateKey: "-----BEGIN PRIVATE KEY-----",
|
}{
|
||||||
LeafCertificate: "-----BEGIN CERTIFICATE-----",
|
{
|
||||||
CertificateChain: "-----BEGIN 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"
|
for _, test := range tests {
|
||||||
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
v := new(CertificateRequest)
|
setup()
|
||||||
err := json.NewDecoder(r.Body).Decode(v)
|
defer teardown()
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testMethod(t, r, http.MethodPost)
|
urlStr := "/v2/certificates"
|
||||||
assert.Equal(t, createRequest, v)
|
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)
|
fmt.Fprint(w, test.certJSONResponse)
|
||||||
if err != nil {
|
})
|
||||||
t.Errorf("Certificates.Create returned error: %v", err)
|
|
||||||
|
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) {
|
func TestCertificates_Delete(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue