github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/google/resource_storage_object_acl.go (about) 1 package google 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 9 "google.golang.org/api/storage/v1" 10 ) 11 12 func resourceStorageObjectAcl() *schema.Resource { 13 return &schema.Resource{ 14 Create: resourceStorageObjectAclCreate, 15 Read: resourceStorageObjectAclRead, 16 Update: resourceStorageObjectAclUpdate, 17 Delete: resourceStorageObjectAclDelete, 18 19 Schema: map[string]*schema.Schema{ 20 "bucket": &schema.Schema{ 21 Type: schema.TypeString, 22 Required: true, 23 ForceNew: true, 24 }, 25 "object": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 }, 30 "role_entity": &schema.Schema{ 31 Type: schema.TypeList, 32 Optional: true, 33 Elem: &schema.Schema{Type: schema.TypeString}, 34 }, 35 "predefined_acl": &schema.Schema{ 36 Type: schema.TypeString, 37 Optional: true, 38 ForceNew: true, 39 }, 40 }, 41 } 42 } 43 44 func getObjectAclId(object string) string { 45 return object + "-acl" 46 } 47 48 func resourceStorageObjectAclCreate(d *schema.ResourceData, meta interface{}) error { 49 config := meta.(*Config) 50 51 bucket := d.Get("bucket").(string) 52 object := d.Get("object").(string) 53 54 predefined_acl := "" 55 role_entity := make([]interface{}, 0) 56 57 if v, ok := d.GetOk("predefined_acl"); ok { 58 predefined_acl = v.(string) 59 } 60 61 if v, ok := d.GetOk("role_entity"); ok { 62 role_entity = v.([]interface{}) 63 } 64 65 if len(predefined_acl) > 0 { 66 if len(role_entity) > 0 { 67 return fmt.Errorf("Error, you cannot specify both " + 68 "\"predefined_acl\" and \"role_entity\"") 69 } 70 71 res, err := config.clientStorage.Objects.Get(bucket, object).Do() 72 73 if err != nil { 74 return fmt.Errorf("Error reading object %s: %v", bucket, err) 75 } 76 77 res, err = config.clientStorage.Objects.Update(bucket, object, 78 res).PredefinedAcl(predefined_acl).Do() 79 80 if err != nil { 81 return fmt.Errorf("Error updating object %s: %v", bucket, err) 82 } 83 84 return resourceStorageBucketAclRead(d, meta) 85 } else if len(role_entity) > 0 { 86 for _, v := range role_entity { 87 pair, err := getRoleEntityPair(v.(string)) 88 89 objectAccessControl := &storage.ObjectAccessControl{ 90 Role: pair.Role, 91 Entity: pair.Entity, 92 } 93 94 log.Printf("[DEBUG]: setting role = %s, entity = %s", pair.Role, pair.Entity) 95 96 _, err = config.clientStorage.ObjectAccessControls.Insert(bucket, 97 object, objectAccessControl).Do() 98 99 if err != nil { 100 return fmt.Errorf("Error setting ACL for %s on object %s: %v", pair.Entity, object, err) 101 } 102 } 103 104 return resourceStorageObjectAclRead(d, meta) 105 } 106 107 return fmt.Errorf("Error, you must specify either " + 108 "\"predefined_acl\" or \"role_entity\"") 109 } 110 111 func resourceStorageObjectAclRead(d *schema.ResourceData, meta interface{}) error { 112 config := meta.(*Config) 113 114 bucket := d.Get("bucket").(string) 115 object := d.Get("object").(string) 116 117 // Predefined ACLs cannot easily be parsed once they have been processed 118 // by the GCP server 119 if _, ok := d.GetOk("predefined_acl"); !ok { 120 role_entity := make([]interface{}, 0) 121 re_local := d.Get("role_entity").([]interface{}) 122 re_local_map := make(map[string]string) 123 for _, v := range re_local { 124 res, err := getRoleEntityPair(v.(string)) 125 126 if err != nil { 127 return fmt.Errorf( 128 "Old state has malformed Role/Entity pair: %v", err) 129 } 130 131 re_local_map[res.Entity] = res.Role 132 } 133 134 res, err := config.clientStorage.ObjectAccessControls.List(bucket, object).Do() 135 136 if err != nil { 137 return err 138 } 139 140 for _, v := range res.Items { 141 role := "" 142 entity := "" 143 for key, val := range v.(map[string]interface{}) { 144 if key == "role" { 145 role = val.(string) 146 } else if key == "entity" { 147 entity = val.(string) 148 } 149 } 150 if _, in := re_local_map[entity]; in { 151 role_entity = append(role_entity, fmt.Sprintf("%s:%s", role, entity)) 152 log.Printf("[DEBUG]: saving re %s-%s", role, entity) 153 } 154 } 155 156 d.Set("role_entity", role_entity) 157 } 158 159 d.SetId(getObjectAclId(object)) 160 return nil 161 } 162 163 func resourceStorageObjectAclUpdate(d *schema.ResourceData, meta interface{}) error { 164 config := meta.(*Config) 165 166 bucket := d.Get("bucket").(string) 167 object := d.Get("object").(string) 168 169 if d.HasChange("role_entity") { 170 o, n := d.GetChange("role_entity") 171 old_re, new_re := o.([]interface{}), n.([]interface{}) 172 173 old_re_map := make(map[string]string) 174 for _, v := range old_re { 175 res, err := getRoleEntityPair(v.(string)) 176 177 if err != nil { 178 return fmt.Errorf( 179 "Old state has malformed Role/Entity pair: %v", err) 180 } 181 182 old_re_map[res.Entity] = res.Role 183 } 184 185 for _, v := range new_re { 186 pair, err := getRoleEntityPair(v.(string)) 187 188 objectAccessControl := &storage.ObjectAccessControl{ 189 Role: pair.Role, 190 Entity: pair.Entity, 191 } 192 193 // If the old state is missing this entity, it needs to 194 // be created. Otherwise it is updated 195 if _, ok := old_re_map[pair.Entity]; ok { 196 _, err = config.clientStorage.ObjectAccessControls.Update( 197 bucket, object, pair.Entity, objectAccessControl).Do() 198 } else { 199 _, err = config.clientStorage.ObjectAccessControls.Insert( 200 bucket, object, objectAccessControl).Do() 201 } 202 203 // Now we only store the keys that have to be removed 204 delete(old_re_map, pair.Entity) 205 206 if err != nil { 207 return fmt.Errorf("Error updating ACL for object %s: %v", bucket, err) 208 } 209 } 210 211 for entity, _ := range old_re_map { 212 log.Printf("[DEBUG]: removing entity %s", entity) 213 err := config.clientStorage.ObjectAccessControls.Delete(bucket, object, entity).Do() 214 215 if err != nil { 216 return fmt.Errorf("Error updating ACL for object %s: %v", bucket, err) 217 } 218 } 219 220 return resourceStorageObjectAclRead(d, meta) 221 } 222 223 return nil 224 } 225 226 func resourceStorageObjectAclDelete(d *schema.ResourceData, meta interface{}) error { 227 config := meta.(*Config) 228 229 bucket := d.Get("bucket").(string) 230 object := d.Get("object").(string) 231 232 re_local := d.Get("role_entity").([]interface{}) 233 for _, v := range re_local { 234 res, err := getRoleEntityPair(v.(string)) 235 if err != nil { 236 return err 237 } 238 239 entity := res.Entity 240 241 log.Printf("[DEBUG]: removing entity %s", entity) 242 243 err = config.clientStorage.ObjectAccessControls.Delete(bucket, object, 244 entity).Do() 245 246 if err != nil { 247 return fmt.Errorf("Error deleting entity %s ACL: %s", 248 entity, err) 249 } 250 } 251 252 return nil 253 }