backend/remote-state/gcloud: Refactor Backend.States().
The previous code listed all objects in the bucket and used local filtering (using regular expressions) to find .tfstate objects. This new code sets the delimiter to "/", which causes GCS to only return objects directly in the given prefix, but not any sub"directories". Fixes: * https://github.com/golang/go/wiki/CodeReviewComments#doc-comments * https://github.com/golang/go/wiki/CodeReviewComments#error-strings
This commit is contained in:
parent
97e1aa7ce9
commit
fabba5c0c8
|
@ -3,6 +3,7 @@ package gcloud
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"cloud.google.com/go/storage"
|
"cloud.google.com/go/storage"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
|
@ -67,7 +68,7 @@ func (b *Backend) configure(ctx context.Context) error {
|
||||||
data := schema.FromContextBackendConfig(b.storageContext)
|
data := schema.FromContextBackendConfig(b.storageContext)
|
||||||
|
|
||||||
b.bucketName = data.Get("bucket").(string)
|
b.bucketName = data.Get("bucket").(string)
|
||||||
b.stateDir = data.Get("state_dir").(string)
|
b.stateDir = strings.TrimLeft(data.Get("state_dir").(string), "/")
|
||||||
|
|
||||||
var tokenSource oauth2.TokenSource
|
var tokenSource oauth2.TokenSource
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package gcloud
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -15,42 +15,38 @@ import (
|
||||||
"google.golang.org/api/iterator"
|
"google.golang.org/api/iterator"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// States returns a list of names for the states found on GCS. The default
|
||||||
|
// state is always returned as the first element in the slice.
|
||||||
func (b *Backend) States() ([]string, error) {
|
func (b *Backend) States() ([]string, error) {
|
||||||
workspaces := []string{backend.DefaultStateName}
|
states := []string{backend.DefaultStateName}
|
||||||
var stateRegex *regexp.Regexp
|
|
||||||
var err error
|
|
||||||
if b.stateDir == "" {
|
|
||||||
stateRegex = regexp.MustCompile(`^(.+)\.tfstate$`)
|
|
||||||
} else {
|
|
||||||
stateRegex, err = regexp.Compile(fmt.Sprintf("^%v/(.+)\\.tfstate$", regexp.QuoteMeta(b.stateDir)))
|
|
||||||
if err != nil {
|
|
||||||
return []string{}, fmt.Errorf("Failed to compile regex for querying states: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bucket := b.storageClient.Bucket(b.bucketName)
|
bucket := b.storageClient.Bucket(b.bucketName)
|
||||||
query := &storage.Query{
|
objs := bucket.Objects(b.storageContext, &storage.Query{
|
||||||
|
Delimiter: "/",
|
||||||
Prefix: b.stateDir,
|
Prefix: b.stateDir,
|
||||||
}
|
})
|
||||||
|
|
||||||
files := bucket.Objects(b.storageContext, query)
|
|
||||||
for {
|
for {
|
||||||
attrs, err := files.Next()
|
attrs, err := objs.Next()
|
||||||
if err == iterator.Done {
|
if err == iterator.Done {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, fmt.Errorf("Failed to query remote states: %v", err)
|
return nil, fmt.Errorf("querying Cloud Storage failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
matches := stateRegex.FindStringSubmatch(attrs.Name)
|
name := path.Base(attrs.Name)
|
||||||
if len(matches) == 2 && matches[1] != backend.DefaultStateName {
|
if !strings.HasSuffix(name, ".tfstate") {
|
||||||
workspaces = append(workspaces, matches[1])
|
continue
|
||||||
|
}
|
||||||
|
st := strings.TrimSuffix(name, ".tfstate")
|
||||||
|
|
||||||
|
if st != backend.DefaultStateName {
|
||||||
|
states = append(states, st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(workspaces[1:])
|
sort.Strings(states[1:])
|
||||||
return workspaces, nil
|
return states, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) DeleteState(name string) error {
|
func (b *Backend) DeleteState(name string) error {
|
||||||
|
|
Loading…
Reference in New Issue