Make S3 remote state pass tests

TODO: update S3Client to make full use of the state.Locker interface
This commit is contained in:
James Bardin 2017-02-14 18:00:59 -05:00
parent 0ad6f08204
commit 6d32b70637

View File

@ -17,6 +17,7 @@ import (
"github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3"
"github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
uuid "github.com/hashicorp/go-uuid"
terraformAws "github.com/hashicorp/terraform/builtin/providers/aws" terraformAws "github.com/hashicorp/terraform/builtin/providers/aws"
"github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/state"
) )
@ -203,27 +204,31 @@ func (c *S3Client) Delete() error {
return err return err
} }
func (c *S3Client) Lock(info string) error { func (c *S3Client) Lock(info *state.LockInfo) (string, error) {
if c.lockTable == "" { if c.lockTable == "" {
return nil return "", nil
} }
stateName := fmt.Sprintf("%s/%s", c.bucketName, c.keyName) stateName := fmt.Sprintf("%s/%s", c.bucketName, c.keyName)
lockInfo := &state.LockInfo{
Path: stateName, lockID, err := uuid.GenerateUUID()
Created: time.Now().UTC(), if err != nil {
Info: info, return "", err
} }
info.ID = lockID
info.Path = stateName
info.Created = time.Now().UTC()
putParams := &dynamodb.PutItemInput{ putParams := &dynamodb.PutItemInput{
Item: map[string]*dynamodb.AttributeValue{ Item: map[string]*dynamodb.AttributeValue{
"LockID": {S: aws.String(stateName)}, "LockID": {S: aws.String(stateName)},
"Info": {S: aws.String(lockInfo.String())}, "Info": {S: aws.String(info.String())},
}, },
TableName: aws.String(c.lockTable), TableName: aws.String(c.lockTable),
ConditionExpression: aws.String("attribute_not_exists(LockID)"), ConditionExpression: aws.String("attribute_not_exists(LockID)"),
} }
_, err := c.dynClient.PutItem(putParams) _, err = c.dynClient.PutItem(putParams)
if err != nil { if err != nil {
getParams := &dynamodb.GetItemInput{ getParams := &dynamodb.GetItemInput{
@ -236,7 +241,7 @@ func (c *S3Client) Lock(info string) error {
resp, err := c.dynClient.GetItem(getParams) resp, err := c.dynClient.GetItem(getParams)
if err != nil { if err != nil {
return fmt.Errorf("s3 state file %q locked, failed to retrieve info: %s", stateName, err) return "", fmt.Errorf("s3 state file %q locked, failed to retrieve info: %s", stateName, err)
} }
var infoData string var infoData string
@ -244,18 +249,18 @@ func (c *S3Client) Lock(info string) error {
infoData = *v.S infoData = *v.S
} }
lockInfo = &state.LockInfo{} lockInfo := &state.LockInfo{}
err = json.Unmarshal([]byte(infoData), lockInfo) err = json.Unmarshal([]byte(infoData), lockInfo)
if err != nil { if err != nil {
return fmt.Errorf("s3 state file %q locked, failed get lock info: %s", stateName, err) return "", fmt.Errorf("s3 state file %q locked, failed get lock info: %s", stateName, err)
} }
return lockInfo.Err() return "", lockInfo.Err()
} }
return nil return "", nil
} }
func (c *S3Client) Unlock() error { func (c *S3Client) Unlock(string) error {
if c.lockTable == "" { if c.lockTable == "" {
return nil return nil
} }