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