mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
[WIP] Add provider/google/google_storage_bucket lifecycle interface
This commit is contained in:
parent
a08c7c4fac
commit
7dc4c9d5e0
@ -1,12 +1,14 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
@ -77,6 +79,64 @@ func resourceStorageBucket() *schema.Resource {
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"lifecycle_rule": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"action": {
|
||||
Type: schema.TypeSet,
|
||||
Required: true,
|
||||
MaxItems: 1,
|
||||
Set: resourceGCSBucketLifecycleRuleActionHash,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"storage_class": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"condition": {
|
||||
Type: schema.TypeSet,
|
||||
Required: true,
|
||||
MaxItems: 1,
|
||||
Set: resourceGCSBucketLifecycleRuleConditionHash,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"age": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
"created_before": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"is_live": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"matches_storage_class": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
"number_of_newer_versions": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"website": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
@ -150,6 +210,10 @@ func resourceStorageBucketCreate(d *schema.ResourceData, meta interface{}) error
|
||||
sb.StorageClass = v.(string)
|
||||
}
|
||||
|
||||
if err := resourceGCSBucketLifecycleCreateOrUpdate(d, sb, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("website"); ok {
|
||||
websites := v.([]interface{})
|
||||
|
||||
@ -208,6 +272,12 @@ func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error
|
||||
|
||||
sb := &storage.Bucket{}
|
||||
|
||||
if d.HasChange("lifecycle_rule") {
|
||||
if err := resourceGCSBucketLifecycleCreateOrUpdate(d, sb, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("website") {
|
||||
if v, ok := d.GetOk("website"); ok {
|
||||
websites := v.([]interface{})
|
||||
@ -382,3 +452,135 @@ func flattenCors(corsRules []*storage.BucketCors) []map[string]interface{} {
|
||||
}
|
||||
return corsRulesSchema
|
||||
}
|
||||
|
||||
func resourceGCSBucketLifecycleCreateOrUpdate(d *schema.ResourceData, sb *storage.Bucket, update bool) error {
|
||||
if v, ok := d.GetOk("lifecycle_rule"); ok {
|
||||
lifecycle_rules := v.([]interface{})
|
||||
|
||||
if len(lifecycle_rules) > 100 {
|
||||
return fmt.Errorf("At most 100 lifecycle_rule blocks are allowed")
|
||||
}
|
||||
|
||||
sb.Lifecycle = &storage.BucketLifecycle{}
|
||||
sb.Lifecycle.Rule = make([]*storage.BucketLifecycleRule, 0, len(lifecycle_rules))
|
||||
|
||||
for _, lifecycle_rule := range lifecycle_rules {
|
||||
lifecycle_rule := lifecycle_rule.(map[string]interface{})
|
||||
|
||||
target_lifecycle_rule := &storage.BucketLifecycleRule{}
|
||||
|
||||
if v, ok := lifecycle_rule["action"]; ok {
|
||||
action := v.(*schema.Set).List()[0].(map[string]interface{})
|
||||
|
||||
target_lifecycle_rule.Action = &storage.BucketLifecycleRuleAction{}
|
||||
|
||||
if v, ok := action["type"]; ok {
|
||||
target_lifecycle_rule.Action.Type = v.(string)
|
||||
}
|
||||
|
||||
if v, ok := action["storage_class"]; ok {
|
||||
target_lifecycle_rule.Action.StorageClass = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := lifecycle_rule["condition"]; ok {
|
||||
condition := v.(*schema.Set).List()[0].(map[string]interface{})
|
||||
condition_elements := 0
|
||||
|
||||
target_lifecycle_rule.Condition = &storage.BucketLifecycleRuleCondition{}
|
||||
|
||||
if v, ok := condition["age"]; ok {
|
||||
condition_elements++
|
||||
target_lifecycle_rule.Condition.Age = int64(v.(int))
|
||||
}
|
||||
|
||||
if v, ok := condition["created_before"]; ok {
|
||||
condition_elements++
|
||||
target_lifecycle_rule.Condition.CreatedBefore = v.(string)
|
||||
}
|
||||
|
||||
if v, ok := condition["is_live"]; ok {
|
||||
condition_elements++
|
||||
target_lifecycle_rule.Condition.IsLive = v.(bool)
|
||||
}
|
||||
|
||||
if v, ok := condition["matches_storage_class"]; ok {
|
||||
matches_storage_classes := v.([]interface{})
|
||||
|
||||
target_matches_storage_classes := make([]string, 0, len(matches_storage_classes))
|
||||
|
||||
for _, v := range matches_storage_classes {
|
||||
target_matches_storage_classes = append(target_matches_storage_classes, v.(string))
|
||||
condition_elements++
|
||||
}
|
||||
|
||||
target_lifecycle_rule.Condition.MatchesStorageClass = target_matches_storage_classes
|
||||
}
|
||||
|
||||
if v, ok := condition["number_of_newer_versions"]; ok {
|
||||
condition_elements++
|
||||
target_lifecycle_rule.Condition.NumNewerVersions = int64(v.(int))
|
||||
}
|
||||
|
||||
if condition_elements < 1 {
|
||||
return fmt.Errorf("At least one condition element is required")
|
||||
}
|
||||
|
||||
sb.Lifecycle.Rule = append(sb.Lifecycle.Rule, target_lifecycle_rule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGCSBucketLifecycleRuleActionHash(v interface{}) int {
|
||||
if v == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
m := v.(map[string]interface{})
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s-", m["type"].(string)))
|
||||
|
||||
if v, ok := m["storage_class"]; ok {
|
||||
buf.WriteString(fmt.Sprintf("%s-", v.(string)))
|
||||
}
|
||||
|
||||
return hashcode.String(buf.String())
|
||||
}
|
||||
|
||||
func resourceGCSBucketLifecycleRuleConditionHash(v interface{}) int {
|
||||
if v == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
m := v.(map[string]interface{})
|
||||
|
||||
if v, ok := m["age"]; ok {
|
||||
buf.WriteString(fmt.Sprintf("%d-", v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := m["created_before"]; ok {
|
||||
buf.WriteString(fmt.Sprintf("%s-", v.(string)))
|
||||
}
|
||||
|
||||
if v, ok := m["is_live"]; ok {
|
||||
buf.WriteString(fmt.Sprintf("%t-", v.(bool)))
|
||||
}
|
||||
|
||||
if v, ok := m["matches_storage_class"]; ok {
|
||||
matches_storage_classes := v.([]interface{})
|
||||
for _, matches_storage_class := range matches_storage_classes {
|
||||
buf.WriteString(fmt.Sprintf("%s-", matches_storage_class))
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := m["number_of_newer_versions"]; ok {
|
||||
buf.WriteString(fmt.Sprintf("%d-", v.(int)))
|
||||
}
|
||||
|
||||
return hashcode.String(buf.String())
|
||||
}
|
||||
|
@ -82,6 +82,52 @@ func TestAccStorageBucket_customAttributes(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccStorageBucket_lifecycleRules(t *testing.T) {
|
||||
var bucket storage.Bucket
|
||||
bucketName := fmt.Sprintf("tf-test-acc-bucket-%d", acctest.RandInt())
|
||||
|
||||
hash_step0_lc0_action := resourceGCSBucketLifecycleRuleActionHash(map[string]interface{}{"type": "SetStorageClass", "storage_class": "NEARLINE"})
|
||||
hash_step0_lc0_condition := resourceGCSBucketLifecycleRuleConditionHash(map[string]interface{}{"age": 2, "created_before": "", "is_live": false, "number_of_newer_versions": 0})
|
||||
|
||||
hash_step0_lc1_action := resourceGCSBucketLifecycleRuleActionHash(map[string]interface{}{"type": "Delete", "storage_class": ""})
|
||||
hash_step0_lc1_condition := resourceGCSBucketLifecycleRuleConditionHash(map[string]interface{}{"age": 10, "created_before": "", "is_live": false, "number_of_newer_versions": 0})
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccStorageBucketDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccStorageBucket_lifecycleRules(bucketName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckStorageBucketExists(
|
||||
"google_storage_bucket.bucket", bucketName, &bucket),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.#", "2"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.0.action.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.action.%d.type", hash_step0_lc0_action), "SetStorageClass"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.action.%d.storage_class", hash_step0_lc0_action), "NEARLINE"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.0.condition.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.condition.%d.age", hash_step0_lc0_condition), "2"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.1.action.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.1.action.%d.type", hash_step0_lc1_action), "Delete"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.1.condition.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.1.condition.%d.age", hash_step0_lc1_condition), "10"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccStorageBucket_storageClass(t *testing.T) {
|
||||
var bucket storage.Bucket
|
||||
bucketName := fmt.Sprintf("tf-test-acc-bucket-%d", acctest.RandInt())
|
||||
@ -128,6 +174,15 @@ func TestAccStorageBucket_update(t *testing.T) {
|
||||
var bucket storage.Bucket
|
||||
bucketName := fmt.Sprintf("tf-test-acl-bucket-%d", acctest.RandInt())
|
||||
|
||||
hash_step2_lc0_action := resourceGCSBucketLifecycleRuleActionHash(map[string]interface{}{"type": "Delete", "storage_class": ""})
|
||||
hash_step2_lc0_condition := resourceGCSBucketLifecycleRuleConditionHash(map[string]interface{}{"age": 10, "created_before": "", "is_live": false, "number_of_newer_versions": 0})
|
||||
|
||||
hash_step3_lc0_action := resourceGCSBucketLifecycleRuleActionHash(map[string]interface{}{"type": "SetStorageClass", "storage_class": "NEARLINE"})
|
||||
hash_step3_lc0_condition := resourceGCSBucketLifecycleRuleConditionHash(map[string]interface{}{"age": 2, "created_before": "", "is_live": false, "number_of_newer_versions": 0})
|
||||
|
||||
hash_step3_lc1_action := resourceGCSBucketLifecycleRuleActionHash(map[string]interface{}{"type": "Delete", "storage_class": ""})
|
||||
hash_step3_lc1_condition := resourceGCSBucketLifecycleRuleConditionHash(map[string]interface{}{"age": 10, "created_before": "", "is_live": false, "number_of_newer_versions": 2})
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
@ -142,6 +197,8 @@ func TestAccStorageBucket_update(t *testing.T) {
|
||||
"google_storage_bucket.bucket", "location", "US"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "force_destroy", "false"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.#", "0"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
@ -155,6 +212,81 @@ func TestAccStorageBucket_update(t *testing.T) {
|
||||
"google_storage_bucket.bucket", "location", "EU"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "force_destroy", "true"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.#", "0"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccStorageBucket_customAttributes_withLifecycle1(bucketName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckStorageBucketExists(
|
||||
"google_storage_bucket.bucket", bucketName, &bucket),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "predefined_acl", "publicReadWrite"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "location", "EU"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "force_destroy", "true"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.0.action.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.action.%d.type", hash_step2_lc0_action), "Delete"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.0.condition.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.condition.%d.age", hash_step2_lc0_condition), "10"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccStorageBucket_customAttributes_withLifecycle2(bucketName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckStorageBucketExists(
|
||||
"google_storage_bucket.bucket", bucketName, &bucket),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "predefined_acl", "publicReadWrite"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "location", "EU"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "force_destroy", "true"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.#", "2"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.0.action.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.action.%d.type", hash_step3_lc0_action), "SetStorageClass"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.action.%d.storage_class", hash_step3_lc0_action), "NEARLINE"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.0.condition.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.0.condition.%d.age", hash_step3_lc0_condition), "2"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.1.action.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.1.action.%d.type", hash_step3_lc1_action), "Delete"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.1.condition.#", "1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.1.condition.%d.age", hash_step3_lc1_condition), "10"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", fmt.Sprintf("lifecycle_rule.1.condition.%d.number_of_newer_versions", hash_step3_lc1_condition), "2"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccStorageBucket_customAttributes(bucketName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckStorageBucketExists(
|
||||
"google_storage_bucket.bucket", bucketName, &bucket),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "predefined_acl", "publicReadWrite"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "location", "EU"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "force_destroy", "true"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"google_storage_bucket.bucket", "lifecycle_rule.#", "0"),
|
||||
),
|
||||
},
|
||||
},
|
||||
@ -375,6 +507,54 @@ resource "google_storage_bucket" "bucket" {
|
||||
`, bucketName)
|
||||
}
|
||||
|
||||
func testAccStorageBucket_customAttributes_withLifecycle1(bucketName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_storage_bucket" "bucket" {
|
||||
name = "%s"
|
||||
predefined_acl = "publicReadWrite"
|
||||
location = "EU"
|
||||
force_destroy = "true"
|
||||
lifecycle_rule {
|
||||
action {
|
||||
type = "Delete"
|
||||
}
|
||||
condition {
|
||||
age = 10
|
||||
}
|
||||
}
|
||||
}
|
||||
`, bucketName)
|
||||
}
|
||||
|
||||
func testAccStorageBucket_customAttributes_withLifecycle2(bucketName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_storage_bucket" "bucket" {
|
||||
name = "%s"
|
||||
predefined_acl = "publicReadWrite"
|
||||
location = "EU"
|
||||
force_destroy = "true"
|
||||
lifecycle_rule {
|
||||
action {
|
||||
type = "SetStorageClass"
|
||||
storage_class = "NEARLINE"
|
||||
}
|
||||
condition {
|
||||
age = 2
|
||||
}
|
||||
}
|
||||
lifecycle_rule {
|
||||
action {
|
||||
type = "Delete"
|
||||
}
|
||||
condition {
|
||||
age = 10
|
||||
number_of_newer_versions = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
`, bucketName)
|
||||
}
|
||||
|
||||
func testAccStorageBucket_storageClass(bucketName, storageClass, location string) string {
|
||||
var locationBlock string
|
||||
if location != "" {
|
||||
@ -409,3 +589,28 @@ resource "google_storage_bucket" "bucket" {
|
||||
}
|
||||
`, bucketName)
|
||||
}
|
||||
|
||||
func testAccStorageBucket_lifecycleRules(bucketName string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_storage_bucket" "bucket" {
|
||||
name = "%s"
|
||||
lifecycle_rule {
|
||||
action {
|
||||
type = "SetStorageClass"
|
||||
storage_class = "NEARLINE"
|
||||
}
|
||||
condition {
|
||||
age = 2
|
||||
}
|
||||
}
|
||||
lifecycle_rule {
|
||||
action {
|
||||
type = "Delete"
|
||||
}
|
||||
condition {
|
||||
age = 10
|
||||
}
|
||||
}
|
||||
}
|
||||
`, bucketName)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user