Skip to content

Commit 3cc5881

Browse files
author
Sander van Harmelen
committed
backend/remote: use a search query and use pagination
To prevent making unnecessary heavy calls to the backend, we should use a search query to limit the result. But even if we use a search query, we should still use the pagination details to make sure we retrieved all items.
1 parent cd8fcf7 commit 3cc5881

File tree

3 files changed

+62
-29
lines changed

3 files changed

+62
-29
lines changed

backend/remote/backend.go

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,10 @@ func (b *Remote) State(workspace string) (state.State, error) {
251251
}
252252

253253
// Configure the remote workspace name.
254-
if workspace == backend.DefaultStateName {
254+
switch {
255+
case workspace == backend.DefaultStateName:
255256
workspace = b.workspace
256-
} else if b.prefix != "" && !strings.HasPrefix(workspace, b.prefix) {
257+
case b.prefix != "" && !strings.HasPrefix(workspace, b.prefix):
257258
workspace = b.prefix + workspace
258259
}
259260

@@ -293,9 +294,10 @@ func (b *Remote) DeleteState(workspace string) error {
293294
}
294295

295296
// Configure the remote workspace name.
296-
if workspace == backend.DefaultStateName {
297+
switch {
298+
case workspace == backend.DefaultStateName:
297299
workspace = b.workspace
298-
} else if b.prefix != "" && !strings.HasPrefix(workspace, b.prefix) {
300+
case b.prefix != "" && !strings.HasPrefix(workspace, b.prefix):
299301
workspace = b.prefix + workspace
300302
}
301303

@@ -336,20 +338,39 @@ func (b *Remote) states() ([]string, error) {
336338
}
337339

338340
options := tfe.WorkspaceListOptions{}
339-
wl, err := b.client.Workspaces.List(context.Background(), b.organization, options)
340-
if err != nil {
341-
return nil, err
341+
switch {
342+
case b.workspace != "":
343+
options.Search = tfe.String(b.workspace)
344+
case b.prefix != "":
345+
options.Search = tfe.String(b.prefix)
342346
}
343347

348+
// Create a slice to contain all the names.
344349
var names []string
345-
for _, w := range wl.Items {
346-
if b.workspace != "" && w.Name == b.workspace {
347-
names = append(names, backend.DefaultStateName)
348-
continue
350+
351+
for {
352+
wl, err := b.client.Workspaces.List(context.Background(), b.organization, options)
353+
if err != nil {
354+
return nil, err
349355
}
350-
if b.prefix != "" && strings.HasPrefix(w.Name, b.prefix) {
351-
names = append(names, strings.TrimPrefix(w.Name, b.prefix))
356+
357+
for _, w := range wl.Items {
358+
if b.workspace != "" && w.Name == b.workspace {
359+
names = append(names, backend.DefaultStateName)
360+
continue
361+
}
362+
if b.prefix != "" && strings.HasPrefix(w.Name, b.prefix) {
363+
names = append(names, strings.TrimPrefix(w.Name, b.prefix))
364+
}
352365
}
366+
367+
// Exit the loop when we've seen all pages.
368+
if wl.CurrentPage == wl.TotalPages {
369+
break
370+
}
371+
372+
// Update the page number to get the next page.
373+
options.PageNumber = wl.NextPage
353374
}
354375

355376
// Sort the result so we have consistent output.
@@ -361,9 +382,10 @@ func (b *Remote) states() ([]string, error) {
361382
// Operation implements backend.Enhanced
362383
func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend.RunningOperation, error) {
363384
// Configure the remote workspace name.
364-
if op.Workspace == backend.DefaultStateName {
385+
switch {
386+
case op.Workspace == backend.DefaultStateName:
365387
op.Workspace = b.workspace
366-
} else if b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix) {
388+
case b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix):
367389
op.Workspace = b.prefix + op.Workspace
368390
}
369391

backend/remote/backend_mock.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,17 +413,38 @@ func newMockWorkspaces(client *mockClient) *mockWorkspaces {
413413
}
414414

415415
func (m *mockWorkspaces) List(ctx context.Context, organization string, options tfe.WorkspaceListOptions) (*tfe.WorkspaceList, error) {
416+
dummyWorkspaces := 10
416417
wl := &tfe.WorkspaceList{}
418+
419+
// We return dummy workspaces for the first page to test pagination.
420+
if options.PageNumber <= 1 {
421+
for i := 0; i < dummyWorkspaces; i++ {
422+
wl.Items = append(wl.Items, &tfe.Workspace{
423+
ID: generateID("ws-"),
424+
Name: fmt.Sprintf("dummy-workspace-%d", i),
425+
})
426+
}
427+
428+
wl.Pagination = &tfe.Pagination{
429+
CurrentPage: 1,
430+
NextPage: 2,
431+
TotalPages: 2,
432+
TotalCount: len(wl.Items) + len(m.workspaceIDs),
433+
}
434+
435+
return wl, nil
436+
}
437+
438+
// The second page will return any actual results.
417439
for _, w := range m.workspaceIDs {
418440
wl.Items = append(wl.Items, w)
419441
}
420442

421443
wl.Pagination = &tfe.Pagination{
422-
CurrentPage: 1,
423-
NextPage: 1,
444+
CurrentPage: 2,
424445
PreviousPage: 1,
425-
TotalPages: 1,
426-
TotalCount: len(wl.Items),
446+
TotalPages: 2,
447+
TotalCount: len(wl.Items) + dummyWorkspaces,
427448
}
428449

429450
return wl, nil

backend/remote/test-fixtures/plan-scaleout/main.tf

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)