Skip to content

Commit

Permalink
resource/alicloud_ess_scaling_rule: support PredictiveScalingRule and…
Browse files Browse the repository at this point in the history
… add attributes of predictive_scaling_mode, initial_max_size, predictive_value_behavior, predictive_value_buffer, predictive_task_buffer_time
  • Loading branch information
fuliu-zln committed Apr 18, 2024
1 parent 1857165 commit d21a291
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 1 deletion.
1 change: 1 addition & 0 deletions alicloud/extension_ess.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
SimpleScalingRule = ScalingRuleType("SimpleScalingRule")
TargetTrackingScalingRule = ScalingRuleType("TargetTrackingScalingRule")
StepScalingRule = ScalingRuleType("StepScalingRule")
PredictiveScalingRule = ScalingRuleType("PredictiveScalingRule")
)

type BatchSize int
Expand Down
94 changes: 94 additions & 0 deletions alicloud/resource_alicloud_ess_scaling_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func resourceAlicloudEssScalingRule() *schema.Resource {
string(SimpleScalingRule),
string(TargetTrackingScalingRule),
string(StepScalingRule),
string(PredictiveScalingRule),
}, false),
},
"estimated_instance_warmup": {
Expand Down Expand Up @@ -92,6 +93,42 @@ func resourceAlicloudEssScalingRule() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"predictive_scaling_mode": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{
"PredictOnly",
"PredictAndScale",
}, false),
},
"initial_max_size": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"predictive_value_behavior": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{
"MaxOverridePredictiveValue",
"PredictiveValueOverrideMax",
"PredictiveValueOverrideMaxWithBuffer",
}, false),
},
"predictive_value_buffer": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: IntBetween(0, 100),
},
"predictive_task_buffer_time": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ValidateFunc: IntBetween(0, 60),
},
"target_value": {
Type: schema.TypeFloat,
Optional: true,
Expand Down Expand Up @@ -202,6 +239,11 @@ func resourceAliyunEssScalingRuleRead(d *schema.ResourceData, meta interface{})
d.Set("scale_out_evaluation_count", object.ScaleOutEvaluationCount)
d.Set("min_adjustment_magnitude", object.MinAdjustmentMagnitude)
d.Set("metric_name", object.MetricName)
d.Set("predictive_scaling_mode", object.PredictiveScalingMode)
d.Set("initial_max_size", object.InitialMaxSize)
d.Set("predictive_value_behavior", object.PredictiveValueBehavior)
d.Set("predictive_value_buffer", object.PredictiveValueBuffer)
d.Set("predictive_task_buffer_time", object.PredictiveTaskBufferTime)
targetValue, err := strconv.ParseFloat(strconv.FormatFloat(object.TargetValue, 'f', 3, 64), 64)
if err != nil {
return WrapError(err)
Expand Down Expand Up @@ -327,6 +369,32 @@ func resourceAliyunEssScalingRuleUpdate(d *schema.ResourceData, meta interface{}
}
request.StepAdjustment = &steps
}
case string(PredictiveScalingRule):
if d.HasChange("metric_name") {
request.MetricName = d.Get("metric_name").(string)
}
if d.HasChange("target_value") {
targetValue, err := strconv.ParseFloat(strconv.FormatFloat(d.Get("target_value").(float64), 'f', 3, 64), 64)
if err != nil {
return WrapError(err)
}
request.TargetValue = requests.NewFloat(targetValue)
}
if d.HasChange("initial_max_size") {
request.InitialMaxSize = requests.NewInteger(d.Get("initial_max_size").(int))
}
if d.HasChange("predictive_value_buffer") {
request.PredictiveValueBuffer = requests.NewInteger(d.Get("predictive_value_buffer").(int))
}
if d.HasChange("predictive_task_buffer_time") {
request.PredictiveTaskBufferTime = requests.NewInteger(d.Get("predictive_task_buffer_time").(int))
}
if d.HasChange("predictive_scaling_mode") {
request.PredictiveScalingMode = d.Get("predictive_scaling_mode").(string)
}
if d.HasChange("predictive_value_behavior") {
request.PredictiveValueBehavior = d.Get("predictive_value_behavior").(string)
}
}

