github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/builtin/providers/google/resource_storage_bucket.go (about) 1 package google 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 8 "github.com/hashicorp/terraform/helper/schema" 9 10 "google.golang.org/api/googleapi" 11 "google.golang.org/api/storage/v1" 12 ) 13 14 func resourceStorageBucket() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceStorageBucketCreate, 17 Read: resourceStorageBucketRead, 18 Update: resourceStorageBucketUpdate, 19 Delete: resourceStorageBucketDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "name": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 }, 27 28 "force_destroy": &schema.Schema{ 29 Type: schema.TypeBool, 30 Optional: true, 31 Default: false, 32 }, 33 34 "location": &schema.Schema{ 35 Type: schema.TypeString, 36 Default: "US", 37 Optional: true, 38 ForceNew: true, 39 }, 40 41 "predefined_acl": &schema.Schema{ 42 Type: schema.TypeString, 43 Deprecated: "Please use resource \"storage_bucket_acl.predefined_acl\" instead.", 44 Optional: true, 45 ForceNew: true, 46 }, 47 48 "project": &schema.Schema{ 49 Type: schema.TypeString, 50 Optional: true, 51 ForceNew: true, 52 }, 53 54 "self_link": &schema.Schema{ 55 Type: schema.TypeString, 56 Computed: true, 57 }, 58 59 "storage_class": &schema.Schema{ 60 Type: schema.TypeString, 61 Optional: true, 62 Default: "STANDARD", 63 ForceNew: true, 64 }, 65 66 "website": &schema.Schema{ 67 Type: schema.TypeList, 68 Optional: true, 69 Elem: &schema.Resource{ 70 Schema: map[string]*schema.Schema{ 71 "main_page_suffix": &schema.Schema{ 72 Type: schema.TypeString, 73 Optional: true, 74 }, 75 "not_found_page": &schema.Schema{ 76 Type: schema.TypeString, 77 Optional: true, 78 }, 79 }, 80 }, 81 }, 82 }, 83 } 84 } 85 86 func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error { 87 config := meta.(*Config) 88 89 project, err := getProject(d, config) 90 if err != nil { 91 return err 92 } 93 94 // Get the bucket and acl 95 bucket := d.Get("name").(string) 96 location := d.Get("location").(string) 97 98 // Create a bucket, setting the acl, location and name. 99 sb := &storage.Bucket{Name: bucket, Location: location} 100 101 if v, ok := d.GetOk("storage_class"); ok { 102 sb.StorageClass = v.(string) 103 } 104 105 if v, ok := d.GetOk("website"); ok { 106 websites := v.([]interface{}) 107 108 if len(websites) > 1 { 109 return fmt.Errorf("At most one website block is allowed") 110 } 111 112 sb.Website = &storage.BucketWebsite{} 113 114 website := websites[0].(map[string]interface{}) 115 116 if v, ok := website["not_found_page"]; ok { 117 sb.Website.NotFoundPage = v.(string) 118 } 119 120 if v, ok := website["main_page_suffix"]; ok { 121 sb.Website.MainPageSuffix = v.(string) 122 } 123 } 124 125 call := config.clientStorage.Buckets.Insert(project, sb) 126 if v, ok := d.GetOk("predefined_acl"); ok { 127 call = call.PredefinedAcl(v.(string)) 128 } 129 130 res, err := call.Do() 131 132 if err != nil { 133 fmt.Printf("Error creating bucket %s: %v", bucket, err) 134 return err 135 } 136 137 log.Printf("[DEBUG] Created bucket %v at location %v\n\n", res.Name, res.SelfLink) 138 139 // Assign the bucket ID as the resource ID 140 d.Set("self_link", res.SelfLink) 141 d.SetId(res.Id) 142 143 return nil 144 } 145 146 func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error { 147 config := meta.(*Config) 148 149 sb := &storage.Bucket{} 150 151 if d.HasChange("website") { 152 if v, ok := d.GetOk("website"); ok { 153 websites := v.([]interface{}) 154 155 if len(websites) > 1 { 156 return fmt.Errorf("At most one website block is allowed") 157 } 158 159 // Setting fields to "" to be explicit that the PATCH call will 160 // delete this field. 161 if len(websites) == 0 { 162 sb.Website.NotFoundPage = "" 163 sb.Website.MainPageSuffix = "" 164 } else { 165 website := websites[0].(map[string]interface{}) 166 sb.Website = &storage.BucketWebsite{} 167 if v, ok := website["not_found_page"]; ok { 168 sb.Website.NotFoundPage = v.(string) 169 } else { 170 sb.Website.NotFoundPage = "" 171 } 172 173 if v, ok := website["main_page_suffix"]; ok { 174 sb.Website.MainPageSuffix = v.(string) 175 } else { 176 sb.Website.MainPageSuffix = "" 177 } 178 } 179 } 180 } 181 182 res, err := config.clientStorage.Buckets.Patch(d.Get("name").(string), sb).Do() 183 184 if err != nil { 185 return err 186 } 187 188 log.Printf("[DEBUG] Patched bucket %v at location %v\n\n", res.Name, res.SelfLink) 189 190 // Assign the bucket ID as the resource ID 191 d.Set("self_link", res.SelfLink) 192 d.SetId(res.Id) 193 194 return nil 195 } 196 197 func resourceStorageBucketRead(d *schema.ResourceData, meta interface{}) error { 198 config := meta.(*Config) 199 200 // Get the bucket and acl 201 bucket := d.Get("name").(string) 202 res, err := config.clientStorage.Buckets.Get(bucket).Do() 203 204 if err != nil { 205 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 206 log.Printf("[WARN] Removing Bucket %q because it's gone", d.Get("name").(string)) 207 // The resource doesn't exist anymore 208 d.SetId("") 209 210 return nil 211 } 212 213 return fmt.Errorf("Error reading bucket %s: %v", bucket, err) 214 } 215 216 log.Printf("[DEBUG] Read bucket %v at location %v\n\n", res.Name, res.SelfLink) 217 218 // Update the bucket ID according to the resource ID 219 d.Set("self_link", res.SelfLink) 220 d.SetId(res.Id) 221 222 return nil 223 } 224 225 func resourceStorageBucketDelete(d *schema.ResourceData, meta interface{}) error { 226 config := meta.(*Config) 227 228 // Get the bucket 229 bucket := d.Get("name").(string) 230 231 for { 232 res, err := config.clientStorage.Objects.List(bucket).Do() 233 if err != nil { 234 fmt.Printf("Error Objects.List failed: %v", err) 235 return err 236 } 237 238 if len(res.Items) != 0 { 239 if d.Get("force_destroy").(bool) { 240 // purge the bucket... 241 log.Printf("[DEBUG] GCS Bucket attempting to forceDestroy\n\n") 242 243 for _, object := range res.Items { 244 log.Printf("[DEBUG] Found %s", object.Name) 245 if err := config.clientStorage.Objects.Delete(bucket, object.Name).Do(); err != nil { 246 log.Fatalf("Error trying to delete object: %s %s\n\n", object.Name, err) 247 } else { 248 log.Printf("Object deleted: %s \n\n", object.Name) 249 } 250 } 251 252 } else { 253 delete_err := errors.New("Error trying to delete a bucket containing objects without `force_destroy` set to true") 254 log.Printf("Error! %s : %s\n\n", bucket, delete_err) 255 return delete_err 256 } 257 } else { 258 break // 0 items, bucket empty 259 } 260 } 261 262 // remove empty bucket 263 err := config.clientStorage.Buckets.Delete(bucket).Do() 264 if err != nil { 265 fmt.Printf("Error deleting bucket %s: %v\n\n", bucket, err) 266 return err 267 } 268 log.Printf("[DEBUG] Deleted bucket %v\n\n", bucket) 269 270 return nil 271 }