forked from fastly/go-fastly
/
version.go
335 lines (279 loc) · 8.19 KB
/
version.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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
package fastly
import (
"fmt"
"sort"
)
// Version represents a distinct configuration version.
type Version struct {
Number int `mapstructure:"number"`
Comment string `mapstructure:"comment"`
ServiceID string `mapstructure:"service_id"`
Active bool `mapstructure:"active"`
Locked bool `mapstructure:"locked"`
Deployed bool `mapstructure:"deployed"`
Staging bool `mapstructure:"staging"`
Testing bool `mapstructure:"testing"`
}
// versionsByNumber is a sortable list of versions. This is used by the version
// `List()` function to sort the API responses.
type versionsByNumber []*Version
// Len, Swap, and Less implement the sortable interface.
func (s versionsByNumber) Len() int { return len(s) }
func (s versionsByNumber) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s versionsByNumber) Less(i, j int) bool {
return s[i].Number < s[j].Number
}
// ListVersionsInput is the input to the ListVersions function.
type ListVersionsInput struct {
// Service is the ID of the service (required).
Service string
}
// ListVersions returns the full list of all versions of the given service.
func (c *Client) ListVersions(i *ListVersionsInput) ([]*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
path := fmt.Sprintf("/service/%s/version", i.Service)
resp, err := c.Get(path, nil)
if err != nil {
return nil, err
}
var e []*Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
sort.Sort(versionsByNumber(e))
return e, nil
}
// LatestVersionInput is the input to the LatestVersion function.
type LatestVersionInput struct {
// Service is the ID of the service (required).
Service string
}
// LatestVersion fetches the latest version. If there are no versions, this
// function will return nil (but not an error).
func (c *Client) LatestVersion(i *LatestVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
list, err := c.ListVersions(&ListVersionsInput{Service: i.Service})
if err != nil {
return nil, err
}
if len(list) < 1 {
return nil, nil
}
e := list[len(list)-1]
return e, nil
}
// CreateVersionInput is the input to the CreateVersion function.
type CreateVersionInput struct {
// Service is the ID of the service (required).
Service string
}
// CreateVersion constructs a new version. There are no request parameters, but
// you should consult the resulting version number. Note that `CloneVersion` is
// preferred in almost all scenarios, since `Create()` creates a _blank_
// configuration where `Clone()` builds off of an existing configuration.
func (c *Client) CreateVersion(i *CreateVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
path := fmt.Sprintf("/service/%s/version", i.Service)
resp, err := c.Post(path, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}
// GetVersionInput is the input to the GetVersion function.
type GetVersionInput struct {
// Service is the ID of the service (required).
Service string
// Version is the version number to fetch (required).
Version int
}
// GetVersion fetches a version with the given information.
func (c *Client) GetVersion(i *GetVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
if i.Version == 0 {
return nil, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d", i.Service, i.Version)
resp, err := c.Get(path, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}
// UpdateVersionInput is the input to the UpdateVersion function.
type UpdateVersionInput struct {
// Service is the ID of the service. Version is the specific configuration
// version. Both fields are required.
Service string
Version int
Comment string `form:"comment,omitempty"`
}
// UpdateVersion updates the given version
func (c *Client) UpdateVersion(i *UpdateVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
if i.Version == 0 {
return nil, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d", i.Service, i.Version)
resp, err := c.PutForm(path, i, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}
// ActivateVersionInput is the input to the ActivateVersion function.
type ActivateVersionInput struct {
// Service is the ID of the service. Version is the specific configuration
// version. Both fields are required.
Service string
Version int
}
// ActivateVersion activates the given version.
func (c *Client) ActivateVersion(i *ActivateVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
if i.Version == 0 {
return nil, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d/activate", i.Service, i.Version)
resp, err := c.Put(path, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}
// DeactivateVersionInput is the input to the DeactivateVersion function.
type DeactivateVersionInput struct {
// Service is the ID of the service. Version is the specific configuration
// version. Both fields are required.
Service string
Version int
}
// DeactivateVersion deactivates the given version.
func (c *Client) DeactivateVersion(i *DeactivateVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
if i.Version == 0 {
return nil, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d/deactivate", i.Service, i.Version)
resp, err := c.Put(path, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}
// CloneVersionInput is the input to the CloneVersion function.
type CloneVersionInput struct {
// Service is the ID of the service. Version is the specific configuration
// version. Both fields are required.
Service string
Version int
}
// CloneVersion creates a clone of the version with and returns a new
// configuration version with all the same configuration options, but an
// incremented number.
func (c *Client) CloneVersion(i *CloneVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
if i.Version == 0 {
return nil, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d/clone", i.Service, i.Version)
resp, err := c.Put(path, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}
// ValidateVersionInput is the input to the ValidateVersion function.
type ValidateVersionInput struct {
// Service is the ID of the service. Version is the specific configuration
// version. Both fields are required.
Service string
Version int
}
// ValidateVersion validates if the given version is okay.
func (c *Client) ValidateVersion(i *ValidateVersionInput) (bool, string, error) {
var msg string
if i.Service == "" {
return false, msg, ErrMissingService
}
if i.Version == 0 {
return false, msg, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d/validate", i.Service, i.Version)
resp, err := c.Get(path, nil)
if err != nil {
return false, msg, err
}
var r *statusResp
if err := decodeJSON(&r, resp.Body); err != nil {
return false, msg, err
}
msg = r.Msg
return r.Ok(), msg, nil
}
// LockVersionInput is the input to the LockVersion function.
type LockVersionInput struct {
// Service is the ID of the service. Version is the specific configuration
// version. Both fields are required.
Service string
Version int
}
// LockVersion locks the specified version.
func (c *Client) LockVersion(i *LockVersionInput) (*Version, error) {
if i.Service == "" {
return nil, ErrMissingService
}
if i.Version == 0 {
return nil, ErrMissingVersion
}
path := fmt.Sprintf("/service/%s/version/%d/lock", i.Service, i.Version)
resp, err := c.Put(path, nil)
if err != nil {
return nil, err
}
var e *Version
if err := decodeJSON(&e, resp.Body); err != nil {
return nil, err
}
return e, nil
}