github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/alicloud/resource_alicloud_ess_scalingconfiguration.go (about)

     1  package alicloud
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/denverdino/aliyungo/common"
     6  	"github.com/denverdino/aliyungo/ecs"
     7  	"github.com/denverdino/aliyungo/ess"
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  func resourceAlicloudEssScalingConfiguration() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceAliyunEssScalingConfigurationCreate,
    17  		Read:   resourceAliyunEssScalingConfigurationRead,
    18  		Update: resourceAliyunEssScalingConfigurationUpdate,
    19  		Delete: resourceAliyunEssScalingConfigurationDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"active": &schema.Schema{
    23  				Type:     schema.TypeBool,
    24  				Optional: true,
    25  				Computed: true,
    26  			},
    27  			"enable": &schema.Schema{
    28  				Type:     schema.TypeBool,
    29  				Optional: true,
    30  			},
    31  			"scaling_group_id": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				ForceNew: true,
    34  				Required: true,
    35  			},
    36  			"image_id": &schema.Schema{
    37  				Type:     schema.TypeString,
    38  				ForceNew: true,
    39  				Required: true,
    40  			},
    41  			"instance_type": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				ForceNew: true,
    44  				Required: true,
    45  			},
    46  			"io_optimized": &schema.Schema{
    47  				Type:         schema.TypeString,
    48  				Required:     true,
    49  				ForceNew:     true,
    50  				ValidateFunc: validateIoOptimized,
    51  			},
    52  			"security_group_id": &schema.Schema{
    53  				Type:     schema.TypeString,
    54  				ForceNew: true,
    55  				Required: true,
    56  			},
    57  			"scaling_configuration_name": &schema.Schema{
    58  				Type:     schema.TypeString,
    59  				Optional: true,
    60  				Computed: true,
    61  			},
    62  			"internet_charge_type": &schema.Schema{
    63  				Type:         schema.TypeString,
    64  				ForceNew:     true,
    65  				Optional:     true,
    66  				Computed:     true,
    67  				ValidateFunc: validateInternetChargeType,
    68  			},
    69  			"internet_max_bandwidth_in": &schema.Schema{
    70  				Type:     schema.TypeInt,
    71  				Optional: true,
    72  				ForceNew: true,
    73  				Computed: true,
    74  			},
    75  			"internet_max_bandwidth_out": &schema.Schema{
    76  				Type:         schema.TypeInt,
    77  				Optional:     true,
    78  				ForceNew:     true,
    79  				ValidateFunc: validateInternetMaxBandWidthOut,
    80  			},
    81  			"system_disk_category": &schema.Schema{
    82  				Type:     schema.TypeString,
    83  				Optional: true,
    84  				ForceNew: true,
    85  				Computed: true,
    86  				ValidateFunc: validateAllowedStringValue([]string{
    87  					string(ecs.DiskCategoryCloud),
    88  					string(ecs.DiskCategoryCloudSSD),
    89  					string(ecs.DiskCategoryCloudEfficiency),
    90  					string(ecs.DiskCategoryEphemeralSSD),
    91  				}),
    92  			},
    93  			"data_disk": &schema.Schema{
    94  				Optional: true,
    95  				ForceNew: true,
    96  				Type:     schema.TypeList,
    97  				Elem: &schema.Resource{
    98  					Schema: map[string]*schema.Schema{
    99  						"size": &schema.Schema{
   100  							Type:     schema.TypeInt,
   101  							Optional: true,
   102  						},
   103  						"category": &schema.Schema{
   104  							Type:     schema.TypeString,
   105  							Optional: true,
   106  						},
   107  						"snapshot_id": &schema.Schema{
   108  							Type:     schema.TypeString,
   109  							Optional: true,
   110  						},
   111  						"device": &schema.Schema{
   112  							Type:     schema.TypeString,
   113  							Optional: true,
   114  						},
   115  					},
   116  				},
   117  			},
   118  			"instance_ids": &schema.Schema{
   119  				Type:     schema.TypeList,
   120  				Elem:     &schema.Schema{Type: schema.TypeString},
   121  				Optional: true,
   122  				MaxItems: 20,
   123  			},
   124  		},
   125  	}
   126  }
   127  
   128  func resourceAliyunEssScalingConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
   129  
   130  	args, err := buildAlicloudEssScalingConfigurationArgs(d, meta)
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	essconn := meta.(*AliyunClient).essconn
   136  
   137  	scaling, err := essconn.CreateScalingConfiguration(args)
   138  	if err != nil {
   139  		return err
   140  	}
   141  
   142  	d.SetId(d.Get("scaling_group_id").(string) + COLON_SEPARATED + scaling.ScalingConfigurationId)
   143  
   144  	return resourceAliyunEssScalingConfigurationUpdate(d, meta)
   145  }
   146  
   147  func resourceAliyunEssScalingConfigurationUpdate(d *schema.ResourceData, meta interface{}) error {
   148  	client := meta.(*AliyunClient)
   149  	if d.HasChange("active") {
   150  		active := d.Get("active").(bool)
   151  		if !active {
   152  			return fmt.Errorf("Please active the scaling configuration directly.")
   153  		}
   154  		ids := strings.Split(d.Id(), COLON_SEPARATED)
   155  		err := client.ActiveScalingConfigurationById(ids[0], ids[1])
   156  
   157  		if err != nil {
   158  			return fmt.Errorf("Active scaling configuration %s err: %#v", ids[1], err)
   159  		}
   160  	}
   161  
   162  	if err := enableEssScalingConfiguration(d, meta); err != nil {
   163  		return err
   164  	}
   165  
   166  	return resourceAliyunEssScalingConfigurationRead(d, meta)
   167  }
   168  
   169  func enableEssScalingConfiguration(d *schema.ResourceData, meta interface{}) error {
   170  	client := meta.(*AliyunClient)
   171  	ids := strings.Split(d.Id(), COLON_SEPARATED)
   172  
   173  	if d.HasChange("enable") {
   174  		d.SetPartial("enable")
   175  		enable := d.Get("enable").(bool)
   176  		if !enable {
   177  			err := client.DisableScalingConfigurationById(ids[0])
   178  
   179  			if err != nil {
   180  				return fmt.Errorf("Disable scaling group %s err: %#v", ids[0], err)
   181  			}
   182  		}
   183  
   184  		instance_ids := []string{}
   185  		if d.HasChange("instance_ids") {
   186  			d.SetPartial("instance_ids")
   187  			instances := d.Get("instance_ids").([]interface{})
   188  			instance_ids = expandStringList(instances)
   189  		}
   190  		err := client.EnableScalingConfigurationById(ids[0], ids[1], instance_ids)
   191  
   192  		if err != nil {
   193  			return fmt.Errorf("Enable scaling configuration %s err: %#v", ids[1], err)
   194  		}
   195  	}
   196  	return nil
   197  }
   198  
   199  func resourceAliyunEssScalingConfigurationRead(d *schema.ResourceData, meta interface{}) error {
   200  
   201  	client := meta.(*AliyunClient)
   202  	ids := strings.Split(d.Id(), COLON_SEPARATED)
   203  	c, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
   204  	if err != nil {
   205  		if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
   206  			d.SetId("")
   207  			return nil
   208  		}
   209  		return fmt.Errorf("Error Describe ESS scaling configuration Attribute: %#v", err)
   210  	}
   211  
   212  	d.Set("scaling_group_id", c.ScalingGroupId)
   213  	d.Set("active", c.LifecycleState == ess.Active)
   214  	d.Set("image_id", c.ImageId)
   215  	d.Set("instance_type", c.InstanceType)
   216  	d.Set("io_optimized", c.IoOptimized)
   217  	d.Set("security_group_id", c.SecurityGroupId)
   218  	d.Set("scaling_configuration_name", c.ScalingConfigurationName)
   219  	d.Set("internet_charge_type", c.InternetChargeType)
   220  	d.Set("internet_max_bandwidth_in", c.InternetMaxBandwidthIn)
   221  	d.Set("internet_max_bandwidth_out", c.InternetMaxBandwidthOut)
   222  	d.Set("system_disk_category", c.SystemDiskCategory)
   223  	d.Set("data_disk", flattenDataDiskMappings(c.DataDisks.DataDisk))
   224  
   225  	return nil
   226  }
   227  
   228  func resourceAliyunEssScalingConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
   229  	client := meta.(*AliyunClient)
   230  
   231  	return resource.Retry(5*time.Minute, func() *resource.RetryError {
   232  		ids := strings.Split(d.Id(), COLON_SEPARATED)
   233  		err := client.DeleteScalingConfigurationById(ids[0], ids[1])
   234  
   235  		if err != nil {
   236  			e, _ := err.(*common.Error)
   237  			if e.ErrorResponse.Code == IncorrectScalingConfigurationLifecycleState {
   238  				return resource.NonRetryableError(
   239  					fmt.Errorf("Scaling configuration is active - please active another one and trying again."))
   240  			}
   241  			if e.ErrorResponse.Code != InvalidScalingGroupIdNotFound {
   242  				return resource.RetryableError(
   243  					fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
   244  			}
   245  		}
   246  
   247  		_, err = client.DescribeScalingConfigurationById(ids[0], ids[1])
   248  		if err != nil {
   249  			if notFoundError(err) {
   250  				return nil
   251  			}
   252  			return resource.NonRetryableError(err)
   253  		}
   254  
   255  		return resource.RetryableError(
   256  			fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
   257  	})
   258  }
   259  
   260  func buildAlicloudEssScalingConfigurationArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingConfigurationArgs, error) {
   261  	args := &ess.CreateScalingConfigurationArgs{
   262  		ScalingGroupId:  d.Get("scaling_group_id").(string),
   263  		ImageId:         d.Get("image_id").(string),
   264  		InstanceType:    d.Get("instance_type").(string),
   265  		IoOptimized:     ecs.IoOptimized(d.Get("io_optimized").(string)),
   266  		SecurityGroupId: d.Get("security_group_id").(string),
   267  	}
   268  
   269  	if v := d.Get("scaling_configuration_name").(string); v != "" {
   270  		args.ScalingConfigurationName = v
   271  	}
   272  
   273  	if v := d.Get("internet_charge_type").(string); v != "" {
   274  		args.InternetChargeType = common.InternetChargeType(v)
   275  	}
   276  
   277  	if v := d.Get("internet_max_bandwidth_in").(int); v != 0 {
   278  		args.InternetMaxBandwidthIn = v
   279  	}
   280  
   281  	if v := d.Get("internet_max_bandwidth_out").(int); v != 0 {
   282  		args.InternetMaxBandwidthOut = v
   283  	}
   284  
   285  	if v := d.Get("system_disk_category").(string); v != "" {
   286  		args.SystemDisk_Category = common.UnderlineString(v)
   287  	}
   288  
   289  	dds, ok := d.GetOk("data_disk")
   290  	if ok {
   291  		disks := dds.([]interface{})
   292  		diskTypes := []ess.DataDiskType{}
   293  
   294  		for _, e := range disks {
   295  			pack := e.(map[string]interface{})
   296  			disk := ess.DataDiskType{
   297  				Size:       pack["size"].(int),
   298  				Category:   pack["category"].(string),
   299  				SnapshotId: pack["snapshot_id"].(string),
   300  				Device:     pack["device"].(string),
   301  			}
   302  			if v := pack["size"].(int); v != 0 {
   303  				disk.Size = v
   304  			}
   305  			if v := pack["category"].(string); v != "" {
   306  				disk.Category = v
   307  			}
   308  			if v := pack["snapshot_id"].(string); v != "" {
   309  				disk.SnapshotId = v
   310  			}
   311  			if v := pack["device"].(string); v != "" {
   312  				disk.Device = v
   313  			}
   314  			diskTypes = append(diskTypes, disk)
   315  		}
   316  		args.DataDisk = diskTypes
   317  	}
   318  
   319  	return args, nil
   320  }