mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-15 07:27:15 +00:00
186 lines
4.8 KiB
Go
186 lines
4.8 KiB
Go
|
package google
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
|
||
|
"github.com/hashicorp/terraform/helper/schema"
|
||
|
"google.golang.org/api/storage/v1"
|
||
|
)
|
||
|
|
||
|
func resourceStorageDefaultObjectAcl() *schema.Resource {
|
||
|
return &schema.Resource{
|
||
|
Create: resourceStorageDefaultObjectAclCreate,
|
||
|
Read: resourceStorageDefaultObjectAclRead,
|
||
|
Update: resourceStorageDefaultObjectAclUpdate,
|
||
|
Delete: resourceStorageDefaultObjectAclDelete,
|
||
|
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"bucket": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
ForceNew: true,
|
||
|
},
|
||
|
|
||
|
"role_entity": &schema.Schema{
|
||
|
Type: schema.TypeList,
|
||
|
Required: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
MinItems: 1,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func resourceStorageDefaultObjectAclCreate(d *schema.ResourceData, meta interface{}) error {
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
bucket := d.Get("bucket").(string)
|
||
|
roleEntity := d.Get("role_entity").([]interface{})
|
||
|
|
||
|
for _, v := range roleEntity {
|
||
|
pair, err := getRoleEntityPair(v.(string))
|
||
|
|
||
|
ObjectAccessControl := &storage.ObjectAccessControl{
|
||
|
Role: pair.Role,
|
||
|
Entity: pair.Entity,
|
||
|
}
|
||
|
|
||
|
log.Printf("[DEBUG]: setting role = %s, entity = %s on bucket %s", pair.Role, pair.Entity, bucket)
|
||
|
|
||
|
_, err = config.clientStorage.DefaultObjectAccessControls.Insert(bucket, ObjectAccessControl).Do()
|
||
|
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Error setting Default Object ACL for %s on bucket %s: %v", pair.Entity, bucket, err)
|
||
|
}
|
||
|
}
|
||
|
d.SetId(bucket)
|
||
|
return resourceStorageDefaultObjectAclRead(d, meta)
|
||
|
}
|
||
|
|
||
|
func resourceStorageDefaultObjectAclRead(d *schema.ResourceData, meta interface{}) error {
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
bucket := d.Get("bucket").(string)
|
||
|
|
||
|
roleEntities := make([]interface{}, 0)
|
||
|
reLocal := d.Get("role_entity").([]interface{})
|
||
|
reLocalMap := make(map[string]string)
|
||
|
for _, v := range reLocal {
|
||
|
res, err := getRoleEntityPair(v.(string))
|
||
|
|
||
|
if err != nil {
|
||
|
return fmt.Errorf(
|
||
|
"Old state has malformed Role/Entity pair: %v", err)
|
||
|
}
|
||
|
|
||
|
reLocalMap[res.Entity] = res.Role
|
||
|
}
|
||
|
|
||
|
res, err := config.clientStorage.DefaultObjectAccessControls.List(bucket).Do()
|
||
|
|
||
|
if err != nil {
|
||
|
return handleNotFoundError(err, d, fmt.Sprintf("Storage Default Object ACL for bucket %q", d.Get("bucket").(string)))
|
||
|
}
|
||
|
|
||
|
for _, v := range res.Items {
|
||
|
role := v.Role
|
||
|
entity := v.Entity
|
||
|
// We only store updates to the locally defined access controls
|
||
|
if _, in := reLocalMap[entity]; in {
|
||
|
roleEntities = append(roleEntities, fmt.Sprintf("%s:%s", role, entity))
|
||
|
log.Printf("[DEBUG]: saving re %s-%s", v.Role, v.Entity)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
d.Set("role_entity", roleEntities)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func resourceStorageDefaultObjectAclUpdate(d *schema.ResourceData, meta interface{}) error {
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
bucket := d.Get("bucket").(string)
|
||
|
|
||
|
if !d.HasChange("role_entity") {
|
||
|
return nil
|
||
|
}
|
||
|
o, n := d.GetChange("role_entity")
|
||
|
oldRe := o.([]interface{})
|
||
|
newRe := n.([]interface{})
|
||
|
|
||
|
oldReMap := make(map[string]string)
|
||
|
for _, v := range oldRe {
|
||
|
res, err := getRoleEntityPair(v.(string))
|
||
|
|
||
|
if err != nil {
|
||
|
return fmt.Errorf(
|
||
|
"Old state has malformed Role/Entity pair: %v", err)
|
||
|
}
|
||
|
|
||
|
oldReMap[res.Entity] = res.Role
|
||
|
}
|
||
|
|
||
|
for _, v := range newRe {
|
||
|
pair, err := getRoleEntityPair(v.(string))
|
||
|
|
||
|
ObjectAccessControl := &storage.ObjectAccessControl{
|
||
|
Role: pair.Role,
|
||
|
Entity: pair.Entity,
|
||
|
}
|
||
|
|
||
|
// If the old state is present for the entity, it is updated
|
||
|
// If the old state is missing, it is inserted
|
||
|
if _, ok := oldReMap[pair.Entity]; ok {
|
||
|
_, err = config.clientStorage.DefaultObjectAccessControls.Update(
|
||
|
bucket, pair.Entity, ObjectAccessControl).Do()
|
||
|
} else {
|
||
|
_, err = config.clientStorage.DefaultObjectAccessControls.Insert(
|
||
|
bucket, ObjectAccessControl).Do()
|
||
|
}
|
||
|
|
||
|
// Now we only store the keys that have to be removed
|
||
|
delete(oldReMap, pair.Entity)
|
||
|
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Error updating Storage Default Object ACL for bucket %s: %v", bucket, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for entity := range oldReMap {
|
||
|
log.Printf("[DEBUG]: removing entity %s", entity)
|
||
|
err := config.clientStorage.DefaultObjectAccessControls.Delete(bucket, entity).Do()
|
||
|
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Error updating Storage Default Object ACL for bucket %s: %v", bucket, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return resourceStorageDefaultObjectAclRead(d, meta)
|
||
|
}
|
||
|
|
||
|
func resourceStorageDefaultObjectAclDelete(d *schema.ResourceData, meta interface{}) error {
|
||
|
config := meta.(*Config)
|
||
|
|
||
|
bucket := d.Get("bucket").(string)
|
||
|
|
||
|
reLocal := d.Get("role_entity").([]interface{})
|
||
|
for _, v := range reLocal {
|
||
|
res, err := getRoleEntityPair(v.(string))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
log.Printf("[DEBUG]: removing entity %s", res.Entity)
|
||
|
|
||
|
err = config.clientStorage.DefaultObjectAccessControls.Delete(bucket, res.Entity).Do()
|
||
|
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Error deleting entity %s ACL: %s", res.Entity, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|