@@ -11,9 +11,8 @@ import (
1111
1212 "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
1313 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
14- "github.com/aliyun/alibaba-cloud-sdk-go/sdk/resource"
15- "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
1614 "github.com/aliyun/alibaba-cloud-sdk-go/services/location"
15+ "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
1716 "github.com/hashicorp/go-cleanhttp"
1817 "github.com/hashicorp/terraform/version"
1918 "log"
@@ -44,7 +43,7 @@ func New() backend.Backend {
4443 Type : schema .TypeString ,
4544 Optional : true ,
4645 Description : "Alibaba Cloud Security Token" ,
47- DefaultFunc : schema .EnvDefaultFunc ("ALICLOUD_SECURITY_TOKEN" , os . Getenv ( "SECURITY_TOKEN" ) ),
46+ DefaultFunc : schema .EnvDefaultFunc ("ALICLOUD_SECURITY_TOKEN" , "" ),
4847 },
4948
5049 "region" : & schema.Schema {
@@ -53,7 +52,12 @@ func New() backend.Backend {
5352 Description : "The region of the OSS bucket." ,
5453 DefaultFunc : schema .EnvDefaultFunc ("ALICLOUD_REGION" , os .Getenv ("ALICLOUD_DEFAULT_REGION" )),
5554 },
56-
55+ "tablestore_endpoint" : {
56+ Type : schema .TypeString ,
57+ Optional : true ,
58+ Description : "A custom endpoint for the TableStore API" ,
59+ DefaultFunc : schema .EnvDefaultFunc ("ALICLOUD_TABLESTORE_ENDPOINT" , "" ),
60+ },
5761 "endpoint" : {
5862 Type : schema .TypeString ,
5963 Optional : true ,
@@ -67,30 +71,38 @@ func New() backend.Backend {
6771 Description : "The name of the OSS bucket" ,
6872 },
6973
70- "path " : & schema.Schema {
74+ "prefix " : & schema.Schema {
7175 Type : schema .TypeString ,
72- Required : true ,
73- Description : "The path relative to your object storage directory where the state file will be stored." ,
76+ Optional : true ,
77+ Description : "The directory where state files will be saved inside the bucket" ,
78+ Default : "env:" ,
79+ ValidateFunc : func (v interface {}, s string ) ([]string , []error ) {
80+ prefix := v .(string )
81+ if strings .HasPrefix (prefix , "/" ) || strings .HasPrefix (prefix , "./" ) {
82+ return nil , []error {fmt .Errorf ("workspace_key_prefix must not start with '/' or './'" )}
83+ }
84+ return nil , nil
85+ },
7486 },
7587
76- "name " : & schema.Schema {
88+ "key " : & schema.Schema {
7789 Type : schema .TypeString ,
7890 Optional : true ,
79- Description : "The name of the state file inside the bucket" ,
91+ Description : "The path of the state file inside the bucket" ,
8092 ValidateFunc : func (v interface {}, s string ) ([]string , []error ) {
8193 if strings .HasPrefix (v .(string ), "/" ) || strings .HasSuffix (v .(string ), "/" ) {
82- return nil , []error {fmt .Errorf ("name can not start and end with '/'" )}
94+ return nil , []error {fmt .Errorf ("key can not start and end with '/'" )}
8395 }
8496 return nil , nil
8597 },
8698 Default : "terraform.tfstate" ,
8799 },
88100
89- "lock " : & schema. Schema {
90- Type : schema .TypeBool ,
101+ "tablestore_table " : {
102+ Type : schema .TypeString ,
91103 Optional : true ,
92- Description : "Whether to lock state access. Defaults to true " ,
93- Default : true ,
104+ Description : "TableStore table for state locking and consistency " ,
105+ Default : "" ,
94106 },
95107
96108 "encrypt" : & schema.Schema {
@@ -130,14 +142,16 @@ type Backend struct {
130142
131143 // The fields below are set from configure
132144 ossClient * oss.Client
145+ otsClient * tablestore.TableStoreClient
133146
134147 bucketName string
135- statePath string
136- stateName string
148+ statePrefix string
149+ stateKey string
137150 serverSideEncryption bool
138151 acl string
139152 endpoint string
140- lock bool
153+ otsEndpoint string
154+ otsTable string
141155}
142156
143157func (b * Backend ) configure (ctx context.Context ) error {
@@ -149,27 +163,20 @@ func (b *Backend) configure(ctx context.Context) error {
149163 d := schema .FromContextBackendConfig (ctx )
150164
151165 b .bucketName = d .Get ("bucket" ).(string )
152- dir := strings .Trim (d .Get ("path" ).(string ), "/" )
153- if strings .HasPrefix (dir , "./" ) {
154- dir = strings .TrimPrefix (dir , "./" )
155-
156- }
157-
158- b .statePath = dir
159- b .stateName = d .Get ("name" ).(string )
166+ b .statePrefix = strings .TrimPrefix (strings .Trim (d .Get ("prefix" ).(string ), "/" ), "./" )
167+ b .stateKey = d .Get ("key" ).(string )
160168 b .serverSideEncryption = d .Get ("encrypt" ).(bool )
161169 b .acl = d .Get ("acl" ).(string )
162- b .lock = d .Get ("lock" ).(bool )
163170
164- access_key := d .Get ("access_key" ).(string )
165- secret_key := d .Get ("secret_key" ).(string )
166- security_token := d .Get ("security_token" ).(string )
171+ accessKey := d .Get ("access_key" ).(string )
172+ secretKey := d .Get ("secret_key" ).(string )
173+ securityToken := d .Get ("security_token" ).(string )
167174 region := d .Get ("region" ).(string )
168175 endpoint := d .Get ("endpoint" ).(string )
169176 schma := "https"
170177
171178 if endpoint == "" {
172- endpointItem , _ := b .getOSSEndpointByRegion (access_key , secret_key , security_token , region )
179+ endpointItem , _ := b .getOSSEndpointByRegion (accessKey , secretKey , securityToken , region )
173180 if endpointItem != nil && len (endpointItem .Endpoint ) > 0 {
174181 if len (endpointItem .Protocols .Protocols ) > 0 {
175182 // HTTP or HTTPS
@@ -191,13 +198,23 @@ func (b *Backend) configure(ctx context.Context) error {
191198 }
192199 log .Printf ("[DEBUG] Instantiate OSS client using endpoint: %#v" , endpoint )
193200 var options []oss.ClientOption
194- if security_token != "" {
195- options = append (options , oss .SecurityToken (security_token ))
201+ if securityToken != "" {
202+ options = append (options , oss .SecurityToken (securityToken ))
196203 }
197204 options = append (options , oss .UserAgent (fmt .Sprintf ("%s/%s" , TerraformUA , TerraformVersion )))
198205
199- client , err := oss .New (endpoint , access_key , secret_key , options ... )
206+ client , err := oss .New (endpoint , accessKey , secretKey , options ... )
200207 b .ossClient = client
208+ otsEndpoint := d .Get ("tablestore_endpoint" ).(string )
209+ if otsEndpoint != "" {
210+ if ! strings .HasPrefix (otsEndpoint , "http" ) {
211+ otsEndpoint = fmt .Sprintf ("%s://%s" , schma , otsEndpoint )
212+ }
213+ b .otsEndpoint = otsEndpoint
214+ parts := strings .Split (strings .TrimPrefix (strings .TrimPrefix (otsEndpoint , "https://" ), "http://" ), "." )
215+ b .otsClient = tablestore .NewClientWithConfig (otsEndpoint , parts [0 ], accessKey , secretKey , securityToken , tablestore .NewDefaultTableStoreConfig ())
216+ }
217+ b .otsTable = d .Get ("tablestore_table" ).(string )
201218
202219 return err
203220}
@@ -222,11 +239,6 @@ func (b *Backend) getOSSEndpointByRegion(access_key, secret_key, security_token,
222239}
223240
224241func getSdkConfig () * sdk.Config {
225- // Fix bug "open /usr/local/go/lib/time/zoneinfo.zip: no such file or directory" which happened in windows.
226- if data , ok := resource .GetTZData ("GMT" ); ok {
227- utils .TZData = data
228- utils .LoadLocationFromTZData = time .LoadLocationFromTZData
229- }
230242 return sdk .NewConfig ().
231243 WithMaxRetryTime (5 ).
232244 WithTimeout (time .Duration (30 ) * time .Second ).
0 commit comments