diff --git a/backend/remote-state/oss/backend_state.go b/backend/remote-state/oss/backend_state.go index a336134be2..1af33d2680 100644 --- a/backend/remote-state/oss/backend_state.go +++ b/backend/remote-state/oss/backend_state.go @@ -57,28 +57,39 @@ func (b *Backend) Workspaces() ([]string, error) { } var options []oss.Option - options = append(options, oss.Prefix(b.statePrefix+"/")) + options = append(options, oss.Prefix(b.statePrefix+"/"), oss.MaxKeys(1000)) resp, err := bucket.ListObjects(options...) - if err != nil { return nil, err } result := []string{backend.DefaultStateName} prefix := b.statePrefix - for _, obj := range resp.Objects { - // we have 3 parts, the state prefix, the workspace name, and the state file: // - if path.Join(b.statePrefix, b.stateKey) == obj.Key { - // filter the default workspace - continue + lastObj := "" + for { + for _, obj := range resp.Objects { + // we have 3 parts, the state prefix, the workspace name, and the state file: // + if path.Join(b.statePrefix, b.stateKey) == obj.Key { + // filter the default workspace + continue + } + lastObj = obj.Key + parts := strings.Split(strings.TrimPrefix(obj.Key, prefix+"/"), "/") + if len(parts) > 0 && parts[0] != "" { + result = append(result, parts[0]) + } } - - parts := strings.Split(strings.TrimPrefix(obj.Key, prefix+"/"), "/") - if len(parts) > 0 && parts[0] != "" { - result = append(result, parts[0]) + if resp.IsTruncated { + if len(options) == 3 { + options[2] = oss.Marker(lastObj) + } else { + options = append(options, oss.Marker(lastObj)) + } + resp, err = bucket.ListObjects(options...) + } else { + break } } - sort.Strings(result[1:]) return result, nil } diff --git a/backend/remote-state/oss/backend_test.go b/backend/remote-state/oss/backend_test.go index c81367bb4c..42f99b7542 100644 --- a/backend/remote-state/oss/backend_test.go +++ b/backend/remote-state/oss/backend_test.go @@ -67,6 +67,44 @@ func TestBackendConfig(t *testing.T) { } } +func TestBackendConfigWorkSpace(t *testing.T) { + testACC(t) + config := map[string]interface{}{ + "region": "cn-beijing", + "bucket": "terraform-backend-oss-test", + "prefix": "mystate", + "key": "first.tfstate", + "tablestore_endpoint": "https://terraformstate.cn-beijing.ots.aliyuncs.com", + "tablestore_table": "TableStore", + } + + b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend) + createOSSBucket(t, b.ossClient, "terraform-backend-oss-test") + defer deleteOSSBucket(t, b.ossClient, "terraform-backend-oss-test") + if _, err := b.Workspaces(); err != nil { + t.Fatal(err.Error()) + } + if !strings.HasPrefix(b.ossClient.Config.Endpoint, "https://oss-cn-beijing") { + t.Fatalf("Incorrect region was provided") + } + if b.bucketName != "terraform-backend-oss-test" { + t.Fatalf("Incorrect bucketName was provided") + } + if b.statePrefix != "mystate" { + t.Fatalf("Incorrect state file path was provided") + } + if b.stateKey != "first.tfstate" { + t.Fatalf("Incorrect keyName was provided") + } + + if b.ossClient.Config.AccessKeyID == "" { + t.Fatalf("No Access Key Id was provided") + } + if b.ossClient.Config.AccessKeySecret == "" { + t.Fatalf("No Secret Access Key was provided") + } +} + func TestBackendConfigProfile(t *testing.T) { testACC(t) config := map[string]interface{}{