provider/google: Add CORS support for google_storage_bucket. (#14695)

This commit is contained in:
Riley Karson 2017-05-31 12:44:25 -07:00 committed by Dana Hoffman
parent fe0bf11965
commit 2ca5b657cd
2 changed files with 174 additions and 0 deletions

View File

@ -89,6 +89,40 @@ func resourceStorageBucket() *schema.Resource {
},
},
},
"cors": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"origin": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"method": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"response_header": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"max_age_seconds": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
},
},
},
},
}
}
@ -132,6 +166,10 @@ func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error
}
}
if v, ok := d.GetOk("cors"); ok {
sb.Cors = expandCors(v.([]interface{}))
}
var res *storage.Bucket
err = resource.Retry(1*time.Minute, func() *resource.RetryError {
@ -197,6 +235,10 @@ func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error
}
}
if v, ok := d.GetOk("cors"); ok {
sb.Cors = expandCors(v.([]interface{}))
}
res, err := config.clientStorage.Buckets.Patch(d.Get("name").(string), sb).Do()
if err != nil {
@ -230,6 +272,7 @@ func resourceStorageBucketRead(d *schema.ResourceData, meta interface{}) error {
d.Set("url", fmt.Sprintf("gs://%s", bucket))
d.Set("storage_class", res.StorageClass)
d.Set("location", res.Location)
d.Set("cors", flattenCors(res.Cors))
d.SetId(res.Id)
return nil
}
@ -295,3 +338,43 @@ func resourceStorageBucketStateImporter(d *schema.ResourceData, meta interface{}
d.Set("name", d.Id())
return []*schema.ResourceData{d}, nil
}
func expandCors(configured []interface{}) []*storage.BucketCors {
corsRules := make([]*storage.BucketCors, 0, len(configured))
for _, raw := range configured {
data := raw.(map[string]interface{})
corsRule := storage.BucketCors{
Origin: convertSchemaArrayToStringArray(data["origin"].([]interface{})),
Method: convertSchemaArrayToStringArray(data["method"].([]interface{})),
ResponseHeader: convertSchemaArrayToStringArray(data["response_header"].([]interface{})),
MaxAgeSeconds: int64(data["max_age_seconds"].(int)),
}
corsRules = append(corsRules, &corsRule)
}
return corsRules
}
func convertSchemaArrayToStringArray(input []interface{}) []string {
output := make([]string, 0, len(input))
for _, val := range input {
output = append(output, val.(string))
}
return output
}
func flattenCors(corsRules []*storage.BucketCors) []map[string]interface{} {
corsRulesSchema := make([]map[string]interface{}, 0, len(corsRules))
for _, corsRule := range corsRules {
data := map[string]interface{}{
"origin": corsRule.Origin,
"method": corsRule.Method,
"response_header": corsRule.ResponseHeader,
"max_age_seconds": corsRule.MaxAgeSeconds,
}
corsRulesSchema = append(corsRulesSchema, data)
}
return corsRulesSchema
}

View File

@ -173,6 +173,76 @@ func TestAccStorageBucket_forceDestroy(t *testing.T) {
})
}
func TestAccStorageBucket_cors(t *testing.T) {
var bucket storage.Bucket
bucketName := fmt.Sprintf("tf-test-acl-bucket-%d", acctest.RandInt())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccStorageBucketDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testGoogleStorageBucketsCors(bucketName),
Check: resource.ComposeTestCheckFunc(
testAccCheckStorageBucketExists(
"google_storage_bucket.bucket", bucketName, &bucket),
),
},
},
})
if len(bucket.Cors) != 2 {
t.Errorf("Expected # of cors elements to be 2, got %d", len(bucket.Cors))
}
firstArr := bucket.Cors[0]
if firstArr.MaxAgeSeconds != 10 {
t.Errorf("Expected first block's MaxAgeSeconds to be 10, got %d", firstArr.MaxAgeSeconds)
}
for i, v := range []string{"abc", "def"} {
if firstArr.Origin[i] != v {
t.Errorf("Expected value in first block origin to be to be %v, got %v", v, firstArr.Origin[i])
}
}
for i, v := range []string{"a1a"} {
if firstArr.Method[i] != v {
t.Errorf("Expected value in first block method to be to be %v, got %v", v, firstArr.Method[i])
}
}
for i, v := range []string{"123", "456", "789"} {
if firstArr.ResponseHeader[i] != v {
t.Errorf("Expected value in first block response headerto be to be %v, got %v", v, firstArr.ResponseHeader[i])
}
}
secondArr := bucket.Cors[1]
if secondArr.MaxAgeSeconds != 5 {
t.Errorf("Expected second block's MaxAgeSeconds to be 5, got %d", secondArr.MaxAgeSeconds)
}
for i, v := range []string{"ghi", "jkl"} {
if secondArr.Origin[i] != v {
t.Errorf("Expected value in second block origin to be to be %v, got %v", v, secondArr.Origin[i])
}
}
for i, v := range []string{"z9z"} {
if secondArr.Method[i] != v {
t.Errorf("Expected value in second block method to be to be %v, got %v", v, secondArr.Method[i])
}
}
for i, v := range []string{"000"} {
if secondArr.ResponseHeader[i] != v {
t.Errorf("Expected value in second block response headerto be to be %v, got %v", v, secondArr.ResponseHeader[i])
}
}
}
func testAccCheckStorageBucketExists(n string, bucketName string, bucket *storage.Bucket) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
@ -289,3 +359,24 @@ resource "google_storage_bucket" "bucket" {
}
`, bucketName, storageClass, locationBlock)
}
func testGoogleStorageBucketsCors(bucketName string) string {
return fmt.Sprintf(`
resource "google_storage_bucket" "bucket" {
name = "%s"
cors {
origin = ["abc", "def"]
method = ["a1a"]
response_header = ["123", "456", "789"]
max_age_seconds = 10
}
cors {
origin = ["ghi", "jkl"]
method = ["z9z"]
response_header = ["000"]
max_age_seconds = 5
}
}
`, bucketName)
}