alicloud/resource_alicloud_cms_alarm.go (939 lines of code) (raw):

package alicloud import ( "encoding/json" "fmt" "strings" "time" util "github.com/alibabacloud-go/tea-utils/service" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "strconv" ) func resourceAliCloudCmsAlarm() *schema.Resource { return &schema.Resource{ Create: resourceAliCloudCmsAlarmCreate, Read: resourceAliCloudCmsAlarmRead, Update: resourceAliCloudCmsAlarmUpdate, Delete: resourceAliCloudCmsAlarmDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(1 * time.Minute), Update: schema.DefaultTimeout(1 * time.Minute), Delete: schema.DefaultTimeout(1 * time.Minute), }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, }, "project": { Type: schema.TypeString, Required: true, ForceNew: true, }, "metric": { Type: schema.TypeString, Required: true, ForceNew: true, }, "contact_groups": { Type: schema.TypeList, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "metric_dimensions": { Type: schema.TypeString, Optional: true, Computed: true, ConflictsWith: []string{"dimensions"}, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { equal, _ := compareArrayJsonTemplateAreEquivalent(old, new) return equal }, }, "effective_interval": { Type: schema.TypeString, Optional: true, Default: "00:00-23:59", ConflictsWith: []string{"start_time", "end_time"}, }, "period": { Type: schema.TypeInt, Optional: true, Default: 300, }, "silence_time": { Type: schema.TypeInt, Optional: true, Default: 86400, ValidateFunc: IntBetween(300, 86400), }, "webhook": { Type: schema.TypeString, Optional: true, }, "enabled": { Type: schema.TypeBool, Optional: true, Default: true, }, "tags": tagsSchema(), "escalations_critical": { Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "comparison_operator": { Type: schema.TypeString, Optional: true, Default: MoreThan, ValidateFunc: StringInSlice([]string{ MoreThan, MoreThanOrEqual, LessThan, LessThanOrEqual, NotEqual, Equal, "GreaterThanYesterday", "LessThanYesterday", "GreaterThanLastWeek", "LessThanLastWeek", "GreaterThanLastPeriod", "LessThanLastPeriod", }, false), }, "statistics": { Type: schema.TypeString, Optional: true, Default: Average, }, "threshold": { Type: schema.TypeString, Optional: true, }, "times": { Type: schema.TypeInt, Optional: true, Default: 3, }, }, }, }, "escalations_info": { Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "comparison_operator": { Type: schema.TypeString, Optional: true, Default: MoreThan, ValidateFunc: StringInSlice([]string{ MoreThan, MoreThanOrEqual, LessThan, LessThanOrEqual, NotEqual, Equal, "GreaterThanYesterday", "LessThanYesterday", "GreaterThanLastWeek", "LessThanLastWeek", "GreaterThanLastPeriod", "LessThanLastPeriod", }, false), }, "statistics": { Type: schema.TypeString, Optional: true, Default: Average, }, "threshold": { Type: schema.TypeString, Optional: true, }, "times": { Type: schema.TypeInt, Optional: true, Default: 3, }, }, }, }, "escalations_warn": { Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "comparison_operator": { Type: schema.TypeString, Optional: true, Default: MoreThan, ValidateFunc: StringInSlice([]string{ MoreThan, MoreThanOrEqual, LessThan, LessThanOrEqual, NotEqual, Equal, "GreaterThanYesterday", "LessThanYesterday", "GreaterThanLastWeek", "LessThanLastWeek", "GreaterThanLastPeriod", "LessThanLastPeriod", }, false), }, "statistics": { Type: schema.TypeString, Optional: true, Default: Average, }, "threshold": { Type: schema.TypeString, Optional: true, }, "times": { Type: schema.TypeInt, Optional: true, Default: 3, }, }, }, }, "prometheus": { Type: schema.TypeList, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "prom_ql": { Type: schema.TypeString, Optional: true, }, "level": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: StringInSlice([]string{"Critical", "Warn", "Info"}, false), }, "times": { Type: schema.TypeInt, Optional: true, Computed: true, }, "annotations": { Type: schema.TypeMap, Optional: true, Elem: schema.TypeString, }, }, }, }, "targets": { Type: schema.TypeSet, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "target_id": { Type: schema.TypeString, Optional: true, }, "json_params": { Type: schema.TypeString, Optional: true, }, "level": { Type: schema.TypeString, Optional: true, ValidateFunc: StringInSlice([]string{"Critical", "Warn", "Info"}, false), }, "arn": { Type: schema.TypeString, Optional: true, }, }, }, }, "composite_expression": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "level": { Type: schema.TypeString, Optional: true, ValidateFunc: StringInSlice([]string{"CRITICAL", "WARN", "INFO"}, false), }, "times": { Type: schema.TypeInt, Optional: true, }, "expression_raw": { Type: schema.TypeString, Optional: true, }, "expression_list_join": { Type: schema.TypeString, Optional: true, ValidateFunc: StringInSlice([]string{"&&", "||"}, false), }, "expression_list": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "metric_name": { Type: schema.TypeString, Optional: true, }, "comparison_operator": { Type: schema.TypeString, Optional: true, ValidateFunc: StringInSlice([]string{ MoreThan, MoreThanOrEqual, LessThan, LessThanOrEqual, NotEqual, Equal, "GreaterThanYesterday", "LessThanYesterday", "GreaterThanLastWeek", "LessThanLastWeek", "GreaterThanLastPeriod", "LessThanLastPeriod", }, false), }, "statistics": { Type: schema.TypeString, Optional: true, }, "threshold": { Type: schema.TypeString, Optional: true, }, "period": { Type: schema.TypeString, Optional: true, }, }, }, }, }, }, }, "status": { Type: schema.TypeString, Computed: true, }, "dimensions": { Type: schema.TypeMap, Optional: true, Computed: true, Elem: schema.TypeString, ConflictsWith: []string{"metric_dimensions"}, Deprecated: "Field `dimensions` has been deprecated from provider version 1.173.0. New field `metric_dimensions` instead.", }, "start_time": { Type: schema.TypeInt, Optional: true, //Default: 0, //ValidateFunc: IntBetween(0, 24), ConflictsWith: []string{"effective_interval"}, Deprecated: "Field `start_time` has been deprecated from provider version 1.50.0. New field `effective_interval` instead.", }, "end_time": { Type: schema.TypeInt, Optional: true, //Default: 24, //ValidateFunc: IntBetween(0, 24), ConflictsWith: []string{"effective_interval"}, Deprecated: "Field `end_time` has been deprecated from provider version 1.50.0. New field `effective_interval` instead.", }, "operator": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: StringInSlice([]string{ MoreThan, MoreThanOrEqual, LessThan, LessThanOrEqual, NotEqual, }, false), Removed: "Field `operator` has been removed from provider version 1.216.0. New field `escalations_critical.comparison_operator` instead.", }, "statistics": { Type: schema.TypeString, Optional: true, Computed: true, Removed: "Field `statistics` has been removed from provider version 1.216.0. New field `escalations_critical.statistics` instead.", }, "threshold": { Type: schema.TypeString, Optional: true, Computed: true, Removed: "Field `threshold` has been removed from provider version 1.216.0. New field `escalations_critical.threshold` instead.", }, "triggered_count": { Type: schema.TypeInt, Optional: true, Computed: true, Removed: "Field `triggered_count` has been removed from provider version 1.216.0. New field `escalations_critical.times` instead.", }, "notify_type": { Type: schema.TypeInt, Optional: true, ValidateFunc: IntInSlice([]int{0, 1}), Removed: "Field `notify_type` has been removed from provider version 1.50.0.", }, }, } } func resourceAliCloudCmsAlarmCreate(d *schema.ResourceData, meta interface{}) error { d.SetId(resource.UniqueId()) return resourceAliCloudCmsAlarmUpdate(d, meta) } func resourceAliCloudCmsAlarmRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) cmsService := CmsService{client} object, err := cmsService.DescribeAlarm(d.Id()) if err != nil { if !d.IsNewResource() && NotFoundError(err) { d.SetId("") return nil } return WrapError(err) } d.Set("name", object["RuleName"]) d.Set("project", object["Namespace"]) d.Set("metric", object["MetricName"]) d.Set("contact_groups", strings.Split(object["ContactGroups"].(string), ",")) d.Set("effective_interval", object["EffectiveInterval"]) d.Set("period", object["Period"]) d.Set("silence_time", object["SilenceTime"]) d.Set("webhook", object["Webhook"]) d.Set("enabled", object["EnableState"]) d.Set("status", object["AlertState"]) if err := d.Set("metric_dimensions", object["Resources"]); err != nil { return WrapError(err) } if tags, ok := object["Labels"]; ok { tagsArg := tags.(map[string]interface{}) if labels, ok := tagsArg["Labels"]; ok { d.Set("tags", tagsToMap(labels)) } } if escalations, ok := object["Escalations"].(map[string]interface{}); ok { if critical, ok := escalations["Critical"].(map[string]interface{}); ok { mapping := map[string]interface{}{ "statistics": critical["Statistics"], "comparison_operator": convertCmsAlarmComparisonOperator(fmt.Sprint(critical["ComparisonOperator"])), "threshold": critical["Threshold"], "times": formatInt(critical["Times"]), } d.Set("escalations_critical", []map[string]interface{}{mapping}) } if info, ok := escalations["Info"].(map[string]interface{}); ok { mappingInfo := map[string]interface{}{ "statistics": info["Statistics"], "comparison_operator": convertCmsAlarmComparisonOperator(fmt.Sprint(info["ComparisonOperator"])), "threshold": info["Threshold"], "times": formatInt(info["Times"]), } d.Set("escalations_info", []map[string]interface{}{mappingInfo}) } if warn, ok := escalations["Warn"].(map[string]interface{}); ok { mappingWarn := map[string]interface{}{ "statistics": warn["Statistics"], "comparison_operator": convertCmsAlarmComparisonOperator(fmt.Sprint(warn["ComparisonOperator"])), "threshold": warn["Threshold"], "times": formatInt(warn["Times"]), } d.Set("escalations_warn", []map[string]interface{}{mappingWarn}) } } if v, ok := object["Prometheus"]; ok { if prometheus, ok := v.(map[string]interface{}); ok && len(prometheus) > 0 { prometheusList := make([]map[string]interface{}, 0) mapping := map[string]interface{}{ "prom_ql": prometheus["PromQL"], } if v, ok := prometheus["Level"]; ok { mapping["level"] = convertCmsAlarmPrometheusLevelResponse(v.(string)) } if v, ok := prometheus["Times"]; ok { mapping["times"] = v } annotationsMap := make(map[string]interface{}, 0) if v, ok := prometheus["Annotations"]; ok { annotations := v.(map[string]interface{}) if v, ok := annotations["Annotations"]; ok && len(v.([]interface{})) > 0 { for _, item := range v.([]interface{}) { itemArg := item.(map[string]interface{}) annotationsMap[itemArg["Key"].(string)] = itemArg["Value"] } } } mapping["annotations"] = annotationsMap prometheusList = append(prometheusList, mapping) if err := d.Set("prometheus", prometheusList); err != nil { return WrapError(err) } } } if compositeExpression, ok := object["CompositeExpression"]; ok { compositeExpressionMaps := make([]map[string]interface{}, 0) compositeExpressionArg := compositeExpression.(map[string]interface{}) compositeExpressionMap := make(map[string]interface{}) if level, ok := compositeExpressionArg["Level"]; ok { compositeExpressionMap["level"] = level } if times, ok := compositeExpressionArg["Times"]; ok { compositeExpressionMap["times"] = times } if expressionRaw, ok := compositeExpressionArg["ExpressionRaw"]; ok { compositeExpressionMap["expression_raw"] = expressionRaw } if expressionListJoin, ok := compositeExpressionArg["ExpressionListJoin"]; ok { compositeExpressionMap["expression_list_join"] = expressionListJoin } if expressionList, ok := compositeExpressionArg["ExpressionList"]; ok { if expressionLists, ok := expressionList.(map[string]interface{})["ExpressionList"]; ok { expressionListMaps := make([]map[string]interface{}, 0) for _, v := range expressionLists.([]interface{}) { expressionListArg := v.(map[string]interface{}) expressionListMap := map[string]interface{}{} if metricName, ok := expressionListArg["MetricName"]; ok { expressionListMap["metric_name"] = metricName } if comparisonOperator, ok := expressionListArg["ComparisonOperator"]; ok { expressionListMap["comparison_operator"] = convertCmsAlarmComparisonOperator(fmt.Sprint(comparisonOperator)) } if statistics, ok := expressionListArg["Statistics"]; ok { expressionListMap["statistics"] = statistics } if threshold, ok := expressionListArg["Threshold"]; ok { expressionListMap["threshold"] = threshold } if period, ok := expressionListArg["Period"]; ok { expressionListMap["period"] = period } expressionListMaps = append(expressionListMaps, expressionListMap) } compositeExpressionMap["expression_list"] = expressionListMaps } } if len(compositeExpressionMap) > 0 { compositeExpressionMaps = append(compositeExpressionMaps, compositeExpressionMap) } d.Set("composite_expression", compositeExpressionMaps) } dims := make([]map[string]interface{}, 0) if fmt.Sprint(object["Resources"]) != "" { if err := json.Unmarshal([]byte(object["Resources"].(string)), &dims); err != nil { return fmt.Errorf("Unmarshaling Dimensions got an error: %#v.", err) } } dimensionList := make(map[string]interface{}, 0) for _, raw := range dims { for k, v := range raw { if dimensionListValue, ok := dimensionList[k]; ok { dimensionList[k] = fmt.Sprint(dimensionListValue.(string), ",", v.(string)) } else { dimensionList[k] = v } } } if err := d.Set("dimensions", dimensionList); err != nil { return WrapError(err) } targetsList, err := cmsService.DescribeMetricRuleTargets(d.Id()) if err != nil { if NotFoundError(err) { return nil } return WrapError(err) } targetsMaps := make([]map[string]interface{}, 0) for _, targets := range targetsList { targetsArg := targets.(map[string]interface{}) targetsMap := map[string]interface{}{} if id, ok := targetsArg["Id"]; ok { targetsMap["target_id"] = id } if jsonParams, ok := targetsArg["JsonParams"]; ok { targetsMap["json_params"] = jsonParams } if level, ok := targetsArg["Level"]; ok { targetsMap["level"] = level } if arn, ok := targetsArg["Arn"]; ok { targetsMap["arn"] = arn } targetsMaps = append(targetsMaps, targetsMap) } d.Set("targets", targetsMaps) return nil } func resourceAliCloudCmsAlarmUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) cmsService := CmsService{client} var response map[string]interface{} d.Partial(true) action := "PutResourceMetricRule" request := make(map[string]interface{}) var err error request["RuleId"] = d.Id() request["RuleName"] = d.Get("name").(string) request["Namespace"] = d.Get("project").(string) request["MetricName"] = d.Get("metric").(string) request["ContactGroups"] = strings.Join(expandStringList(d.Get("contact_groups").([]interface{})), ",") if v, ok := d.GetOk("metric_dimensions"); ok && v.(string) != "" { request["Resources"] = v.(string) } else { var dimList []map[string]string if dimensions, ok := d.GetOk("dimensions"); ok { for k, v := range dimensions.(map[string]interface{}) { values := strings.Split(v.(string), COMMA_SEPARATED) if len(values) > 0 { for _, vv := range values { dimList = append(dimList, map[string]string{k: Trim(vv)}) } } else { dimList = append(dimList, map[string]string{k: Trim(v.(string))}) } } } if len(dimList) > 0 { if bytes, err := json.Marshal(dimList); err != nil { return fmt.Errorf("Marshaling dimensions to json string got an error: %#v.", err) } else { request["Resources"] = string(bytes[:]) } } } if v, ok := d.GetOk("effective_interval"); ok && v.(string) != "" { request["EffectiveInterval"] = v.(string) } else { start, startOk := d.GetOk("start_time") end, endOk := d.GetOk("end_time") if startOk && endOk && end.(int) > 0 { // The EffectiveInterval valid value between 00:00 and 23:59 request["EffectiveInterval"] = fmt.Sprintf("%d:00-%d:59", start.(int), end.(int)-1) } } if v, ok := d.GetOkExists("period"); ok { request["Period"] = strconv.Itoa(v.(int)) } if v, ok := d.GetOkExists("silence_time"); ok { request["SilenceTime"] = requests.NewInteger(v.(int)) } if v, ok := d.GetOk("webhook"); ok && v.(string) != "" { request["Webhook"] = v.(string) } // Critical if v, ok := d.GetOk("escalations_critical"); ok && len(v.([]interface{})) != 0 { for _, escalationsCriticalList := range v.([]interface{}) { escalationsCriticalArg := escalationsCriticalList.(map[string]interface{}) if comparisonOperator, ok := escalationsCriticalArg["comparison_operator"]; ok { request["Escalations.Critical.ComparisonOperator"] = convertCmsAlarmComparisonOperator(fmt.Sprint(comparisonOperator)) } if statistics, ok := escalationsCriticalArg["statistics"]; ok { request["Escalations.Critical.Statistics"] = statistics } if threshold, ok := escalationsCriticalArg["threshold"]; ok { request["Escalations.Critical.Threshold"] = threshold } if times, ok := escalationsCriticalArg["times"]; ok { request["Escalations.Critical.Times"] = times } } } // Info if v, ok := d.GetOk("escalations_info"); ok && len(v.([]interface{})) != 0 { for _, escalationsInfoList := range v.([]interface{}) { escalationsInfoArg := escalationsInfoList.(map[string]interface{}) if comparisonOperator, ok := escalationsInfoArg["comparison_operator"]; ok { request["Escalations.Info.ComparisonOperator"] = convertCmsAlarmComparisonOperator(fmt.Sprint(comparisonOperator)) } if statistics, ok := escalationsInfoArg["statistics"]; ok { request["Escalations.Info.Statistics"] = statistics } if threshold, ok := escalationsInfoArg["threshold"]; ok { request["Escalations.Info.Threshold"] = threshold } if times, ok := escalationsInfoArg["times"]; ok { request["Escalations.Info.Times"] = times } } } // Warn if v, ok := d.GetOk("escalations_warn"); ok && len(v.([]interface{})) != 0 { for _, escalationsWarnList := range v.([]interface{}) { escalationsWarnArg := escalationsWarnList.(map[string]interface{}) if comparisonOperator, ok := escalationsWarnArg["comparison_operator"]; ok { request["Escalations.Warn.ComparisonOperator"] = convertCmsAlarmComparisonOperator(fmt.Sprint(comparisonOperator)) } if statistics, ok := escalationsWarnArg["statistics"]; ok { request["Escalations.Warn.Statistics"] = statistics } if threshold, ok := escalationsWarnArg["threshold"]; ok { request["Escalations.Warn.Threshold"] = threshold } if times, ok := escalationsWarnArg["times"]; ok { request["Escalations.Warn.Times"] = times } } } if v, ok := d.GetOk("prometheus"); ok && len(v.([]interface{})) > 0 { prometheus := v.([]interface{})[0] prometheusMap := make(map[string]interface{}, 0) prometheusArg := prometheus.(map[string]interface{}) prometheusMap["PromQL"] = prometheusArg["prom_ql"] prometheusMap["Level"] = prometheusArg["level"] prometheusMap["Times"] = prometheusArg["times"] if vv, ok := prometheusArg["annotations"]; ok { tags := make([]map[string]interface{}, 0) for key, value := range vv.(map[string]interface{}) { tags = append(tags, map[string]interface{}{ "Key": key, "Value": value, }) } prometheusMap["Annotations"] = tags } request["Prometheus"], _ = convertMaptoJsonString(prometheusMap) } if v, ok := d.GetOk("composite_expression"); ok { compositeExpressionMap := map[string]interface{}{} for _, compositeExpression := range v.([]interface{}) { compositeExpressionArg := compositeExpression.(map[string]interface{}) if level, ok := compositeExpressionArg["level"]; ok { compositeExpressionMap["Level"] = level } if times, ok := compositeExpressionArg["times"]; ok { compositeExpressionMap["Times"] = times } if expressionRaw, ok := compositeExpressionArg["expression_raw"]; ok { compositeExpressionMap["ExpressionRaw"] = expressionRaw } if expressionListJoin, ok := compositeExpressionArg["expression_list_join"]; ok { compositeExpressionMap["ExpressionListJoin"] = expressionListJoin } if expressionList, ok := compositeExpressionArg["expression_list"]; ok { expressionListMaps := make([]map[string]interface{}, 0) for _, expressionListArgList := range expressionList.([]interface{}) { expressionListMap := map[string]interface{}{} expressionListArg := expressionListArgList.(map[string]interface{}) if metricName, ok := expressionListArg["metric_name"]; ok { expressionListMap["MetricName"] = metricName } if comparisonOperator, ok := expressionListArg["comparison_operator"]; ok { expressionListMap["ComparisonOperator"] = convertCmsAlarmComparisonOperator(fmt.Sprint(comparisonOperator)) } if statistics, ok := expressionListArg["statistics"]; ok { expressionListMap["Statistics"] = statistics } if threshold, ok := expressionListArg["threshold"]; ok { expressionListMap["Threshold"] = threshold } if period, ok := expressionListArg["period"]; ok { expressionListMap["Period"] = period } expressionListMaps = append(expressionListMaps, expressionListMap) } compositeExpressionMap["ExpressionList"] = expressionListMaps } } compositeExpressionJson, err := convertMaptoJsonString(compositeExpressionMap) if err != nil { return WrapError(err) } request["CompositeExpression"] = compositeExpressionJson } if v, ok := d.GetOk("tags"); ok { tags := make([]map[string]interface{}, 0) for key, value := range v.(map[string]interface{}) { tags = append(tags, map[string]interface{}{ "Key": key, "Value": value.(string), }) } request["Labels"] = tags } runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { response, err = client.RpcPost("Cms", "2019-01-01", action, nil, request, false) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } d.SetPartial("name") d.SetPartial("contact_groups") d.SetPartial("metric_dimensions") d.SetPartial("effective_interval") d.SetPartial("period") d.SetPartial("silence_time") d.SetPartial("webhook") d.SetPartial("escalations_critical") d.SetPartial("escalations_info") d.SetPartial("escalations_warn") d.SetPartial("prometheus") d.SetPartial("composite_expression") d.SetPartial("tags") d.SetPartial("dimensions") d.SetPartial("start_time") d.SetPartial("end_time") if d.Get("enabled").(bool) { action := "EnableMetricRules" enableMetricRequest := make(map[string]interface{}) enableMetricRequest["RuleId"] = []string{d.Id()} runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { response, err = client.RpcPost("Cms", "2019-01-01", action, nil, enableMetricRequest, false) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) addDebug(action, response, enableMetricRequest) } else { action := "DisableMetricRules" disableMetricRequest := make(map[string]interface{}) disableMetricRequest["RuleId"] = []string{d.Id()} runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { response, err = client.RpcPost("Cms", "2019-01-01", action, nil, disableMetricRequest, false) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) addDebug(action, response, disableMetricRequest) } if err := cmsService.WaitForCmsAlarm(d.Id(), d.Get("enabled").(bool), 102); err != nil { return WrapError(err) } d.SetPartial("enabled") update := false putMetricRuleTargetsReq := map[string]interface{}{ "RuleId": d.Id(), } if d.HasChange("targets") { update = true } if v, ok := d.GetOk("targets"); ok { targetsMaps := make([]map[string]interface{}, 0) for _, targets := range v.(*schema.Set).List() { targetsMap := map[string]interface{}{} targetsArg := targets.(map[string]interface{}) if id, ok := targetsArg["target_id"]; ok { targetsMap["Id"] = id } if jsonParams, ok := targetsArg["json_params"]; ok { targetsMap["JsonParams"] = jsonParams } if level, ok := targetsArg["level"]; ok { targetsMap["Level"] = level } if arn, ok := targetsArg["arn"]; ok { targetsMap["Arn"] = arn } targetsMaps = append(targetsMaps, targetsMap) } putMetricRuleTargetsReq["Targets"] = targetsMaps } if update { action := "PutMetricRuleTargets" runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { response, err = client.RpcPost("Cms", "2019-01-01", action, nil, putMetricRuleTargetsReq, false) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) addDebug(action, response, putMetricRuleTargetsReq) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } if fmt.Sprint(response["Success"]) == "false" { return WrapError(fmt.Errorf("%s failed, response: %v", action, response)) } d.SetPartial("targets") } d.Partial(false) return resourceAliCloudCmsAlarmRead(d, meta) } func resourceAliCloudCmsAlarmDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) cmsService := CmsService{client} action := "DeleteMetricRules" var response map[string]interface{} var err error request := map[string]interface{}{ "Id": []string{d.Id()}, } runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { response, err = client.RpcPost("Cms", "2019-01-01", action, nil, request, false) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } _, err = cmsService.DescribeAlarm(d.Id()) if err != nil { if NotFoundError(err) { return nil } return resource.NonRetryableError(fmt.Errorf("Describe alarm rule got an error: %#v", err)) } return nil }) addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } return nil } func convertCmsAlarmComparisonOperator(comparisonOperator string) string { switch comparisonOperator { case MoreThan: return "GreaterThanThreshold" case MoreThanOrEqual: return "GreaterThanOrEqualToThreshold" case LessThan: return "LessThanThreshold" case LessThanOrEqual: return "LessThanOrEqualToThreshold" case NotEqual: return "NotEqualToThreshold" case Equal: return "EqualToThreshold" case "GreaterThanThreshold": return MoreThan case "GreaterThanOrEqualToThreshold": return MoreThanOrEqual case "LessThanThreshold": return LessThan case "LessThanOrEqualToThreshold": return LessThanOrEqual case "NotEqualToThreshold": return NotEqual case "EqualToThreshold": return Equal default: return comparisonOperator } } func convertCmsAlarmPrometheusLevelResponse(source interface{}) interface{} { switch source { case "2": return "Critical" case "3": return "Warn" case "4": return "Info" } return source }