raw, err := client.WithEssClient(func(essClient *ess.Client) (interface{}, error) {
Expand Down Expand Up @@ -435,6 +503,32 @@ func buildAlicloudEssScalingRuleArgs(d *schema.ResourceData, meta interface{}) (
}
request.StepAdjustment = &steps
}
case string(PredictiveScalingRule):
if v, ok := d.GetOk("metric_name"); ok && v.(string) != "" {
request.MetricName = v.(string)
}
if v, ok := d.GetOk("target_value"); ok {
targetValue, err := strconv.ParseFloat(strconv.FormatFloat(v.(float64), 'f', 3, 64), 64)
if err != nil {
return nil, WrapError(err)
}
request.TargetValue = requests.NewFloat(targetValue)
}
if v, ok := d.GetOk("predictive_scaling_mode"); ok && v.(string) != "" {
request.PredictiveScalingMode = v.(string)
}
if v, ok := d.GetOk("predictive_value_behavior"); ok && v.(string) != "" {
request.PredictiveValueBehavior = v.(string)
}
if v, ok := d.GetOkExists("predictive_value_buffer"); ok {
request.PredictiveValueBuffer = requests.NewInteger(v.(int))
}
if v, ok := d.GetOkExists("predictive_task_buffer_time"); ok {
request.PredictiveTaskBufferTime = requests.NewInteger(v.(int))
}
if v, ok := d.GetOkExists("initial_max_size"); ok {
request.InitialMaxSize = requests.NewInteger(v.(int))
}
}
return request, nil
}
Expand Down
110 changes: 110 additions & 0 deletions alicloud/resource_alicloud_ess_scaling_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,116 @@ func TestAccAliCloudEssScalingRule_target_tracking_rule_basic(t *testing.T) {
})
}

