Skip to content

cos bucket adds abort_incomplete_multipart_upload parameter #2449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/2449.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/tencentcloud_cos_bucket: add `abort_incomplete_multipart_upload` field
```

```release-note:enhancement
datasource/tencentcloud_cos_buckets: add `abort_incomplete_multipart_upload` field
```
14 changes: 14 additions & 0 deletions tencentcloud/services/cos/data_source_tc_cos_buckets.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,20 @@ func DataSourceTencentCloudCosBuckets() *schema.Resource {
},
},
},
"abort_incomplete_multipart_upload": {
Type: schema.TypeList,
Computed: true,
Description: "Set the maximum time a multipart upload is allowed to remain running.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"days_after_initiation": {
Type: schema.TypeInt,
Computed: true,
Description: "Specifies the number of days after the multipart upload starts that the upload must be completed. The maximum value is 3650.",
},
},
},
},
},
},
},
Expand Down
8 changes: 8 additions & 0 deletions tencentcloud/services/cos/data_source_tc_cos_buckets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ func TestAccTencentCloudCosBucketDataSource_full(t *testing.T) {
"bucket_list.0.lifecycle_rules.0.non_current_expiration.#", "1"),
resource.TestCheckResourceAttr("data.tencentcloud_cos_buckets.bucket_list",
"bucket_list.0.lifecycle_rules.0.non_current_transition.#", "2"),
resource.TestCheckResourceAttr("data.tencentcloud_cos_buckets.bucket_list",
"bucket_list.0.lifecycle_rules.0.abort_incomplete_multipart_upload.#", "1"),
resource.TestCheckResourceAttr("data.tencentcloud_cos_buckets.bucket_list",
"bucket_list.0.lifecycle_rules.0.abort_incomplete_multipart_upload.0.days_after_initiation", "1"),
resource.TestCheckResourceAttr("data.tencentcloud_cos_buckets.bucket_list", "bucket_list.0.website.#", "1"),
resource.TestCheckResourceAttr("data.tencentcloud_cos_buckets.bucket_list", "bucket_list.0.website.0.index_document", "index.html"),
resource.TestCheckResourceAttr("data.tencentcloud_cos_buckets.bucket_list", "bucket_list.0.website.0.error_document", "error.html"),
Expand Down Expand Up @@ -158,6 +162,10 @@ resource "tencentcloud_cos_bucket" "bucket_full" {
non_current_days = 180
storage_class = "ARCHIVE"
}

abort_incomplete_multipart_upload {
days_after_initiation = 1
}
}

website {
Expand Down
49 changes: 42 additions & 7 deletions tencentcloud/services/cos/resource_tc_cos_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,23 @@ func ResourceTencentCloudCosBucket() *schema.Resource {
},
},
},
"abort_incomplete_multipart_upload": {
Type: schema.TypeSet,
Optional: true,
Set: abortIncompleteMultipartUploadHash,
MaxItems: 1,
Description: "Set the maximum time a multipart upload is allowed to remain running.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"days_after_initiation": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: tccommon.ValidateIntegerMin(1),
Description: "Specifies the number of days after the multipart upload starts that the upload must be completed. The maximum value is 3650.",
},
},
},
},
},
},
},
Expand Down Expand Up @@ -920,13 +937,9 @@ func waitAclEnable(ctx context.Context, meta interface{}, bucket string) error {
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
aclResult, e := cosService.GetBucketACL(ctx, bucket)
if e != nil {
sdkError, ok := e.(*errors.TencentCloudSDKError)
if ok {
log.Printf("[CRITAL]%s api[%s] fail when try to update acl, reason[%s,%s,%s]\n", logId, "GetBucketACL", sdkError.Error(), sdkError.GetCode(), sdkError.GetMessage())

if strings.Contains(sdkError.GetMessage(), "NoSuchBucket") {
return resource.RetryableError(fmt.Errorf("[CRITAL][retry]%s api[%s] it still on creating, need try again.\n", logId, "GetBucketACL"))
}
if strings.Contains(e.Error(), "NoSuchBucket") {
log.Printf("[CRITAL][retry]%s api[%s] because of bucket[%s] still on creating, need try again.\n", logId, "GetBucketACL", bucket)
return resource.RetryableError(fmt.Errorf("[CRITAL][retry]%s api[%s] it still on creating, need try again.\n", logId, "GetBucketACL"))
}
log.Printf("[CRITAL]%s api[%s] fail when try to update acl, reason[%s]\n", logId, "GetBucketACL", e.Error())
return resource.NonRetryableError(e)
Expand Down Expand Up @@ -1291,6 +1304,19 @@ func resourceTencentCloudCosBucketLifecycleUpdate(ctx context.Context, meta inte

rule.NoncurrentVersionExpiration = e
}

// AbortIncompleteMultipartUpload
abortIncompleteMultipartUploads := d.Get(fmt.Sprintf("lifecycle_rules.%d.abort_incomplete_multipart_upload", i)).(*schema.Set).List()
if len(abortIncompleteMultipartUploads) > 0 {
abortIncompleteMultipartUpload := abortIncompleteMultipartUploads[0].(map[string]interface{})
e := &s3.AbortIncompleteMultipartUpload{}

if val, ok := abortIncompleteMultipartUpload["days_after_initiation"].(int); ok && val > 0 {
e.DaysAfterInitiation = aws.Int64(int64(val))
}

rule.AbortIncompleteMultipartUpload = e
}
rules = append(rules, rule)
}

Expand Down Expand Up @@ -1664,6 +1690,15 @@ func nonCurrentExpirationHash(v interface{}) int {
return helper.HashString(buf.String())
}

func abortIncompleteMultipartUploadHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
if v, ok := m["days_after_initiation"]; ok {
buf.WriteString(fmt.Sprintf("%d-", v.(int)))
}
return helper.HashString(buf.String())
}

func transitionHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
Expand Down
6 changes: 6 additions & 0 deletions tencentcloud/services/cos/resource_tc_cos_bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ func TestAccTencentCloudCosBucketResource_lifecycle(t *testing.T) {
}),
resource.TestCheckResourceAttr("tencentcloud_cos_bucket.bucket_lifecycle", "lifecycle_rules.0.non_current_expiration.#", "1"),
resource.TestCheckResourceAttr("tencentcloud_cos_bucket.bucket_lifecycle", "lifecycle_rules.0.non_current_transition.#", "2"),
resource.TestCheckResourceAttr("tencentcloud_cos_bucket.bucket_lifecycle", "lifecycle_rules.0.abort_incomplete_multipart_upload.#", "1"),
resource.TestCheckResourceAttr("tencentcloud_cos_bucket.bucket_lifecycle", "lifecycle_rules.0.abort_incomplete_multipart_upload.0.days_after_initiation", "1"),
),
},
{
Expand Down Expand Up @@ -786,6 +788,10 @@ resource "tencentcloud_cos_bucket" "bucket_lifecycle" {
non_current_days = 180
storage_class = "ARCHIVE"
}

abort_incomplete_multipart_upload {
days_after_initiation = 1
}
}
}
`, tcacctest.UserInfoData)
Expand Down
16 changes: 16 additions & 0 deletions tencentcloud/services/cos/service_tencentcloud_cos.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,14 @@ func (me *CosService) GetBucketLifecycle(ctx context.Context, bucket string) (li
}
rule["non_current_expiration"] = schema.NewSet(nonCurrentExpirationHash, []interface{}{e})
}
// abortIncompleteMultipartUpload
if value.AbortIncompleteMultipartUpload != nil {
e := make(map[string]interface{})
if value.AbortIncompleteMultipartUpload.DaysAfterInitiation != nil {
e["days_after_initiation"] = int(*value.AbortIncompleteMultipartUpload.DaysAfterInitiation)
}
rule["abort_incomplete_multipart_upload"] = schema.NewSet(abortIncompleteMultipartUploadHash, []interface{}{e})
}

