alicloud/data_source_alicloud_db_instances.go (710 lines of code) (raw):
package alicloud
import (
"encoding/json"
"fmt"
"regexp"
"time"
"github.com/PaesslerAG/jsonpath"
util "github.com/alibabacloud-go/tea-utils/service"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
func dataSourceAlicloudDBInstances() *schema.Resource {
return &schema.Resource{
Read: dataSourceAlicloudDBInstancesRead,
Schema: map[string]*schema.Schema{
"name_regex": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.ValidateRegexp,
},
"ids": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
"engine": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
string(MySQL),
string(SQLServer),
string(PPAS),
string(PostgreSQL),
string(MariaDB),
}, false),
},
"status": {
Type: schema.TypeString,
Optional: true,
// please follow the link below to see more details on available statusesplease follow the link below to see more details on available statuses
// https://help.aliyun.com/document_detail/26315.html
},
"db_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"Primary",
"Readonly",
"Guard",
"Temp",
}, false),
},
"vpc_id": {
Type: schema.TypeString,
Optional: true,
},
"vswitch_id": {
Type: schema.TypeString,
Optional: true,
},
"enable_details": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"connection_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"Standard",
"Safe",
}, false),
},
"tags": tagsSchema(),
"output_file": {
Type: schema.TypeString,
Optional: true,
},
"page_number": {
Type: schema.TypeInt,
Optional: true,
},
"page_size": {
Type: schema.TypeInt,
Optional: true,
Default: 100,
},
// Computed values
"names": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"instances": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"parameters": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"force_modify": {
Type: schema.TypeString,
Computed: true,
},
"checking_code": {
Type: schema.TypeString,
Computed: true,
},
"parameter_value": {
Type: schema.TypeString,
Computed: true,
},
"force_restart": {
Type: schema.TypeString,
Computed: true,
},
"parameter_name": {
Type: schema.TypeString,
Computed: true,
},
"parameter_description": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"charge_type": {
Type: schema.TypeString,
Computed: true,
},
"db_type": {
Type: schema.TypeString,
Computed: true,
},
"region_id": {
Type: schema.TypeString,
Computed: true,
},
"create_time": {
Type: schema.TypeString,
Computed: true,
},
"expire_time": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"engine": {
Type: schema.TypeString,
Computed: true,
},
"engine_version": {
Type: schema.TypeString,
Computed: true,
},
"net_type": {
Type: schema.TypeString,
Computed: true,
},
"connection_mode": {
Type: schema.TypeString,
Computed: true,
},
"instance_type": {
Type: schema.TypeString,
Computed: true,
},
"availability_zone": {
Type: schema.TypeString,
Computed: true,
},
"master_instance_id": {
Type: schema.TypeString,
Computed: true,
},
"guard_instance_id": {
Type: schema.TypeString,
Computed: true,
},
"temp_instance_id": {
Type: schema.TypeString,
Computed: true,
},
"readonly_instance_ids": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
"vpc_id": {
Type: schema.TypeString,
Computed: true,
},
"vswitch_id": {
Type: schema.TypeString,
Computed: true,
},
"connection_string": {
Type: schema.TypeString,
Computed: true,
},
"port": {
Type: schema.TypeString,
Computed: true,
},
"db_instance_storage_type": {
Type: schema.TypeString,
Computed: true,
},
"instance_storage": {
Type: schema.TypeInt,
Computed: true,
},
"master_zone": {
Type: schema.TypeString,
Computed: true,
},
"zone_id_slave_a": {
Type: schema.TypeString,
Computed: true,
},
"zone_id_slave_b": {
Type: schema.TypeString,
Computed: true,
},
"ssl_expire_time": {
Type: schema.TypeString,
Computed: true,
},
"require_update": {
Type: schema.TypeString,
Computed: true,
},
"acl": {
Type: schema.TypeString,
Computed: true,
},
"ca_type": {
Type: schema.TypeString,
Computed: true,
},
"client_ca_cert": {
Type: schema.TypeString,
Computed: true,
},
"client_ca_cert_expire_time": {
Type: schema.TypeString,
Computed: true,
},
"client_cert_revocation_list": {
Type: schema.TypeString,
Computed: true,
},
"last_modify_status": {
Type: schema.TypeString,
Computed: true,
},
"modify_status_reason": {
Type: schema.TypeString,
Computed: true,
},
"replication_acl": {
Type: schema.TypeString,
Computed: true,
},
"require_update_item": {
Type: schema.TypeString,
Computed: true,
},
"require_update_reason": {
Type: schema.TypeString,
Computed: true,
},
"ssl_create_time": {
Type: schema.TypeString,
Computed: true,
},
"ssl_enabled": {
Type: schema.TypeString,
Computed: true,
},
"server_ca_url": {
Type: schema.TypeString,
Computed: true,
},
"server_cert": {
Type: schema.TypeString,
Computed: true,
},
"server_key": {
Type: schema.TypeString,
Computed: true,
},
"creator": {
Type: schema.TypeString,
Computed: true,
},
"delete_date": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"encryption_key": {
Type: schema.TypeString,
Computed: true,
},
"encryption_key_status": {
Type: schema.TypeString,
Computed: true,
},
"key_usage": {
Type: schema.TypeString,
Computed: true,
},
"material_expire_time": {
Type: schema.TypeString,
Computed: true,
},
"origin": {
Type: schema.TypeString,
Computed: true,
},
"deletion_protection": {
Type: schema.TypeBool,
Computed: true,
},
"db_instance_type": {
Type: schema.TypeString,
Computed: true,
},
"ha_mode": {
Type: schema.TypeString,
Computed: true,
},
"sync_mode": {
Type: schema.TypeString,
Computed: true,
},
"host_instance_infos": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"log_sync_time": {
Type: schema.TypeString,
Computed: true,
},
"node_type": {
Type: schema.TypeString,
Computed: true,
},
"zone_id": {
Type: schema.TypeString,
Computed: true,
},
"sync_status": {
Type: schema.TypeString,
Computed: true,
},
"data_sync_time": {
Type: schema.TypeString,
Computed: true,
},
"node_id": {
Type: schema.TypeString,
Computed: true,
},
"region_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
"total_count": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}
func dataSourceAlicloudDBInstancesRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AliyunClient)
action := "DescribeDBInstances"
request := map[string]interface{}{
"RegionId": client.RegionId,
"SourceIp": client.SourceIp,
}
if v, ok := d.GetOk("page_number"); ok && v.(int) > 0 {
request["PageNumber"] = v.(int)
} else {
request["PageNumber"] = 1
}
if v, ok := d.GetOk("page_size"); ok && v.(int) > 0 {
request["PageSize"] = v.(int)
} else {
request["PageSize"] = PageSizeLarge
}
if v, ok := d.GetOk("engine"); ok && v.(string) != "" {
request["Engine"] = v.(string)
}
if v, ok := d.GetOk("status"); ok && v.(string) != "" {
request["DBInstanceStatus"] = v.(string)
}
if v, ok := d.GetOk("db_type"); ok && v.(string) != "" {
request["DBInstanceType"] = v.(string)
}
if v, ok := d.GetOk("vpc_id"); ok && v.(string) != "" {
request["VpcId"] = v.(string)
}
if v, ok := d.GetOk("vswitch_id"); ok && v.(string) != "" {
request["VSwitchId"] = v.(string)
}
if v, ok := d.GetOk("connection_mode"); ok && v.(string) != "" {
request["ConnectionMode"] = v.(string)
}
if v, ok := d.GetOk("tags"); ok {
tagsMap := v.(map[string]interface{})
bs, err := json.Marshal(tagsMap)
if err != nil {
return WrapError(err)
}
request["Tags"] = string(bs)
}
var response map[string]interface{}
var err error
var objects []interface{}
var nameRegex *regexp.Regexp
if v, ok := d.GetOk("name_regex"); ok {
r, err := regexp.Compile(v.(string))
if err != nil {
return WrapError(err)
}
nameRegex = r
}
// ids
idsMap := make(map[string]string)
if v, ok := d.GetOk("ids"); ok {
for _, vv := range v.([]interface{}) {
if vv == nil {
continue
}
idsMap[vv.(string)] = vv.(string)
}
}
for {
runtime := util.RuntimeOptions{}
runtime.SetAutoretry(true)
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Rds", "2014-08-15", 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, DataDefaultErrorMsg, "alicloud_db_instances", action, AlibabaCloudSdkGoERROR)
}
resp, err := jsonpath.Get("$.Items.DBInstance", response)
if err != nil {
return WrapErrorf(err, FailedGetAttributeMsg, action, "$.Items.DBInstance", response)
}
result, _ := resp.([]interface{})
if isPagingRequest(d) {
objects = result
break
}
for _, v := range result {
item := v.(map[string]interface{})
if nameRegex != nil {
if !nameRegex.MatchString(fmt.Sprint(item["DBInstanceDescription"])) {
continue
}
}
if len(idsMap) > 0 {
if _, ok := idsMap[fmt.Sprint(item["DBInstanceId"])]; !ok {
continue
}
}
objects = append(objects, item)
}
if len(result) < request["PageSize"].(int) {
break
}
request["PageNumber"] = request["PageNumber"].(int) + 1
}
return rdsInstancesDescription(d, meta, objects, formatInt(response["TotalRecordCount"]))
}
func rdsInstancesDescription(d *schema.ResourceData, meta interface{}, objects []interface{}, totalCount int) error {
client := meta.(*connectivity.AliyunClient)
rdsService := RdsService{client}
var ids []string
var names []string
var s []map[string]interface{}
for _, v := range objects {
item := v.(map[string]interface{})
readOnlyInstanceIDs := []string{}
for _, id := range item["ReadOnlyDBInstanceIds"].(map[string]interface{})["ReadOnlyDBInstanceId"].([]interface{}) {
readOnlyInstanceIDs = append(readOnlyInstanceIDs, fmt.Sprint(id.(map[string]interface{})["DBInstanceId"]))
}
instance, err := rdsService.DescribeDBInstance(fmt.Sprint(item["DBInstanceId"]))
if err != nil {
return WrapError(err)
}
mapping := map[string]interface{}{
"id": fmt.Sprint(item["DBInstanceId"]),
"name": fmt.Sprint(item["DBInstanceDescription"]),
"charge_type": fmt.Sprint(item["PayType"]),
"db_type": fmt.Sprint(item["DBInstanceType"]),
"region_id": fmt.Sprint(item["RegionId"]),
"create_time": fmt.Sprint(item["CreationTime"]),
"expire_time": fmt.Sprint(item["ExpireTime"]),
"status": fmt.Sprint(item["DBInstanceStatus"]),
"engine": fmt.Sprint(item["Engine"]),
"engine_version": fmt.Sprint(item["EngineVersion"]),
"net_type": fmt.Sprint(item["DBInstanceNetType"]),
"connection_mode": fmt.Sprint(item["ConnectionMode"]),
"instance_type": fmt.Sprint(item["DBInstanceClass"]),
"availability_zone": fmt.Sprint(item["ZoneId"]),
"master_instance_id": fmt.Sprint(item["MasterInstanceId"]),
"guard_instance_id": fmt.Sprint(item["GuardDBInstanceId"]),
"temp_instance_id": fmt.Sprint(item["TempDBInstanceId"]),
"readonly_instance_ids": readOnlyInstanceIDs,
"vpc_id": fmt.Sprint(item["VpcId"]),
"vswitch_id": fmt.Sprint(item["VSwitchId"]),
"connection_string": instance["ConnectionString"],
"port": instance["Port"],
"db_instance_storage_type": instance["DBInstanceStorageType"],
"instance_storage": instance["DBInstanceStorage"],
"master_zone": instance["MasterZone"],
"deletion_protection": instance["DeletionProtection"],
"db_instance_type": instance["DBInstanceType"],
}
sslResponse, sslErr := rdsService.DescribeDBInstanceSSL(fmt.Sprint(item["DBInstanceId"]))
if sslErr == nil {
if v, ok := sslResponse["SSLExpireTime"]; ok && v != "" {
mapping["ssl_expire_time"] = sslResponse["SSLExpireTime"]
}
if v, ok := sslResponse["RequireUpdate"]; ok && v != "" {
mapping["require_update"] = sslResponse["RequireUpdate"]
}
if v, ok := sslResponse["ACL"]; ok && v != "" {
mapping["acl"] = sslResponse["ACL"]
}
if v, ok := sslResponse["CAType"]; ok && v != "" {
mapping["ca_type"] = sslResponse["CAType"]
}
if v, ok := sslResponse["ClientCACert"]; ok && v != "" {
mapping["client_ca_cert"] = sslResponse["ClientCACert"]
}
if v, ok := sslResponse["ClientCACertExpireTime"]; ok && v != "" {
mapping["client_ca_cert_expire_time"] = sslResponse["ClientCACertExpireTime"]
}
if v, ok := sslResponse["ClientCertRevocationList"]; ok && v != "" {
mapping["client_cert_revocation_list"] = sslResponse["ClientCertRevocationList"]
}
if v, ok := sslResponse["LastModifyStatus"]; ok && v != "" {
mapping["last_modify_status"] = sslResponse["LastModifyStatus"]
}
if v, ok := sslResponse["ModifyStatusReason"]; ok && v != "" {
mapping["modify_status_reason"] = sslResponse["ModifyStatusReason"]
}
if v, ok := sslResponse["ReplicationACL"]; ok && v != "" {
mapping["replication_acl"] = sslResponse["ReplicationACL"]
}
if v, ok := sslResponse["RequireUpdateItem"]; ok && v != "" {
mapping["require_update_item"] = sslResponse["RequireUpdateItem"]
}
if v, ok := sslResponse["RequireUpdateReason"]; ok && v != "" {
mapping["require_update_reason"] = sslResponse["RequireUpdateReason"]
}
if v, ok := sslResponse["SSLCreateTime"]; ok && v != "" {
mapping["ssl_create_time"] = sslResponse["SSLCreateTime"]
}
if v, ok := sslResponse["SSLEnabled"]; ok && v != "" {
mapping["ssl_enabled"] = sslResponse["SSLEnabled"]
}
if v, ok := sslResponse["ServerCAUrl"]; ok && v != "" {
mapping["server_ca_url"] = sslResponse["ServerCAUrl"]
}
if v, ok := sslResponse["ServerCert"]; ok && v != "" {
mapping["server_cert"] = sslResponse["ServerCert"]
}
if v, ok := sslResponse["ServerKey"]; ok && v != "" {
mapping["server_key"] = sslResponse["ServerKey"]
}
}
encResponse, encError := rdsService.DescribeDBInstanceEncryptionKey(fmt.Sprint(item["DBInstanceId"]))
if encError == nil {
if v, ok := encResponse["Creator"]; ok && v != "" {
mapping["creator"] = encResponse["Creator"]
}
if v, ok := encResponse["DeleteDate"]; ok && v != "" {
mapping["delete_date"] = encResponse["DeleteDate"]
}
if v, ok := encResponse["Description"]; ok && v != "" {
mapping["description"] = encResponse["Description"]
}
if v, ok := encResponse["EncryptionKey"]; ok && v != "" {
mapping["encryption_key"] = encResponse["EncryptionKey"]
}
if v, ok := encResponse["EncryptionKeyStatus"]; ok && v != "" {
mapping["encryption_key_status"] = encResponse["EncryptionKeyStatus"]
}
if v, ok := encResponse["KeyUsage"]; ok && v != "" {
mapping["key_usage"] = encResponse["KeyUsage"]
}
if v, ok := encResponse["MaterialExpireTime"]; ok && v != "" {
mapping["material_expire_time"] = encResponse["MaterialExpireTime"]
}
if v, ok := encResponse["Origin"]; ok && v != "" {
mapping["origin"] = encResponse["Origin"]
}
}
slaveZones := instance["SlaveZones"].(map[string]interface{})["SlaveZone"].([]interface{})
if len(slaveZones) == 2 {
mapping["zone_id_slave_a"] = slaveZones[0].(map[string]interface{})["ZoneId"]
mapping["zone_id_slave_b"] = slaveZones[1].(map[string]interface{})["ZoneId"]
} else if len(slaveZones) == 1 {
mapping["zone_id_slave_a"] = slaveZones[0].(map[string]interface{})["ZoneId"]
}
if d.Get("enable_details").(bool) {
paramResponse, paramError := rdsService.DescribeParameterTemplates(item["DBInstanceId"].(string), item["Engine"].(string), item["EngineVersion"].(string))
if paramError == nil {
parameterDetail := make([]map[string]interface{}, 0)
for _, val := range paramResponse {
item := val.(map[string]interface{})
parameterDetail = append(parameterDetail, map[string]interface{}{
"force_modify": item["ForceModify"],
"checking_code": item["CheckingCode"],
"parameter_value": item["ParameterValue"],
"force_restart": item["ForceRestart"],
"parameter_name": item["ParameterName"],
"parameter_description": item["ParameterDescription"],
})
}
mapping["parameters"] = parameterDetail
}
}
describeDBInstanceHAConfigObject, haError := rdsService.DescribeDBInstanceHAConfig(item["DBInstanceId"].(string))
if haError == nil {
if v, ok := describeDBInstanceHAConfigObject["HAMode"]; ok && v != "" {
mapping["ha_mode"] = describeDBInstanceHAConfigObject["HAMode"]
}
if v, ok := describeDBInstanceHAConfigObject["SyncMode"]; ok && v != "" {
mapping["sync_mode"] = describeDBInstanceHAConfigObject["SyncMode"]
}
hostInstanceInfoDetail := make([]map[string]interface{}, 0)
hostInstanceInfos := describeDBInstanceHAConfigObject["HostInstanceInfos"].(map[string]interface{})["NodeInfo"].([]interface{})
for _, val := range hostInstanceInfos {
item := val.(map[string]interface{})
hostInstanceInfoDetail = append(hostInstanceInfoDetail, map[string]interface{}{
"log_sync_time": item["LogSyncTime"],
"node_type": item["NodeType"],
"zone_id": item["ZoneId"],
"sync_status": item["SyncStatus"],
"data_sync_time": item["DataSyncTime"],
"node_id": item["NodeId"],
"region_id": item["RegionId"],
})
}
mapping["host_instance_infos"] = hostInstanceInfoDetail
}
ids = append(ids, fmt.Sprint(item["DBInstanceId"]))
names = append(names, fmt.Sprint(item["DBInstanceDescription"]))
s = append(s, mapping)
}
d.SetId(dataResourceIdHash(ids))
if err := d.Set("instances", s); err != nil {
return WrapError(err)
}
if err := d.Set("ids", ids); err != nil {
return WrapError(err)
}
if err := d.Set("names", names); err != nil {
return WrapError(err)
}
if err := d.Set("total_count", totalCount); err != nil {
return WrapError(err)
}
// create a json file in current directory and write data source to it
if output, ok := d.GetOk("output_file"); ok && output.(string) != "" {
writeToFile(output.(string), s)
}
return nil
}