func TestAccAliCloudEssScalingRule_predictive_rule_basic(t *testing.T) {
var v ess.ScalingRule
rand := acctest.RandIntRange(1000, 999999)
resourceId := "alicloud_ess_scaling_rule.default"
basicMap := map[string]string{
"scaling_group_id": CHECKSET,
"scaling_rule_type": "PredictiveScalingRule",
"metric_name": "CpuUtilization",
"target_value": "20.1",
"predictive_scaling_mode": "PredictAndScale",
"initial_max_size": "1",
"predictive_value_behavior": "MaxOverridePredictiveValue",
"predictive_value_buffer": "0",
"predictive_task_buffer_time": "0",
}
ra := resourceAttrInit(resourceId, basicMap)
rc := resourceCheckInit(resourceId, &v, func() interface{} {
return &EssService{testAccProvider.Meta().(*connectivity.AliyunClient)}
})
rac := resourceAttrCheckInit(rc, ra)

testAccCheck := rac.resourceAttrMapUpdateSet()
name := fmt.Sprintf("tf-testAccEssTargetTrackingScalingRuleConfig-%d", rand)
testAccConfig := resourceTestAccConfigFunc(resourceId, name, testAccEssTargetTrackingScalingRuleConfig)
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: resourceId,
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccConfig(map[string]interface{}{
"scaling_group_id": "${alicloud_ess_scaling_group.default.id}",
"scaling_rule_type": "PredictiveScalingRule",
"metric_name": "CpuUtilization",
"target_value": "20.1",
}),
Check: resource.ComposeTestCheckFunc(
testAccCheck(nil),
),
},
{
Config: testAccConfig(map[string]interface{}{
"scaling_group_id": "${alicloud_ess_scaling_group.default.id}",
"scaling_rule_type": "PredictiveScalingRule",
"metric_name": "IntranetRx",
"target_value": "20",
}),
Check: resource.ComposeTestCheckFunc(
testAccCheck(map[string]string{
"metric_name": "IntranetRx",
"target_value": "20",
"predictive_scaling_mode": CHECKSET,
"initial_max_size": CHECKSET,
"predictive_value_behavior": CHECKSET,
"predictive_value_buffer": CHECKSET,
"predictive_task_buffer_time": CHECKSET,
}),
),
},
{
Config: testAccConfig(map[string]interface{}{
"scaling_group_id": "${alicloud_ess_scaling_group.default.id}",
"scaling_rule_type": "PredictiveScalingRule",
"metric_name": "IntranetRx",
"target_value": "20",
"predictive_scaling_mode": "PredictOnly",
"initial_max_size": "1",
"predictive_value_behavior": "PredictiveValueOverrideMaxWithBuffer",
"predictive_value_buffer": "1",
"predictive_task_buffer_time": "60",
}),
Check: resource.ComposeTestCheckFunc(
testAccCheck(map[string]string{
"predictive_scaling_mode": "PredictOnly",
"initial_max_size": "1",
"predictive_value_behavior": "PredictiveValueOverrideMaxWithBuffer",
"predictive_value_buffer": "1",
"predictive_task_buffer_time": "60",
}),
),
},
{
Config: testAccConfig(map[string]interface{}{
"scaling_group_id": "${alicloud_ess_scaling_group.default.id}",
"scaling_rule_type": "PredictiveScalingRule",
"metric_name": "CpuUtilization",
"target_value": "20.1",
"predictive_scaling_mode": "PredictAndScale",
"initial_max_size": "1",
"predictive_value_behavior": "MaxOverridePredictiveValue",
"predictive_value_buffer": "0",
"predictive_task_buffer_time": "0",
}),
Check: resource.ComposeTestCheckFunc(
testAccCheck(basicMap),
),
},
{
ResourceName: resourceId,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAliCloudEssScalingRule_target_tracking_rule_alarm_dimension(t *testing.T) {
var v ess.ScalingRule
rand := acctest.RandIntRange(1000, 999999)
Expand Down
9 changes: 8 additions & 1 deletion website/docs/r/ess_scaling_rule.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ The following arguments are supported:
- TotalCapacity:[0, 1000]
* `scaling_rule_name` - (Optional) Name shown for the scaling rule, which must contain 2-64 characters (English or Chinese), starting with numbers, English letters or Chinese characters, and can contain number, underscores `_`, hypens `-`, and decimal point `.`. If this parameter value is not specified, the default value is scaling rule id.
* `cooldown` - (Optional) The cooldown time of the scaling rule. This parameter is applicable only to simple scaling rules. Value range: [0, 86,400], in seconds. The default value is empty,if not set, the return value will be 0, which is the default value of integer.
* `scaling_rule_type` - (Optional, ForceNew, Available since v1.58.0) The scaling rule type, either "SimpleScalingRule", "TargetTrackingScalingRule", "StepScalingRule". Default to "SimpleScalingRule".
* `scaling_rule_type` - (Optional, ForceNew, Available since v1.58.0) The scaling rule type, either "SimpleScalingRule", "TargetTrackingScalingRule", "StepScalingRule", "PredictiveScalingRule". Default to "SimpleScalingRule".
* `estimated_instance_warmup` - (Optional, Available since v1.58.0) The estimated time, in seconds, until a newly launched instance will contribute CloudMonitor metrics. Default to 300.
* `min_adjustment_magnitude` - (Optional, Available since v1.221.0) The minimum number of instances that must be scaled. This parameter takes effect if you set ScalingRuleType to SimpleScalingRule or StepScalingRule, and AdjustmentType to PercentChangeInCapacity.
* `scale_in_evaluation_count` - (Optional, Available since v1.221.0) The number of consecutive times that the event-triggered task created for scale-ins must meet the threshold conditions before an alert is triggered. After a target tracking scaling rule is created, an event-triggered task is automatically created and associated with the target tracking scaling rule.
Expand All @@ -130,6 +130,13 @@ The following arguments are supported:
* `step_adjustment` - (Optional, Available since v1.58.0) Steps for StepScalingRule. See [`step_adjustment`](#step_adjustment) below.
* `ari` - (Optional) The unique identifier of the scaling rule.
* `alarm_dimension` - (Optional, ForceNew, Available since v1.216.0) AlarmDimension for StepScalingRule. See [`alarm_dimension`](#alarm_dimension) below.
* `predictive_scaling_mode` - (Optional, Available since v1.222.0) The mode of the predictive scaling rule. Valid values: PredictAndScale, PredictOnly.
* `initial_max_size` - (Optional, Available since v1.222.0) The maximum number of ECS instances that can be added to the scaling group. If you specify InitialMaxSize, you must also specify PredictiveValueBehavior.
* `predictive_value_behavior` - (Optional, Available since v1.222.0) The action on the predicted maximum value. Valid values: MaxOverridePredictiveValue, PredictiveValueOverrideMax, PredictiveValueOverrideMaxWithBuffer.
* `predictive_value_buffer` - (Optional, Available since v1.222.0) The ratio based on which the predicted value is increased if you set PredictiveValueBehavior to PredictiveValueOverrideMaxWithBuffer. If the predicted value increased by this ratio is greater than the initial maximum capacity, the increased value is used as the maximum value for prediction tasks. Valid values: 0 to 100.
* `predictive_task_buffer_time` - (Optional, Available since v1.222.0) The amount of buffer time before the prediction task runs. By default, all prediction tasks that are automatically created by a predictive scaling rule run on the hour. You can specify a buffer time to run prediction tasks and prepare resources in advance. Valid values: 0 to 60. Unit: minutes.




### `step_adjustment`
Expand Down

0 comments on commit d21a291

Please sign in to comment.