alicloud/resource_alicloud_gpdb_instance.go (1,307 lines of code) (raw):
package alicloud
import (
"encoding/json"
"fmt"
"log"
"reflect"
"sort"
"strconv"
"strings"
"time"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func resourceAliCloudGpdbInstance() *schema.Resource {
return &schema.Resource{
Create: resourceAliCloudGpdbDbInstanceCreate,
Read: resourceAliCloudGpdbDbInstanceRead,
Update: resourceAliCloudGpdbDbInstanceUpdate,
Delete: resourceAliCloudGpdbDbInstanceDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(60 * time.Minute),
Update: schema.DefaultTimeout(60 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
},
Schema: map[string]*schema.Schema{
"engine": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"engine_version": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"vswitch_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"db_instance_mode": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: StringInSlice([]string{"StorageElastic", "Serverless", "Classic"}, false),
},
"db_instance_class": {
Type: schema.TypeString,
Optional: true,
},
"db_instance_category": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"Basic", "HighAvailability"}, false),
},
"instance_spec": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: StringInSlice([]string{"2C16G", "4C32G", "16C128G", "2C8G", "4C16G", "8C32G", "16C64G"}, false),
},
"storage_size": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"resource_management_mode": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"resourceGroup", "resourceQueue"}, false),
},
"instance_network_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"VPC"}, false),
},
"vpc_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"zone_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ConflictsWith: []string{"availability_zone"},
},
"instance_group_count": {
Type: schema.TypeInt,
Optional: true,
},
"payment_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"PayAsYouGo", "Subscription"}, false),
},
"period": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: StringInSlice([]string{"Month", "Year"}, false),
},
"resource_group_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"master_cu": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: IntInSlice([]int{2, 4, 8, 16, 32}),
},
"seg_node_num": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: IntBetween(2, 512),
},
"seg_storage_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"seg_disk_performance_level": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"pl0", "pl1", "pl2"}, false),
},
"create_sample_data": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"ssl_enabled": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: IntInSlice([]int{0, 1}),
},
"encryption_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: StringInSlice([]string{"CloudDisk"}, false),
},
"encryption_key": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"vector_configuration_status": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"enabled", "disabled"}, false),
},
"maintain_start_time": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"maintain_end_time": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"serverless_mode": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"Manual", "Auto"}, false),
},
"prod_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"data_share_status": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"opened", "closed"}, false),
},
"used_time": {
Type: schema.TypeString,
Optional: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"tags": tagsSchema(),
"ip_whitelist": {
Type: schema.TypeList,
Optional: true,
Computed: true,
ConflictsWith: []string{"security_ip_list"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip_group_attribute": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"ip_group_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"security_ip_list": {
Type: schema.TypeString,
Optional: true,
Computed: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
if old != "" && new != "" && old != new {
oldParts := strings.Split(old, ",")
sort.Strings(oldParts)
newParts := strings.Split(new, ",")
sort.Strings(newParts)
return reflect.DeepEqual(newParts, oldParts)
}
return false
},
},
},
},
},
"parameters": {
Type: schema.TypeSet,
Set: parameterToHash,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
"default_value": {
Type: schema.TypeString,
Computed: true,
},
"is_changeable_config": {
Type: schema.TypeString,
Computed: true,
},
"force_restart_instance": {
Type: schema.TypeString,
Computed: true,
},
"optional_range": {
Type: schema.TypeString,
Computed: true,
},
"parameter_description": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"security_ip_list": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
ConflictsWith: []string{"ip_whitelist"},
Deprecated: "Field 'security_ip_list' has been deprecated from version 1.187.0. Use 'ip_whitelist' instead.",
},
"instance_charge_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: StringInSlice([]string{"Prepaid", "Postpaid"}, false),
ConflictsWith: []string{"payment_type"},
Deprecated: "Field `instance_charge_type` has been deprecated from version 1.187.0. Use `payment_type` instead.",
},
"availability_zone": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ConflictsWith: []string{"zone_id"},
Deprecated: "Field 'availability_zone' has been deprecated from version 1.187.0. Use 'zone_id' instead.",
},
"master_node_num": {
Type: schema.TypeInt,
Optional: true,
Default: 1,
ValidateFunc: IntInSlice([]int{1, 2}),
Deprecated: "Field `master_node_num` has been deprecated from provider version 1.213.0.",
},
"private_ip_address": {
Type: schema.TypeString,
Optional: true,
Deprecated: "Field `private_ip_address` has been deprecated from provider version 1.213.0.",
},
"connection_string": {
Type: schema.TypeString,
Computed: true,
},
"port": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceAliCloudGpdbDbInstanceCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
gpdbService := GpdbService{client}
var response map[string]interface{}
action := "CreateDBInstance"
request := make(map[string]interface{})
var err error
request["RegionId"] = client.RegionId
request["ClientToken"] = buildClientToken("CreateDBInstance")
request["Engine"] = d.Get("engine")
request["EngineVersion"] = d.Get("engine_version")
request["VSwitchId"] = d.Get("vswitch_id")
request["DBInstanceMode"] = d.Get("db_instance_mode")
request["SecurityIPList"] = LOCAL_HOST_IP
if v, ok := d.GetOk("db_instance_class"); ok {
request["DBInstanceClass"] = v
}
if v, ok := d.GetOk("db_instance_category"); ok {
request["DBInstanceCategory"] = v
}
if v, ok := d.GetOk("instance_spec"); ok {
request["InstanceSpec"] = v
}
if v, ok := d.GetOk("storage_size"); ok {
request["StorageSize"] = v
}
if v, ok := d.GetOk("instance_network_type"); ok {
request["InstanceNetworkType"] = v
}
if v, ok := d.GetOk("vpc_id"); ok {
request["VPCId"] = v
}
if v, ok := d.GetOk("zone_id"); ok {
request["ZoneId"] = v
} else if v, ok := d.GetOk("availability_zone"); ok {
request["ZoneId"] = v
}
if v, ok := d.GetOk("instance_group_count"); ok {
request["DBInstanceGroupCount"] = v
}
if v, ok := d.GetOk("payment_type"); ok {
request["PayType"] = convertGpdbDbInstancePaymentTypeRequest(v.(string))
} else if v, ok := d.GetOk("instance_charge_type"); ok {
request["PayType"] = v
}
if v, ok := d.GetOk("period"); ok {
request["Period"] = v
}
if v, ok := d.GetOk("resource_group_id"); ok {
request["ResourceGroupId"] = v
}
if v, ok := d.GetOk("master_cu"); ok {
request["MasterCU"] = v
}
if v, ok := d.GetOk("seg_node_num"); ok {
request["SegNodeNum"] = v
}
if v, ok := d.GetOk("seg_storage_type"); ok {
request["SegStorageType"] = v
}
if v, ok := d.GetOk("seg_disk_performance_level"); ok {
request["SegDiskPerformanceLevel"] = v
}
if v, ok := d.GetOkExists("create_sample_data"); ok {
request["CreateSampleData"] = v
}
if v, ok := d.GetOk("encryption_type"); ok {
request["EncryptionType"] = v
}
if v, ok := d.GetOk("encryption_key"); ok {
request["EncryptionKey"] = v
}
if v, ok := d.GetOk("vector_configuration_status"); ok {
request["VectorConfigurationStatus"] = v
}
if v, ok := d.GetOk("serverless_mode"); ok {
request["ServerlessMode"] = v
}
if v, ok := d.GetOk("prod_type"); ok {
request["ProdType"] = v
}
if v, ok := d.GetOk("used_time"); ok {
request["UsedTime"] = v
}
if v, ok := d.GetOk("description"); ok {
request["DBInstanceDescription"] = v
}
if request["VpcId"] == nil && request["VSwitchId"] != nil {
vpcService := VpcService{client}
vsw, err := vpcService.DescribeVSwitchWithTeadsl(request["VSwitchId"].(string))
if err != nil {
return WrapError(err)
}
if v, ok := request["VPCId"].(string); !ok || v == "" {
request["VPCId"] = vsw["VpcId"]
}
}
if v, ok := d.GetOk("security_ip_list"); ok {
if len(v.(*schema.Set).List()) > 0 {
request["SecurityIpList"] = strings.Join(expandStringList(v.(*schema.Set).List())[:], COMMA_SEPARATED)
}
}
if v, ok := d.GetOk("master_node_num"); ok {
request["MasterNodeNum"] = v
}
if v, ok := d.GetOk("private_ip_address"); ok {
request["PrivateIpAddress"] = v
}
if v, ok := d.GetOkExists("ssl_enabled"); ok {
request["EnableSSL"] = convertGpdbDbInstanceSSLEnabledRequest(v)
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, "alicloud_gpdb_instance", action, AlibabaCloudSdkGoERROR)
}
d.SetId(fmt.Sprint(response["DBInstanceId"]))
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
if v, ok := d.GetOkExists("ssl_enabled"); ok {
sslEnabledStateConf := BuildStateConf([]string{}, []string{fmt.Sprint(v)}, d.Timeout(schema.TimeoutCreate), 5*time.Second, gpdbService.DBInstanceSSLStateRefreshFunc(d, []string{}))
if _, err := sslEnabledStateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
}
return resourceAliCloudGpdbDbInstanceUpdate(d, meta)
}
func resourceAliCloudGpdbDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
gpdbService := GpdbService{client}
object, err := gpdbService.DescribeGpdbDbInstance(d.Id())
if err != nil {
if !d.IsNewResource() && NotFoundError(err) {
log.Printf("[DEBUG] Resource alicloud_gpdb_db_instance gpdbService.DescribeGpdbDbInstance Failed!!! %s", err)
d.SetId("")
return nil
}
return WrapError(err)
}
d.Set("engine", object["Engine"])
d.Set("engine_version", object["EngineVersion"])
d.Set("vswitch_id", object["VSwitchId"])
d.Set("db_instance_category", object["DBInstanceCategory"])
d.Set("db_instance_mode", object["DBInstanceMode"])
d.Set("instance_network_type", object["InstanceNetworkType"])
d.Set("vpc_id", object["VpcId"])
d.Set("zone_id", object["ZoneId"])
d.Set("availability_zone", object["ZoneId"])
d.Set("payment_type", convertGpdbDbInstancePaymentTypeResponse(object["PayType"]))
d.Set("instance_charge_type", object["PayType"])
d.Set("resource_group_id", object["ResourceGroupId"])
d.Set("master_cu", formatInt(object["MasterCU"]))
d.Set("seg_node_num", formatInt(object["SegNodeNum"]))
d.Set("seg_storage_type", object["StorageType"])
d.Set("seg_disk_performance_level", convertGpdbDbInstanceSegDiskPerformanceLevelResponse(object["SegDiskPerformanceLevel"]))
d.Set("encryption_type", object["EncryptionType"])
d.Set("encryption_key", object["EncryptionKey"])
d.Set("vector_configuration_status", object["VectorConfigurationStatus"])
d.Set("maintain_start_time", object["MaintainStartTime"])
d.Set("maintain_end_time", object["MaintainEndTime"])
d.Set("serverless_mode", object["ServerlessMode"])
d.Set("prod_type", object["ProdType"])
d.Set("description", object["DBInstanceDescription"])
d.Set("connection_string", object["ConnectionString"])
d.Set("port", object["Port"])
d.Set("master_node_num", formatInt(object["MasterNodeNum"]))
d.Set("status", object["DBInstanceStatus"])
if v, ok := object["SegmentCounts"]; ok && fmt.Sprint(v) != "0" {
d.Set("node_num", formatInt(v))
}
if v, ok := object["StorageSize"]; ok && fmt.Sprint(v) != "0" {
d.Set("storage_size", formatInt(v))
}
if v, ok := object["Tags"].(map[string]interface{}); ok {
d.Set("tags", tagsToMap(v["Tag"]))
}
describeDBInstanceIPArrayListObject, err := gpdbService.DescribeDBInstanceIPArrayList(d.Id())
if err != nil {
return WrapError(err)
}
if iPWhitelistMap, ok := describeDBInstanceIPArrayListObject["Items"].(map[string]interface{}); ok && iPWhitelistMap != nil {
if dBInstanceIPArrayList, ok := iPWhitelistMap["DBInstanceIPArray"]; ok && dBInstanceIPArrayList != nil {
iPWhitelistMaps := make([]map[string]interface{}, 0)
for _, dBInstanceIPArrayListItem := range dBInstanceIPArrayList.([]interface{}) {
if dBInstanceIPArrayListItemMap, ok := dBInstanceIPArrayListItem.(map[string]interface{}); ok {
if dBInstanceIPArrayListItem.(map[string]interface{})["DBInstanceIPArrayAttribute"] == "hidden" {
continue
}
dBInstanceIPArrayListMap := map[string]interface{}{}
dBInstanceIPArrayListMap["ip_group_attribute"] = dBInstanceIPArrayListItemMap["DBInstanceIPArrayAttribute"]
dBInstanceIPArrayListMap["ip_group_name"] = dBInstanceIPArrayListItemMap["DBInstanceIPArrayName"]
dBInstanceIPArrayListMap["security_ip_list"] = dBInstanceIPArrayListItemMap["SecurityIPList"]
iPWhitelistMaps = append(iPWhitelistMaps, dBInstanceIPArrayListMap)
}
}
d.Set("ip_whitelist", iPWhitelistMaps)
}
}
describeDBInstanceSSLObject, err := gpdbService.DescribeDBInstanceSSL(d.Id())
if err != nil {
return WrapError(err)
}
if v, ok := describeDBInstanceSSLObject["SSLEnabled"]; ok && strconv.FormatBool(v.(bool)) != "" {
d.Set("ssl_enabled", convertGpdbDbInstanceSSLEnabledResponse(v))
}
resourceManagementModeObject, err := gpdbService.DescribeDBResourceManagementMode(d.Id())
if err != nil {
return WrapError(err)
}
if v, ok := resourceManagementModeObject["ResourceManagementMode"]; ok {
d.Set("resource_management_mode", v)
}
dataShareStatusObject, err := gpdbService.DescribeGpdbDbInstanceDataShareStatus(d.Id())
if err != nil {
return WrapError(err)
}
if dataShareStatus, ok := dataShareStatusObject["DataShareStatus"]; ok {
d.Set("data_share_status", dataShareStatus)
}
parameterObject, err := gpdbService.DescribeParameters(d.Id())
if err != nil {
return WrapError(err)
}
if parameterList, ok := parameterObject["Parameters"].([]interface{}); ok && parameterList != nil {
parameterListMaps := make([]map[string]interface{}, 0)
for _, parameterListItem := range parameterList {
if parameterListValueItemMap, ok := parameterListItem.(map[string]interface{}); ok {
parameterListMap := map[string]interface{}{}
parameterListMap["name"] = parameterListValueItemMap["ParameterName"]
parameterListMap["value"] = parameterListValueItemMap["CurrentValue"]
parameterListMap["default_value"] = parameterListValueItemMap["ParameterValue"]
parameterListMap["is_changeable_config"] = parameterListValueItemMap["IsChangeableConfig"]
parameterListMap["force_restart_instance"] = parameterListValueItemMap["ForceRestartInstance"]
parameterListMap["optional_range"] = parameterListValueItemMap["OptionalRange"]
parameterListMap["parameter_description"] = parameterListValueItemMap["ParameterDescription"]
parameterListMaps = append(parameterListMaps, parameterListMap)
}
}
d.Set("parameters", parameterListMaps)
}
return nil
}
func resourceAliCloudGpdbDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
gpdbService := GpdbService{client}
var err error
var response map[string]interface{}
request := make(map[string]interface{})
d.Partial(true)
if d.HasChange("tags") {
if err := gpdbService.SetResourceTags(d, "ALIYUN::GPDB::INSTANCE"); err != nil {
return WrapError(err)
}
d.SetPartial("tags")
}
update := false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("description") {
update = true
}
if v, ok := d.GetOk("description"); ok {
request["DBInstanceDescription"] = v
}
if update {
action := "ModifyDBInstanceDescription"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
d.SetPartial("description")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("resource_group_id") {
update = true
}
if v, ok := d.GetOk("resource_group_id"); ok {
request["NewResourceGroupId"] = v
}
if update {
action := "ModifyDBInstanceResourceGroup"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
d.SetPartial("resource_group_id")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("maintain_end_time") {
update = true
}
if v, ok := d.GetOk("maintain_end_time"); ok {
request["EndTime"] = v
}
if !d.IsNewResource() && d.HasChange("maintain_start_time") {
update = true
}
if v, ok := d.GetOk("maintain_start_time"); ok {
request["StartTime"] = v
}
if update {
action := "ModifyDBInstanceMaintainTime"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
d.SetPartial("maintain_end_time")
d.SetPartial("maintain_start_time")
}
if d.HasChange("ip_whitelist") {
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
o, n := d.GetChange("ip_whitelist")
newGroupKeys := make(map[string]struct{})
if n != nil {
for _, iPWhitelist := range n.([]interface{}) {
iPWhitelistArg := iPWhitelist.(map[string]interface{})
request["DBInstanceIPArrayAttribute"] = iPWhitelistArg["ip_group_attribute"]
request["DBInstanceIPArrayName"] = iPWhitelistArg["ip_group_name"]
request["SecurityIPList"] = iPWhitelistArg["security_ip_list"]
request["ModifyMode"] = 0
ipGroupName := "default"
if fmt.Sprint(iPWhitelistArg["ip_group_name"]) != "" {
ipGroupName = fmt.Sprint(iPWhitelistArg["ip_group_name"])
}
newGroupKeys[ipGroupName] = struct{}{}
action := "ModifySecurityIps"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
}
}
if o != nil {
for _, iPWhitelist := range o.([]interface{}) {
iPWhitelistArg := iPWhitelist.(map[string]interface{})
request["DBInstanceIPArrayAttribute"] = iPWhitelistArg["ip_group_attribute"]
request["DBInstanceIPArrayName"] = iPWhitelistArg["ip_group_name"]
request["SecurityIPList"] = iPWhitelistArg["security_ip_list"]
request["ModifyMode"] = 2
ipGroupName := "default"
if fmt.Sprint(iPWhitelistArg["ip_group_name"]) != "" {
ipGroupName = fmt.Sprint(iPWhitelistArg["ip_group_name"])
}
if _, ok := newGroupKeys[ipGroupName]; ok {
continue
}
action := "ModifySecurityIps"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
}
}
d.SetPartial("ip_whitelist")
}
if !d.IsNewResource() && d.HasChange("security_ip_list") {
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
if v, ok := d.GetOk("security_ip_list"); ok {
if len(v.(*schema.Set).List()) > 0 {
request["SecurityIpList"] = strings.Join(expandStringList(v.(*schema.Set).List())[:], COMMA_SEPARATED)
}
action := "ModifySecurityIps"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
d.SetPartial("security_ip_list")
}
}
update = false
request = map[string]interface{}{
"RegionId": client.RegionId,
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("seg_node_num") {
update = true
if v, ok := d.GetOkExists("seg_node_num"); ok {
request["UpgradeType"] = 0
request["SegNodeNum"] = v
}
}
if update {
action := "UpgradeDBInstance"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if IsExpectedErrors(err, []string{"OperationDenied.OrderProcessing"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("seg_node_num")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
request["RegionId"] = client.RegionId
if !d.IsNewResource() && d.HasChange("master_node_num") {
update = true
if v, ok := d.GetOk("master_node_num"); ok {
request["UpgradeType"] = 2
request["MasterNodeNum"] = v
}
}
if update {
action := "UpgradeDBInstance"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, false)
if err != nil {
if IsExpectedErrors(err, []string{"OperationDenied.OrderProcessing"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("master_node_num")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
request["RegionId"] = client.RegionId
if !d.IsNewResource() && d.HasChange("instance_spec") {
update = true
if v, ok := d.GetOk("instance_spec"); ok {
request["UpgradeType"] = 1
request["InstanceSpec"] = v
}
}
if update {
action := "UpgradeDBInstance"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if IsExpectedErrors(err, []string{"OperationDenied.OrderProcessing"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("instance_spec")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
request["RegionId"] = client.RegionId
if !d.IsNewResource() && d.HasChange("storage_size") {
update = true
if v, ok := d.GetOk("storage_size"); ok {
request["UpgradeType"] = 1
request["StorageSize"] = v
}
}
if update {
action := "UpgradeDBInstance"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if IsExpectedErrors(err, []string{"OperationDenied.OrderProcessing", "InternalError"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("storage_size")
}
update = false
modifySegDiskPerformanceLevelReq := map[string]interface{}{
"RegionId": client.RegionId,
"DBInstanceId": d.Id(),
"UpgradeType": 3,
}
if v, ok := d.GetOk("seg_storage_type"); ok {
modifySegDiskPerformanceLevelReq["SegStorageType"] = v
}
if !d.IsNewResource() && d.HasChange("seg_disk_performance_level") {
update = true
}
if v, ok := d.GetOk("seg_disk_performance_level"); ok {
modifySegDiskPerformanceLevelReq["SegDiskPerformanceLevel"] = v
}
if update {
action := "UpgradeDBInstance"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, modifySegDiskPerformanceLevelReq, false)
if err != nil {
if IsExpectedErrors(err, []string{"OperationDenied.OrderProcessing"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, modifySegDiskPerformanceLevelReq)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("seg_disk_performance_level")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("ssl_enabled") {
update = true
}
if v, ok := d.GetOkExists("ssl_enabled"); ok {
request["SSLEnabled"] = v
}
if update {
action := "ModifyDBInstanceSSL"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
sslEnabledStateConf := BuildStateConf([]string{}, []string{fmt.Sprint(request["SSLEnabled"])}, d.Timeout(schema.TimeoutCreate), 5*time.Second, gpdbService.DBInstanceSSLStateRefreshFunc(d, []string{}))
if _, err := sslEnabledStateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("ssl_enabled")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("vector_configuration_status") {
update = true
}
if v, ok := d.GetOk("vector_configuration_status"); ok {
request["VectorConfigurationStatus"] = v
}
if update {
action := "ModifyVectorConfiguration"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("vector_configuration_status")
}
if d.HasChange("parameters") {
action := "ModifyParameters"
request, err = getModifyParametersRequest(d)
if err != nil {
return WrapError(err)
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 30*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("parameters")
}
update = false
modifyMasterSpec := map[string]interface{}{
"DBInstanceId": d.Id(),
}
if !d.IsNewResource() && d.HasChange("master_cu") {
update = true
}
if v, ok := d.GetOk("master_cu"); ok {
modifyMasterSpec["MasterCU"] = v
}
if update {
action := "ModifyMasterSpec"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, modifyMasterSpec, false)
if err != nil {
if IsExpectedErrors(err, []string{"OperationDenied.OrderProcessing"}) || NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, modifyMasterSpec)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("master_cu")
}
update = false
request = map[string]interface{}{
"DBInstanceId": d.Id(),
}
action := "EnableDBResourceGroup"
request["RegionId"] = client.RegionId
if v, ok := d.GetOk("resource_management_mode"); ok && d.HasChange("resource_management_mode") {
update = true
if v == "resourceGroup" {
action = "EnableDBResourceGroup"
} else {
action = "DisableDBResourceGroup"
}
}
if update {
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running", "IDLE"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
}
update = false
dataShareStatus := ""
setDataShareInstanceReq := map[string]interface{}{
"RegionId": client.RegionId,
"InstanceList": "[\"" + d.Id() + "\"]",
}
if d.HasChange("data_share_status") {
update = true
}
if v, ok := d.GetOk("data_share_status"); ok {
setDataShareInstanceReq["OperationType"] = convertGpdbDbInstanceDataShareStatusRequest(v.(string))
dataShareStatus = v.(string)
}
if update {
action := "SetDataShareInstance"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, setDataShareInstanceReq, false)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, setDataShareInstanceReq)
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 60*time.Second, gpdbService.GpdbDbInstanceStateRefreshFunc(d.Id(), "DBInstanceStatus", []string{}))
if _, err := stateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
dataShareStatusStateConf := BuildStateConf([]string{}, []string{dataShareStatus}, d.Timeout(schema.TimeoutUpdate), 30*time.Second, gpdbService.GpdbDbInstanceDataShareStatusStateRefreshFunc(d.Id(), []string{}))
if _, err := dataShareStatusStateConf.WaitForState(); err != nil {
return WrapErrorf(err, IdMsg, d.Id())
}
d.SetPartial("data_share_status")
}
d.Partial(false)
return resourceAliCloudGpdbDbInstanceRead(d, meta)
}
func resourceAliCloudGpdbDbInstanceDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
action := "DeleteDBInstance"
var response map[string]interface{}
var err error
request := map[string]interface{}{
"DBInstanceId": d.Id(),
}
if v, ok := d.GetOk("payment_type"); ok && v.(string) == "Subscription" {
log.Printf("[WARN] Cannot destroy resourceGpdbDbInstance. Because payment_type = 'Subscription'. Terraform will remove this resource from the state file, however resources may remain.")
return nil
}
request["ClientToken"] = buildClientToken("DeleteDBInstance")
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError {
response, err = client.RpcPost("gpdb", "2016-05-03", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
if IsExpectedErrors(err, []string{"InvalidDBInstanceId.NotFound", "OperationDenied.DBInstancePayType"}) {
return nil
}
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
return nil
}
func getModifyParametersRequest(d *schema.ResourceData) (map[string]interface{}, error) {
request := map[string]interface{}{
"DBInstanceId": d.Id(),
}
o, n := d.GetChange("parameters")
os, ns := o.(*schema.Set), n.(*schema.Set)
add := ns.Difference(os).List()
config := make(map[string]string)
if len(add) > 0 {
for _, i := range add {
key := i.(map[string]interface{})["name"].(string)
value := i.(map[string]interface{})["value"].(string)
config[key] = value
}
}
configJson, err := json.Marshal(config)
if err != nil {
return nil, err
}
request["Parameters"] = string(configJson)
return request, nil
}
func convertGpdbDbInstancePaymentTypeRequest(source interface{}) interface{} {
switch source {
case "Subscription":
return "Prepaid"
case "PayAsYouGo":
return "Postpaid"
}
return source
}
func convertGpdbDbInstancePaymentTypeResponse(source interface{}) interface{} {
switch source {
case "Prepaid":
return "Subscription"
case "Postpaid":
return "PayAsYouGo"
}
return source
}
func convertGpdbDbInstanceSSLEnabledRequest(source interface{}) interface{} {
switch source {
case 0:
return false
case 1:
return true
}
return source
}
func convertGpdbDbInstanceSSLEnabledResponse(source interface{}) interface{} {
switch source {
case false:
return 0
case true:
return 1
}
return source
}
func convertGpdbDbInstanceDataShareStatusRequest(source interface{}) interface{} {
switch source {
case "opened":
return "add"
case "closed":
return "remove"
}
return source
}
func convertGpdbDbInstanceSegDiskPerformanceLevelResponse(source interface{}) interface{} {
switch source {
case "PL0":
return "pl0"
case "PL1":
return "pl1"
case "PL2":
return "pl2"
}
return source
}