alibabacloudstack/resource_apsarastack_gpdb_instance.go (339 lines of code) (raw):

package alibabacloudstack import ( "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/aliyun/alibaba-cloud-sdk-go/services/gpdb" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func resourceAlibabacloudStackGpdbInstance() *schema.Resource { resource := &schema.Resource{ Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), }, Schema: map[string]*schema.Schema{ "availability_zone": { Type: schema.TypeString, Optional: true, ForceNew: true, Computed: true, }, "instance_class": { Type: schema.TypeString, Optional: true, Computed:true, ForceNew: true, Deprecated: "Field 'instance_class' 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, ForceNew: true, ConflictsWith: []string{"instance_class"}, }, "instance_id": { Type: schema.TypeString, Computed: true, Deprecated: "Field 'instance_id' is deprecated and will be removed in a future release. Please use new field 'instance_id' instead.", }, "db_instance_id": { Type: schema.TypeString, Computed: true, }, "region_id": { Type: schema.TypeString, Computed: true, }, "status": { Type: schema.TypeString, Computed: true, }, "instance_network_type": { Type: schema.TypeString, Computed: true, Deprecated: "Field 'instance_network_type' is deprecated and will be removed in a future release. Please use new field 'network_type' instead.", }, "network_type": { Type: schema.TypeString, Computed: true, }, "instance_group_count": { Type: schema.TypeString, Required: true, }, "instance_charge_type": { Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{"PostPaid"}, false), Optional: true, ForceNew: 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{"PostPaid"}, false), Optional: true, ForceNew: true, Computed: true, ConflictsWith: []string{"instance_charge_type"}, }, "description": { Type: schema.TypeString, ValidateFunc: validation.StringLenBetween(2, 256), Optional: true, Computed:true, Deprecated: "Field 'description' 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, ValidateFunc: validation.StringLenBetween(2, 256), Optional: true, Computed:true, ConflictsWith: []string{"description"}, }, "vswitch_id": { Type: schema.TypeString, ForceNew: true, Optional: true, Computed: true, }, "instance_inner_connection": { Type: schema.TypeString, ForceNew: true, Optional: true, Computed: true, }, "instance_inner_port": { Type: schema.TypeString, ForceNew: true, Computed: true, Deprecated: "Field 'instance_inner_port' is deprecated and will be removed in a future release. Please use new field 'port' instead.", }, "port": { Type: schema.TypeString, ForceNew: true, Computed: true, }, "instance_vpc_id": { Type: schema.TypeString, Computed: true, Deprecated: "Field 'instance_vpc_id' is deprecated and will be removed in a future release. Please use new field 'vpc_id' instead.", }, "vpc_id": { Type: schema.TypeString, Computed: true, }, "security_ip_list": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, Optional: true, }, "engine": { Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{"gpdb"}, false), Optional: true, Computed: true, ForceNew: true, }, "engine_version": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, "tags": tagsSchema(), }, } setResourceFunc(resource, resourceAlibabacloudStackGpdbInstanceCreate, resourceAlibabacloudStackGpdbInstanceRead, resourceAlibabacloudStackGpdbInstanceUpdate, resourceAlibabacloudStackGpdbInstanceDelete) return resource } func resourceAlibabacloudStackGpdbInstanceRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) gpdbService := GpdbService{client} instance, err := gpdbService.DescribeGpdbInstance(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { d.SetId("") return nil } return errmsgs.WrapError(err) } connectivity.SetResourceData(d, instance.DBInstanceId, "db_instance_id", "instance_id") d.Set("region_id", instance.RegionId) d.Set("availability_zone", instance.ZoneId) d.Set("engine", instance.Engine) d.Set("engine_version", instance.EngineVersion) d.Set("status", instance.DBInstanceStatus) connectivity.SetResourceData(d, instance.DBInstanceDescription, "db_instance_description", "description") connectivity.SetResourceData(d, instance.DBInstanceClass, "db_instance_class", "instance_class") connectivity.SetResourceData(d, instance.InstanceNetworkType, "network_type", "instance_network_type") d.Set("instance_group_count", instance.DBInstanceGroupCount) security_ips, err := gpdbService.DescribeGpdbSecurityIps(d.Id()) if err != nil { return errmsgs.WrapError(err) } d.Set("security_ip_list", security_ips) //d.Set("create_time", instance.CreationTime) connectivity.SetResourceData(d, instance.PayType, "payment_type", "instance_charge_type") d.Set("tags", gpdbService.tagsToMap(instance.Tags.Tag)) d.Set("instance_inner_connection", instance.ConnectionString) connectivity.SetResourceData(d, instance.Port, "port", "instance_inner_port") connectivity.SetResourceData(d, instance.VpcId, "vpc_id", "instance_vpc_id") return nil } func resourceAlibabacloudStackGpdbInstanceCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) gpdbService := GpdbService{client} request, err := buildGpdbCreateRequest(d, meta) client.InitRpcRequest(*request.RpcRequest) if err != nil { return errmsgs.WrapError(err) } var raw interface{} err = resource.Retry(5*time.Minute, func() *resource.RetryError { raw, err = client.WithGpdbClient(func(client *gpdb.Client) (interface{}, error) { return client.CreateDBInstance(request) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"SYSTEM.CONCURRENT_OPERATE"}) { return resource.RetryableError(err) } return resource.NonRetryableError(err) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) response, ok := raw.(*gpdb.CreateDBInstanceResponse) if err != nil { errmsg := "" if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse) } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_gpdb_instance", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } d.SetId(response.DBInstanceId) stateConf := BuildStateConf([]string{"Creating"}, []string{"Running"}, d.Timeout(schema.TimeoutCreate), 10*time.Minute, gpdbService.GpdbInstanceStateRefreshFunc(d.Id(), []string{"Deleting"})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } return nil } func resourceAlibabacloudStackGpdbInstanceUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) gpdbService := GpdbService{client} // Begin Update d.Partial(true) // Update Instance Description if d.HasChanges("db_instance_description", "description"){ request := gpdb.CreateModifyDBInstanceDescriptionRequest() client.InitRpcRequest(*request.RpcRequest) request.DBInstanceId = d.Id() request.DBInstanceDescription = connectivity.GetResourceData(d, "db_instance_description", "description").(string) raw, err := client.WithGpdbClient(func(gpdbClient *gpdb.Client) (interface{}, error) { return gpdbClient.ModifyDBInstanceDescription(request) }) if err != nil { response, ok := raw.(*gpdb.ModifyDBInstanceDescriptionResponse) 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.RpcRequest, request) //d.SetPartial("db_instance_description") } // Update Security Ips if d.HasChange("security_ip_list") { ipList := expandStringList(d.Get("security_ip_list").(*schema.Set).List()) ipStr := strings.Join(ipList[:], COMMA_SEPARATED) // default disable connect from outside if ipStr == "" { ipStr = LOCAL_HOST_IP } if err := gpdbService.ModifyGpdbSecurityIps(d.Id(), ipStr); err != nil { return errmsgs.WrapError(err) } //d.SetPartial("security_ip_list") } if err := gpdbService.setInstanceTags(d); err != nil { return errmsgs.WrapError(err) } // Finish Update d.Partial(false) return nil } func resourceAlibabacloudStackGpdbInstanceDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) request := gpdb.CreateDeleteDBInstanceRequest() client.InitRpcRequest(*request.RpcRequest) request.DBInstanceId = d.Id() err := resource.Retry(10*5*time.Minute, func() *resource.RetryError { raw, err := client.WithGpdbClient(func(client *gpdb.Client) (interface{}, error) { return client.DeleteDBInstance(request) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"OperationDenied.DBInstanceStatus"}) { return resource.RetryableError(err) } response, ok := raw.(*gpdb.DeleteDBInstanceResponse) errmsg := "" 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.RpcRequest, request) return nil }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"InvalidDBInstanceId.NotFound"}) { return nil } return err } // because DeleteDBInstance is called synchronously, there is no wait or describe here. return nil } func buildGpdbCreateRequest(d *schema.ResourceData, meta interface{}) (*gpdb.CreateDBInstanceRequest, error) { client := meta.(*connectivity.AlibabacloudStackClient) request := gpdb.CreateCreateDBInstanceRequest() client.InitRpcRequest(*request.RpcRequest) request.ZoneId = Trim(d.Get("availability_zone").(string)) request.PayType = connectivity.GetResourceData(d, "payment_type", "instance_charge_type").(string) request.VSwitchId = Trim(d.Get("vswitch_id").(string)) request.DBInstanceDescription = connectivity.GetResourceData(d, "db_instance_description", "description").(string) request.DBInstanceClass = Trim(connectivity.GetResourceData(d, "db_instance_class", "instance_class").(string)) if err := errmsgs.CheckEmpty(request.DBInstanceClass, schema.TypeString, "db_instance_class", "instance_class"); err != nil { return nil, errmsgs.WrapError(err) } request.DBInstanceGroupCount = Trim(d.Get("instance_group_count").(string)) request.Engine = Trim(d.Get("engine").(string)) request.EngineVersion = Trim(d.Get("engine_version").(string)) // Instance NetWorkType request.InstanceNetworkType = string(Classic) if request.VSwitchId != "" { // check vswitchId in zone vpcService := VpcService{client} object, err := vpcService.DescribeVSwitch(request.VSwitchId) if err != nil { return nil, errmsgs.WrapError(err) } if request.ZoneId == "" { request.ZoneId = object.ZoneId } else if strings.Contains(request.ZoneId, MULTI_IZ_SYMBOL) { zoneStr := strings.Split(strings.SplitAfter(request.ZoneId, "(")[1], ")")[0] if !strings.Contains(zoneStr, string([]byte(object.ZoneId)[len(object.ZoneId)-1])) { return nil, errmsgs.WrapError(errmsgs.Error("The specified vswitch %s isn't in the multi zone %s.", object.VSwitchId, request.ZoneId)) } } else if request.ZoneId != object.ZoneId { return nil, errmsgs.WrapError(errmsgs.Error("The specified vswitch %s isn't in the zone %s.", object.VSwitchId, request.ZoneId)) } request.VPCId = object.VpcId request.InstanceNetworkType = strings.ToUpper(string(Vpc)) } // Security Ips request.SecurityIPList = LOCAL_HOST_IP if len(d.Get("security_ip_list").(*schema.Set).List()) > 0 { request.SecurityIPList = strings.Join(expandStringList(d.Get("security_ip_list").(*schema.Set).List())[:], COMMA_SEPARATED) } // ClientToken request.ClientToken = buildClientToken(request.GetActionName()) return request, nil }