Skip to content

Commit

Permalink
backend/remote: use a search query and use pagination
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Sander van Harmelen committed Sep 9, 2018
1 parent cd8fcf7 commit 3cc5881
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 29 deletions.
52 changes: 37 additions & 15 deletions backend/remote/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,10 @@ func (b *Remote) State(workspace string) (state.State, error) {
}

// Configure the remote workspace name.
if workspace == backend.DefaultStateName {
switch {
case workspace == backend.DefaultStateName:
workspace = b.workspace
} else if b.prefix != "" && !strings.HasPrefix(workspace, b.prefix) {
case b.prefix != "" && !strings.HasPrefix(workspace, b.prefix):
workspace = b.prefix + workspace
}

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

// Configure the remote workspace name.
if workspace == backend.DefaultStateName {
switch {
case workspace == backend.DefaultStateName:
workspace = b.workspace
} else if b.prefix != "" && !strings.HasPrefix(workspace, b.prefix) {
case b.prefix != "" && !strings.HasPrefix(workspace, b.prefix):
workspace = b.prefix + workspace
}

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

options := tfe.WorkspaceListOptions{}
wl, err := b.client.Workspaces.List(context.Background(), b.organization, options)
if err != nil {
return nil, err
switch {
case b.workspace != "":
options.Search = tfe.String(b.workspace)
case b.prefix != "":
options.Search = tfe.String(b.prefix)
}

// Create a slice to contain all the names.
var names []string
for _, w := range wl.Items {
if b.workspace != "" && w.Name == b.workspace {
names = append(names, backend.DefaultStateName)
continue

for {
wl, err := b.client.Workspaces.List(context.Background(), b.organization, options)
if err != nil {
return nil, err
}
if b.prefix != "" && strings.HasPrefix(w.Name, b.prefix) {
names = append(names, strings.TrimPrefix(w.Name, b.prefix))

for _, w := range wl.Items {
if b.workspace != "" && w.Name == b.workspace {
names = append(names, backend.DefaultStateName)
continue
}
if b.prefix != "" && strings.HasPrefix(w.Name, b.prefix) {
names = append(names, strings.TrimPrefix(w.Name, b.prefix))
}
}

// Exit the loop when we've seen all pages.
if wl.CurrentPage == wl.TotalPages {
break
}

// Update the page number to get the next page.
options.PageNumber = wl.NextPage
}

// Sort the result so we have consistent output.
Expand All @@ -361,9 +382,10 @@ func (b *Remote) states() ([]string, error) {
// Operation implements backend.Enhanced
func (b *Remote) Operation(ctx context.Context, op *backend.Operation) (*backend.RunningOperation, error) {
// Configure the remote workspace name.
if op.Workspace == backend.DefaultStateName {
switch {
case op.Workspace == backend.DefaultStateName:
op.Workspace = b.workspace
} else if b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix) {
case b.prefix != "" && !strings.HasPrefix(op.Workspace, b.prefix):
op.Workspace = b.prefix + op.Workspace
}

Expand Down
29 changes: 25 additions & 4 deletions backend/remote/backend_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,17 +413,38 @@ func newMockWorkspaces(client *mockClient) *mockWorkspaces {
}

func (m *mockWorkspaces) List(ctx context.Context, organization string, options tfe.WorkspaceListOptions) (*tfe.WorkspaceList, error) {
dummyWorkspaces := 10
wl := &tfe.WorkspaceList{}

// We return dummy workspaces for the first page to test pagination.
if options.PageNumber <= 1 {
for i := 0; i < dummyWorkspaces; i++ {
wl.Items = append(wl.Items, &tfe.Workspace{
ID: generateID("ws-"),
Name: fmt.Sprintf("dummy-workspace-%d", i),
})
}

wl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 2,
TotalPages: 2,
TotalCount: len(wl.Items) + len(m.workspaceIDs),
}

return wl, nil
}

// The second page will return any actual results.
for _, w := range m.workspaceIDs {
wl.Items = append(wl.Items, w)
}

wl.Pagination = &tfe.Pagination{
CurrentPage: 1,
NextPage: 1,
CurrentPage: 2,
PreviousPage: 1,
TotalPages: 1,
TotalCount: len(wl.Items),
TotalPages: 2,
TotalCount: len(wl.Items) + dummyWorkspaces,
}

return wl, nil
Expand Down
10 changes: 0 additions & 10 deletions backend/remote/test-fixtures/plan-scaleout/main.tf

This file was deleted.

0 comments on commit 3cc5881

Please sign in to comment.