Merge pull request #439 from terraform-providers/paddy_undeletable_bucket_acls

Deal with undeletable bucket ACLs in storage.
This commit is contained in:
Paddy 2017-09-25 10:29:15 -07:00 committed by GitHub
commit c31bfdc4df
2 changed files with 62 additions and 21 deletions

View File

@ -3,6 +3,7 @@ package google
import (
"fmt"
"log"
"strconv"
"strings"
"github.com/hashicorp/terraform/helper/schema"
@ -101,9 +102,26 @@ func resourceStorageBucketAclCreate(d *schema.ResourceData, meta interface{}) er
}
if len(role_entity) > 0 {
current, err := config.clientStorage.BucketAccessControls.List(bucket).Do()
if err != nil {
return fmt.Errorf("Error retrieving current ACLs: %s", err)
}
for _, v := range role_entity {
pair, err := getRoleEntityPair(v.(string))
if err != nil {
return err
}
var alreadyInserted bool
for _, cur := range current.Items {
if cur.Entity == pair.Entity && cur.Role == pair.Role {
alreadyInserted = true
break
}
}
if alreadyInserted {
log.Printf("[DEBUG]: pair %s-%s already exists, not trying to insert again\n", pair.Role, pair.Entity)
continue
}
bucketAccessControl := &storage.BucketAccessControl{
Role: pair.Role,
Entity: pair.Entity,
@ -174,6 +192,12 @@ func resourceStorageBucketAclUpdate(d *schema.ResourceData, meta interface{}) er
bucket := d.Get("bucket").(string)
if d.HasChange("role_entity") {
bkt, err := config.clientStorage.Buckets.Get(bucket).Do()
if err != nil {
return fmt.Errorf("Error reading bucket %q: %v", bucket, err)
}
project := strconv.FormatUint(bkt.ProjectNumber, 10)
o, n := d.GetChange("role_entity")
old_re, new_re := o.([]interface{}), n.([]interface{})
@ -197,12 +221,8 @@ func resourceStorageBucketAclUpdate(d *schema.ResourceData, meta interface{}) er
Entity: pair.Entity,
}
// If the old state is missing this entity, it needs to
// be created. Otherwise it is updated
if _, ok := old_re_map[pair.Entity]; ok {
_, err = config.clientStorage.BucketAccessControls.Update(
bucket, pair.Entity, bucketAccessControl).Do()
} else {
// If the old state is missing this entity, it needs to be inserted
if _, ok := old_re_map[pair.Entity]; !ok {
_, err = config.clientStorage.BucketAccessControls.Insert(
bucket, bucketAccessControl).Do()
}
@ -215,7 +235,11 @@ func resourceStorageBucketAclUpdate(d *schema.ResourceData, meta interface{}) er
}
}
for entity, _ := range old_re_map {
for entity, role := range old_re_map {
if entity == fmt.Sprintf("project-owners-%s", project) && role == "OWNER" {
log.Printf("Skipping %s-%s; not deleting owner ACL.", role, entity)
continue
}
log.Printf("[DEBUG]: removing entity %s", entity)
err := config.clientStorage.BucketAccessControls.Delete(bucket, entity).Do()
@ -254,6 +278,12 @@ func resourceStorageBucketAclDelete(d *schema.ResourceData, meta interface{}) er
bucket := d.Get("bucket").(string)
bkt, err := config.clientStorage.Buckets.Get(bucket).Do()
if err != nil {
return fmt.Errorf("Error retrieving bucket %q: %v", bucket, err)
}
project := strconv.FormatUint(bkt.ProjectNumber, 10)
re_local := d.Get("role_entity").([]interface{})
for _, v := range re_local {
res, err := getRoleEntityPair(v.(string))
@ -261,6 +291,11 @@ func resourceStorageBucketAclDelete(d *schema.ResourceData, meta interface{}) er
return err
}
if res.Entity == fmt.Sprintf("project-owners-%s", project) && res.Role == "OWNER" {
log.Printf("Skipping %s-%s; not deleting owner ACL.", res.Role, res.Entity)
continue
}
log.Printf("[DEBUG]: removing entity %s", res.Entity)
err = config.clientStorage.BucketAccessControls.Delete(bucket, res.Entity).Do()

View File

@ -2,21 +2,24 @@ package google
import (
"fmt"
"os"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
//"google.golang.org/api/storage/v1"
)
var roleEntityBasic1 = "OWNER:user-omeemail@gmail.com"
var (
roleEntityBasic1 = "OWNER:user-paddy@hashicorp.com"
roleEntityBasic2 = "READER:user-paddy@carvers.co"
roleEntityBasic3_owner = "OWNER:user-paddy@paddy.io"
roleEntityBasic3_reader = "READER:user-foran.paddy@gmail.com"
var roleEntityBasic2 = "READER:user-anotheremail@gmail.com"
var roleEntityBasic3_owner = "OWNER:user-yetanotheremail@gmail.com"
var roleEntityBasic3_reader = "READER:user-yetanotheremail@gmail.com"
roleEntityOwners = "OWNER:project-owners-" + os.Getenv("GOOGLE_PROJECT_NUMBER")
roleEntityEditors = "OWNER:project-editors-" + os.Getenv("GOOGLE_PROJECT_NUMBER")
roleEntityViewers = "READER:project-viewers-" + os.Getenv("GOOGLE_PROJECT_NUMBER")
)
func testBucketName() string {
return fmt.Sprintf("%s-%d", "tf-test-acl-bucket", acctest.RandInt())
@ -24,6 +27,7 @@ func testBucketName() string {
func TestAccGoogleStorageBucketAcl_basic(t *testing.T) {
bucketName := testBucketName()
skipIfEnvNotSet(t, "GOOGLE_PROJECT_NUMBER")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
@ -42,6 +46,7 @@ func TestAccGoogleStorageBucketAcl_basic(t *testing.T) {
func TestAccGoogleStorageBucketAcl_upgrade(t *testing.T) {
bucketName := testBucketName()
skipIfEnvNotSet(t, "GOOGLE_PROJECT_NUMBER")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
@ -77,6 +82,7 @@ func TestAccGoogleStorageBucketAcl_upgrade(t *testing.T) {
func TestAccGoogleStorageBucketAcl_downgrade(t *testing.T) {
bucketName := testBucketName()
skipIfEnvNotSet(t, "GOOGLE_PROJECT_NUMBER")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
@ -186,9 +192,9 @@ resource "google_storage_bucket" "bucket" {
resource "google_storage_bucket_acl" "acl" {
bucket = "${google_storage_bucket.bucket.name}"
role_entity = ["%s", "%s"]
role_entity = ["%s", "%s", "%s", "%s", "%s"]
}
`, bucketName, roleEntityBasic1, roleEntityBasic2)
`, bucketName, roleEntityOwners, roleEntityEditors, roleEntityViewers, roleEntityBasic1, roleEntityBasic2)
}
func testGoogleStorageBucketsAclBasic2(bucketName string) string {
@ -199,9 +205,9 @@ resource "google_storage_bucket" "bucket" {
resource "google_storage_bucket_acl" "acl" {
bucket = "${google_storage_bucket.bucket.name}"
role_entity = ["%s", "%s"]
role_entity = ["%s", "%s", "%s", "%s", "%s"]
}
`, bucketName, roleEntityBasic2, roleEntityBasic3_owner)
`, bucketName, roleEntityOwners, roleEntityEditors, roleEntityViewers, roleEntityBasic2, roleEntityBasic3_owner)
}
func testGoogleStorageBucketsAclBasicDelete(bucketName string) string {
@ -225,9 +231,9 @@ resource "google_storage_bucket" "bucket" {
resource "google_storage_bucket_acl" "acl" {
bucket = "${google_storage_bucket.bucket.name}"
role_entity = ["%s", "%s"]
role_entity = ["%s", "%s", "%s", "%s", "%s"]
}
`, bucketName, roleEntityBasic2, roleEntityBasic3_reader)
`, bucketName, roleEntityOwners, roleEntityEditors, roleEntityViewers, roleEntityBasic2, roleEntityBasic3_reader)
}
func testGoogleStorageBucketsAclPredefined(bucketName string) string {