updates based on feedback
This commit is contained in:
parent
1b5f12bab6
commit
9915503d9a
|
@ -34,6 +34,11 @@ type CombinedConfig struct {
|
||||||
func (c *CombinedConfig) godoClient() *godo.Client { return c.client }
|
func (c *CombinedConfig) godoClient() *godo.Client { return c.client }
|
||||||
|
|
||||||
func (c *CombinedConfig) spacesClient(region string) (*session.Session, error) {
|
func (c *CombinedConfig) spacesClient(region string) (*session.Session, error) {
|
||||||
|
if c.accessID == "" || c.secretKey == "" {
|
||||||
|
err := fmt.Errorf("Spaces credentials not configured")
|
||||||
|
return &session.Session{}, err
|
||||||
|
}
|
||||||
|
|
||||||
endpoint := fmt.Sprintf("https://%s.digitaloceanspaces.com", region)
|
endpoint := fmt.Sprintf("https://%s.digitaloceanspaces.com", region)
|
||||||
client, err := session.NewSession(&aws.Config{
|
client, err := session.NewSession(&aws.Config{
|
||||||
Region: aws.String("us-east-1"),
|
Region: aws.String("us-east-1"),
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package digitalocean
|
package digitalocean
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccDigitalOceanBucket_importBasic(t *testing.T) {
|
func TestAccDigitalOceanBucket_importBasic(t *testing.T) {
|
||||||
resourceName := "digitalocean_bucket.foobar"
|
resourceName := "digitalocean_bucket.bucket"
|
||||||
|
rInt := acctest.RandInt()
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -15,13 +18,15 @@ func TestAccDigitalOceanBucket_importBasic(t *testing.T) {
|
||||||
CheckDestroy: testAccCheckDigitalOceanBucketDestroy,
|
CheckDestroy: testAccCheckDigitalOceanBucketDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
{
|
{
|
||||||
Config: testAccDigitalOceanBucketConfigWithAcl,
|
Config: testAccDigitalOceanBucketConfigImport(rInt),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
ResourceName: resourceName,
|
ResourceName: resourceName,
|
||||||
ImportState: true,
|
ImportState: true,
|
||||||
ImportStateVerify: true,
|
ImportStateVerify: true,
|
||||||
|
ImportStateIdPrefix: fmt.Sprintf("%s,", "nyc3"),
|
||||||
|
ImportStateVerifyIgnore: []string{"acl"}, // ACLs are not saved to tf state
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -17,13 +17,13 @@ func Provider() terraform.ResourceProvider {
|
||||||
},
|
},
|
||||||
"access_id": {
|
"access_id": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DO_ACCESS_KEY_ID", nil),
|
DefaultFunc: schema.EnvDefaultFunc("DO_ACCESS_KEY_ID", nil),
|
||||||
Description: "The access key ID for Spaces API operations.",
|
Description: "The access key ID for Spaces API operations.",
|
||||||
},
|
},
|
||||||
"secret_key": {
|
"secret_key": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DO_SECRET_ACCESS_KEY", nil),
|
DefaultFunc: schema.EnvDefaultFunc("DO_SECRET_ACCESS_KEY", nil),
|
||||||
Description: "The secret access key for Spaces API operations.",
|
Description: "The secret access key for Spaces API operations.",
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,7 @@ package digitalocean
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -19,7 +20,7 @@ func resourceDigitalOceanBucket() *schema.Resource {
|
||||||
Update: resourceDigitalOceanBucketUpdate,
|
Update: resourceDigitalOceanBucketUpdate,
|
||||||
Delete: resourceDigitalOceanBucketDelete,
|
Delete: resourceDigitalOceanBucketDelete,
|
||||||
Importer: &schema.ResourceImporter{
|
Importer: &schema.ResourceImporter{
|
||||||
State: schema.ImportStatePassthrough,
|
State: resourceDigitalOceanBucketImport,
|
||||||
},
|
},
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
@ -47,12 +48,13 @@ func resourceDigitalOceanBucket() *schema.Resource {
|
||||||
func resourceDigitalOceanBucketCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanBucketCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
region := d.Get("region").(string)
|
region := d.Get("region").(string)
|
||||||
client, err := meta.(*CombinedConfig).spacesClient(region)
|
client, err := meta.(*CombinedConfig).spacesClient(region)
|
||||||
svc := s3.New(client)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating bucket: %s", err)
|
return fmt.Errorf("Error creating bucket: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svc := s3.New(client)
|
||||||
|
|
||||||
input := &s3.CreateBucketInput{
|
input := &s3.CreateBucketInput{
|
||||||
Bucket: aws.String(d.Get("name").(string)),
|
Bucket: aws.String(d.Get("name").(string)),
|
||||||
ACL: aws.String(d.Get("acl").(string)),
|
ACL: aws.String(d.Get("acl").(string)),
|
||||||
|
@ -88,14 +90,15 @@ func resourceDigitalOceanBucketCreate(d *schema.ResourceData, meta interface{})
|
||||||
func resourceDigitalOceanBucketUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanBucketUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
region := d.Get("region").(string)
|
region := d.Get("region").(string)
|
||||||
client, err := meta.(*CombinedConfig).spacesClient(region)
|
client, err := meta.(*CombinedConfig).spacesClient(region)
|
||||||
svc := s3.New(client)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error updating bucket: %s", err)
|
return fmt.Errorf("Error updating bucket: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svc := s3.New(client)
|
||||||
|
|
||||||
if d.HasChange("acl") {
|
if d.HasChange("acl") {
|
||||||
if err := resourceDigitalOceanBucketAclUpdate(svc, d); err != nil {
|
if err := resourceDigitalOceanBucketACLUpdate(svc, d); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,12 +109,13 @@ func resourceDigitalOceanBucketUpdate(d *schema.ResourceData, meta interface{})
|
||||||
func resourceDigitalOceanBucketRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanBucketRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
region := d.Get("region").(string)
|
region := d.Get("region").(string)
|
||||||
client, err := meta.(*CombinedConfig).spacesClient(region)
|
client, err := meta.(*CombinedConfig).spacesClient(region)
|
||||||
svc := s3.New(client)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error reading bucket: %s", err)
|
return fmt.Errorf("Error reading bucket: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svc := s3.New(client)
|
||||||
|
|
||||||
_, err = retryOnAwsCode("NoSuchBucket", func() (interface{}, error) {
|
_, err = retryOnAwsCode("NoSuchBucket", func() (interface{}, error) {
|
||||||
return svc.HeadBucket(&s3.HeadBucketInput{
|
return svc.HeadBucket(&s3.HeadBucketInput{
|
||||||
Bucket: aws.String(d.Id()),
|
Bucket: aws.String(d.Id()),
|
||||||
|
@ -165,12 +169,13 @@ func resourceDigitalOceanBucketRead(d *schema.ResourceData, meta interface{}) er
|
||||||
func resourceDigitalOceanBucketDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanBucketDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
region := d.Get("region").(string)
|
region := d.Get("region").(string)
|
||||||
client, err := meta.(*CombinedConfig).spacesClient(region)
|
client, err := meta.(*CombinedConfig).spacesClient(region)
|
||||||
svc := s3.New(client)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting bucket: %s", err)
|
return fmt.Errorf("Error deleting bucket: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svc := s3.New(client)
|
||||||
|
|
||||||
log.Printf("[DEBUG] Spaces Delete Bucket: %s", d.Id())
|
log.Printf("[DEBUG] Spaces Delete Bucket: %s", d.Id())
|
||||||
_, err = svc.DeleteBucket(&s3.DeleteBucketInput{
|
_, err = svc.DeleteBucket(&s3.DeleteBucketInput{
|
||||||
Bucket: aws.String(d.Id()),
|
Bucket: aws.String(d.Id()),
|
||||||
|
@ -239,7 +244,7 @@ func resourceDigitalOceanBucketDelete(d *schema.ResourceData, meta interface{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanBucketAclUpdate(svc *s3.S3, d *schema.ResourceData) error {
|
func resourceDigitalOceanBucketACLUpdate(svc *s3.S3, d *schema.ResourceData) error {
|
||||||
acl := d.Get("acl").(string)
|
acl := d.Get("acl").(string)
|
||||||
bucket := d.Get("name").(string)
|
bucket := d.Get("name").(string)
|
||||||
|
|
||||||
|
@ -259,6 +264,25 @@ func resourceDigitalOceanBucketAclUpdate(svc *s3.S3, d *schema.ResourceData) err
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resourceDigitalOceanBucketImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
|
if strings.Contains(d.Id(), ",") {
|
||||||
|
s := strings.Split(d.Id(), ",")
|
||||||
|
|
||||||
|
d.SetId(s[1])
|
||||||
|
d.Set("region", s[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
err := resourceDigitalOceanBucketRead(d, meta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to import bucket: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make([]*schema.ResourceData, 0)
|
||||||
|
results = append(results, d)
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
func bucketDomainName(bucket string, region string) string {
|
func bucketDomainName(bucket string, region string) string {
|
||||||
return fmt.Sprintf("%q.%q.digitaloceanspaces.com", bucket, region)
|
return fmt.Sprintf("%q.%q.digitaloceanspaces.com", bucket, region)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,8 @@ func TestAccDigitalOceanBucket_region(t *testing.T) {
|
||||||
|
|
||||||
func TestAccDigitalOceanBucket_UpdateAcl(t *testing.T) {
|
func TestAccDigitalOceanBucket_UpdateAcl(t *testing.T) {
|
||||||
ri := acctest.RandInt()
|
ri := acctest.RandInt()
|
||||||
preConfig := fmt.Sprintf(testAccDigitalOceanBucketConfigWithAcl, ri)
|
preConfig := fmt.Sprintf(testAccDigitalOceanBucketConfigWithACL, ri)
|
||||||
postConfig := fmt.Sprintf(testAccDigitalOceanBucketConfigWithAclUpdate, ri)
|
postConfig := fmt.Sprintf(testAccDigitalOceanBucketConfigWithACLUpdate, ri)
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -121,23 +121,25 @@ func testAccCheckDigitalOceanBucketDestroy(s *terraform.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanBucketDestroyWithProvider(s *terraform.State, provider *schema.Provider) error {
|
func testAccCheckDigitalOceanBucketDestroyWithProvider(s *terraform.State, provider *schema.Provider) error {
|
||||||
sesh, err := session.NewSession(&aws.Config{
|
|
||||||
Region: aws.String("nyc3"),
|
|
||||||
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_ACCESS_KEY_ID"), os.Getenv("DO_SECRET_ACCESS_KEY"), "")},
|
|
||||||
)
|
|
||||||
svc := s3.New(sesh, &aws.Config{
|
|
||||||
Endpoint: aws.String("https://nyc3.digitaloceanspaces.com")},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
sesh, err := session.NewSession(&aws.Config{
|
||||||
|
Region: aws.String(rs.Primary.Attributes["region"]),
|
||||||
|
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_ACCESS_KEY_ID"), os.Getenv("DO_SECRET_ACCESS_KEY"), "")},
|
||||||
|
)
|
||||||
|
|
||||||
|
svc := s3.New(sesh, &aws.Config{
|
||||||
|
Endpoint: aws.String(fmt.Sprintf("https://%s.digitaloceanspaces.com", rs.Primary.Attributes["region"]))},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if rs.Type != "digitalocean_bucket" {
|
if rs.Type != "digitalocean_bucket" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err := svc.DeleteBucket(&s3.DeleteBucketInput{
|
_, err = svc.DeleteBucket(&s3.DeleteBucketInput{
|
||||||
Bucket: aws.String(rs.Primary.ID),
|
Bucket: aws.String(rs.Primary.ID),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -166,11 +168,11 @@ func testAccCheckDigitalOceanBucketExistsWithProvider(n string, providerF func()
|
||||||
}
|
}
|
||||||
|
|
||||||
sesh, err := session.NewSession(&aws.Config{
|
sesh, err := session.NewSession(&aws.Config{
|
||||||
Region: aws.String("nyc3"),
|
Region: aws.String(rs.Primary.Attributes["region"]),
|
||||||
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_ACCESS_KEY_ID"), os.Getenv("DO_SECRET_ACCESS_KEY"), "")},
|
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_ACCESS_KEY_ID"), os.Getenv("DO_SECRET_ACCESS_KEY"), "")},
|
||||||
)
|
)
|
||||||
svc := s3.New(sesh, &aws.Config{
|
svc := s3.New(sesh, &aws.Config{
|
||||||
Endpoint: aws.String("https://nyc3.digitaloceanspaces.com")},
|
Endpoint: aws.String(fmt.Sprintf("https://%s.digitaloceanspaces.com", rs.Primary.Attributes["region"]))},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -204,11 +206,11 @@ func testAccCheckDigitalOceanDestroyBucket(n string) resource.TestCheckFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
sesh, err := session.NewSession(&aws.Config{
|
sesh, err := session.NewSession(&aws.Config{
|
||||||
Region: aws.String("nyc3"),
|
Region: aws.String(rs.Primary.Attributes["region"]),
|
||||||
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_ACCESS_KEY_ID"), os.Getenv("DO_SECRET_ACCESS_KEY"), "")},
|
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_ACCESS_KEY_ID"), os.Getenv("DO_SECRET_ACCESS_KEY"), "")},
|
||||||
)
|
)
|
||||||
svc := s3.New(sesh, &aws.Config{
|
svc := s3.New(sesh, &aws.Config{
|
||||||
Endpoint: aws.String("https://nyc3.digitaloceanspaces.com")},
|
Endpoint: aws.String(fmt.Sprintf("https://%s.digitaloceanspaces.com", rs.Primary.Attributes["region"]))},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -266,14 +268,22 @@ resource "digitalocean_bucket" "bucket" {
|
||||||
`, randInt)
|
`, randInt)
|
||||||
}
|
}
|
||||||
|
|
||||||
var testAccDigitalOceanBucketConfigWithAcl = `
|
func testAccDigitalOceanBucketConfigImport(randInt int) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "digitalocean_bucket" "bucket" {
|
||||||
|
name = "tf-test-bucket-%d"
|
||||||
|
}
|
||||||
|
`, randInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAccDigitalOceanBucketConfigWithACL = `
|
||||||
resource "digitalocean_bucket" "bucket" {
|
resource "digitalocean_bucket" "bucket" {
|
||||||
name = "tf-test-bucket-%d"
|
name = "tf-test-bucket-%d"
|
||||||
acl = "public-read"
|
acl = "public-read"
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
var testAccDigitalOceanBucketConfigWithAclUpdate = `
|
var testAccDigitalOceanBucketConfigWithACLUpdate = `
|
||||||
resource "digitalocean_bucket" "bucket" {
|
resource "digitalocean_bucket" "bucket" {
|
||||||
name = "tf-test-bucket-%d"
|
name = "tf-test-bucket-%d"
|
||||||
acl = "private"
|
acl = "private"
|
||||||
|
|
|
@ -49,8 +49,8 @@ The following attributes are exported:
|
||||||
|
|
||||||
## Import
|
## Import
|
||||||
|
|
||||||
Buckets can be imported using the `name`, e.g.
|
Buckets can be imported using the `region` and `name` attributes (delimited by a comma):
|
||||||
|
|
||||||
```
|
```
|
||||||
terraform import digitalocean_bucket.foobar `name`
|
terraform import digitalocean_bucket.foobar `region`,`name`
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue