-
Notifications
You must be signed in to change notification settings - Fork 127
/
Copy pathapp.go
306 lines (271 loc) · 10.4 KB
/
app.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
package client
import (
"context"
"net/url"
"github.com/cloudfoundry/go-cfclient/v3/internal/path"
"github.com/cloudfoundry/go-cfclient/v3/resource"
)
type AppClient commonClient
// AppListOptions list filters
type AppListOptions struct {
*ListOptions
GUIDs Filter `qs:"guids"`
Names Filter `qs:"names"`
OrganizationGUIDs Filter `qs:"organization_guids"`
SpaceGUIDs Filter `qs:"space_guids"`
Stacks Filter `qs:"stacks"`
LifecycleType resource.LifecycleType `qs:"lifecycle_type"`
Include resource.AppIncludeType `qs:"include"`
}
// NewAppListOptions creates new options to pass to list
func NewAppListOptions() *AppListOptions {
return &AppListOptions{
ListOptions: NewListOptions(),
}
}
func (o AppListOptions) ToQueryString() (url.Values, error) {
return o.ListOptions.ToQueryString(o)
}
// Create a new app
func (c *AppClient) Create(ctx context.Context, r *resource.AppCreate) (*resource.App, error) {
var app resource.App
_, err := c.client.post(ctx, "/v3/apps", r, &app)
if err != nil {
return nil, err
}
return &app, nil
}
// Delete the specified app asynchronously and return a jobGUID.
func (c *AppClient) Delete(ctx context.Context, guid string) (string, error) {
return c.client.delete(ctx, path.Format("/v3/apps/%s", guid))
}
// First returns the first app matching the options or an error when less than 1 match
func (c *AppClient) First(ctx context.Context, opts *AppListOptions) (*resource.App, error) {
return First[*AppListOptions, *resource.App](opts, func(opts *AppListOptions) ([]*resource.App, *Pager, error) {
return c.List(ctx, opts)
})
}
// Get the specified app
func (c *AppClient) Get(ctx context.Context, guid string) (*resource.App, error) {
var app resource.App
err := c.client.get(ctx, path.Format("/v3/apps/%s", guid), &app)
if err != nil {
return nil, err
}
return &app, nil
}
// GetIncludeSpace allows callers to fetch an app and include the parent space
func (c *AppClient) GetIncludeSpace(ctx context.Context, guid string) (*resource.App, *resource.Space, error) {
var app resource.AppWithIncluded
err := c.client.get(ctx, path.Format("/v3/apps/%s?include=%s", guid, resource.AppIncludeSpace), &app)
if err != nil {
return nil, nil, err
}
return &app.App, app.Included.Spaces[0], nil
}
// GetIncludeSpaceAndOrganization allows callers to fetch an app and include the parent space and organizations
func (c *AppClient) GetIncludeSpaceAndOrganization(ctx context.Context, guid string) (*resource.App, *resource.Space, *resource.Organization, error) {
var app resource.AppWithIncluded
err := c.client.get(ctx, path.Format("/v3/apps/%s?include=%s", guid, resource.AppIncludeSpaceOrganization), &app)
if err != nil {
return nil, nil, nil, err
}
return &app.App, app.Included.Spaces[0], app.Included.Organizations[0], nil
}
// GetEnvironment retrieves the environment variables that will be provided to an app at runtime.
// It will include environment variables for Environment Variable Groups and Service Bindings.
func (c *AppClient) GetEnvironment(ctx context.Context, guid string) (*resource.AppEnvironment, error) {
var appEnv resource.AppEnvironment
err := c.client.get(ctx, path.Format("/v3/apps/%s/env", guid), &appEnv)
if err != nil {
return nil, err
}
return &appEnv, nil
}
// GetEnvironmentVariables retrieves the environment variables that are associated with the given app
func (c *AppClient) GetEnvironmentVariables(ctx context.Context, guid string) (map[string]*string, error) {
var appEnv resource.EnvVarResponse
err := c.client.get(ctx, path.Format("/v3/apps/%s/environment_variables", guid), &appEnv)
if err != nil {
return nil, err
}
return appEnv.Var, nil
}
// List pages all the apps the user has access to
func (c *AppClient) List(ctx context.Context, opts *AppListOptions) ([]*resource.App, *Pager, error) {
if opts == nil {
opts = NewAppListOptions()
}
opts.Include = resource.AppIncludeNone
var res resource.AppList
err := c.client.list(ctx, "/v3/apps", opts.ToQueryString, &res)
if err != nil {
return nil, nil, err
}
pager := NewPager(res.Pagination)
return res.Resources, pager, nil
}
// ListAll retrieves all apps the user has access to
func (c *AppClient) ListAll(ctx context.Context, opts *AppListOptions) ([]*resource.App, error) {
if opts == nil {
opts = NewAppListOptions()
}
return AutoPage[*AppListOptions, *resource.App](opts, func(opts *AppListOptions) ([]*resource.App, *Pager, error) {
return c.List(ctx, opts)
})
}
// ListIncludeSpaces page all apps the user has access to and include the associated spaces
func (c *AppClient) ListIncludeSpaces(ctx context.Context, opts *AppListOptions) ([]*resource.App, []*resource.Space, *Pager, error) {
if opts == nil {
opts = NewAppListOptions()
}
opts.Include = resource.AppIncludeSpace
var res resource.AppList
err := c.client.list(ctx, "/v3/apps", opts.ToQueryString, &res)
if err != nil {
return nil, nil, nil, err
}
pager := NewPager(res.Pagination)
return res.Resources, res.Included.Spaces, pager, nil
}
// ListIncludeSpacesAll retrieves all apps the user has access to and include the associated spaces
func (c *AppClient) ListIncludeSpacesAll(ctx context.Context, opts *AppListOptions) ([]*resource.App, []*resource.Space, error) {
if opts == nil {
opts = NewAppListOptions()
}
var all []*resource.App
var allSpaces []*resource.Space
for {
page, spaces, pager, err := c.ListIncludeSpaces(ctx, opts)
if err != nil {
return nil, nil, err
}
all = append(all, page...)
allSpaces = append(allSpaces, spaces...)
if !pager.HasNextPage() {
break
}
pager.NextPage(opts)
}
return all, allSpaces, nil
}
// ListIncludeSpacesAndOrganizations page all apps the user has access to and include the associated spaces and organizations
func (c *AppClient) ListIncludeSpacesAndOrganizations(ctx context.Context, opts *AppListOptions) ([]*resource.App, []*resource.Space, []*resource.Organization, *Pager, error) {
if opts == nil {
opts = NewAppListOptions()
}
opts.Include = resource.AppIncludeSpaceOrganization
var res resource.AppList
err := c.client.list(ctx, "/v3/apps", opts.ToQueryString, &res)
if err != nil {
return nil, nil, nil, nil, err
}
pager := NewPager(res.Pagination)
return res.Resources, res.Included.Spaces, res.Included.Organizations, pager, nil
}
// ListIncludeSpacesAndOrganizationsAll retrieves all apps the user has access to and include the associated spaces and organizations
func (c *AppClient) ListIncludeSpacesAndOrganizationsAll(ctx context.Context, opts *AppListOptions) ([]*resource.App, []*resource.Space, []*resource.Organization, error) {
if opts == nil {
opts = NewAppListOptions()
}
var all []*resource.App
var allSpaces []*resource.Space
var allOrgs []*resource.Organization
for {
page, spaces, orgs, pager, err := c.ListIncludeSpacesAndOrganizations(ctx, opts)
if err != nil {
return nil, nil, nil, err
}
all = append(all, page...)
allSpaces = append(allSpaces, spaces...)
allOrgs = append(allOrgs, orgs...)
if !pager.HasNextPage() {
break
}
pager.NextPage(opts)
}
return all, allSpaces, allOrgs, nil
}
// Permissions gets the current user’s permissions for the given app.
// If a user can see an app, then they can see its basic data.
// Only admin, read-only admins, and space developers can read sensitive data.
func (c *AppClient) Permissions(ctx context.Context, guid string) (*resource.AppPermissions, error) {
var appPerms resource.AppPermissions
err := c.client.get(ctx, path.Format("/v3/apps/%s/permissions", guid), &appPerms)
if err != nil {
return nil, err
}
return &appPerms, nil
}
// Restart will synchronously stop and start an application.
// Unlike the start and stop actions, this endpoint will error if the app is not successfully stopped in the runtime.
// For restarting applications without downtime, see the Deployments resource.
func (c *AppClient) Restart(ctx context.Context, guid string) (*resource.App, error) {
var app resource.App
_, err := c.client.post(ctx, path.Format("/v3/apps/%s/actions/restart", guid), nil, &app)
if err != nil {
return nil, err
}
return &app, nil
}
// SetEnvironmentVariables updates the environment variables associated with the given app.
// The variables given in the request will be merged with the existing app environment variables.
// Any requested variables with a value of null will be removed from the app.
//
// Environment variable names may not start with VCAP_
// PORT is not a valid environment variable.
func (c *AppClient) SetEnvironmentVariables(ctx context.Context, guid string, envRequest map[string]*string) (map[string]*string, error) {
req := &resource.EnvVar{
Var: envRequest,
}
var res resource.EnvVarResponse
_, err := c.client.patch(ctx, path.Format("/v3/apps/%s/environment_variables", guid), req, &res)
if err != nil {
return nil, err
}
return res.Var, nil
}
// Single returns a single app matching the options or an error if not exactly 1 match
func (c *AppClient) Single(ctx context.Context, opts *AppListOptions) (*resource.App, error) {
return Single[*AppListOptions, *resource.App](opts, func(opts *AppListOptions) ([]*resource.App, *Pager, error) {
return c.List(ctx, opts)
})
}
// Start the app if not already started
func (c *AppClient) Start(ctx context.Context, guid string) (*resource.App, error) {
var app resource.App
_, err := c.client.post(ctx, path.Format("/v3/apps/%s/actions/start", guid), nil, &app)
if err != nil {
return nil, err
}
return &app, nil
}
// Stop the app if not already stopped
func (c *AppClient) Stop(ctx context.Context, guid string) (*resource.App, error) {
var app resource.App
_, err := c.client.post(ctx, path.Format("/v3/apps/%s/actions/stop", guid), nil, &app)
if err != nil {
return nil, err
}
return &app, nil
}
// Update the specified attributes of the app
func (c *AppClient) Update(ctx context.Context, guid string, r *resource.AppUpdate) (*resource.App, error) {
var app resource.App
_, err := c.client.patch(ctx, path.Format("/v3/apps/%s", guid), r, &app)
if err != nil {
return nil, err
}
return &app, nil
}
// SSHEnabled returns if an application’s runtime environment will accept ssh connections.
// If ssh is disabled, the reason field will describe whether it is disabled globally,
// at the space level, or at the app level.
func (c *AppClient) SSHEnabled(ctx context.Context, guid string) (*resource.AppSSHEnabled, error) {
var appSSH resource.AppSSHEnabled
err := c.client.get(ctx, path.Format("/v3/apps/%s/ssh_enabled", guid), &appSSH)
if err != nil {
return nil, err
}
return &appSSH, nil
}