Skip to content

Commit

Permalink
storage: make bucket ACLs control the entire resource.
Browse files Browse the repository at this point in the history
Storage bucket ACLs inherited the behaviour of only updating the fields
that were set in the config file. Terraform should track all the fields
in the resource, whether the user has specified a value for them or not,
and correct any drift that may occur.

This has manifested in an issue and unexpected behaviour in hashicorp#50, and
this PR restores the expected behaviour.
  • Loading branch information
paddycarver committed Aug 24, 2017
1 parent d03d247 commit 31b75dd
Showing 1 changed file with 23 additions and 43 deletions.
66 changes: 23 additions & 43 deletions google/resource_storage_bucket_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ func resourceStorageBucketAcl() *schema.Resource {
},

"predefined_acl": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"role_entity"},
},

"role_entity": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
ConflictsWith: []string{"predefined_acl"},
},
},
}
Expand Down Expand Up @@ -84,11 +86,6 @@ func resourceStorageBucketAclCreate(d *schema.ResourceData, meta interface{}) er
}

if len(predefined_acl) > 0 {
if len(role_entity) > 0 {
return fmt.Errorf("Error, you cannot specify both " +
"\"predefined_acl\" and \"role_entity\"")
}

res, err := config.clientStorage.Buckets.Get(bucket).Do()

if err != nil {
Expand All @@ -102,8 +99,8 @@ func resourceStorageBucketAclCreate(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("Error updating bucket %s: %v", bucket, err)
}

return resourceStorageBucketAclRead(d, meta)
} else if len(role_entity) > 0 {
}
if len(role_entity) > 0 {
for _, v := range role_entity {
pair, err := getRoleEntityPair(v.(string))

Expand All @@ -121,7 +118,6 @@ func resourceStorageBucketAclCreate(d *schema.ResourceData, meta interface{}) er
}
}

return resourceStorageBucketAclRead(d, meta)
}

if len(default_acl) > 0 {
Expand All @@ -138,53 +134,37 @@ func resourceStorageBucketAclCreate(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("Error updating bucket %s: %v", bucket, err)
}

return resourceStorageBucketAclRead(d, meta)
}

return nil
d.SetId(getBucketAclId(bucket))
return resourceStorageBucketAclRead(d, meta)
}

func resourceStorageBucketAclRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

bucket := d.Get("bucket").(string)

// Predefined ACLs cannot easily be parsed once they have been processed
// by the GCP server
if _, ok := d.GetOk("predefined_acl"); !ok {
role_entity := make([]interface{}, 0)
re_local := d.Get("role_entity").([]interface{})
re_local_map := make(map[string]string)
for _, v := range re_local {
res, err := getRoleEntityPair(v.(string))

if err != nil {
return fmt.Errorf(
"Old state has malformed Role/Entity pair: %v", err)
}

re_local_map[res.Entity] = res.Role
}

// The API offers no way to retrieve predefined ACLs,
// and we can't tell which access controls were created
// by the predefined roles, so...
//
// This is, needless to say, a bad state of affairs and
// should be fixed.
if _, ok := d.GetOk("role_entity"); ok {
res, err := config.clientStorage.BucketAccessControls.List(bucket).Do()

if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("Storage Bucket ACL for bucket %q", d.Get("bucket").(string)))
}

for _, v := range res.Items {
log.Printf("[DEBUG]: examining re %s-%s", v.Role, v.Entity)
// We only store updates to the locally defined access controls
if _, in := re_local_map[v.Entity]; in {
role_entity = append(role_entity, fmt.Sprintf("%s:%s", v.Role, v.Entity))
log.Printf("[DEBUG]: saving re %s-%s", v.Role, v.Entity)
}
entities := make([]string, 0, len(res.Items))
for _, item := range res.Items {
entities = append(entities, item.Role+":"+item.Entity)
}

d.Set("role_entity", role_entity)
d.Set("role_entity", entities)
}

d.SetId(getBucketAclId(bucket))
return nil
}

Expand Down

0 comments on commit 31b75dd

Please sign in to comment.