terraform/builtin/providers/alicloud/resource_alicloud_ess_scali...

321 lines
8.9 KiB
Go

package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"strings"
"time"
)
func resourceAlicloudEssScalingConfiguration() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunEssScalingConfigurationCreate,
Read: resourceAliyunEssScalingConfigurationRead,
Update: resourceAliyunEssScalingConfigurationUpdate,
Delete: resourceAliyunEssScalingConfigurationDelete,
Schema: map[string]*schema.Schema{
"active": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"enable": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"scaling_group_id": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"image_id": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"instance_type": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"io_optimized": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateIoOptimized,
},
"security_group_id": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"scaling_configuration_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"internet_charge_type": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Computed: true,
ValidateFunc: validateInternetChargeType,
},
"internet_max_bandwidth_in": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Computed: true,
},
"internet_max_bandwidth_out": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
ValidateFunc: validateInternetMaxBandWidthOut,
},
"system_disk_category": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: validateAllowedStringValue([]string{
string(ecs.DiskCategoryCloud),
string(ecs.DiskCategoryCloudSSD),
string(ecs.DiskCategoryCloudEfficiency),
string(ecs.DiskCategoryEphemeralSSD),
}),
},
"data_disk": &schema.Schema{
Optional: true,
ForceNew: true,
Type: schema.TypeList,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"size": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
"category": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"snapshot_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"device": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
},
},
"instance_ids": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
MaxItems: 20,
},
},
}
}
func resourceAliyunEssScalingConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
args, err := buildAlicloudEssScalingConfigurationArgs(d, meta)
if err != nil {
return err
}
essconn := meta.(*AliyunClient).essconn
scaling, err := essconn.CreateScalingConfiguration(args)
if err != nil {
return err
}
d.SetId(d.Get("scaling_group_id").(string) + COLON_SEPARATED + scaling.ScalingConfigurationId)
return resourceAliyunEssScalingConfigurationUpdate(d, meta)
}
func resourceAliyunEssScalingConfigurationUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
if d.HasChange("active") {
active := d.Get("active").(bool)
if !active {
return fmt.Errorf("Please active the scaling configuration directly.")
}
ids := strings.Split(d.Id(), COLON_SEPARATED)
err := client.ActiveScalingConfigurationById(ids[0], ids[1])
if err != nil {
return fmt.Errorf("Active scaling configuration %s err: %#v", ids[1], err)
}
}
if err := enableEssScalingConfiguration(d, meta); err != nil {
return err
}
return resourceAliyunEssScalingConfigurationRead(d, meta)
}
func enableEssScalingConfiguration(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ids := strings.Split(d.Id(), COLON_SEPARATED)
if d.HasChange("enable") {
d.SetPartial("enable")
enable := d.Get("enable").(bool)
if !enable {
err := client.DisableScalingConfigurationById(ids[0])
if err != nil {
return fmt.Errorf("Disable scaling group %s err: %#v", ids[0], err)
}
}
instance_ids := []string{}
if d.HasChange("instance_ids") {
d.SetPartial("instance_ids")
instances := d.Get("instance_ids").([]interface{})
instance_ids = expandStringList(instances)
}
err := client.EnableScalingConfigurationById(ids[0], ids[1], instance_ids)
if err != nil {
return fmt.Errorf("Enable scaling configuration %s err: %#v", ids[1], err)
}
}
return nil
}
func resourceAliyunEssScalingConfigurationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ids := strings.Split(d.Id(), COLON_SEPARATED)
c, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
if err != nil {
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
d.SetId("")
return nil
}
return fmt.Errorf("Error Describe ESS scaling configuration Attribute: %#v", err)
}
d.Set("scaling_group_id", c.ScalingGroupId)
d.Set("active", c.LifecycleState == ess.Active)
d.Set("image_id", c.ImageId)
d.Set("instance_type", c.InstanceType)
d.Set("io_optimized", c.IoOptimized)
d.Set("security_group_id", c.SecurityGroupId)
d.Set("scaling_configuration_name", c.ScalingConfigurationName)
d.Set("internet_charge_type", c.InternetChargeType)
d.Set("internet_max_bandwidth_in", c.InternetMaxBandwidthIn)
d.Set("internet_max_bandwidth_out", c.InternetMaxBandwidthOut)
d.Set("system_disk_category", c.SystemDiskCategory)
d.Set("data_disk", flattenDataDiskMappings(c.DataDisks.DataDisk))
return nil
}
func resourceAliyunEssScalingConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
return resource.Retry(5*time.Minute, func() *resource.RetryError {
ids := strings.Split(d.Id(), COLON_SEPARATED)
err := client.DeleteScalingConfigurationById(ids[0], ids[1])
if err != nil {
e, _ := err.(*common.Error)
if e.ErrorResponse.Code == IncorrectScalingConfigurationLifecycleState {
return resource.NonRetryableError(
fmt.Errorf("Scaling configuration is active - please active another one and trying again."))
}
if e.ErrorResponse.Code != InvalidScalingGroupIdNotFound {
return resource.RetryableError(
fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
}
}
_, err = client.DescribeScalingConfigurationById(ids[0], ids[1])
if err != nil {
if notFoundError(err) {
return nil
}
return resource.NonRetryableError(err)
}
return resource.RetryableError(
fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
})
}
func buildAlicloudEssScalingConfigurationArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingConfigurationArgs, error) {
args := &ess.CreateScalingConfigurationArgs{
ScalingGroupId: d.Get("scaling_group_id").(string),
ImageId: d.Get("image_id").(string),
InstanceType: d.Get("instance_type").(string),
IoOptimized: ecs.IoOptimized(d.Get("io_optimized").(string)),
SecurityGroupId: d.Get("security_group_id").(string),
}
if v := d.Get("scaling_configuration_name").(string); v != "" {
args.ScalingConfigurationName = v
}
if v := d.Get("internet_charge_type").(string); v != "" {
args.InternetChargeType = common.InternetChargeType(v)
}
if v := d.Get("internet_max_bandwidth_in").(int); v != 0 {
args.InternetMaxBandwidthIn = v
}
if v := d.Get("internet_max_bandwidth_out").(int); v != 0 {
args.InternetMaxBandwidthOut = v
}
if v := d.Get("system_disk_category").(string); v != "" {
args.SystemDisk_Category = common.UnderlineString(v)
}
dds, ok := d.GetOk("data_disk")
if ok {
disks := dds.([]interface{})
diskTypes := []ess.DataDiskType{}
for _, e := range disks {
pack := e.(map[string]interface{})
disk := ess.DataDiskType{
Size: pack["size"].(int),
Category: pack["category"].(string),
SnapshotId: pack["snapshot_id"].(string),
Device: pack["device"].(string),
}
if v := pack["size"].(int); v != 0 {
disk.Size = v
}
if v := pack["category"].(string); v != "" {
disk.Category = v
}
if v := pack["snapshot_id"].(string); v != "" {
disk.SnapshotId = v
}
if v := pack["device"].(string); v != "" {
disk.Device = v
}
diskTypes = append(diskTypes, disk)
}
args.DataDisk = diskTypes
}
return args, nil
}