/
resource.go
233 lines (207 loc) · 6.72 KB
/
resource.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
package fastly
import (
"fmt"
"net/url"
"sort"
"time"
)
// Resource represents a response from the Fastly API.
type Resource struct {
// CreatedAt is the date and time in ISO 8601 format.
CreatedAt *time.Time `mapstructure:"created_at" json:"created_at"`
// CreatedAt is the date and time in ISO 8601 format.
DeletedAt *time.Time `mapstructure:"deleted_at" json:"deleted_at"`
// HREF is the path to the resource.
HREF string `mapstructure:"href" json:"href"`
// ID is an alphanumeric string identifying the resource link.
ID string `mapstructure:"id" json:"id"`
// Name is the name of the resource being linked to.
Name string `mapstructure:"name" json:"name"`
// ResourceID is the ID of the linked resource.
ResourceID string `mapstructure:"resource_id" json:"resource_id"`
// ResourceType is the type of the linked resource.
ResourceType string `mapstructure:"resource_type" json:"resource_type"`
// ServiceID is an alphanumeric string identifying the service.
ServiceID string `mapstructure:"service_id" json:"service_id"`
// ServiceVersion is an integer identifying a service version.
ServiceVersion string `mapstructure:"version" json:"version"`
// UpdatedAt is the date and time in ISO 8601 format.
UpdatedAt *time.Time `mapstructure:"updated_at" json:"updated_at"`
}
// resourcesByName is a sortable list of resources.
type resourcesByName []*Resource
// Len, Swap, and Less implement the sortable interface.
func (s resourcesByName) Len() int {
return len(s)
}
func (s resourcesByName) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s resourcesByName) Less(i, j int) bool {
return s[i].Name < s[j].Name
}
// ListResourcesInput is used as input to the ListResources function.
type ListResourcesInput struct {
// ServiceID is the ID of the service (required).
ServiceID string
// ServiceVersion is the specific configuration version (required).
ServiceVersion int
}
// ListResources retrieves all resources.
func (c *Client) ListResources(i *ListResourcesInput) ([]*Resource, error) {
if i.ServiceID == "" {
return nil, ErrMissingServiceID
}
if i.ServiceVersion == 0 {
return nil, ErrMissingServiceVersion
}
path := fmt.Sprintf("/service/%s/version/%d/resource", i.ServiceID, i.ServiceVersion)
resp, err := c.Get(path, nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var rs []*Resource
if err := decodeBodyMap(resp.Body, &rs); err != nil {
return nil, err
}
sort.Stable(resourcesByName(rs))
return rs, nil
}
// CreateResourceInput is used as input to the CreateResource function.
type CreateResourceInput struct {
// Name is the name of the resource being linked to (e.g. a kv store).
//
// NOTE: This doesn't have to match the actual resource name, i.e. the name
// of the KV Store. Rather, this is an opportunity for you to use an
// 'alias' for your KV Store. So your service will now refer to the
// KV Store using this name.
Name *string `url:"name,omitempty"`
// ResourceID is the ID of the linked resource.
ResourceID *string `url:"resource_id,omitempty"`
// ServiceID is the ID of the service (required).
ServiceID string `url:"-"`
// ServiceVersion is the specific configuration version (required).
ServiceVersion int `url:"-"`
}
// CreateResource creates a new resource.
func (c *Client) CreateResource(i *CreateResourceInput) (*Resource, error) {
if i.ServiceID == "" {
return nil, ErrMissingServiceID
}
if i.ServiceVersion == 0 {
return nil, ErrMissingServiceVersion
}
path := fmt.Sprintf("/service/%s/version/%d/resource", i.ServiceID, i.ServiceVersion)
resp, err := c.PostForm(path, i, nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var r *Resource
if err := decodeBodyMap(resp.Body, &r); err != nil {
return nil, err
}
return r, nil
}
// GetResourceInput is used as input to the GetResource function.
type GetResourceInput struct {
// ID is an alphanumeric string identifying the resource link (required).
ID string
// ServiceID is the ID of the service (required).
ServiceID string
// ServiceVersion is the specific configuration version (required).
ServiceVersion int
}
// GetResource retrieves the specified resource.
func (c *Client) GetResource(i *GetResourceInput) (*Resource, error) {
if i.ID == "" {
return nil, ErrMissingID
}
if i.ServiceID == "" {
return nil, ErrMissingServiceID
}
if i.ServiceVersion == 0 {
return nil, ErrMissingServiceVersion
}
path := fmt.Sprintf("/service/%s/version/%d/resource/%s", i.ServiceID, i.ServiceVersion, url.PathEscape(i.ID))
resp, err := c.Get(path, nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var r *Resource
if err := decodeBodyMap(resp.Body, &r); err != nil {
return nil, err
}
return r, nil
}
// UpdateResourceInput is used as input to the UpdateResource function.
type UpdateResourceInput struct {
// Name is the name of the resource being linked to (e.g. a kv store).
Name *string `url:"name,omitempty"`
// ID is an alphanumeric string identifying the resource link (required).
ID string `url:"-"`
// ServiceID is the ID of the service (required).
ServiceID string `url:"-"`
// ServiceVersion is the specific configuration version (required).
ServiceVersion int `url:"-"`
}
// UpdateResource updates the specified resource.
func (c *Client) UpdateResource(i *UpdateResourceInput) (*Resource, error) {
if i.ID == "" {
return nil, ErrMissingID
}
if i.ServiceID == "" {
return nil, ErrMissingServiceID
}
if i.ServiceVersion == 0 {
return nil, ErrMissingServiceVersion
}
path := fmt.Sprintf("/service/%s/version/%d/resource/%s", i.ServiceID, i.ServiceVersion, url.PathEscape(i.ID))
resp, err := c.PutForm(path, i, nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var b *Resource
if err := decodeBodyMap(resp.Body, &b); err != nil {
return nil, err
}
return b, nil
}
// DeleteResourceInput is the input parameter to DeleteResource.
type DeleteResourceInput struct {
// ID is an alphanumeric string identifying the resource link (required).
ID string `url:"-"`
// ServiceID is the ID of the service (required).
ServiceID string `url:"-"`
// ServiceVersion is the specific configuration version (required).
ServiceVersion int `url:"-"`
}
// DeleteResource deletes the specified resource.
func (c *Client) DeleteResource(i *DeleteResourceInput) error {
if i.ID == "" {
return ErrMissingID
}
if i.ServiceID == "" {
return ErrMissingServiceID
}
if i.ServiceVersion == 0 {
return ErrMissingServiceVersion
}
path := fmt.Sprintf("/service/%s/version/%d/resource/%s", i.ServiceID, i.ServiceVersion, url.PathEscape(i.ID))
resp, err := c.Delete(path, nil)
if err != nil {
return err
}
defer resp.Body.Close()
var r *statusResp
if err := decodeBodyMap(resp.Body, &r); err != nil {
return err
}
if !r.Ok() {
return fmt.Errorf("not ok")
}
return nil
}