diff --git a/builtin/providers/google/resource_storage_bucket.go b/builtin/providers/google/resource_storage_bucket.go index 59370720e..de03d5f6d 100644 --- a/builtin/providers/google/resource_storage_bucket.go +++ b/builtin/providers/google/resource_storage_bucket.go @@ -40,6 +40,26 @@ func resourceStorageBucket() *schema.Resource { Optional: true, Default: false, }, + "website": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "main_page_suffix": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "not_found_page": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "self_link": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -54,6 +74,27 @@ func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error // Create a bucket, setting the acl, location and name. sb := &storage.Bucket{Name: bucket, Location: location} + + if v, ok := d.GetOk("website"); ok { + websites := v.([]interface{}) + + if len(websites) > 1 { + return fmt.Errorf("At most one website block is allowed") + } + + sb.Website = &storage.BucketWebsite{} + + website := websites[0].(map[string]interface{}) + + if v, ok := website["not_found_page"]; ok { + sb.Website.NotFoundPage = v.(string) + } + + if v, ok := website["main_page_suffix"]; ok { + sb.Website.MainPageSuffix = v.(string) + } + } + res, err := config.clientStorage.Buckets.Insert(config.Project, sb).PredefinedAcl(acl).Do() if err != nil { @@ -64,14 +105,60 @@ func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error log.Printf("[DEBUG] Created bucket %v at location %v\n\n", res.Name, res.SelfLink) // Assign the bucket ID as the resource ID + d.Set("self_link", res.SelfLink) d.SetId(res.Id) return nil } func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error { - // Only thing you can currently change is force_delete (all other properties have ForceNew) - // which is just terraform object state change, so nothing to do here + config := meta.(*Config) + + sb := &storage.Bucket{} + + if d.HasChange("website") { + if v, ok := d.GetOk("website"); ok { + websites := v.([]interface{}) + + if len(websites) > 1 { + return fmt.Errorf("At most one website block is allowed") + } + + // Setting fields to "" to be explicit that the PATCH call will + // delete this field. + if len(websites) == 0 { + sb.Website.NotFoundPage = "" + sb.Website.MainPageSuffix = "" + } else { + website := websites[0].(map[string]interface{}) + sb.Website = &storage.BucketWebsite{} + if v, ok := website["not_found_page"]; ok { + sb.Website.NotFoundPage = v.(string) + } else { + sb.Website.NotFoundPage = "" + } + + if v, ok := website["main_page_suffix"]; ok { + sb.Website.MainPageSuffix = v.(string) + } else { + sb.Website.MainPageSuffix = "" + } + } + } + } + + res, err := config.clientStorage.Buckets.Patch(d.Get("name").(string), sb).Do() + + if err != nil { + return err + } + + log.Printf("[DEBUG] Patched bucket %v at location %v\n\n", res.Name, res.SelfLink) + + // Assign the bucket ID as the resource ID + d.Set("self_link", res.SelfLink) + d.SetId(res.Id) + return nil } @@ -90,6 +177,7 @@ func resourceStorageBucketRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] Read bucket %v at location %v\n\n", res.Name, res.SelfLink) // Update the bucket ID according to the resource ID + d.Set("self_link", res.SelfLink) d.SetId(res.Id) return nil diff --git a/website/source/docs/providers/google/r/storage_bucket.html.markdown b/website/source/docs/providers/google/r/storage_bucket.html.markdown index b5aa15353..a7eea21b1 100644 --- a/website/source/docs/providers/google/r/storage_bucket.html.markdown +++ b/website/source/docs/providers/google/r/storage_bucket.html.markdown @@ -17,16 +17,33 @@ Example creating a private bucket in standard storage, in the EU region. ``` resource "google_storage_bucket" "image-store" { - name = "image-store-bucket" - predefined_acl = "projectPrivate" - location = "EU" + name = "image-store-bucket" + predefined_acl = "projectPrivate" + location = "EU" + website { + main_page_suffix = "index.html" + not_found_page = "404.html" + } } ``` ## Argument Reference +The following arguments are supported: + * `name` - (Required) The name of the bucket. * `predefined_acl` - (Optional, Default: 'private') The [canned GCS ACL](https://cloud.google.com/storage/docs/access-control#predefined-acl) to apply. * `location` - (Optional, Default: 'US') The [GCS location](https://cloud.google.com/storage/docs/bucket-locations) * `force_destroy` - (Optional, Default: false) When deleting a bucket, this boolean option will delete all contained objects. If you try to delete a bucket that contains objects, Terraform will fail that run. + +The optional `website` block supports: + +* `main_page_suffix` - (Optional) Behaves as the bucket's directory index where missing objects are treated as potential directories. +* `not_found_page` - (Optional) The custom object to return when a requested resource is not found. + +## Attributes Reference + +The following attributes are exported: + +* `self_link` - The URI of the created resource.