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.
This commit is contained in:
Sander van Harmelen 2018-09-08 11:12:03 +02:00
parent cd8fcf74e0
commit 3cc58813f0
3 changed files with 62 additions and 29 deletions

View File

@ -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
}
@ -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
}
@ -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.
@ -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
}

View File

@ -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

View File

@ -1,10 +0,0 @@
resource "test_instance" "foo" {
count = 3
ami = "bar"
# This is here because at some point it caused a test failure
network_interface {
device_index = 0
description = "Main network interface"
}
}