alicloud/resource_alicloud_mongodb_replica_set_role.go (171 lines of code) (raw):
package alicloud
import (
"fmt"
"strconv"
"strings"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/samber/lo"
)
func resourceAlicloudMongoDBReplicaSetRole() *schema.Resource {
return &schema.Resource{
Create: resourceAlicloudMongoDBReplicaSetRoleCreate,
Read: resourceAlicloudMongoDBReplicaSetRoleRead,
Update: resourceAlicloudMongoDBReplicaSetRoleUpdate,
Delete: resourceAlicloudMongoDBReplicaSetRoleDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"db_instance_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"role_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"connection_prefix": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"connection_port": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: IntBetween(1000, 65535),
},
"network_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: StringInSlice([]string{
"Public",
"VPC",
// "Classic",
}, false),
},
"replica_set_role": {
Type: schema.TypeString,
Computed: true,
},
"connection_domain": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func makeKeyOfMongoReplica(instanceId, networkType, roleId string) string {
return fmt.Sprintf("%s:%s:%s", instanceId, networkType, roleId)
}
func parseKeyOfMongoReplica(key string) (instanceId, networkType, roleId string) {
parts := strings.Split(key, ":")
return parts[0], parts[1], parts[2]
}
func makeSecondaryIndexOfMongoReplica(roleId, networkType string) string {
return fmt.Sprintf("%s:%s", roleId, networkType)
}
func resourceAlicloudMongoDBReplicaSetRoleCreate(d *schema.ResourceData, meta interface{}) error {
return resourceAlicloudMongoDBReplicaSetRoleUpdate(d, meta)
}
func resourceAlicloudMongoDBReplicaSetRoleUpdate(d *schema.ResourceData, meta interface{}) error {
instanceId := d.Get("db_instance_id").(string)
client := meta.(*connectivity.AliyunClient)
ddsService := MongoDBService{client}
replicaSetsObjects, err := ddsService.DescribeReplicaSetRole(instanceId)
if err != nil {
return WrapError(err)
}
replicaSets := transferToMongoReplicaSets(replicaSetsObjects, false)
replicasGroupByRoleIdAndNetworkType := lo.FilterSliceToMap(replicaSets, func(replica map[string]interface{}) (string, map[string]interface{}, bool) {
roleID, roleIdOk := replica["role_id"]
networkType, networkTypeOk := replica["network_type"]
if roleIdOk && networkTypeOk {
return makeSecondaryIndexOfMongoReplica(roleID.(string), networkType.(string)), replica, true
}
return "", replica, false
})
roleId := d.Get("role_id").(string)
networkType := d.Get("network_type").(string)
replica, ok := replicasGroupByRoleIdAndNetworkType[makeSecondaryIndexOfMongoReplica(roleId, networkType)]
if !ok {
return WrapError(fmt.Errorf("connection address not found, roleId: %s, network type: %s", roleId, networkType))
}
d.SetId(makeKeyOfMongoReplica(instanceId, networkType, roleId))
currentConnectionDomain, ok := replica["connection_domain"]
if !ok {
// though should not happen.
return WrapError(fmt.Errorf("current connection domain not found, roleId: %s, network type: %s", roleId, networkType))
}
currentConnectionPort, ok := replica["connection_port"]
if !ok {
// though should not happen.
return WrapError(fmt.Errorf("current connection port not found, roleId: %s, network type: %s", roleId, networkType))
}
connectionChanged := false
newConnectionPrefix := getPrefixOfConnectionDomain(currentConnectionDomain.(string))
newPort := currentConnectionPort.(string)
if d.HasChange("connection_prefix") {
if connectionPrefix, ok := d.GetOk("connection_prefix"); ok && connectionPrefix.(string) != newConnectionPrefix {
newConnectionPrefix = connectionPrefix.(string)
connectionChanged = true
}
}
if d.HasChange("connection_port") {
if connectionPort, ok := d.GetOk("connection_port"); ok && fmt.Sprint(connectionPort) != newPort {
newPort = fmt.Sprint(connectionPort)
connectionChanged = true
}
}
if connectionChanged {
err = ddsService.ModifyDBInstanceConnectionString(d, instanceId, currentConnectionDomain.(string), newConnectionPrefix, newPort)
if err != nil {
return WrapError(err)
}
}
return resourceAlicloudMongoDBReplicaSetRoleRead(d, meta)
}
func resourceAlicloudMongoDBReplicaSetRoleRead(d *schema.ResourceData, meta interface{}) error {
instanceId, networkType, roleId := parseKeyOfMongoReplica(d.Id())
client := meta.(*connectivity.AliyunClient)
ddsService := MongoDBService{client}
replicaSetsObjects, err := ddsService.DescribeReplicaSetRole(instanceId)
if err != nil {
return WrapError(err)
}
replicaSets := transferToMongoReplicaSets(replicaSetsObjects, false)
replicasGroupByRoleIdAndNetworkType := lo.FilterSliceToMap(replicaSets, func(replica map[string]interface{}) (string, map[string]interface{}, bool) {
roleID, roleIdOk := replica["role_id"]
networkType, networkTypeOk := replica["network_type"]
if roleIdOk && networkTypeOk {
return makeSecondaryIndexOfMongoReplica(roleID.(string), networkType.(string)), replica, true
}
return "", replica, false
})
d.Set("db_instance_id", instanceId)
d.Set("network_type", networkType)
d.Set("role_id", roleId)
replica, ok := replicasGroupByRoleIdAndNetworkType[makeSecondaryIndexOfMongoReplica(roleId, networkType)]
if !ok {
return WrapError(fmt.Errorf("connection address not found, roleId: %s, network type: %s", roleId, networkType))
}
if connectionDomain, ok := replica["connection_domain"]; ok {
d.Set("connection_domain", connectionDomain)
d.Set("connection_prefix", getPrefixOfConnectionDomain(connectionDomain.(string)))
}
if connectionPort, ok := replica["connection_port"]; ok {
port, err := strconv.Atoi(fmt.Sprint(connectionPort))
if err != nil {
return WrapError(err)
}
d.Set("connection_port", port)
}
if replicaSetRole, ok := replica["replica_set_role"]; ok {
d.Set("replica_set_role", replicaSetRole)
}
return nil
}
func resourceAlicloudMongoDBReplicaSetRoleDelete(d *schema.ResourceData, meta interface{}) error {
// dont do anything.
return nil
}