-
Notifications
You must be signed in to change notification settings - Fork 2
/
service.go
198 lines (176 loc) · 6.9 KB
/
service.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright (c) 2016, Janoš Guljaš <janos@resenje.org>
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package httpCertificate provides a Service that is a HTTP client to
// an external certificate service that can respond to HTTP requests defined here.
package httpCertificate
import (
"bytes"
"encoding/json"
"net/url"
"strconv"
"time"
"resenje.org/httputils/client/api"
"gopherpit.com/gopherpit/services/certificate"
)
// Service implements gopherpit.com/gopherpit/services/certificates.Service interface.
type Service struct {
Client *apiClient.Client
}
// NewService creates a new Service and injects certificate.ErrorRegistry
// in the API Client.
func NewService(c *apiClient.Client) *Service {
if c == nil {
c = &apiClient.Client{}
}
c.ErrorRegistry = certificate.ErrorRegistry
return &Service{Client: c}
}
// Certificate retrieves an existing Certificate instance by making a HTTP GET request
// to {Client.Endpoint}/certificates/{fqdn}.
func (s Service) Certificate(fqdn string) (c *certificate.Certificate, err error) {
err = s.Client.JSON("GET", "/certificates/"+fqdn, nil, nil, c)
return
}
// ObtainCertificateRequest is a structure that is passed as JSON-encoded body
// to ObtainCertificate HTTP request.
type ObtainCertificateRequest struct {
FQDN string `json:"fqdn"`
}
// ObtainCertificate obtains a new certificate from ACME provider by making a HTTP POST
// request to {Client.Endpoint}/certificates. Post body is a JSON-encoded
// ObtainCertificateRequest instance.
func (s Service) ObtainCertificate(fqdn string) (c *certificate.Certificate, err error) {
body, err := json.Marshal(ObtainCertificateRequest{
FQDN: fqdn,
})
if err != nil {
return
}
err = s.Client.JSON("POST", "/certificates", nil, bytes.NewReader(body), c)
return
}
// IsCertificateBeingObtainedResponse is expected structure of JSON-encoded response
// body for IsCertificateBeingObtained HTTP request.
type IsCertificateBeingObtainedResponse struct {
Yes bool `json:"yes"`
}
// IsCertificateBeingObtained tests if certificate is being obtained currently
// by making a HTTP GET request to {Client.Endpoint}/certificates/{fqdn}/being-obtained.
// Expected response body is a JSON-encoded instance of IsCertificateBeingObtainedResponse.
func (s Service) IsCertificateBeingObtained(fqdn string) (yes bool, err error) {
response := &IsCertificateBeingObtainedResponse{}
err = s.Client.JSON("GET", "/certificates/"+fqdn+"/being-obtained", nil, nil, response)
yes = response.Yes
return
}
// UpdateCertificate changes the data of an existing Certificate by making a HTTP POST
// request to {Client.Endpoint}/certificates/{fqdn}. Post body is a JSON-encoded
// certificate.Options instance.
func (s Service) UpdateCertificate(fqdn string, o *certificate.Options) (c *certificate.Certificate, err error) {
body, err := json.Marshal(o)
if err != nil {
return
}
err = s.Client.JSON("POST", "/certificates/"+fqdn, nil, bytes.NewReader(body), c)
return
}
// DeleteCertificate deletes an existing Certificate by making a HTTP DELETE request
// to {Client.Endpoint}/certificates/{fqdn}.
func (s Service) DeleteCertificate(fqdn string) (c *certificate.Certificate, err error) {
err = s.Client.JSON("DELETE", "/certificates/"+fqdn, nil, nil, c)
return
}
// Certificates retrieves a paginated list of Certificate instances
// ordered by FQDN, by making a HTTP GET request to {Client.Endpoint}/certificates.
func (s Service) Certificates(start string, limit int) (page *certificate.CertificatesPage, err error) {
query := url.Values{}
if start != "" {
query.Set("start", start)
}
if limit > 0 {
query.Set("limit", strconv.Itoa(limit))
}
err = s.Client.JSON("GET", "/certificates", query, nil, page)
return
}
// CertificatesInfoByExpiry retrieves a paginated list of Info instances
// ordered by expiration time by making a HTTP GET request to
// {Client.Endpoint}/certificates-info-by-expiry.
func (s Service) CertificatesInfoByExpiry(since time.Time, start string, limit int) (page *certificate.InfosPage, err error) {
query := url.Values{}
if start != "" {
query.Set("start", start)
}
if limit > 0 {
query.Set("limit", strconv.Itoa(limit))
}
if !since.IsZero() {
query.Set("since", since.String())
}
err = s.Client.JSON("GET", "/certificates-info-by-expiry", query, nil, page)
return
}
// ACMEUser returns ACME user with ACME authentication details by making a HTTP GET
// request to {Client.Endpoint}/acme/user.
func (s Service) ACMEUser() (u *certificate.ACMEUser, err error) {
err = s.Client.JSON("GET", "/acme/user", nil, nil, u)
return
}
// RegisterACMEUserRequest is a structure that is passed as JSON-encoded body
// to RegisterACMEUser HTTP request.
type RegisterACMEUserRequest struct {
DirectoryURL string `json:"directory-url"`
Email string `json:"email"`
}
// RegisterACMEUser registers and saves ACME user authentication data by making a
// HTTP POST request to {Client.Endpoint}/acme/user. Post body is a JSON-encoded
// RegisterACMEUserRequest instance.
func (s Service) RegisterACMEUser(directoryURL, email string) (u *certificate.ACMEUser, err error) {
body, err := json.Marshal(RegisterACMEUserRequest{
DirectoryURL: directoryURL,
Email: email,
})
if err != nil {
return
}
err = s.Client.JSON("POST", "/acme/user", nil, bytes.NewReader(body), u)
return
}
// ACMEChallenge returns an instance of ACMEChallenge for a FQDN by making a
// HTTP GET request to {Client.Endpoint}/acme/challenges/{fqdn}.
func (s Service) ACMEChallenge(fqdn string) (c *certificate.ACMEChallenge, err error) {
err = s.Client.JSON("GET", "/acme/challenges/"+fqdn, nil, nil, c)
return
}
// UpdateACMEChallenge alters the fields of existing ACMEChallenge by making a
// HTTP POST request to {Client.Endpoint}/acme/challenges/{fqdn}. Post body is a JSON-encoded
// certificate.ACMEChallengeOptions instance.
func (s Service) UpdateACMEChallenge(fqdn string, o *certificate.ACMEChallengeOptions) (c *certificate.ACMEChallenge, err error) {
body, err := json.Marshal(o)
if err != nil {
return
}
err = s.Client.JSON("POST", "/acme/challenges/"+fqdn, nil, bytes.NewReader(body), c)
return
}
// DeleteACMEChallenge deletes an existing ACMEChallenge for a provided FQDN
// and returns it by making a HTTP DELETE request to {Client.Endpoint}/acme/challenges/{fqdn}.
func (s Service) DeleteACMEChallenge(fqdn string) (c *certificate.ACMEChallenge, err error) {
err = s.Client.JSON("DELETE", "/acme/challenges/"+fqdn, nil, nil, c)
return
}
// ACMEChallenges retrieves a paginated list of ACMEChallenge instances by making a
// HTTP GET request to {Client.Endpoint}/acme/challenges.
func (s Service) ACMEChallenges(start string, limit int) (page *certificate.ACMEChallengesPage, err error) {
query := url.Values{}
if start != "" {
query.Set("start", start)
}
if limit > 0 {
query.Set("limit", strconv.Itoa(limit))
}
err = s.Client.JSON("GET", "/acme/challenges", query, nil, page)
return
}