alibabacloudstack/resource_apsarastack_kvstore_instance.go (655 lines of code) (raw):

package alibabacloudstack import ( "encoding/json" "fmt" "log" "strings" "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" r_kvstore "github.com/aliyun/alibaba-cloud-sdk-go/services/r-kvstore" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func resourceAlibabacloudStackKVStoreInstance() *schema.Resource { resource := &schema.Resource{ Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(40 * time.Minute), Update: schema.DefaultTimeout(30 * time.Minute), Delete: schema.DefaultTimeout(40 * time.Minute), }, Schema: map[string]*schema.Schema{ "tair_instance_name": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: validation.StringLenBetween(2, 128), ConflictsWith: []string{"instance_name"}, }, "instance_name": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: validation.StringLenBetween(2, 128), Deprecated: "Field 'instance_name' is deprecated and will be removed in a future release. Please use new field 'tair_instance_name' instead.", ConflictsWith: []string{"tair_instance_name"}, }, "password": { Type: schema.TypeString, Optional: true, Sensitive: true, }, "kms_encrypted_password": { Type: schema.TypeString, Optional: true, DiffSuppressFunc: kmsDiffSuppressFunc, }, "kms_encryption_context": { Type: schema.TypeMap, Optional: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { return d.Get("kms_encrypted_password").(string) == "" }, Elem: schema.TypeString, }, "instance_class": { Type: schema.TypeString, Required: true, }, "engine_version": { Type: schema.TypeString, ForceNew: true, Optional: true, Default: KVStore5Dot0, }, "zone_id": { Type: schema.TypeString, Optional: true, ForceNew: true, Computed: true, ConflictsWith: []string{"availability_zone"}, }, "availability_zone": { Type: schema.TypeString, Optional: true, ForceNew: true, Computed: true, Deprecated: "Field 'availability_zone' is deprecated and will be removed in a future release. Please use new field 'zone_id' instead.", ConflictsWith: []string{"zone_id"}, }, "instance_charge_type": { Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{string(PrePaid), string(PostPaid)}, false), Optional: true, Computed: true, Deprecated: "Field 'instance_charge_type' is deprecated and will be removed in a future release, and not for any use now.", }, "instance_type": { Type: schema.TypeString, Optional: true, ForceNew: true, Default: string(KVStoreRedis), ValidateFunc: validation.StringInSlice([]string{ string(KVStoreMemcache), string(KVStoreRedis), }, false), }, "vswitch_id": { Type: schema.TypeString, ForceNew: true, Optional: true, }, "connection_domain": { Type: schema.TypeString, Computed: true, }, "private_ip": { Type: schema.TypeString, Computed: true, // Optional: true, ASCM不支持设定 }, "backup_id": { Type: schema.TypeString, Optional: true, }, "security_ips": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, Optional: true, }, "vpc_auth_mode": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: validation.StringInSlice([]string{"Open", "Close"}, false), }, "parameters": { Type: schema.TypeSet, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, }, "value": { Type: schema.TypeString, Required: true, }, }, }, Set: func(v interface{}) int { return hashcode.String( v.(map[string]interface{})["name"].(string) + "|" + v.(map[string]interface{})["value"].(string)) }, Optional: true, Computed: true, }, "maintain_start_time": { Type: schema.TypeString, Optional: true, Computed: true, }, "maintain_end_time": { Type: schema.TypeString, Optional: true, Computed: true, }, "cpu_type": { Type: schema.TypeString, Optional: true, Deprecated: "Field 'cpu_type' is deprecated and will be removed in a future release.", }, "node_type": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: validation.StringInSlice([]string{"MASTER_SLAVE", "STAND_ALONE", "double", "readone"}, false), DiffSuppressFunc: NodeTypeDiffSuppressFunc, }, "architecture_type": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: validation.StringInSlice([]string{"cluster", "rwsplit", "standard"}, false), DiffSuppressFunc: ArchitectureTypeDiffSuppressFunc, }, "series": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{"community", "enterprise"}, false), }, "tde_status": { Type: schema.TypeString, Optional: true, }, "encryption_key": { Type: schema.TypeString, Optional: true, Deprecated: "TDE does not support the simultaneous use of `encryption_key` and `role_arn`.", ConflictsWith: []string{"role_arn"}, }, "role_arn": { Type: schema.TypeString, Optional: true, Deprecated: "TDE does not support the simultaneous use of `encryption_key` and `role_arn`.", ConflictsWith: []string{"encryption_key"}, }, }, } setResourceFunc(resource, resourceAlibabacloudStackKVStoreInstanceCreate, resourceAlibabacloudStackKVStoreInstanceRead, resourceAlibabacloudStackKVStoreInstanceUpdate, resourceAlibabacloudStackKVStoreInstanceDelete) return resource } func resourceAlibabacloudStackKVStoreInstanceCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} kvstoreService := KvstoreService{client} var response map[string]interface{} action := "CreateInstance" request := make(map[string]interface{}) request["ClientToken"] = buildClientToken("CreateInstance") if v, ok := connectivity.GetResourceDataOk(d, "tair_instance_name", "instance_name"); ok { request["InstanceName"] = v.(string) } if v, ok := d.GetOk("cpu_type"); ok { request["CpuType"] = v.(string) } if v, ok := d.GetOk("node_type"); ok { request["NodeType"] = v.(string) } if v, ok := d.GetOk("architecture_type"); ok && v.(string) != "" { request["ArchitectureType"] = v.(string) } if v, ok := d.GetOk("instance_type"); ok { request["InstanceType"] = v.(string) } if v, ok := d.GetOk("engine_version"); ok { request["EngineVersion"] = v.(string) } if v, ok := d.GetOk("instance_class"); ok { request["InstanceClass"] = v.(string) } // if v, ok := connectivity.GetResourceDataOk(d, "payment_type", "instance_charge_type"); ok { // request["ChargeType"] = v.(string) // } else { // request["ChargeType"] = string(PostPaid) // } if v, ok := d.GetOk("password"); ok { request["Password"] = v.(string) } if v, ok := d.GetOk("series"); ok { request["Series"] = v.(string) } if request["Password"] == "" { if v := d.Get("kms_encrypted_password").(string); v != "" { kmsService := KmsService{client} decryptResp, err := kmsService.Decrypt(v, d.Get("kms_encryption_context").(map[string]interface{})) if err != nil { return errmsgs.WrapError(err) } request["Password"] = decryptResp.Plaintext } } if v, ok := d.GetOk("backup_id"); ok { request["BackupId"] = v.(string) } // if request["ChargeType"] == PrePaid { // request["Period"] = strconv.Itoa(d.Get("period").(int)) // } if v, ok := connectivity.GetResourceDataOk(d, "zone_id", "availability_zone"); ok && Trim(v.(string)) != "" { request["ZoneId"] = Trim(v.(string)) } request["NetworkType"] = strings.ToUpper(string(Classic)) if vswitchId, ok := d.GetOk("vswitch_id"); ok && vswitchId.(string) != "" { request["VSwitchId"] = vswitchId.(string) request["NetworkType"] = strings.ToUpper(string(Vpc)) // request["PrivateIpAddress"] = Trim(d.Get("private_ip").(string)) // check vswitchId in zone object, err := vpcService.DescribeVSwitch(vswitchId.(string)) if err != nil { return errmsgs.WrapError(err) } if request["ZoneId"] == "" { request["ZoneId"] = object.ZoneId } request["VpcId"] = object.VpcId } response, err := client.DoTeaRequest("POST", "R-kvstore", "2015-01-01", action, "", nil, nil, request) log.Printf(" create kvstroe instances Finished !! response: %v", response) if err != nil { return err } if value, exist := response["asapiSuccess"]; !exist || !value.(bool) { err = errmsgs.Error("create kvstroe instances Failed !!") return errmsgs.WrapErrorf(err, "create kvstroe instances Failed !! %s", action, errmsgs.AlibabacloudStackSdkGoERROR) } d.SetId(fmt.Sprint(response["InstanceId"])) log.Printf("begin describe kvstroe instances !!") // wait instance status change from Creating to Normal stateConf := BuildStateConfByTimes([]string{"Creating"}, []string{"Normal"}, d.Timeout(schema.TimeoutCreate), 1*time.Minute, kvstoreService.RdsKvstoreInstanceStateRefreshFunc(d.Id(), []string{"Deleting"}), 200) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } log.Printf("begin update kvstroe instances !!") if tde, ok := d.GetOk("tde_status"); ok && tde.(string) == "Enabled" { tde_req := make(map[string]interface{}) tde_req["InstanceId"] = d.Id() tde_req["TDEStatus"] = tde.(string) if encryption_key, ok := d.GetOk("encryption_key"); ok && encryption_key != "" { tde_req["EncryptionKey"] = encryption_key } else { if role_arn, ok := d.GetOk("role_arn"); ok && role_arn.(string) != "" { tde_req["RoleArn"] = d.Get("role_arn").(string) } else if client.Config.RamRoleArn != "" { tde_req["RoleArn"] = client.Config.RamRoleArn } } tde_response, err := client.DoTeaRequest("POST", "R-kvstore", "2015-01-01", "ModifyInstanceTDE", "", nil, nil, tde_req) addDebug("ModifyInstanceTDE", tde_response, tde_req) if err != nil { return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "apsarastack_kvstroe_instance", "ModifyInstanceTDE", errmsgs.AlibabacloudStackSdkGoERROR) } if value, exist := tde_response["asapiSuccess"]; !exist || !value.(bool) { err = errmsgs.Error("kvstroe ModifyInstanceTDE Failed !!") return errmsgs.WrapErrorf(err, "kvstroe ModifyInstanceTDE Failed !! %s", action, errmsgs.AlibabacloudStackSdkGoERROR) } log.Print("enabled TDE") } return nil } func resourceAlibabacloudStackKVStoreInstanceUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) kvstoreService := KvstoreService{client} d.Partial(true) stateConf := BuildStateConf([]string{"DBInstanceClassChanging", "DBInstanceNetTypeChanging", "Changing"}, []string{"Normal"}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, kvstoreService.RdsKvstoreInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) if d.HasChange("parameters") { config := make(map[string]interface{}) documented := d.Get("parameters").(*schema.Set).List() if len(documented) > 0 { for _, i := range documented { key := i.(map[string]interface{})["name"].(string) value := i.(map[string]interface{})["value"] config[key] = value } cfg, _ := json.Marshal(config) if err := kvstoreService.ModifyInstanceConfig(d.Id(), string(cfg)); err != nil { return errmsgs.WrapError(err) } } //d.SetPartial("parameters") } if d.HasChange("security_ips") { // wait instance status is Normal before modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } request := r_kvstore.CreateModifySecurityIpsRequest() client.InitRpcRequest(*request.RpcRequest) request.SecurityIpGroupName = "default" request.InstanceId = d.Id() if len(d.Get("security_ips").(*schema.Set).List()) > 0 { request.SecurityIps = strings.Join(expandStringList(d.Get("security_ips").(*schema.Set).List())[:], COMMA_SEPARATED) } else { return errmsgs.WrapError(errmsgs.Error("Security ips cannot be empty")) } raw, err := client.WithRkvClient(func(rkvClient *r_kvstore.Client) (interface{}, error) { return rkvClient.ModifySecurityIps(request) }) if err != nil { return err } addDebug(request.GetActionName(), raw, request.RpcRequest, request) //d.SetPartial("security_ips") // wait instance status is Normal after modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } } if d.HasChange("vpc_auth_mode") { if vswitchId, ok := d.GetOk("vswitch_id"); ok && vswitchId.(string) != "" { // vpc_auth_mode works only if the network type is VPC instanceType := d.Get("instance_type").(string) if string(KVStoreRedis) == instanceType { // wait instance status is Normal before modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } request := r_kvstore.CreateModifyInstanceVpcAuthModeRequest() client.InitRpcRequest(*request.RpcRequest) request.InstanceId = d.Id() request.VpcAuthMode = d.Get("vpc_auth_mode").(string) raw, err := client.WithRkvClient(func(rkvClient *r_kvstore.Client) (interface{}, error) { return rkvClient.ModifyInstanceVpcAuthMode(request) }) if err != nil { errmsg := "" if raw != nil { baseResponse := &responses.BaseResponse{} err = json.Unmarshal([]byte(raw.(*r_kvstore.ModifyInstanceVpcAuthModeResponse).GetHttpContentString()), baseResponse) if err == nil { errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) } } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) //d.SetPartial("vpc_auth_mode") // The auth mode take some time to be effective, so wait to ensure the state ! if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } } } } // configPayType := PayType(connectivity.GetResourceData(d, "payment_type", "instance_charge_type").(string)) // if !d.IsNewResource() && (d.HasChanges("payment_type", "instance_charge_type")) && configPayType == PrePaid { // // for now we just support charge change from PostPaid to PrePaid // prePaidRequest := r_kvstore.CreateTransformToPrePaidRequest() // client.InitRpcRequest(*prePaidRequest.RpcRequest) // prePaidRequest.InstanceId = d.Id() // prePaidRequest.Period = requests.Integer(strconv.Itoa(d.Get("period").(int))) // prePaidRequest.AutoPay = requests.NewBoolean(true) // raw, err := client.WithRkvClient(func(rkvClient *r_kvstore.Client) (interface{}, error) { // return rkvClient.TransformToPrePaid(prePaidRequest) // }) // if err != nil { // errmsg := "" // if raw != nil { // baseResponse := &responses.BaseResponse{} // err = json.Unmarshal([]byte(raw.(*r_kvstore.TransformToPrePaidResponse).GetHttpContentString()), baseResponse) // if err == nil { // errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) // } // } // return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), prePaidRequest.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) // } // addDebug(prePaidRequest.GetActionName(), raw, prePaidRequest.RpcRequest, prePaidRequest) // // wait instance status is Normal after modifying // if _, err := stateConf.WaitForState(); err != nil { // return errmsgs.WrapError(err) // } // //d.SetPartial("instance_charge_type") // //d.SetPartial("period") // } if d.HasChanges("maintain_start_time", "maintain_end_time") { request := r_kvstore.CreateModifyInstanceMaintainTimeRequest() client.InitRpcRequest(*request.RpcRequest) request.InstanceId = d.Id() request.MaintainStartTime = d.Get("maintain_start_time").(string) request.MaintainEndTime = d.Get("maintain_end_time").(string) raw, err := client.WithRkvClient(func(client *r_kvstore.Client) (interface{}, error) { return client.ModifyInstanceMaintainTime(request) }) if err != nil { errmsg := "" if raw != nil { baseResponse := &responses.BaseResponse{} err = json.Unmarshal([]byte(raw.(*r_kvstore.ModifyInstanceMaintainTimeResponse).GetHttpContentString()), baseResponse) if err == nil { errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) } } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) //d.SetPartial("maintain_start_time") //d.SetPartial("maintain_end_time") } if d.IsNewResource() { d.Partial(false) return nil } if d.HasChange("instance_class") { // wait instance status is Normal before modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } request := r_kvstore.CreateModifyInstanceSpecRequest() client.InitRpcRequest(*request.RpcRequest) request.InstanceId = d.Id() request.InstanceClass = d.Get("instance_class").(string) request.EffectiveTime = "Immediately" err := resource.Retry(5*time.Minute, func() *resource.RetryError { raw, err := client.WithRkvClient(func(rkvClient *r_kvstore.Client) (interface{}, error) { return rkvClient.ModifyInstanceSpec(request) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"MissingRedisUsedmemoryUnsupportPerfItem"}) { time.Sleep(time.Duration(5) * time.Second) return resource.RetryableError(err) } errmsg := "" if raw != nil { baseResponse := &responses.BaseResponse{} err = json.Unmarshal([]byte(raw.(*r_kvstore.ModifyInstanceSpecResponse).GetHttpContentString()), baseResponse) if err == nil { errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) } } return resource.NonRetryableError(errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { return err } // wait instance status is Normal after modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } // There needs more time to sync instance class update err = resource.Retry(1*time.Minute, func() *resource.RetryError { object, err := kvstoreService.DescribeKVstoreInstance(d.Id()) if err != nil { return resource.NonRetryableError(err) } if object.InstanceClass != request.InstanceClass { return resource.RetryableError(errmsgs.Error("Waitting for instance class is changed timeout. Expect instance class %s, got %s.", object.InstanceClass, request.InstanceClass)) } return nil }) if err != nil { return errmsgs.WrapError(err) } //d.SetPartial("instance_class") } request := r_kvstore.CreateModifyInstanceAttributeRequest() client.InitRpcRequest(*request.RpcRequest) request.InstanceId = d.Id() update := false if d.HasChanges("tair_instance_name", "instance_name") { request.InstanceName = connectivity.GetResourceData(d, "tair_instance_name", "instance_name").(string) update = true } if d.HasChanges("password", "kms_encrypted_password") { if v := d.Get("password").(string); v != "" { //d.SetPartial("password") request.NewPassword = v update = true } if v := d.Get("kms_encrypted_password").(string); v != "" { kmsService := KmsService{meta.(*connectivity.AlibabacloudStackClient)} decryptResp, err := kmsService.Decrypt(v, d.Get("kms_encryption_context").(map[string]interface{})) if err != nil { return errmsgs.WrapError(err) } request.NewPassword = decryptResp.Plaintext //d.SetPartial("kms_encrypted_password") //d.SetPartial("kms_encryption_context") update = true } } if update { // wait instance status is Normal before modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } raw, err := client.WithRkvClient(func(rkvClient *r_kvstore.Client) (interface{}, error) { return rkvClient.ModifyInstanceAttribute(request) }) if err != nil { errmsg := "" if raw != nil { baseResponse := &responses.BaseResponse{} err = json.Unmarshal([]byte(raw.(*r_kvstore.ModifyInstanceAttributeResponse).GetHttpContentString()), baseResponse) if err == nil { errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) } } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) // wait instance status is Normal after modifying if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapError(err) } //d.SetPartial("instance_name") //d.SetPartial("password") } d.Partial(false) return nil } func resourceAlibabacloudStackKVStoreInstanceRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) kvstoreService := KvstoreService{client} object, err := kvstoreService.DescribeKVstoreInstance(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { d.SetId("") return nil } return errmsgs.WrapError(err) } connectivity.SetResourceData(d, object.InstanceName, "tair_instance_name", "instance_name") d.Set("instance_class", object.InstanceClass) // 目前查询接口没有返回是否为企业版本,只能从类型判断 if strings.HasPrefix(object.InstanceClass, strings.ToLower(object.InstanceType)+".amber.") { d.Set("series", "enterprise") } else { d.Set("series", "community") } connectivity.SetResourceData(d, object.ZoneId, "zone_id", "availability_zone") // connectivity.SetResourceData(d, object.ChargeType, "payment_type", "instance_charge_type") d.Set("instance_type", object.InstanceType) d.Set("vswitch_id", object.VSwitchId) d.Set("connection_domain", object.ConnectionDomain) d.Set("engine_version", object.EngineVersion) d.Set("private_ip", object.PrivateIp) d.Set("security_ips", strings.Split(object.SecurityIPList, COMMA_SEPARATED)) d.Set("vpc_auth_mode", object.VpcAuthMode) d.Set("maintain_start_time", object.MaintainStartTime) d.Set("maintain_end_time", object.MaintainEndTime) if object.ChargeType == string(PrePaid) { request := r_kvstore.CreateDescribeInstanceAutoRenewalAttributeRequest() client.InitRpcRequest(*request.RpcRequest) request.DBInstanceId = d.Id() raw, err := client.WithRkvClient(func(client *r_kvstore.Client) (interface{}, error) { return client.DescribeInstanceAutoRenewalAttribute(request) }) if err != nil { errmsg := "" if raw != nil { baseResponse := &responses.BaseResponse{} err = json.Unmarshal([]byte(raw.(*r_kvstore.DescribeInstanceAutoRenewalAttributeResponse).GetHttpContentString()), baseResponse) if err == nil { errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) } } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) period, err := computePeriodByUnit(object.CreateTime, object.EndTime, d.Get("period").(int), "Month") if err != nil { return errmsgs.WrapError(err) } d.Set("period", period) } //refresh parameters if err = refreshParameters(d, meta); err != nil { return errmsgs.WrapError(err) } return nil } func resourceAlibabacloudStackKVStoreInstanceDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) kvstoreService := KvstoreService{client} object, err := kvstoreService.DescribeKVstoreInstance(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { return nil } return errmsgs.WrapError(err) } if PayType(object.ChargeType) == PrePaid { return errmsgs.WrapError(errmsgs.Error("At present, 'PrePaid' instance cannot be deleted and must wait it to be expired and release it automatically")) } request := r_kvstore.CreateDeleteInstanceRequest() client.InitRpcRequest(*request.RpcRequest) request.InstanceId = d.Id() raw, err := client.WithRkvClient(func(rkvClient *r_kvstore.Client) (interface{}, error) { return rkvClient.DeleteInstance(request) }) if err != nil { if !errmsgs.IsExpectedErrors(err, []string{"InvalidInstanceId.NotFound"}) { errmsg := "" if raw != nil { baseResponse := &responses.BaseResponse{} err = json.Unmarshal([]byte(raw.(*r_kvstore.DeleteInstanceResponse).GetHttpContentString()), baseResponse) if err == nil { errmsg = errmsgs.GetBaseResponseErrorMessage(baseResponse) } } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } } addDebug(request.GetActionName(), raw, request.RpcRequest, request) stateConf := BuildStateConf([]string{"Creating", "Active", "Deleting"}, []string{}, d.Timeout(schema.TimeoutDelete), 1*time.Minute, kvstoreService.RdsKvstoreInstanceStateRefreshFunc(d.Id(), []string{})) _, err = stateConf.WaitForState() return errmsgs.WrapError(err) } func refreshParameters(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) kvstoreService := KvstoreService{client} var param []map[string]interface{} documented, ok := d.GetOk("parameters") if !ok { d.Set("parameters", param) return nil } object, err := kvstoreService.DescribeParameters(d.Id()) if err != nil { return errmsgs.WrapError(err) } var parameters = make(map[string]interface{}) for _, i := range object.RunningParameters.Parameter { if i.ParameterName != "" { parameter := map[string]interface{}{ "name": i.ParameterName, "value": i.ParameterValue, } parameters[i.ParameterName] = parameter } } for _, i := range object.ConfigParameters.Parameter { if i.ParameterName != "" { parameter := map[string]interface{}{ "name": i.ParameterName, "value": i.ParameterValue, } parameters[i.ParameterName] = parameter } } for _, parameter := range documented.(*schema.Set).List() { name := parameter.(map[string]interface{})["name"] for _, value := range parameters { if value.(map[string]interface{})["name"] == name { param = append(param, value.(map[string]interface{})) break } } } d.Set("parameters", param) return nil }