alicloud/resource_alicloud_oss_bucket.go (1,667 lines of code) (raw):

package alicloud import ( "bytes" "fmt" "io/ioutil" "log" "time" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) func resourceAlicloudOssBucket() *schema.Resource { return &schema.Resource{ Create: resourceAlicloudOssBucketCreate, Read: resourceAlicloudOssBucketRead, Update: resourceAlicloudOssBucketUpdate, Delete: resourceAlicloudOssBucketDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ "bucket": { Type: schema.TypeString, Optional: true, ForceNew: true, Computed: true, ValidateFunc: StringLenBetween(3, 63), }, "acl": { Type: schema.TypeString, Computed: true, Optional: true, ValidateFunc: StringInSlice([]string{"private", "public-read", "public-read-write"}, false), Deprecated: "Field 'acl' has been deprecated since provider version 1.220.0. New resource 'alicloud_oss_bucket_acl' instead.", }, "cors_rule": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "allowed_headers": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "allowed_methods": { Type: schema.TypeList, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "allowed_origins": { Type: schema.TypeList, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "expose_headers": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "max_age_seconds": { Type: schema.TypeInt, Optional: true, }, }, }, MaxItems: 10, }, "website": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "index_document": { Type: schema.TypeString, Required: true, }, "error_document": { Type: schema.TypeString, Optional: true, }, }, }, MaxItems: 1, }, "logging": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "target_bucket": { Type: schema.TypeString, Required: true, }, "target_prefix": { Type: schema.TypeString, Optional: true, }, }, }, MaxItems: 1, }, "logging_isenable": { Type: schema.TypeBool, Optional: true, Deprecated: "Deprecated from 1.37.0. When `logging` is set, the bucket logging will be able.", }, "referer_config": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "allow_empty": { Type: schema.TypeBool, Optional: true, Computed: true, }, "referers": { Type: schema.TypeList, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, MaxItems: 1, }, "lifecycle_rule_allow_same_action_overlap": { Type: schema.TypeBool, Optional: true, Default: false, }, "lifecycle_rule": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: StringLenBetween(0, 255), }, "prefix": { Type: schema.TypeString, Optional: true, Default: "", }, "enabled": { Type: schema.TypeBool, Required: true, }, "expiration": { Type: schema.TypeSet, Optional: true, Set: expirationHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "date": { Type: schema.TypeString, Optional: true, ValidateFunc: validateOssBucketDateTimestamp, }, "created_before_date": { Type: schema.TypeString, Optional: true, ValidateFunc: validateOssBucketDateTimestamp, }, "days": { Type: schema.TypeInt, Optional: true, }, "expired_object_delete_marker": { Type: schema.TypeBool, Optional: true, }, }, }, }, "transitions": { Type: schema.TypeSet, Optional: true, Set: transitionsHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "created_before_date": { Type: schema.TypeString, Optional: true, ValidateFunc: validateOssBucketDateTimestamp, }, "days": { Type: schema.TypeInt, Optional: true, }, "storage_class": { Type: schema.TypeString, Required: true, ValidateFunc: StringInSlice([]string{ string(oss.StorageStandard), string(oss.StorageIA), string(oss.StorageArchive), string(oss.StorageColdArchive), string(oss.StorageDeepColdArchive), }, false), }, "is_access_time": { Type: schema.TypeBool, Optional: true, }, "return_to_std_when_visit": { Type: schema.TypeBool, Optional: true, }, }, }, }, "abort_multipart_upload": { Type: schema.TypeSet, Optional: true, Set: abortMultipartUploadHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "created_before_date": { Type: schema.TypeString, Optional: true, ValidateFunc: validateOssBucketDateTimestamp, }, "days": { Type: schema.TypeInt, Optional: true, }, }, }, }, "noncurrent_version_expiration": { Type: schema.TypeSet, Optional: true, Set: expirationHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "days": { Type: schema.TypeInt, Required: true, }, }, }, }, "noncurrent_version_transition": { Type: schema.TypeSet, Optional: true, Set: transitionsHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "days": { Type: schema.TypeInt, Required: true, }, "storage_class": { Type: schema.TypeString, Required: true, ValidateFunc: StringInSlice([]string{ string(oss.StorageStandard), string(oss.StorageIA), string(oss.StorageArchive), string(oss.StorageColdArchive), string(oss.StorageDeepColdArchive), }, false), }, "is_access_time": { Type: schema.TypeBool, Optional: true, }, "return_to_std_when_visit": { Type: schema.TypeBool, Optional: true, }, }, }, }, "tags": tagsSchema(), "filter": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "not": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "prefix": { Type: schema.TypeString, Optional: true, }, "tag": { Type: schema.TypeList, MaxItems: 1, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "key": { Type: schema.TypeString, Required: true, }, "value": { Type: schema.TypeString, Required: true, }, }, }, }, }, }, }, "object_size_greater_than": { Type: schema.TypeInt, Optional: true, ValidateFunc: IntAtLeast(1), }, "object_size_less_than": { Type: schema.TypeInt, Optional: true, ValidateFunc: IntAtLeast(1), }, }, }, }, }, }, MaxItems: 1000, }, "policy": { Type: schema.TypeString, Optional: true, }, "creation_date": { Type: schema.TypeString, Computed: true, }, "extranet_endpoint": { Type: schema.TypeString, Computed: true, }, "intranet_endpoint": { Type: schema.TypeString, Computed: true, }, "location": { Type: schema.TypeString, Computed: true, }, "owner": { Type: schema.TypeString, Computed: true, }, "storage_class": { Type: schema.TypeString, Default: oss.StorageStandard, Optional: true, ForceNew: true, ValidateFunc: StringInSlice([]string{ string(oss.StorageStandard), string(oss.StorageIA), string(oss.StorageArchive), string(oss.StorageColdArchive), string(oss.StorageDeepColdArchive), }, false), }, "redundancy_type": { Type: schema.TypeString, Default: oss.RedundancyLRS, Optional: true, ForceNew: true, ValidateFunc: StringInSlice([]string{ string(oss.RedundancyLRS), string(oss.RedundancyZRS), }, false), }, "server_side_encryption_rule": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "sse_algorithm": { Type: schema.TypeString, Required: true, ValidateFunc: StringInSlice([]string{ ServerSideEncryptionAes256, ServerSideEncryptionKMS, ServerSideEncryptionSM4, }, false), }, "kms_master_key_id": { Type: schema.TypeString, Optional: true, }, "kms_data_encryption": { Type: schema.TypeString, Optional: true, ValidateFunc: StringInSlice([]string{ ServerSideEncryptionSM4, "", }, false), }, }, }, MaxItems: 1, }, "tags": tagsSchema(), "force_destroy": { Type: schema.TypeBool, Optional: true, Default: false, }, "versioning": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "status": { Type: schema.TypeString, Required: true, ValidateFunc: StringInSlice([]string{ "Enabled", "Suspended", }, false), }, }, }, MaxItems: 1, }, "transfer_acceleration": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "enabled": { Type: schema.TypeBool, Required: true, }, }, }, MaxItems: 1, }, "access_monitor": { Type: schema.TypeList, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "status": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: StringInSlice([]string{ "Enabled", "Disabled", }, false), }, }, }, MaxItems: 1, }, "resource_group_id": { Type: schema.TypeString, Computed: true, Optional: true, }, }, } } func resourceAlicloudOssBucketCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) var bucketName string if v, ok := d.GetOk("bucket"); ok && v != "" { bucketName = v.(string) } else { bucketName = resource.PrefixedUniqueId("tf-oss-bucket-") if len(bucketName) > 63 { bucketName = bucketName[:63] } } request := map[string]string{"bucketName": bucketName} var requestInfo *oss.Client raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return ossClient.IsBucketExist(request["bucketName"]) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_oss_bucket", "IsBucketExist", AliyunOssGoSdk) } addDebug("IsBucketExist", raw, requestInfo, request) isExist, _ := raw.(bool) if isExist { return WrapError(Error("[ERROR] The specified bucket name: %#v is not available. The bucket namespace is shared by all users of the OSS system. Please select a different name and try again.", request["bucketName"])) } type Request struct { BucketName string StorageClassOption oss.Option RedundancyTypeOption oss.Option AclTypeOption oss.Option } req := Request{ bucketName, oss.StorageClass(oss.StorageClassType(d.Get("storage_class").(string))), oss.RedundancyType(oss.DataRedundancyType(d.Get("redundancy_type").(string))), oss.ACL(oss.ACLType(d.Get("acl").(string))), } options := []oss.Option{ req.StorageClassOption, req.RedundancyTypeOption, req.AclTypeOption, } // server_side_encryption_rule if encryption_rule, ok := d.Get("server_side_encryption_rule").([]interface{}); ok && encryption_rule != nil && len(encryption_rule) > 0 { if sse_rule, ok := encryption_rule[0].(map[string]interface{}); ok { if sse_algorithm, ok := sse_rule["sse_algorithm"].(string); ok { options = append(options, oss.SetHeader("x-oss-server-side-encryption", sse_algorithm)) } if sse_kms_id, ok := sse_rule["kms_master_key_id"].(string); ok && sse_kms_id != "" { options = append(options, oss.SetHeader("x-oss-server-side-encryption-key-id", sse_kms_id)) } if kms_data_encryption, ok := sse_rule["kms_data_encryption"].(string); ok && kms_data_encryption != "" { options = append(options, oss.SetHeader("x-oss-server-side-data-encryption", kms_data_encryption)) } } } //resource_group_id if resourceGroupId, ok := d.Get("resource_group_id").(string); ok { if len(resourceGroupId) > 0 { options = append(options, oss.SetHeader("x-oss-resource-group-id", resourceGroupId)) } } raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return nil, ossClient.CreateBucket(req.BucketName, options...) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_oss_bucket", "CreateBucket", AliyunOssGoSdk) } addDebug("CreateBucket", raw, requestInfo, req) err = resource.Retry(3*time.Minute, func() *resource.RetryError { raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.IsBucketExist(request["bucketName"]) }) if err != nil { return resource.NonRetryableError(err) } isExist, _ := raw.(bool) if !isExist { return resource.RetryableError(Error("Trying to ensure new OSS bucket %#v has been created successfully.", request["bucketName"])) } addDebug("IsBucketExist", raw, requestInfo, request) return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_oss_bucket", "IsBucketExist", AliyunOssGoSdk) } // Assign the bucket name as the resource ID d.SetId(request["bucketName"]) return resourceAlicloudOssBucketUpdate(d, meta) } func resourceAlicloudOssBucketRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) ossService := OssService{client} object, err := ossService.DescribeOssBucket(d.Id()) if err != nil { if NotFoundError(err) { d.SetId("") return nil } return WrapError(err) } d.Set("bucket", d.Id()) d.Set("acl", object.BucketInfo.ACL) d.Set("creation_date", object.BucketInfo.CreationDate.Format("2006-01-02")) d.Set("extranet_endpoint", object.BucketInfo.ExtranetEndpoint) d.Set("intranet_endpoint", object.BucketInfo.IntranetEndpoint) d.Set("location", object.BucketInfo.Location) d.Set("owner", object.BucketInfo.Owner.ID) d.Set("storage_class", object.BucketInfo.StorageClass) d.Set("redundancy_type", object.BucketInfo.RedundancyType) if &object.BucketInfo.SseRule != nil { if len(object.BucketInfo.SseRule.SSEAlgorithm) > 0 && object.BucketInfo.SseRule.SSEAlgorithm != "None" { rule := make(map[string]interface{}) rule["sse_algorithm"] = object.BucketInfo.SseRule.SSEAlgorithm if object.BucketInfo.SseRule.KMSMasterKeyID != "" { rule["kms_master_key_id"] = object.BucketInfo.SseRule.KMSMasterKeyID } if object.BucketInfo.SseRule.KMSDataEncryption != "" { rule["kms_data_encryption"] = object.BucketInfo.SseRule.KMSDataEncryption } data := make([]map[string]interface{}, 0) data = append(data, rule) d.Set("server_side_encryption_rule", data) } } if object.BucketInfo.Versioning != "" { data := map[string]interface{}{ "status": object.BucketInfo.Versioning, } versioning := make([]map[string]interface{}, 0) versioning = append(versioning, data) d.Set("versioning", versioning) } if object.BucketInfo.AccessMonitor != "" { data := map[string]interface{}{ "status": object.BucketInfo.AccessMonitor, } accessmonitor := make([]map[string]interface{}, 0) accessmonitor = append(accessmonitor, data) d.Set("access_monitor", accessmonitor) } request := map[string]string{"bucketName": d.Id()} var requestInfo *oss.Client // Read the CORS raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return ossClient.GetBucketCORS(request["bucketName"]) }) if err != nil && !IsExpectedErrors(err, []string{"NoSuchCORSConfiguration"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketCORS", AliyunOssGoSdk) } addDebug("GetBucketCORS", raw, requestInfo, request) cors, _ := raw.(oss.GetBucketCORSResult) rules := make([]map[string]interface{}, 0, len(cors.CORSRules)) for _, r := range cors.CORSRules { rule := make(map[string]interface{}) rule["allowed_headers"] = r.AllowedHeader rule["allowed_methods"] = r.AllowedMethod rule["allowed_origins"] = r.AllowedOrigin rule["expose_headers"] = r.ExposeHeader rule["max_age_seconds"] = r.MaxAgeSeconds rules = append(rules, rule) } if err := d.Set("cors_rule", rules); err != nil { return WrapError(err) } // Read the website configuration raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.GetBucketWebsite(d.Id()) }) if err != nil && !IsExpectedErrors(err, []string{"NoSuchWebsiteConfiguration"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketWebsite", AliyunOssGoSdk) } addDebug("GetBucketWebsite", raw, requestInfo, request) ws, _ := raw.(oss.GetBucketWebsiteResult) websites := make([]map[string]interface{}, 0) if err == nil && &ws != nil { w := make(map[string]interface{}) if v := &ws.IndexDocument; v != nil { w["index_document"] = v.Suffix } if v := &ws.ErrorDocument; v != nil { w["error_document"] = v.Key } websites = append(websites, w) } if err := d.Set("website", websites); err != nil { return WrapError(err) } // Read the logging configuration raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.GetBucketLogging(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketLogging", AliyunOssGoSdk) } addDebug("GetBucketLogging", raw, requestInfo, request) logging, _ := raw.(oss.GetBucketLoggingResult) if &logging != nil { enable := logging.LoggingEnabled if &enable != nil { lgs := make([]map[string]interface{}, 0) tb := logging.LoggingEnabled.TargetBucket tp := logging.LoggingEnabled.TargetPrefix if tb != "" || tp != "" { lgs = append(lgs, map[string]interface{}{ "target_bucket": tb, "target_prefix": tp, }) } if err := d.Set("logging", lgs); err != nil { return WrapError(err) } } } // Read the bucket referer raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.GetBucketReferer(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketReferer", AliyunOssGoSdk) } addDebug("GetBucketReferer", raw, requestInfo, request) referers := make([]map[string]interface{}, 0) referer, _ := raw.(oss.GetBucketRefererResult) if len(referer.RefererList) > 0 { referers = append(referers, map[string]interface{}{ "allow_empty": referer.AllowEmptyReferer, "referers": referer.RefererList, }) if err := d.Set("referer_config", referers); err != nil { return WrapError(err) } } // Read the lifecycle rule configuration raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.GetBucketLifecycle(d.Id()) }) if err != nil && !ossNotFoundError(err) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketLifecycle", AliyunOssGoSdk) } addDebug("GetBucketLifecycle", raw, requestInfo, request) lrules := make([]map[string]interface{}, 0) lifecycle, _ := raw.(oss.GetBucketLifecycleResult) for _, lifecycleRule := range lifecycle.Rules { rule := make(map[string]interface{}) rule["id"] = lifecycleRule.ID rule["prefix"] = lifecycleRule.Prefix if LifecycleRuleStatus(lifecycleRule.Status) == ExpirationStatusEnabled { rule["enabled"] = true } else { rule["enabled"] = false } // expiration if lifecycleRule.Expiration != nil { e := make(map[string]interface{}) if lifecycleRule.Expiration.Date != "" { t, err := time.Parse("2006-01-02T15:04:05.000Z", lifecycleRule.Expiration.Date) if err != nil { return WrapError(err) } e["date"] = t.Format("2006-01-02") } if lifecycleRule.Expiration.CreatedBeforeDate != "" { t, err := time.Parse("2006-01-02T15:04:05.000Z", lifecycleRule.Expiration.CreatedBeforeDate) if err != nil { return WrapError(err) } e["created_before_date"] = t.Format("2006-01-02") } if lifecycleRule.Expiration.ExpiredObjectDeleteMarker != nil { e["expired_object_delete_marker"] = *lifecycleRule.Expiration.ExpiredObjectDeleteMarker } e["days"] = int(lifecycleRule.Expiration.Days) rule["expiration"] = schema.NewSet(expirationHash, []interface{}{e}) } // transitions if len(lifecycleRule.Transitions) != 0 { var eSli []interface{} for _, transition := range lifecycleRule.Transitions { e := make(map[string]interface{}) if transition.CreatedBeforeDate != "" { t, err := time.Parse("2006-01-02T15:04:05.000Z", transition.CreatedBeforeDate) if err != nil { return WrapError(err) } e["created_before_date"] = t.Format("2006-01-02") } e["days"] = transition.Days e["storage_class"] = string(transition.StorageClass) if transition.IsAccessTime != nil { e["is_access_time"] = *transition.IsAccessTime } if transition.ReturnToStdWhenVisit != nil { e["return_to_std_when_visit"] = *transition.ReturnToStdWhenVisit } eSli = append(eSli, e) } rule["transitions"] = schema.NewSet(transitionsHash, eSli) } // abort_multipart_upload if lifecycleRule.AbortMultipartUpload != nil { e := make(map[string]interface{}) if lifecycleRule.AbortMultipartUpload.CreatedBeforeDate != "" { t, err := time.Parse("2006-01-02T15:04:05.000Z", lifecycleRule.AbortMultipartUpload.CreatedBeforeDate) if err != nil { return WrapError(err) } e["created_before_date"] = t.Format("2006-01-02") } valDays := int(lifecycleRule.AbortMultipartUpload.Days) if valDays > 0 { e["days"] = int(lifecycleRule.AbortMultipartUpload.Days) } rule["abort_multipart_upload"] = schema.NewSet(abortMultipartUploadHash, []interface{}{e}) } // NoncurrentVersionExpiration if lifecycleRule.NonVersionExpiration != nil { e := make(map[string]interface{}) e["days"] = int(lifecycleRule.NonVersionExpiration.NoncurrentDays) rule["noncurrent_version_expiration"] = schema.NewSet(expirationHash, []interface{}{e}) } // NoncurrentVersionTransitions if len(lifecycleRule.NonVersionTransitions) != 0 { var eSli []interface{} for _, transition := range lifecycleRule.NonVersionTransitions { e := make(map[string]interface{}) e["days"] = transition.NoncurrentDays e["storage_class"] = string(transition.StorageClass) if transition.IsAccessTime != nil { e["is_access_time"] = *transition.IsAccessTime } if transition.ReturnToStdWhenVisit != nil { e["return_to_std_when_visit"] = *transition.ReturnToStdWhenVisit } eSli = append(eSli, e) } rule["noncurrent_version_transition"] = schema.NewSet(transitionsHash, eSli) } // Tags if len(lifecycleRule.Tags) != 0 { ruleTagsMap := make(map[string]string) for _, t := range lifecycleRule.Tags { ruleTagsMap[t.Key] = t.Value } rule["tags"] = ruleTagsMap } // Filter if lifecycleRule.Filter != nil { var filterSli []interface{} filterE := make(map[string]interface{}) //not var notSli []interface{} for _, not := range lifecycleRule.Filter.Not { notE := make(map[string]interface{}) notE["prefix"] = string(not.Prefix) var tagSli []interface{} if not.Tag != nil { tagE := make(map[string]interface{}) tagE["key"] = string(not.Tag.Key) tagE["value"] = string(not.Tag.Value) notE["tag"] = append(tagSli, tagE) } notSli = append(notSli, notE) } filterE["not"] = notSli // object_size_greater_than if lifecycleRule.Filter.ObjectSizeGreaterThan != nil { filterE["object_size_greater_than"] = *lifecycleRule.Filter.ObjectSizeGreaterThan } // object_size_less_than if lifecycleRule.Filter.ObjectSizeLessThan != nil { filterE["object_size_less_than"] = *lifecycleRule.Filter.ObjectSizeLessThan } rule["filter"] = append(filterSli, filterE) } lrules = append(lrules, rule) } if err := d.Set("lifecycle_rule", lrules); err != nil { return WrapError(err) } // Read Policy raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { params := map[string]interface{}{} params["policy"] = nil return ossClient.Conn.Do("GET", d.Id(), "", params, nil, nil, 0, nil) }) if err != nil && !ossNotFoundError(err) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetPolicyByConn", AliyunOssGoSdk) } addDebug("GetPolicyByConn", raw, requestInfo, request) policy := "" if err == nil { rawResp := raw.(*oss.Response) defer rawResp.Body.Close() rawData, err := ioutil.ReadAll(rawResp.Body) if err != nil { return WrapError(err) } policy = string(rawData) } if err := d.Set("policy", policy); err != nil { return WrapError(err) } // Read tags raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.GetBucketTagging(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketTagging", AliyunOssGoSdk) } addDebug("GetBucketTagging", raw, requestInfo, request) tagging, _ := raw.(oss.GetBucketTaggingResult) tagsMap := make(map[string]string) if len(tagging.Tags) > 0 { for _, t := range tagging.Tags { tagsMap[t.Key] = t.Value } } if err := d.Set("tags", tagsMap); err != nil { return WrapError(err) } // Read the bucket transfer acceleration status raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return ossClient.GetBucketTransferAcc(d.Id()) }) if err != nil && !ossNotFoundError(err) && !IsExpectedErrors(err, []string{"TransferAccelerationDisabled"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketTransferAcc", AliyunOssGoSdk) } acc, _ := raw.(oss.TransferAccConfiguration) accMap := make([]map[string]interface{}, 0) if err == nil && &acc != nil { data := map[string]interface{}{ "enabled": acc.Enabled, } accMap = append(accMap, data) } if err := d.Set("transfer_acceleration", accMap); err != nil { return WrapError(err) } // Read the bucket resource-group-id raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return ossClient.GetBucketResourceGroup(d.Id()) }) if err != nil && !IsExpectedErrors(err, []string{"NotImplemented"}) { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "GetBucketResourceGroup", AliyunOssGoSdk) } if err == nil { addDebug("GetBucketResourceGroup", raw, requestInfo, request) resourceGroup, _ := raw.(oss.GetBucketResourceGroupResult) d.Set("resource_group_id", resourceGroup.ResourceGroupId) } return nil } func resourceAlicloudOssBucketUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) d.Partial(true) if d.HasChange("acl") && !d.IsNewResource() { request := map[string]string{"bucketName": d.Id(), "bucketACL": d.Get("acl").(string)} var requestInfo *oss.Client raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketACL(d.Id(), oss.ACLType(d.Get("acl").(string))) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketACL", AliyunOssGoSdk) } addDebug("SetBucketACL", raw, requestInfo, request) d.SetPartial("acl") } if d.HasChange("cors_rule") { if err := resourceAlicloudOssBucketCorsUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("cors_rule") } if d.HasChange("website") { if err := resourceAlicloudOssBucketWebsiteUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("website") } if d.HasChange("logging") { if err := resourceAlicloudOssBucketLoggingUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("logging") } if d.HasChange("referer_config") { if err := resourceAlicloudOssBucketRefererUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("referer_config") } //set access_monitor status to enable before lifecycle rule accessMonitorChange := false if d.HasChange("access_monitor") { accessMonitorChange = true if err := resourceAlicloudOssBucketAccessMonitorUpdate(client, d, true); err != nil { return WrapError(err) } } if d.HasChange("lifecycle_rule") { if err := resourceAlicloudOssBucketLifecycleRuleUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("lifecycle_rule") } //set access_monitor status to disable after lifecycle rule if accessMonitorChange { if err := resourceAlicloudOssBucketAccessMonitorUpdate(client, d, false); err != nil { return WrapError(err) } d.SetPartial("access_monitor") } if d.HasChange("policy") { if err := resourceAlicloudOssBucketPolicyUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("policy") } if !d.IsNewResource() && d.HasChange("server_side_encryption_rule") { if err := resourceAlicloudOssBucketEncryptionUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("server_side_encryption_rule") } if d.HasChange("tags") { if err := resourceAlicloudOssBucketTaggingUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("tags") } if d.HasChange("versioning") { if err := resourceAlicloudOssBucketVersioningUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("versioning") } if d.HasChange("transfer_acceleration") { if err := resourceAlicloudOssBucketTransferAccUpdate(client, d); err != nil { return WrapError(err) } d.SetPartial("transfer_acceleration") } if !d.IsNewResource() && d.HasChange("resource_group_id") { resourceGroupId := d.Get("resource_group_id").(string) request := map[string]string{"bucketName": d.Id(), "resourceGroupId": resourceGroupId} var requestInfo *oss.Client raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.PutBucketResourceGroup(d.Id(), oss.PutBucketResourceGroup{ ResourceGroupId: resourceGroupId, }) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "PutBucketResourceGroup", AliyunOssGoSdk) } addDebug("PutBucketResourceGroup", raw, requestInfo, request) d.SetPartial("resource_group_id") } d.Partial(false) return resourceAlicloudOssBucketRead(d, meta) } func resourceAlicloudOssBucketCorsUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { cors := d.Get("cors_rule").([]interface{}) var requestInfo *oss.Client if cors == nil || len(cors) == 0 { err := resource.Retry(3*time.Minute, func() *resource.RetryError { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.DeleteBucketCORS(d.Id()) }) if err != nil { return resource.NonRetryableError(err) } addDebug("DeleteBucketCORS", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucketCORS", AliyunOssGoSdk) } return nil } // Put CORS rules := make([]oss.CORSRule, 0, len(cors)) for _, c := range cors { corsMap := c.(map[string]interface{}) rule := oss.CORSRule{} for k, v := range corsMap { log.Printf("[DEBUG] OSS bucket: %s, put CORS: %#v, %#v", d.Id(), k, v) if k == "max_age_seconds" { rule.MaxAgeSeconds = v.(int) } else { rMap := make([]string, len(v.([]interface{}))) for i, vv := range v.([]interface{}) { rMap[i] = vv.(string) } switch k { case "allowed_headers": rule.AllowedHeader = rMap case "allowed_methods": rule.AllowedMethod = rMap case "allowed_origins": rule.AllowedOrigin = rMap case "expose_headers": rule.ExposeHeader = rMap } } } rules = append(rules, rule) } log.Printf("[DEBUG] Oss bucket: %s, put CORS: %#v", d.Id(), cors) raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketCORS(d.Id(), rules) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketCORS", AliyunOssGoSdk) } addDebug("SetBucketCORS", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "corsRules": rules, }) return nil } func resourceAlicloudOssBucketWebsiteUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { ws := d.Get("website").([]interface{}) var requestInfo *oss.Client if ws == nil || len(ws) == 0 { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.DeleteBucketWebsite(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucketWebsite", AliyunOssGoSdk) } addDebug("DeleteBucketWebsite", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return nil } var index_document, error_document string w := ws[0].(map[string]interface{}) if v, ok := w["index_document"]; ok { index_document = v.(string) } if v, ok := w["error_document"]; ok { error_document = v.(string) } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketWebsite(d.Id(), index_document, error_document) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketWebsite", AliyunOssGoSdk) } addDebug("SetBucketWebsite", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "indexDocument": index_document, "errorDocument": error_document, }) return nil } func resourceAlicloudOssBucketLoggingUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { logging := d.Get("logging").([]interface{}) var requestInfo *oss.Client if logging == nil || len(logging) == 0 { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.DeleteBucketLogging(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucketLogging", AliyunOssGoSdk) } addDebug("DeleteBucketLogging", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return nil } c := logging[0].(map[string]interface{}) var target_bucket, target_prefix string if v, ok := c["target_bucket"]; ok { target_bucket = v.(string) } if v, ok := c["target_prefix"]; ok { target_prefix = v.(string) } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketLogging(d.Id(), target_bucket, target_prefix, target_bucket != "" || target_prefix != "") }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketLogging", AliyunOssGoSdk) } addDebug("SetBucketLogging", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "targetBucket": target_bucket, "targetPrefix": target_prefix, "isEnable": target_bucket != "", }) return nil } func resourceAlicloudOssBucketRefererUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { config := d.Get("referer_config").([]interface{}) var requestInfo *oss.Client if config == nil || len(config) < 1 { log.Printf("[DEBUG] OSS set bucket referer as nil") raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketReferer(d.Id(), nil, true) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketReferer", AliyunOssGoSdk) } addDebug("SetBucketReferer", raw, requestInfo, map[string]interface{}{ "allowEmptyReferer": true, "bucketName": d.Id(), }) return nil } c := config[0].(map[string]interface{}) var allow bool var referers []string if v, ok := c["allow_empty"]; ok { allow = v.(bool) } if v, ok := c["referers"]; ok { for _, referer := range v.([]interface{}) { referers = append(referers, referer.(string)) } } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketReferer(d.Id(), referers, allow) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketReferer", AliyunOssGoSdk) } addDebug("SetBucketReferer", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "referers": referers, "allowEmptyReferer": allow, }) return nil } func resourceAlicloudOssBucketLifecycleRuleUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { bucket := d.Id() lifecycleRules := d.Get("lifecycle_rule").([]interface{}) var requestInfo *oss.Client if lifecycleRules == nil || len(lifecycleRules) == 0 { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.DeleteBucketLifecycle(bucket) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucketLifecycle", AliyunOssGoSdk) } addDebug("DeleteBucketLifecycle", raw, requestInfo, map[string]interface{}{ "bucketName": bucket, }) return nil } rules := make([]oss.LifecycleRule, 0, len(lifecycleRules)) for i, lifecycleRule := range lifecycleRules { r := lifecycleRule.(map[string]interface{}) rule := oss.LifecycleRule{ Prefix: r["prefix"].(string), } // ID if val, ok := r["id"].(string); ok && val != "" { rule.ID = val } // Enabled if val, ok := r["enabled"].(bool); ok && val { rule.Status = string(ExpirationStatusEnabled) } else { rule.Status = string(ExpirationStatusDisabled) } // Expiration expiration := d.Get(fmt.Sprintf("lifecycle_rule.%d.expiration", i)).(*schema.Set).List() if len(expiration) > 0 { e := expiration[0].(map[string]interface{}) i := oss.LifecycleExpiration{} valDate, _ := e["date"].(string) valCreatedBeforeDate, _ := e["created_before_date"].(string) valDays, _ := e["days"].(int) if val, ok := e["expired_object_delete_marker"].(bool); ok && val { if valDays > 0 || valDate != "" || valCreatedBeforeDate != "" { return WrapError(Error("'date/created_before_date/days' conflicts with 'expired_object_delete_marker'. One and only one of them can be specified in one expiration configuration.")) } i.ExpiredObjectDeleteMarker = &val } else { cnt := 0 if valDate != "" { i.Date = fmt.Sprintf("%sT00:00:00.000Z", valDate) cnt++ } if valCreatedBeforeDate != "" { i.CreatedBeforeDate = fmt.Sprintf("%sT00:00:00.000Z", valCreatedBeforeDate) cnt++ } if valDays > 0 { i.Days = valDays cnt++ } if cnt != 1 { return WrapError(Error("One and only one of 'date', 'created_before_date' and 'days' can be specified in one expiration configuration.")) } } rule.Expiration = &i } // Transitions transitions := d.Get(fmt.Sprintf("lifecycle_rule.%d.transitions", i)).(*schema.Set).List() if len(transitions) > 0 { for _, transition := range transitions { i := oss.LifecycleTransition{} valCreatedBeforeDate := transition.(map[string]interface{})["created_before_date"].(string) valDays := transition.(map[string]interface{})["days"].(int) valStorageClass := transition.(map[string]interface{})["storage_class"].(string) if (valCreatedBeforeDate != "" && valDays > 0) || (valCreatedBeforeDate == "" && valDays <= 0) || (valStorageClass == "") { return WrapError(Error("'CreatedBeforeDate' conflicts with 'Days'. One and only one of them can be specified in one transition configuration. 'storage_class' must be set.")) } if valCreatedBeforeDate != "" { i.CreatedBeforeDate = fmt.Sprintf("%sT00:00:00.000Z", valCreatedBeforeDate) } if valDays > 0 { i.Days = valDays } if valStorageClass != "" { i.StorageClass = oss.StorageClassType(valStorageClass) } if val, ok := transition.(map[string]interface{})["is_access_time"].(bool); ok && val { i.IsAccessTime = &val if val1, ok := transition.(map[string]interface{})["return_to_std_when_visit"].(bool); ok { i.ReturnToStdWhenVisit = &val1 } } rule.Transitions = append(rule.Transitions, i) } } // AbortMultipartUpload abortMultipartUpload := d.Get(fmt.Sprintf("lifecycle_rule.%d.abort_multipart_upload", i)).(*schema.Set).List() if len(abortMultipartUpload) > 0 { e := abortMultipartUpload[0].(map[string]interface{}) i := oss.LifecycleAbortMultipartUpload{} valCreatedBeforeDate, _ := e["created_before_date"].(string) valDays, _ := e["days"].(int) if (valCreatedBeforeDate != "" && valDays > 0) || (valCreatedBeforeDate == "" && valDays <= 0) { return WrapError(Error("'CreatedBeforeDate' conflicts with 'days'. One and only one of them can be specified in one abort_multipart_upload configuration.")) } if valCreatedBeforeDate != "" { i.CreatedBeforeDate = fmt.Sprintf("%sT00:00:00.000Z", valCreatedBeforeDate) } if valDays > 0 { i.Days = valDays } rule.AbortMultipartUpload = &i } // Noncurrent Version Expiration noncurrentVersionExpiration := d.Get(fmt.Sprintf("lifecycle_rule.%d.noncurrent_version_expiration", i)).(*schema.Set).List() if len(noncurrentVersionExpiration) > 0 { e := noncurrentVersionExpiration[0].(map[string]interface{}) i := oss.LifecycleVersionExpiration{} valDays, _ := e["days"].(int) i.NoncurrentDays = valDays rule.NonVersionExpiration = &i } // Noncurrent Version Transitions noncurrentVersionTransitions := d.Get(fmt.Sprintf("lifecycle_rule.%d.noncurrent_version_transition", i)).(*schema.Set).List() if len(noncurrentVersionTransitions) > 0 { for _, transition := range noncurrentVersionTransitions { i := oss.LifecycleVersionTransition{} valDays := transition.(map[string]interface{})["days"].(int) valStorageClass := transition.(map[string]interface{})["storage_class"].(string) i.NoncurrentDays = valDays i.StorageClass = oss.StorageClassType(valStorageClass) if val, ok := transition.(map[string]interface{})["is_access_time"].(bool); ok && val { i.IsAccessTime = &val if val1, ok := transition.(map[string]interface{})["return_to_std_when_visit"].(bool); ok { i.ReturnToStdWhenVisit = &val1 } } rule.NonVersionTransitions = append(rule.NonVersionTransitions, i) } } // tags ruleTagsMap := d.Get(fmt.Sprintf("lifecycle_rule.%d.tags", i)).(map[string]interface{}) if ruleTagsMap != nil { for k, v := range ruleTagsMap { rule.Tags = append(rule.Tags, oss.Tag{ Key: k, Value: v.(string), }) } } // filter ruleFilter := d.Get(fmt.Sprintf("lifecycle_rule.%d.filter", i)).([]interface{}) if len(ruleFilter) > 0 { e := ruleFilter[0].(map[string]interface{}) filter := oss.LifecycleFilter{} filterNotElems, _ := e["not"].([]interface{}) for _, notElem := range filterNotElems { filterNot := oss.LifecycleFilterNot{} //prefix filterNot.Prefix = notElem.(map[string]interface{})["prefix"].(string) //tag filterNotTagElems := notElem.(map[string]interface{})["tag"].([]interface{}) if len(filterNotTagElems) > 0 { filterNotTagElem := filterNotTagElems[0].(map[string]interface{}) tag := oss.Tag{} tag.Key = filterNotTagElem["key"].(string) tag.Value = filterNotTagElem["value"].(string) filterNot.Tag = &tag } filter.Not = append(filter.Not, filterNot) } if v, ok := e["object_size_greater_than"].(int); ok && v > 0 { greater := int64(v) filter.ObjectSizeGreaterThan = &greater } if v, ok := e["object_size_less_than"].(int); ok && v > 0 { less := int64(v) filter.ObjectSizeLessThan = &less } rule.Filter = &filter } rules = append(rules, rule) } options := []oss.Option{} if d.Get("lifecycle_rule_allow_same_action_overlap").(bool) { options = append(options, oss.AllowSameActionOverLap(true)) } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketLifecycle(bucket, rules, options...) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketLifecycle", AliyunOssGoSdk) } addDebug("SetBucketLifecycle", raw, requestInfo, map[string]interface{}{ "bucketName": bucket, "rules": rules, }) return nil } func resourceAlicloudOssBucketPolicyUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { bucket := d.Id() policy := d.Get("policy").(string) var requestInfo *oss.Client if len(policy) == 0 { params := map[string]interface{}{} params["policy"] = nil raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return ossClient.Conn.Do("DELETE", bucket, "", params, nil, nil, 0, nil) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeletePolicyByConn", AliyunOssGoSdk) } addDebug("DeletePolicyByConn", raw, requestInfo, params) return nil } params := map[string]interface{}{} params["policy"] = nil raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient buffer := new(bytes.Buffer) buffer.Write([]byte(policy)) return ossClient.Conn.Do("PUT", bucket, "", params, nil, buffer, 0, nil) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "PutPolicyByConn", AliyunOssGoSdk) } addDebug("PutPolicyByConn", raw, requestInfo, params) return nil } func resourceAlicloudOssBucketEncryptionUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { encryption_rule := d.Get("server_side_encryption_rule").([]interface{}) var requestInfo *oss.Client if encryption_rule == nil || len(encryption_rule) == 0 { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.DeleteBucketEncryption(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucketEncryption", AliyunOssGoSdk) } addDebug("DeleteBucketEncryption", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return nil } var sseRule oss.ServerEncryptionRule c := encryption_rule[0].(map[string]interface{}) if v, ok := c["sse_algorithm"]; ok { sseRule.SSEDefault.SSEAlgorithm = v.(string) } if v, ok := c["kms_master_key_id"]; ok { sseRule.SSEDefault.KMSMasterKeyID = v.(string) } if v, ok := c["kms_data_encryption"]; ok { sseRule.SSEDefault.KMSDataEncryption = v.(string) } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketEncryption(d.Id(), sseRule) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketEncryption", AliyunOssGoSdk) } addDebug("SetBucketEncryption", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "encryptionRule": sseRule, }) return nil } func resourceAlicloudOssBucketTaggingUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { tagsMap := d.Get("tags").(map[string]interface{}) var requestInfo *oss.Client if tagsMap == nil || len(tagsMap) == 0 { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.DeleteBucketTagging(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucketTagging", AliyunOssGoSdk) } addDebug("DeleteBucketTagging", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return nil } // Put tagging var bTagging oss.Tagging for k, v := range tagsMap { bTagging.Tags = append(bTagging.Tags, oss.Tag{ Key: k, Value: v.(string), }) } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketTagging(d.Id(), bTagging) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketTagging", AliyunOssGoSdk) } addDebug("SetBucketTagging", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "tagging": bTagging, }) return nil } func resourceAlicloudOssBucketVersioningUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { versioning := d.Get("versioning").([]interface{}) if len(versioning) == 1 { var status string c := versioning[0].(map[string]interface{}) if v, ok := c["status"]; ok { status = v.(string) } versioningCfg := oss.VersioningConfig{} versioningCfg.Status = status var requestInfo *oss.Client raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketVersioning(d.Id(), versioningCfg) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketVersioning", AliyunOssGoSdk) } addDebug("SetBucketVersioning", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "versioningConfig": versioningCfg, }) } return nil } func resourceAlicloudOssBucketTransferAccUpdate(client *connectivity.AliyunClient, d *schema.ResourceData) error { acc := d.Get("transfer_acceleration").([]interface{}) if len(acc) == 1 { var requestInfo *oss.Client var aacCfg oss.TransferAccConfiguration c := acc[0].(map[string]interface{}) if v, ok := c["enabled"]; ok { aacCfg.Enabled = v.(bool) } raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.SetBucketTransferAcc(d.Id(), aacCfg) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "SetBucketTransferAcc", AliyunOssGoSdk) } addDebug("SetBucketTransferAcc", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "TransferAccConfiguration": aacCfg, }) } return nil } func resourceAlicloudOssBucketAccessMonitorUpdate(client *connectivity.AliyunClient, d *schema.ResourceData, flag bool) error { am := d.Get("access_monitor").([]interface{}) if len(am) == 1 { var requestInfo *oss.Client var amCfg oss.PutBucketAccessMonitor c := am[0].(map[string]interface{}) if v, ok := c["status"]; ok { amCfg.Status = v.(string) } if (flag && amCfg.Status == "Enabled") || (!flag && amCfg.Status == "Disabled") { raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return nil, ossClient.PutBucketAccessMonitor(d.Id(), amCfg) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "PutBucketAccessMonitor", AliyunOssGoSdk) } addDebug("PutBucketAccessMonitor", raw, requestInfo, map[string]interface{}{ "bucketName": d.Id(), "PutBucketAccessMonitor": amCfg, }) } } return nil } func resourceAlicloudOssBucketDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) ossService := OssService{client} var requestInfo *oss.Client raw, err := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { requestInfo = ossClient return ossClient.IsBucketExist(d.Id()) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "IsBucketExist", AliyunOssGoSdk) } addDebug("IsBucketExist", raw, requestInfo, map[string]string{"bucketName": d.Id()}) exist, _ := raw.(bool) if !exist { return nil } err = resource.Retry(5*time.Minute, func() *resource.RetryError { raw, err = client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { return nil, ossClient.DeleteBucket(d.Id()) }) if err != nil { if IsExpectedErrors(err, []string{"BucketNotEmpty"}) { if d.Get("force_destroy").(bool) { raw, er := client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { bucket, _ := ossClient.Bucket(d.Id()) lor, err := bucket.ListObjectVersions() if err != nil { return nil, WrapErrorf(err, DefaultErrorMsg, d.Id(), "ListObjectVersions", AliyunOssGoSdk) } addDebug("ListObjectVersions", lor, requestInfo) objectsToDelete := make([]oss.DeleteObject, 0) for _, object := range lor.ObjectDeleteMarkers { objectsToDelete = append(objectsToDelete, oss.DeleteObject{ Key: object.Key, VersionId: object.VersionId, }) } for _, object := range lor.ObjectVersions { objectsToDelete = append(objectsToDelete, oss.DeleteObject{ Key: object.Key, VersionId: object.VersionId, }) } return bucket.DeleteObjectVersions(objectsToDelete) }) if er != nil { return resource.NonRetryableError(er) } addDebug("DeleteObjectVersions", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return resource.RetryableError(err) } } return resource.NonRetryableError(err) } addDebug("DeleteBucket", raw, requestInfo, map[string]string{"bucketName": d.Id()}) return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), "DeleteBucket", AliyunOssGoSdk) } return WrapError(ossService.WaitForOssBucket(d.Id(), Deleted, DefaultTimeoutMedium)) } func expirationHash(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) if v, ok := m["date"]; ok { buf.WriteString(fmt.Sprintf("%s-", v.(string))) } if v, ok := m["created_before_date"]; ok { buf.WriteString(fmt.Sprintf("%s-", v.(string))) } if v, ok := m["days"]; ok { buf.WriteString(fmt.Sprintf("%d-", v.(int))) } if v, ok := m["expired_object_delete_marker"]; ok { buf.WriteString(fmt.Sprintf("%v-", v.(bool))) } return hashcode.String(buf.String()) } func transitionsHash(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) if v, ok := m["created_before_date"]; ok { buf.WriteString(fmt.Sprintf("%s-", v.(string))) } if v, ok := m["storage_class"]; ok { buf.WriteString(fmt.Sprintf("%s-", v.(string))) } if v, ok := m["days"]; ok { buf.WriteString(fmt.Sprintf("%d-", v.(int))) } if v, ok := m["is_access_time"]; ok { buf.WriteString(fmt.Sprintf("%v-", v.(bool))) } if v, ok := m["return_to_std_when_visit"]; ok { buf.WriteString(fmt.Sprintf("%v-", v.(bool))) } return hashcode.String(buf.String()) } func abortMultipartUploadHash(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) if v, ok := m["created_before_date"]; ok { buf.WriteString(fmt.Sprintf("%s-", v.(string))) } if v, ok := m["days"]; ok { buf.WriteString(fmt.Sprintf("%d-", v.(int))) } return hashcode.String(buf.String()) }