]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/DreamItGetIT/statuscake/client.go
vendor: github.com/hashicorp/terraform/...@v0.10.0
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / DreamItGetIT / statuscake / client.go
1 package statuscake
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "io"
8 "io/ioutil"
9 "net/http"
10 "net/url"
11 "strings"
12 )
13
14 const apiBaseURL = "https://app.statuscake.com/API"
15
16 type responseBody struct {
17 io.Reader
18 }
19
20 func (r *responseBody) Close() error {
21 return nil
22 }
23
24 // Auth wraps the authorisation headers required for each request
25 type Auth struct {
26 Username string
27 Apikey string
28 }
29
30 func (a *Auth) validate() error {
31 e := make(ValidationError)
32
33 if a.Username == "" {
34 e["Username"] = "is required"
35 }
36
37 if a.Apikey == "" {
38 e["Apikey"] = "is required"
39 }
40
41 if len(e) > 0 {
42 return e
43 }
44
45 return nil
46 }
47
48 type httpClient interface {
49 Do(*http.Request) (*http.Response, error)
50 }
51
52 type apiClient interface {
53 get(string, url.Values) (*http.Response, error)
54 delete(string, url.Values) (*http.Response, error)
55 put(string, url.Values) (*http.Response, error)
56 }
57
58 // Client is the http client that wraps the remote API.
59 type Client struct {
60 c httpClient
61 username string
62 apiKey string
63 testsClient Tests
64 }
65
66 // New returns a new Client
67 func New(auth Auth) (*Client, error) {
68 if err := auth.validate(); err != nil {
69 return nil, err
70 }
71
72 return &Client{
73 c: &http.Client{},
74 username: auth.Username,
75 apiKey: auth.Apikey,
76 }, nil
77 }
78
79 func (c *Client) newRequest(method string, path string, v url.Values, body io.Reader) (*http.Request, error) {
80 url := fmt.Sprintf("%s%s", apiBaseURL, path)
81 if v != nil {
82 url = fmt.Sprintf("%s?%s", url, v.Encode())
83 }
84
85 r, err := http.NewRequest(method, url, body)
86 if err != nil {
87 return nil, err
88 }
89
90 r.Header.Set("Username", c.username)
91 r.Header.Set("API", c.apiKey)
92
93 return r, nil
94 }
95
96 func (c *Client) doRequest(r *http.Request) (*http.Response, error) {
97 resp, err := c.c.Do(r)
98 if err != nil {
99 return nil, err
100 }
101 defer resp.Body.Close()
102
103 if resp.StatusCode < 200 || resp.StatusCode > 299 {
104 return nil, &httpError{
105 status: resp.Status,
106 statusCode: resp.StatusCode,
107 }
108 }
109
110 var aer autheticationErrorResponse
111
112 // We read and save the response body so that if we don't have error messages
113 // we can set it again for future usage
114 b, err := ioutil.ReadAll(resp.Body)
115 if err != nil {
116 return nil, err
117 }
118
119 err = json.Unmarshal(b, &aer)
120 if err == nil && aer.ErrNo == 0 && aer.Error != "" {
121 return nil, &AuthenticationError{
122 errNo: aer.ErrNo,
123 message: aer.Error,
124 }
125 }
126
127 resp.Body = &responseBody{
128 Reader: bytes.NewReader(b),
129 }
130
131 return resp, nil
132 }
133
134 func (c *Client) get(path string, v url.Values) (*http.Response, error) {
135 r, err := c.newRequest("GET", path, v, nil)
136 if err != nil {
137 return nil, err
138 }
139
140 return c.doRequest(r)
141 }
142
143 func (c *Client) put(path string, v url.Values) (*http.Response, error) {
144 r, err := c.newRequest("PUT", path, nil, strings.NewReader(v.Encode()))
145 r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
146
147 if err != nil {
148 return nil, err
149 }
150
151 return c.doRequest(r)
152 }
153
154 func (c *Client) delete(path string, v url.Values) (*http.Response, error) {
155 r, err := c.newRequest("DELETE", path, v, nil)
156 if err != nil {
157 return nil, err
158 }
159
160 return c.doRequest(r)
161 }
162
163 // Tests returns a client that implements the `Tests` API.
164 func (c *Client) Tests() Tests {
165 if c.testsClient == nil {
166 c.testsClient = newTests(c)
167 }
168
169 return c.testsClient
170 }