lifecycleRules = append(lifecycleRules, rule)
}
Expand Down Expand Up @@ -667,6 +675,14 @@ func (me *CosService) GetDataSourceBucketLifecycle(ctx context.Context, bucket s
}
rule["non_current_expiration"] = []interface{}{e}
}
// abortIncompleteMultipartUpload
if value.AbortIncompleteMultipartUpload != nil {
e := make(map[string]interface{})
if value.AbortIncompleteMultipartUpload.DaysAfterInitiation != nil {
e["days_after_initiation"] = int(*value.AbortIncompleteMultipartUpload.DaysAfterInitiation)
}
rule["abort_incomplete_multipart_upload"] = []interface{}{e}
}

lifecycleRules = append(lifecycleRules, rule)
}
Expand Down
2 changes: 2 additions & 0 deletions website/docs/d/cos_buckets.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ In addition to all arguments above, the following attributes are exported:
* `max_age_seconds` - Specifies time in seconds that browser can cache the response for a preflight request.
* `cos_bucket_url` - The URL of this cos bucket.
* `lifecycle_rules` - The lifecycle configuration of a bucket.
* `abort_incomplete_multipart_upload` - Set the maximum time a multipart upload is allowed to remain running.
* `days_after_initiation` - Specifies the number of days after the multipart upload starts that the upload must be completed. The maximum value is 3650.
* `expiration` - Specifies a period in the object's expire.
* `date` - Specifies the date after which you want the corresponding action to take effect.
* `days` - Specifies the number of days after object creation when the specific rule action takes effect.
Expand Down
5 changes: 5 additions & 0 deletions website/docs/r/cos_bucket.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ The following arguments are supported:
* `versioning_enable` - (Optional, Bool) Enable bucket versioning. NOTE: The `multi_az` feature is true for the current bucket, cannot disable version control.
* `website` - (Optional, List) A website object(documented below).

The `abort_incomplete_multipart_upload` object of `lifecycle_rules` supports the following:

* `days_after_initiation` - (Required, Int) Specifies the number of days after the multipart upload starts that the upload must be completed. The maximum value is 3650.

The `cors_rules` object supports the following:

* `allowed_headers` - (Required, List) Specifies which headers are allowed.
Expand All @@ -273,6 +277,7 @@ The `expiration` object of `lifecycle_rules` supports the following:
The `lifecycle_rules` object supports the following:

* `filter_prefix` - (Required, String) Object key prefix identifying one or more objects to which the rule applies.
* `abort_incomplete_multipart_upload` - (Optional, Set) Set the maximum time a multipart upload is allowed to remain running.
* `expiration` - (Optional, Set) Specifies a period in the object's expire (documented below).
* `id` - (Optional, String) A unique identifier for the rule. It can be up to 255 characters.
* `non_current_expiration` - (Optional, Set) Specifies when non current object versions shall expire.
Expand Down