blob: d2dc9310c5cc4a24a9f0f3c40215d71c5b78c115 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package sql
import (
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
sqladmin "google.golang.org/api/sqladmin/v1beta4"
)
func DataSourceSqlDatabaseInstances() *schema.Resource {
return &schema.Resource{
Read: dataSourceSqlDatabaseInstancesRead,
Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Optional: true,
Description: `Project ID of the project that contains the instances.`,
},
"database_version": {
Type: schema.TypeString,
Optional: true,
Description: `To filter out the database instances which are of the specified database version.`,
},
"region": {
Type: schema.TypeString,
Optional: true,
Description: `To filter out the database instances which are located in this specified region.`,
},
"zone": {
Type: schema.TypeString,
Optional: true,
Description: `To filter out the database instances which are located in this specified zone.`,
},
"tier": {
Type: schema.TypeString,
Optional: true,
Description: `To filter out the database instances based on the machine type.`,
},
"state": {
Type: schema.TypeString,
Optional: true,
Description: `To filter out the database instances based on the current state of the database instance, valid values include : "SQL_INSTANCE_STATE_UNSPECIFIED", "RUNNABLE", "SUSPENDED", "PENDING_DELETE", "PENDING_CREATE", "MAINTENANCE" and "FAILED".`,
},
"instances": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: tpgresource.DatasourceSchemaFromResourceSchema(ResourceSqlDatabaseInstance().Schema),
},
},
},
}
}
func dataSourceSqlDatabaseInstancesRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
project, err := tpgresource.GetProject(d, config)
if err != nil {
return err
}
filter := ""
if v, ok := d.GetOk("database_version"); ok {
filter += fmt.Sprintf("databaseVersion:%s", v.(string))
}
if v, ok := d.GetOk("region"); ok {
if filter != "" {
filter += " AND "
}
filter += fmt.Sprintf("region:%s", v.(string))
}
if v, ok := d.GetOk("zone"); ok {
if filter != "" {
filter += " AND "
}
filter += fmt.Sprintf("gceZone:%s", v.(string))
}
if v, ok := d.GetOk("tier"); ok {
if filter != "" {
filter += " AND "
}
filter += fmt.Sprintf("settings.tier:%s", v.(string))
}
if v, ok := d.GetOk("state"); ok {
if filter != "" {
filter += " AND "
}
filter += fmt.Sprintf("state:%s", v.(string))
}
pageToken := ""
databaseInstances := make([]map[string]interface{}, 0)
for {
var instances *sqladmin.InstancesListResponse
err = transport_tpg.Retry(transport_tpg.RetryOptions{
RetryFunc: func() (rerr error) {
instances, rerr = config.NewSqlAdminClient(userAgent).Instances.List(project).Filter(filter).PageToken(pageToken).Do()
return rerr
},
Timeout: d.Timeout(schema.TimeoutRead),
ErrorRetryPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.IsSqlOperationInProgressError},
})
if err != nil {
return err
}
pageInstances := flattenDatasourceGoogleDatabaseInstancesList(instances.Items, project, d)
databaseInstances = append(databaseInstances, pageInstances...)
pageToken = instances.NextPageToken
if pageToken == "" {
break
}
}
if err := d.Set("instances", databaseInstances); err != nil {
return fmt.Errorf("Error retrieving instances: %s", err)
}
d.SetId(fmt.Sprintf("database_instances_ds/%s/%s/%s/%s/%s/%s", project, d.Get("database_version").(string), d.Get("region").(string), d.Get("zone").(string), d.Get("tier").(string), d.Get("state").(string)))
return nil
}
func flattenDatasourceGoogleDatabaseInstancesList(fetchedInstances []*sqladmin.DatabaseInstance, project string, d *schema.ResourceData) []map[string]interface{} {
if fetchedInstances == nil {
return make([]map[string]interface{}, 0)
}
instances := make([]map[string]interface{}, 0, len(fetchedInstances))
for _, rawInstance := range fetchedInstances {
instance := make(map[string]interface{})
instance["name"] = rawInstance.Name
instance["region"] = rawInstance.Region
instance["database_version"] = rawInstance.DatabaseVersion
instance["connection_name"] = rawInstance.ConnectionName
instance["maintenance_version"] = rawInstance.MaintenanceVersion
instance["available_maintenance_versions"] = rawInstance.AvailableMaintenanceVersions
instance["instance_type"] = rawInstance.InstanceType
instance["service_account_email_address"] = rawInstance.ServiceAccountEmailAddress
instance["settings"] = flattenSettings(rawInstance.Settings, d)
if rawInstance.DiskEncryptionConfiguration != nil {
instance["encryption_key_name"] = rawInstance.DiskEncryptionConfiguration.KmsKeyName
}
instance["replica_configuration"] = flattenReplicaConfigurationforDataSource(rawInstance.ReplicaConfiguration)
ipAddresses := flattenIpAddresses(rawInstance.IpAddresses)
instance["ip_address"] = ipAddresses
if len(ipAddresses) > 0 {
instance["first_ip_address"] = ipAddresses[0]["ip_address"]
}
publicIpAddress := ""
privateIpAddress := ""
for _, ip := range rawInstance.IpAddresses {
if publicIpAddress == "" && ip.Type == "PRIMARY" {
publicIpAddress = ip.IpAddress
}
if privateIpAddress == "" && ip.Type == "PRIVATE" {
privateIpAddress = ip.IpAddress
}
}
instance["public_ip_address"] = publicIpAddress
instance["private_ip_address"] = privateIpAddress
instance["server_ca_cert"] = flattenServerCaCerts([]*sqladmin.SslCert{rawInstance.ServerCaCert})
instance["master_instance_name"] = strings.TrimPrefix(rawInstance.MasterInstanceName, project+":")
instance["project"] = project
instance["self_link"] = rawInstance.SelfLink
instances = append(instances, instance)
}
return instances
}
func flattenReplicaConfigurationforDataSource(replicaConfiguration *sqladmin.ReplicaConfiguration) []map[string]interface{} {
rc := []map[string]interface{}{}
if replicaConfiguration != nil {
data := map[string]interface{}{
"failover_target": replicaConfiguration.FailoverTarget,
// Don't attempt to assign anything from replicaConfiguration.MysqlReplicaConfiguration,
// since those fields are set on create and then not stored. Hence, those fields are not shown.
}
rc = append(rc, data)
}
return rc
}