alicloud/resource_alicloud_drds_instance.go (243 lines of code) (raw):

package alicloud import ( "strconv" "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/aliyun/alibaba-cloud-sdk-go/services/drds" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) func resourceAlicloudDRDSInstance() *schema.Resource { return &schema.Resource{ Create: resourceAliCloudDRDSInstanceCreate, Read: resourceAliCloudDRDSInstanceRead, Update: resourceAliCloudDRDSInstanceUpdate, Delete: resourceAliCloudDRDSInstanceDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(10 * time.Minute), Update: schema.DefaultTimeout(5 * time.Minute), Delete: schema.DefaultTimeout(10 * time.Minute), }, Schema: map[string]*schema.Schema{ "description": { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringLenBetween(1, 129), }, "zone_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, "specification": { Type: schema.TypeString, Required: true, ForceNew: true, }, "instance_charge_type": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{string(PostPaid), string(PrePaid)}, false), ForceNew: true, Default: PostPaid, }, "vswitch_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, "instance_series": { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{"drds.sn1.4c8g", "drds.sn1.8c16g", "drds.sn1.16c32g", "drds.sn1.32c64g", "drds.sn2.4c16g", "drds.sn2.8c32g", "drds.sn2.16c64g"}, false), ForceNew: true, }, "vpc_id": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, "connection_string": { Type: schema.TypeString, Computed: true, }, "port": { Type: schema.TypeString, Computed: true, }, "mysql_version": { Type: schema.TypeInt, Optional: true, Computed: true, ForceNew: true, }, }, } } func resourceAliCloudDRDSInstanceCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) drdsService := DrdsService{client} request := drds.CreateCreateDrdsInstanceRequest() request.RegionId = client.RegionId request.Description = d.Get("description").(string) request.Type = "1" request.ZoneId = d.Get("zone_id").(string) request.Specification = d.Get("specification").(string) request.PayType = d.Get("instance_charge_type").(string) request.VswitchId = d.Get("vswitch_id").(string) request.InstanceSeries = d.Get("instance_series").(string) request.Quantity = "1" if v, ok := d.GetOk("vpc_id"); ok { request.VpcId = v.(string) } if v, ok := d.GetOk("mysql_version"); ok { request.MySQLVersion = requests.Integer(strconv.Itoa(v.(int))) } if (request.ZoneId == "" || request.VpcId == "") && request.VswitchId != "" { vpcService := VpcService{client} vsw, err := vpcService.DescribeVSwitch(request.VswitchId) if err != nil { return WrapError(err) } request.VpcId = vsw.VpcId request.ZoneId = vsw.ZoneId } if request.PayType == string(PostPaid) { request.PayType = "drdsPost" } if request.PayType == string(PrePaid) { request.PayType = "drdsPre" } var response *drds.CreateDrdsInstanceResponse wait := incrementalWait(3*time.Second, 2*time.Second) err := resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { // currently, the ClientToken does not work and it need to update when retry request.ClientToken = buildClientToken(request.GetActionName()) raw, err := client.WithDrdsClient(func(drdsClient *drds.Client) (interface{}, error) { return drdsClient.CreateDrdsInstance(request) }) if err != nil { if IsExpectedErrors(err, []string{"InternalError"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) response, _ = raw.(*drds.CreateDrdsInstanceResponse) return nil }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_drds_instance", request.GetActionName(), AlibabaCloudSdkGoERROR) } idList := response.Data.DrdsInstanceIdList.DrdsInstanceIdList if len(idList) != 1 { return WrapError(Error("failed to get DRDS instance id and response. DrdsInstanceIdList is %#v", idList)) } d.SetId(idList[0]) // wait instance status change from DO_CREATE to RUN stateConf := BuildStateConf([]string{"DO_CREATE"}, []string{"RUN"}, d.Timeout(schema.TimeoutCreate), 1*time.Minute, drdsService.DrdsInstanceStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } return resourceAliCloudDRDSInstanceUpdate(d, meta) } func resourceAliCloudDRDSInstanceUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) drdsService := DrdsService{client} configItem := make(map[string]string) if d.HasChange("description") { request := drds.CreateModifyDrdsInstanceDescriptionRequest() request.DrdsInstanceId = d.Id() request.Description = d.Get("description").(string) configItem["description"] = request.Description client := meta.(*connectivity.AliyunClient) request.RegionId = client.RegionId raw, err := client.WithDrdsClient(func(drdsClient *drds.Client) (interface{}, error) { return drdsClient.ModifyDrdsInstanceDescription(request) }) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) } //wait for update effected and instance status returning to run if err := drdsService.WaitDrdsInstanceConfigEffect( d.Id(), configItem, d.Timeout(schema.TimeoutUpdate)); err != nil { return WrapError(err) } stateConf := BuildStateConf([]string{}, []string{"RUN"}, d.Timeout(schema.TimeoutUpdate), 3*time.Second, drdsService.DrdsInstanceStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } return resourceAliCloudDRDSInstanceRead(d, meta) } func resourceAliCloudDRDSInstanceRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) drdsService := DrdsService{client} object, err := drdsService.DescribeDrdsInstance(d.Id()) if err != nil { if NotFoundError(err) { d.SetId("") return nil } return WrapError(err) } data := object.Data //other attribute not set,because these attribute from `data` can't get d.Set("zone_id", data.ZoneId) d.Set("description", data.Description) d.Set("vpc_id", data.Vips.Vip[0].VpcId) var connectionString, port string for _, vip := range data.Vips.Vip { if vip.Type == "intranet" { connectionString = vip.Dns port = vip.Port break } } d.Set("connection_string", connectionString) d.Set("port", port) d.Set("mysql_version", data.MysqlVersion) return nil } func resourceAliCloudDRDSInstanceDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) drdsService := DrdsService{client} request := drds.CreateRemoveDrdsInstanceRequest() request.RegionId = client.RegionId request.DrdsInstanceId = d.Id() var response *drds.RemoveDrdsInstanceResponse wait := incrementalWait(3*time.Second, 2*time.Second) err := resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { raw, err := client.WithDrdsClient(func(drdsClient *drds.Client) (interface{}, error) { return drdsClient.RemoveDrdsInstance(request) }) if err != nil { if IsExpectedErrors(err, []string{"InternalError"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) response, _ = raw.(*drds.RemoveDrdsInstanceResponse) return nil }) if err != nil { if IsExpectedErrors(err, []string{"InvalidDrdsInstanceId.NotFound"}) { return nil } return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) } if !response.Success { return WrapError(Error("failed to delete instance timeout "+"and got an error: %#v", err)) } //0 -> RUN, 1->DO_CREATE, 2->EXCEPTION, 3->EXPIRE, 4->DO_RELEASE, 5->RELEASE, 6->UPGRADE, 7->DOWNGRADE, 10->VersionUpgrade, 11->VersionRollback, 14->RESTART stateConf := BuildStateConf([]string{}, []string{}, d.Timeout(schema.TimeoutDelete), 3*time.Second, drdsService.DrdsInstanceStateRefreshFunc(d.Id(), []string{})) if _, err = stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } return nil }