-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathaddons.go
186 lines (154 loc) · 5.23 KB
/
addons.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
package scalingo
import (
"context"
"encoding/json"
"io"
"strconv"
"time"
"gopkg.in/errgo.v1"
"github.com/Scalingo/go-scalingo/v7/http"
)
type AddonsService interface {
AddonsList(ctx context.Context, app string) ([]*Addon, error)
AddonProvision(ctx context.Context, app string, params AddonProvisionParams) (AddonRes, error)
AddonDestroy(ctx context.Context, app, addonID string) error
AddonUpgrade(ctx context.Context, app, addonID string, params AddonUpgradeParams) (AddonRes, error)
AddonToken(ctx context.Context, app, addonID string) (string, error)
AddonLogsURL(ctx context.Context, app, addonID string) (string, error)
AddonLogsArchives(ctx context.Context, app, addonID string, page int) (*LogsArchivesResponse, error)
}
var _ AddonsService = (*Client)(nil)
type AddonStatus string
const (
AddonStatusRunning AddonStatus = "running"
AddonStatusProvisioning AddonStatus = "provisioning"
AddonStatusSuspended AddonStatus = "suspended"
)
type Addon struct {
ID string `json:"id"`
AppID string `json:"app_id"`
ResourceID string `json:"resource_id"`
Status AddonStatus `json:"status"`
Plan *Plan `json:"plan"`
AddonProvider *AddonProvider `json:"addon_provider"`
ProvisionedAt time.Time `json:"provisioned_at"`
DeprovisionedAt time.Time `json:"deprovisioned_at"`
}
type AddonsRes struct {
Addons []*Addon `json:"addons"`
}
type AddonRes struct {
Addon Addon `json:"addon"`
Message string `json:"message,omitempty"`
Variables []string `json:"variables,omitempty"`
}
type AddonToken struct {
Token string `json:"token"`
}
type AddonTokenRes struct {
Addon AddonToken `json:"addon"`
}
type AddonLogsURLRes struct {
URL string `json:"url"`
}
func (c *Client) AddonsList(ctx context.Context, app string) ([]*Addon, error) {
var addonsRes AddonsRes
err := c.ScalingoAPI().SubresourceList(ctx, "apps", app, "addons", nil, &addonsRes)
if err != nil {
return nil, errgo.Mask(err, errgo.Any)
}
return addonsRes.Addons, nil
}
func (c *Client) AddonShow(ctx context.Context, app, addonID string) (Addon, error) {
var addonRes AddonRes
err := c.ScalingoAPI().SubresourceGet(ctx, "apps", app, "addons", addonID, nil, &addonRes)
if err != nil {
return Addon{}, errgo.Mask(err, errgo.Any)
}
return addonRes.Addon, nil
}
// AddonProvisionParams gathers all arguments which can be sent to provision an addon
type AddonProvisionParams struct {
AddonProviderID string `json:"addon_provider_id"`
PlanID string `json:"plan_id"`
Options map[string]string `json:"options"`
}
type AddonProvisionParamsWrapper struct {
Addon AddonProvisionParams `json:"addon"`
}
func (c *Client) AddonProvision(ctx context.Context, app string, params AddonProvisionParams) (AddonRes, error) {
var addonRes AddonRes
err := c.ScalingoAPI().SubresourceAdd(ctx, "apps", app, "addons", AddonProvisionParamsWrapper{params}, &addonRes)
if err != nil {
return AddonRes{}, errgo.Mask(err, errgo.Any)
}
return addonRes, nil
}
func (c *Client) AddonDestroy(ctx context.Context, app, addonID string) error {
return c.ScalingoAPI().SubresourceDelete(ctx, "apps", app, "addons", addonID)
}
type AddonUpgradeParams struct {
PlanID string `json:"plan_id"`
}
type AddonUpgradeParamsWrapper struct {
Addon AddonUpgradeParams `json:"addon"`
}
func (c *Client) AddonUpgrade(ctx context.Context, app, addonID string, params AddonUpgradeParams) (AddonRes, error) {
var addonRes AddonRes
err := c.ScalingoAPI().SubresourceUpdate(
ctx, "apps", app, "addons", addonID,
AddonUpgradeParamsWrapper{Addon: params}, &addonRes,
)
if err != nil {
return AddonRes{}, errgo.Mask(err, errgo.Any)
}
return addonRes, nil
}
func (c *Client) AddonToken(ctx context.Context, app, addonID string) (string, error) {
var res AddonTokenRes
err := c.ScalingoAPI().DoRequest(ctx, &http.APIRequest{
Method: "POST",
Endpoint: "/apps/" + app + "/addons/" + addonID + "/token",
}, &res)
if err != nil {
return "", errgo.Notef(err, "fail to get addon token")
}
return res.Addon.Token, nil
}
func (c *Client) AddonLogsURL(ctx context.Context, app, addonID string) (string, error) {
var url AddonLogsURLRes
res, err := c.DBAPI(app, addonID).Do(ctx, &http.APIRequest{
Endpoint: "/databases/" + addonID + "/logs",
})
if err != nil {
return "", errgo.Notef(err, "fail to get log URL")
}
defer res.Body.Close()
err = json.NewDecoder(res.Body).Decode(&url)
if err != nil {
return "", errgo.Notef(err, "invalid response")
}
return url.URL, nil
}
func (c *Client) AddonLogsArchives(ctx context.Context, app, addonID string, page int) (*LogsArchivesResponse, error) {
res, err := c.DBAPI(app, addonID).Do(ctx, &http.APIRequest{
Endpoint: "/databases/" + addonID + "/logs_archives",
Params: map[string]string{
"page": strconv.FormatInt(int64(page), 10),
},
})
if err != nil {
return nil, errgo.Notef(err, "fail to get log archives")
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, errgo.Notef(err, "fail to read body of response")
}
var logsRes = LogsArchivesResponse{}
err = json.Unmarshal(body, &logsRes)
if err != nil {
return nil, errgo.Notef(err, "fail to parse response")
}
return &logsRes, nil
}