alibabacloudstack/resource_apsarastack_db_instance.go (822 lines of code) (raw):
package alibabacloudstack
import (
"encoding/json"
"fmt"
"log"
"strconv"
"strings"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/rds"
"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/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func resourceAlibabacloudStackDBInstance() *schema.Resource {
resource := &schema.Resource{
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(40 * time.Minute),
Update: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},
Schema: map[string]*schema.Schema{
"engine": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"engine_version": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"zone_id_slave1": {
Type: schema.TypeString,
Optional: true,
},
"zone_id_slave2": {
Type: schema.TypeString,
Optional: true,
},
"tde_status": {
Type: schema.TypeBool,
Optional: true,
},
"enable_ssl": {
Type: schema.TypeBool,
Optional: true,
ForceNew: false,
},
"storage_type": {
Type: schema.TypeString,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"local_ssd", "cloud_ssd", "cloud_pperf", "cloud_sperf"}, false),
Optional: true,
Computed: true,
Deprecated: "Field 'storage_type' is deprecated and will be removed in a future release. Please use new field 'db_instance_storage_type' instead.",
ConflictsWith: []string{"db_instance_storage_type"},
},
"db_instance_storage_type": {
Type: schema.TypeString,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"local_ssd", "cloud_ssd", "cloud_pperf", "cloud_sperf"}, false),
Optional: true,
Computed: true,
ConflictsWith: []string{"storage_type"},
},
"encryption_key": {
Type: schema.TypeString,
Optional: true,
},
"encryption": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
},
"instance_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Deprecated: "Field 'instance_type' is deprecated and will be removed in a future release. Please use new field 'db_instance_class' instead.",
ConflictsWith: []string{"db_instance_class"},
},
"db_instance_class": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"instance_type"},
},
"instance_storage": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Deprecated: "Field 'instance_storage' is deprecated and will be removed in a future release. Please use new field 'db_instance_storage' instead.",
ConflictsWith: []string{"db_instance_storage"},
},
"db_instance_storage": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ConflictsWith: []string{"instance_storage"},
},
"instance_charge_type": {
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{string(Postpaid), string(Prepaid)}, false),
Optional: true,
Computed: true,
Deprecated: "Field 'instance_charge_type' is deprecated and will be removed in a future release. Please use new field 'payment_type' instead.",
ConflictsWith: []string{"payment_type"},
},
"payment_type": {
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{string(Postpaid), string(Prepaid)}, false),
Optional: true,
Computed: true,
ConflictsWith: []string{"instance_charge_type"},
},
"period": {
Type: schema.TypeInt,
ValidateFunc: validation.IntInSlice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 24, 36}),
Optional: true,
Default: 1,
DiffSuppressFunc: PostPaidDiffSuppressFunc,
},
"monitoring_period": {
Type: schema.TypeInt,
ValidateFunc: validation.IntInSlice([]int{5, 60, 300}),
Optional: true,
Computed: true,
},
"auto_renew": {
Type: schema.TypeBool,
Optional: true,
Default: false,
DiffSuppressFunc: PostPaidDiffSuppressFunc,
},
"auto_renew_period": {
Type: schema.TypeInt,
ValidateFunc: validation.IntBetween(1, 12),
Optional: true,
Default: 1,
DiffSuppressFunc: PostPaidAndRenewDiffSuppressFunc,
},
"zone_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"vswitch_id": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"instance_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringLenBetween(2, 256),
Deprecated: "Field 'instance_name' is deprecated and will be removed in a future release. Please use new field 'db_instance_description' instead.",
ConflictsWith: []string{"db_instance_description"},
},
"db_instance_description": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringLenBetween(2, 256),
ConflictsWith: []string{"instance_name"},
},
"connection_string": {
Type: schema.TypeString,
Computed: true,
},
"port": {
Type: schema.TypeString,
Computed: true,
},
"security_ips": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
Optional: true,
},
"security_ip_mode": {
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{NormalMode, SafetyMode}, false),
Optional: true,
Default: NormalMode,
},
"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: parameterToHash,
Optional: true,
Computed: true,
},
"tags": tagsSchema(),
"maintain_time": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"role_arn": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
setResourceFunc(resource, resourceAlibabacloudStackDBInstanceCreate, resourceAlibabacloudStackDBInstanceRead, resourceAlibabacloudStackDBInstanceUpdate, resourceAlibabacloudStackDBInstanceDelete)
return resource
}
func parameterToHash(v interface{}) int {
m := v.(map[string]interface{})
return hashcode.String(m["name"].(string) + "|" + m["value"].(string))
}
func resourceAlibabacloudStackDBInstanceCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
rdsService := RdsService{client}
vpcService := VpcService{client}
var VSwitchId, InstanceNetworkType, ZoneIdSlave1, ZoneIdSlave2, ZoneId, VPCId, arnrole string
var encryption bool
EncryptionKey := d.Get("encryption_key").(string)
encryption = d.Get("encryption").(bool)
log.Print("Encryption key input")
if EncryptionKey != "" && encryption == true {
log.Print("Encryption key condition passed")
req := client.NewCommonRequest("POST", "Rds", "2014-08-15", "CheckCloudResourceAuthorized", "")
req.QueryParams["TargetRegionId"] = client.RegionId
ram, err := client.WithRdsClient(func(RdsClient *rds.Client) (interface{}, error) {
return RdsClient.ProcessCommonRequest(req)
})
resparn, ok := ram.(*responses.CommonResponse)
if err != nil {
errmsg := ""
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(resparn.BaseResponse)
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_db_instance", req.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
var arnresp RoleARN
addDebug(req.GetActionName(), ram, req)
log.Printf("raw response %v", resparn)
err = json.Unmarshal(resparn.GetHttpContentBytes(), &arnresp)
if err != nil {
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "CheckCloudResourceAuthorized", req.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR)
}
arnrole = arnresp.RoleArn
d.Set("role_arn", arnrole)
log.Printf("check arnrole %v", arnrole)
} else if EncryptionKey == "" && encryption == true {
return errmsgs.WrapErrorf(nil, "Add EncryptionKey or Set encryption to false", "CheckCloudResourceAuthorized", errmsgs.AlibabacloudStackSdkGoERROR)
} else if EncryptionKey != "" && encryption == false {
return errmsgs.WrapErrorf(nil, "Set encryption to true", "CheckCloudResourceAuthorized", errmsgs.AlibabacloudStackSdkGoERROR)
} else {
log.Print("Encryption key condition failed")
}
d.Set("encryption", encryption)
log.Printf("encryptionbool %v", d.Get("encryption").(bool))
enginever := Trim(d.Get("engine_version").(string))
engine := Trim(d.Get("engine").(string))
DBInstanceStorage := connectivity.GetResourceData(d, "db_instance_storage", "instance_storage").(int)
if err := errmsgs.CheckEmpty(DBInstanceStorage, schema.TypeString, "db_instance_storage", "instance_storage"); err != nil {
return errmsgs.WrapError(err)
}
DBInstanceClass := Trim(connectivity.GetResourceData(d, "db_instance_class", "instance_type").(string))
if err := errmsgs.CheckEmpty(DBInstanceClass, schema.TypeString, "db_instance_class", "instance_type"); err != nil {
return errmsgs.WrapError(err)
}
DBInstanceNetType := string(Intranet)
DBInstanceDescription := connectivity.GetResourceData(d, "db_instance_description", "instance_name").(string)
if zone, ok := d.GetOk("zone_id"); ok && Trim(zone.(string)) != "" {
ZoneId = Trim(zone.(string))
}
vswitchId := Trim(d.Get("vswitch_id").(string))
InstanceNetworkType = string(Classic)
if vswitchId != "" {
VSwitchId = vswitchId
InstanceNetworkType = strings.ToUpper(string(Vpc))
// check vswitchId in zone
vsw, err := vpcService.DescribeVSwitch(vswitchId)
if err != nil {
return nil
}
if ZoneId == "" {
ZoneId = vsw.ZoneId
}
VPCId = vsw.VpcId
}
payType := string(Postpaid)
if v, ok := connectivity.GetResourceDataOk(d, "payment_type", "instance_charge_type"); ok && Trim(v.(string)) != "" {
payType = Trim(v.(string))
}
DBInstanceStorageType := connectivity.GetResourceData(d, "db_instance_storage_type", "storage_type").(string)
if err := errmsgs.CheckEmpty(DBInstanceStorageType, schema.TypeString, "db_instance_storage_type", "storage_type"); err != nil {
return errmsgs.WrapError(err)
}
ZoneIdSlave1 = d.Get("zone_id_slave1").(string)
ZoneIdSlave2 = d.Get("zone_id_slave2").(string)
SecurityIPList := LOCAL_HOST_IP
if len(d.Get("security_ips").(*schema.Set).List()) > 0 {
SecurityIPList = strings.Join(expandStringList(d.Get("security_ips").(*schema.Set).List())[:], COMMA_SEPARATED)
}
uuid, err := uuid.GenerateUUID()
if err != nil {
uuid = resource.UniqueId()
}
ClientToken := fmt.Sprintf("Terraform-AlibabacloudStack-%d-%s", time.Now().Unix(), uuid)
request := client.NewCommonRequest("POST", "Rds", "2014-08-15", "CreateDBInstance", "")
mergeMaps(request.QueryParams, map[string]string{
"EngineVersion": enginever,
"Engine": engine,
"Encryption": strconv.FormatBool(encryption),
"DBInstanceStorage": strconv.Itoa(DBInstanceStorage),
"DBInstanceClass": DBInstanceClass,
"DBInstanceNetType": DBInstanceNetType,
"DBInstanceDescription": DBInstanceDescription,
"InstanceNetworkType": InstanceNetworkType,
"VSwitchId": VSwitchId,
"PayType": payType,
"DBInstanceStorageType": DBInstanceStorageType,
"SecurityIPList": SecurityIPList,
"ClientToken": ClientToken,
"ZoneIdSlave1": ZoneIdSlave1,
"ZoneIdSlave2": ZoneIdSlave2,
"EncryptionKey": EncryptionKey,
"ZoneId": ZoneId,
"VPCId": VPCId,
"RoleARN": arnrole,
})
log.Printf("request245 %v", request.QueryParams)
raw, err := client.WithRdsClient(func(RdsClient *rds.Client) (interface{}, error) {
return RdsClient.ProcessCommonRequest(request)
})
response, ok := raw.(*responses.CommonResponse)
if err != nil {
errmsg := ""
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_db_instance", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
if arnrole != "" {
log.Print("arnrole has been added")
} else {
log.Print("arnrole has not been added")
}
var resp CreateDBInstanceResponse
addDebug(request.GetActionName(), raw, request)
err = json.Unmarshal(response.GetHttpContentBytes(), &resp)
if err != nil {
return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_db_instance", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR)
}
log.Printf("response25 %v", response)
d.SetId(resp.DBInstanceId)
d.Set("connection_string", resp.ConnectionString)
// wait instance status change from Creating to running
stateConf := BuildStateConf([]string{"Creating"}, []string{"Running"}, d.Timeout(schema.TimeoutCreate), 2*time.Minute, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"}))
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
if tde := d.Get("tde_status"); tde == true {
client := meta.(*connectivity.AlibabacloudStackClient)
rdsService = RdsService{client}
tde_req := rds.CreateModifyDBInstanceTDERequest()
client.InitRpcRequest(*tde_req.RpcRequest)
tde_req.QueryParams["RoleARN"] = arnrole
tde_req.DBInstanceId = d.Id()
if EncryptionKey != "" {
tde_req.EncryptionKey = EncryptionKey
}
tde_req.TDEStatus = "Enabled"
tderaw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ModifyDBInstanceTDE(tde_req)
})
if err != nil {
errmsg := ""
if tderaw != nil {
response, ok := tderaw.(*rds.ModifyDBInstanceTDEResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
if err := rdsService.WaitForDBInstance(d.Id(), Running, DefaultTimeoutMedium); err != nil {
return errmsgs.WrapError(err)
}
log.Print("enabled TDE")
addDebug(request.GetActionName(), tderaw, request)
}
if ssl := d.Get("enable_ssl"); ssl == true {
ssl_req := rds.CreateModifyDBInstanceSSLRequest()
client.InitRpcRequest(*ssl_req.RpcRequest)
ssl_req.QueryParams["Forwardedregionid"] = client.RegionId
ssl_req.DBInstanceId = d.Id()
ssl_req.SSLEnabled = "1"
ssl_req.ConnectionString = d.Get("connection_string").(string)
sslraw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ModifyDBInstanceSSL(ssl_req)
})
if err != nil {
errmsg := ""
if sslraw != nil {
response, ok := sslraw.(*rds.ModifyDBInstanceSSLResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
if err := rdsService.WaitForDBInstance(d.Id(), Running, DefaultTimeoutMedium); err != nil {
return errmsgs.WrapError(err)
}
log.Print("enabled SSL")
addDebug(ssl_req.GetActionName(), sslraw, ssl_req)
}
return nil
}
func resourceAlibabacloudStackDBInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
rdsService := RdsService{client}
d.Partial(true)
stateConf := BuildStateConf([]string{"DBInstanceClassChanging", "DBInstanceNetTypeChanging"}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 1*time.Minute, rdsService.RdsDBInstanceStateRefreshFunc(d.Id(), []string{"Deleting"}))
if d.HasChange("parameters") {
if err := rdsService.ModifyParameters(d, "parameters"); err != nil {
return errmsgs.WrapError(err)
}
}
if err := rdsService.setInstanceTags(d); err != nil {
return errmsgs.WrapError(err)
}
payType := Postpaid
if v, ok := connectivity.GetResourceDataOk(d, "payment_type", "instance_charge_type"); ok && Trim(v.(string)) != "" {
payType = PayType(Trim(v.(string)))
}
if !d.IsNewResource() && d.HasChanges("instance_charge_type", "payment_type") && payType == Prepaid {
prePaidRequest := rds.CreateModifyDBInstancePayTypeRequest()
client.InitRpcRequest(*prePaidRequest.RpcRequest)
prePaidRequest.DBInstanceId = d.Id()
prePaidRequest.PayType = string(payType)
prePaidRequest.AutoPay = "true"
period := d.Get("period").(int)
prePaidRequest.UsedTime = requests.Integer(strconv.Itoa(period))
prePaidRequest.Period = string(Month)
if period > 9 {
prePaidRequest.UsedTime = requests.Integer(strconv.Itoa(period / 12))
prePaidRequest.Period = string(Year)
}
raw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ModifyDBInstancePayType(prePaidRequest)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*rds.ModifyDBInstancePayTypeResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), prePaidRequest.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(prePaidRequest.GetActionName(), raw, prePaidRequest, prePaidRequest.QueryParams)
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
}
if payType == Prepaid && d.HasChanges("auto_renew", "auto_renew_period") {
request := rds.CreateModifyInstanceAutoRenewalAttributeRequest()
client.InitRpcRequest(*request.RpcRequest)
request.DBInstanceId = d.Id()
auto_renew := d.Get("auto_renew").(bool)
if auto_renew {
request.AutoRenew = "True"
} else {
request.AutoRenew = "False"
}
request.Duration = strconv.Itoa(d.Get("auto_renew_period").(int))
raw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ModifyInstanceAutoRenewalAttribute(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*rds.ModifyInstanceAutoRenewalAttributeResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request, request.QueryParams)
}
if d.HasChange("monitoring_period") {
period := d.Get("monitoring_period").(int)
request := rds.CreateModifyDBInstanceMonitorRequest()
client.InitRpcRequest(*request.RpcRequest)
request.DBInstanceId = d.Id()
request.Period = strconv.Itoa(period)
raw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ModifyDBInstanceMonitor(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*rds.ModifyDBInstanceMonitorResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
if d.HasChange("maintain_time") {
request := rds.CreateModifyDBInstanceMaintainTimeRequest()
client.InitRpcRequest(*request.RpcRequest)
request.DBInstanceId = d.Id()
request.MaintainTime = d.Get("maintain_time").(string)
request.ClientToken = buildClientToken(request.GetActionName())
raw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ModifyDBInstanceMaintainTime(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*rds.ModifyDBInstanceMaintainTimeResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
if d.IsNewResource() {
d.Partial(false)
return nil
}
if d.HasChanges("instance_name", "db_instance_description") {
request := rds.CreateModifyDBInstanceDescriptionRequest()
client.InitRpcRequest(*request.RpcRequest)
request.DBInstanceId = d.Id()
request.DBInstanceDescription = connectivity.GetResourceData(d, "db_instance_description", "instance_name").(string)
raw, err := client.WithRdsClient(func(rdsClient *rds.Client) (interface{}, error) {
return rdsClient.ModifyDBInstanceDescription(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*rds.ModifyDBInstanceDescriptionResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
if d.HasChange("security_ips") {
ipList := expandStringList(d.Get("security_ips").(*schema.Set).List())
ipstr := strings.Join(ipList[:], COMMA_SEPARATED)
if ipstr == "" {
ipstr = LOCAL_HOST_IP
}
if err := rdsService.ModifyDBSecurityIps(d.Id(), ipstr); err != nil {
return errmsgs.WrapError(err)
}
}
update := false
request := rds.CreateModifyDBInstanceSpecRequest()
client.InitRpcRequest(*request.RpcRequest)
request.DBInstanceId = d.Id()
if v, ok := connectivity.GetResourceDataOk(d, "payment_type", "instance_charge_type"); ok {
request.PayType = v.(string)
} else {
request.PayType = string(Postpaid)
}
if d.HasChanges("instance_type", "db_instance_class") {
request.DBInstanceClass = connectivity.GetResourceData(d, "db_instance_class", "instance_type").(string)
if err := errmsgs.CheckEmpty(request.DBInstanceClass, schema.TypeString, "db_instance_class", "instance_type"); err != nil {
return errmsgs.WrapError(err)
}
update = true
}
if d.HasChanges("instance_storage", "db_instance_storage") {
request.DBInstanceStorage = requests.NewInteger(connectivity.GetResourceData(d, "db_instance_storage", "instance_storage").(int))
if err := errmsgs.CheckEmpty(request.DBInstanceStorage, schema.TypeString, "db_instance_storage", "instance_storage"); err != nil {
return errmsgs.WrapError(err)
}
update = true
}
if update {
// wait instance status is running before modifying
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
err := resource.Retry(5*time.Minute, func() *resource.RetryError {
raw, err := client.WithRdsClient(func(rdsClient *rds.Client) (interface{}, error) {
return rdsClient.ModifyDBInstanceSpec(request)
})
if err != nil {
if errmsgs.IsExpectedErrors(err, []string{"InternalError", "OperationDenied.DBInstanceStatus"}) {
return resource.RetryableError(errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR))
}
errmsg := ""
if raw != nil {
response, ok := raw.(*rds.ModifyDBInstanceSpecResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.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 errmsgs.WrapError(err)
}
// wait instance status is running after modifying
if _, err := stateConf.WaitForState(); err != nil {
return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id())
}
}
d.Partial(false)
if d.HasChange("tde_status") {
tde_req := client.NewCommonRequest("POST", "Rds", "2014-08-15", "ModifyDBInstanceTDE", "")
tde_req.QueryParams["DBInstanceId"] = d.Id()
tde_req.QueryParams["TDEStatus"] = "Enabled"
raw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ProcessCommonRequest(tde_req)
})
response, ok := raw.(*responses.CommonResponse)
if err != nil {
errmsg := ""
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), tde_req.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
if err := rdsService.WaitForDBInstance(d.Id(), Running, DefaultTimeoutMedium); err != nil {
return errmsgs.WrapError(err)
}
log.Print("Updated TDE")
addDebug(tde_req.GetActionName(), raw, tde_req)
}
if d.HasChange("enable_ssl") {
ssl := d.Get("enable_ssl").(bool)
ssl_req := client.NewCommonRequest("POST", "Rds", "2014-08-15", "ModifyDBInstanceSSL", "")
ssl_req.QueryParams["DBInstanceId"] = d.Id()
ssl_req.QueryParams["ConnectionString"] = d.Get("connection_string").(string)
if ssl == true {
ssl_req.QueryParams["SSLEnabled"] = "1"
} else {
ssl_req.QueryParams["SSLEnabled"] = "0"
}
sslraw, err := client.WithRdsClient(func(client *rds.Client) (interface{}, error) {
return client.ProcessCommonRequest(ssl_req)
})
response, ok := sslraw.(*responses.CommonResponse)
if err != nil {
errmsg := ""
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), ssl_req.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
if err := rdsService.WaitForDBInstance(d.Id(), Running, DefaultTimeoutMedium); err != nil {
return errmsgs.WrapError(err)
}
if ssl == true {
log.Print("Updated SSL to true")
} else {
log.Print("Updated SSL to false")
}
addDebug(ssl_req.GetActionName(), sslraw, ssl_req)
}
return nil
}
func resourceAlibabacloudStackDBInstanceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
rdsService := RdsService{client}
instance, err := rdsService.DescribeDBInstance(d.Id())
if err != nil {
if errmsgs.NotFoundError(err) {
d.SetId("")
return nil
}
return errmsgs.WrapError(err)
}
ips, err := rdsService.GetSecurityIps(d.Id())
if err != nil {
return errmsgs.WrapError(err)
}
tags, err := rdsService.describeTags(d)
if err != nil {
return errmsgs.WrapError(err)
}
if len(tags) > 0 {
d.Set("tags", rdsService.tagsToMap(tags))
}
monitoringPeriod, err := rdsService.DescribeDbInstanceMonitor(d.Id())
if err != nil {
return errmsgs.WrapError(err)
}
d.Set("monitoring_period", monitoringPeriod)
d.Set("security_ips", ips)
d.Set("security_ip_mode", instance.SecurityIPMode)
d.Set("engine", instance.Engine)
d.Set("engine_version", instance.EngineVersion)
connectivity.SetResourceData(d, instance.DBInstanceClass, "db_instance_class", "instance_type")
d.Set("port", instance.Port)
connectivity.SetResourceData(d, instance.DBInstanceStorage, "db_instance_storage", "instance_storage")
d.Set("zone_id", instance.ZoneId)
if instance.PayType != "" {
// 专有云场景下不会返回pay type
connectivity.SetResourceData(d, instance.PayType, "payment_type", "instance_charge_type")
}
d.Set("period", d.Get("period"))
d.Set("vswitch_id", instance.VSwitchId)
d.Set("connection_string", instance.ConnectionString)
connectivity.SetResourceData(d, instance.DBInstanceDescription, "db_instance_description", "instance_name")
d.Set("maintain_time", instance.MaintainTime)
connectivity.SetResourceData(d, instance.DBInstanceStorageType, "db_instance_storage_type", "storage_type")
if err = rdsService.RefreshParameters(d, "parameters"); err != nil {
return errmsgs.WrapError(err)
}
if instance.PayType == string(Prepaid) {
request := client.NewCommonRequest("POST", "Rds", "2014-08-15", "DescribeInstanceAutoRenewalAttribute", "")
request.QueryParams["DBInstanceId"] = d.Id()
raw, err := client.WithRdsClient(func(rdsClient *rds.Client) (interface{}, error) {
return rdsClient.ProcessCommonRequest(request)
})
response, ok := raw.(*rds.DescribeInstanceAutoRenewalAttributeResponse)
if err != nil {
errmsg := ""
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request, request.QueryParams)
if response != nil && len(response.Items.Item) > 0 {
renew := response.Items.Item[0]
d.Set("auto_renew", renew.AutoRenew == "True")
d.Set("auto_renew_period", renew.Duration)
}
period, err := computePeriodByUnit(instance.CreationTime, instance.ExpireTime, d.Get("period").(int), "Month")
if err != nil {
return errmsgs.WrapError(err)
}
d.Set("period", period)
}
return nil
}
func resourceAlibabacloudStackDBInstanceDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
rdsService := RdsService{client}
instance, err := rdsService.DescribeDBInstance(d.Id())
if err != nil {
if errmsgs.NotFoundError(err) {
return nil
}
return errmsgs.WrapError(err)
}
if PayType(instance.PayType) == 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 := client.NewCommonRequest("POST", "Rds", "2014-08-15", "DeleteDBInstance", "")
request.QueryParams["DBInstanceId"] = d.Id()
err = resource.Retry(10*time.Minute, func() *resource.RetryError {
raw, err := client.WithRdsClient(func(rdsClient *rds.Client) (interface{}, error) {
return rdsClient.ProcessCommonRequest(request)
})
if err != nil && !errmsgs.NotFoundError(err) {
if errmsgs.IsExpectedErrors(err, []string{"OperationDenied.DBInstanceStatus", "OperationDenied.ReadDBInstanceStatus"}) {
return resource.RetryableError(err)
}
errmsg := ""
response, ok := raw.(*responses.CommonResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
err = errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
return resource.NonRetryableError(err)
}
addDebug(request.GetActionName(), raw, request, request.QueryParams)
return nil
})
if err != nil {
return err
}
return nil
}
type CreateDBInstanceResponse struct {
*responses.BaseResponse
RequestId string `json:"RequestId" xml:"RequestId"`
DBInstanceId string `json:"DBInstanceId" xml:"DBInstanceId"`
OrderId string `json:"OrderId" xml:"OrderId"`
ConnectionString string `json:"ConnectionString" xml:"ConnectionString"`
Port string `json:"Port" xml:"Port"`
}
type RoleARN struct {
AuthorizationState int `json:"AuthorizationState"`
EagleEyeTraceID string `json:"eagleEyeTraceId"`
AsapiSuccess bool `json:"asapiSuccess"`
AsapiRequestID string `json:"asapiRequestId"`
RequestID string `json:"RequestId"`
RoleArn string `json:"RoleArn"`
}