321 lines
8.9 KiB
Go
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
|
||
|
}
|