alibabacloudstack/resource_apsarastack_log_alert.go (403 lines of code) (raw):

package alibabacloudstack import ( "fmt" "time" sls "github.com/aliyun/aliyun-log-go-sdk" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) func resourceAlibabacloudStackLogAlert() *schema.Resource { resource := &schema.Resource{ Schema: map[string]*schema.Schema{ "project_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, "alert_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, "alert_displayname": { Type: schema.TypeString, Required: true, }, "alert_description": { Type: schema.TypeString, Optional: true, }, "condition": { Type: schema.TypeString, Required: true, }, "dashboard": { Type: schema.TypeString, Required: true, }, "mute_until": { Type: schema.TypeFloat, Optional: true, Computed: true, ValidateFunc: validation.FloatAtLeast(0.0), }, "throttling": { Type: schema.TypeString, Optional: true, }, "notify_threshold": { Type: schema.TypeInt, Optional: true, Default: 1, }, "query_list": { Type: schema.TypeList, Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "chart_title": { Type: schema.TypeString, Required: true, }, "logstore": { Type: schema.TypeString, Required: true, }, "query": { Type: schema.TypeString, Required: true, }, "start": { Type: schema.TypeString, Required: true, }, "end": { Type: schema.TypeString, Required: true, }, "time_span_type": { Type: schema.TypeString, Optional: true, Default: "Custom", }, }, }, }, "notification_list": { Type: schema.TypeList, Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{ sls.NotificationTypeSMS, sls.NotificationTypeDingTalk, sls.NotificationTypeEmail, sls.NotificationTypeMessageCenter}, false), }, "content": { Type: schema.TypeString, Required: true, }, "service_uri": { Type: schema.TypeString, Optional: true, }, "mobile_list": { Type: schema.TypeSet, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "email_list": { Type: schema.TypeSet, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, }, "schedule_interval": { Type: schema.TypeString, Optional: true, Default: "60s", }, "schedule_type": { Type: schema.TypeString, Optional: true, Default: "FixedRate", }, }, } setResourceFunc(resource, resourceAlibabacloudStackLogAlertCreate, resourceAlibabacloudStackLogAlertRead, resourceAlibabacloudStackLogAlertUpdate, resourceAlibabacloudStackLogAlertDelete) return resource } func resourceAlibabacloudStackLogAlertCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) project_name := d.Get("project_name").(string) alert_name := d.Get("alert_name").(string) alert_displayname := d.Get("alert_displayname").(string) alert := &sls.Alert{ Name: alert_name, DisplayName: alert_displayname, Description: d.Get("alert_description").(string), State: "Enabled", Schedule: &sls.Schedule{ Type: d.Get("schedule_type").(string), Interval: d.Get("schedule_interval").(string), }, } if err := resource.Retry(2*time.Minute, func() *resource.RetryError { _, err := client.WithSlsDataClient(func(slsClient *sls.Client) (interface{}, error) { dashboard := d.Get("dashboard").(string) err := CreateDashboard(project_name, dashboard, slsClient) if err != nil { return nil, err } alert.Configuration = createAlertConfig(d, project_name, dashboard, slsClient) return nil, slsClient.CreateAlert(project_name, alert) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{errmsgs.LogClientTimeout}) { time.Sleep(5 * time.Second) return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }); err != nil { return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_log_alert", "CreateLogstoreAlert", errmsgs.AlibabacloudStackSdkGoERROR) } d.SetId(fmt.Sprintf("%s%s%s", project_name, COLON_SEPARATED, alert_name)) return nil } func resourceAlibabacloudStackLogAlertRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) logService := LogService{client} parts, err := ParseResourceId(d.Id(), 2) if err != nil { return errmsgs.WrapError(err) } object, err := logService.DescribeLogAlert(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { d.SetId("") return nil } return errmsgs.WrapError(err) } d.Set("project_name", parts[0]) d.Set("alert_name", parts[1]) d.Set("alert_displayname", object.DisplayName) d.Set("alert_description", object.Description) d.Set("condition", object.Configuration.Condition) d.Set("dashboard", object.Configuration.Dashboard) d.Set("mute_until", float64(object.Configuration.MuteUntil)) d.Set("throttling", object.Configuration.Throttling) d.Set("notify_threshold", object.Configuration.NotifyThreshold) d.Set("schedule_interval", object.Schedule.Interval) d.Set("schedule_type", object.Schedule.Type) var notiList []map[string]interface{} for _, v := range object.Configuration.NotificationList { mapping := getNotiMap(v) notiList = append(notiList, mapping) } var queryList []map[string]interface{} for _, v := range object.Configuration.QueryList { mapping := map[string]interface{}{ "chart_title": v.ChartTitle, "logstore": v.LogStore, "query": v.Query, "start": v.Start, "end": v.End, "time_span_type": v.TimeSpanType, } queryList = append(queryList, mapping) } d.Set("notification_list", notiList) d.Set("query_list", queryList) return nil } func resourceAlibabacloudStackLogAlertUpdate(d *schema.ResourceData, meta interface{}) error { parts, err := ParseResourceId(d.Id(), 2) if err != nil { return errmsgs.WrapError(err) } client := meta.(*connectivity.AlibabacloudStackClient) params := &sls.Alert{ Name: parts[1], DisplayName: d.Get("alert_displayname").(string), Description: d.Get("alert_description").(string), State: "Enabled", Schedule: &sls.Schedule{ Type: d.Get("schedule_type").(string), Interval: d.Get("schedule_interval").(string), }, } if err := resource.Retry(2*time.Minute, func() *resource.RetryError { _, err := client.WithSlsDataClient(func(slsClient *sls.Client) (interface{}, error) { project_name := d.Get("project_name").(string) dashboard := d.Get("dashboard").(string) err := CreateDashboard(project_name, dashboard, slsClient) if err != nil { return nil, err } params.Configuration = createAlertConfig(d, project_name, dashboard, slsClient) return nil, slsClient.UpdateAlert(parts[0], params) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{errmsgs.LogClientTimeout}) { time.Sleep(5 * time.Second) return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }); err != nil { return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, d.Id(), "UpdateAlert", errmsgs.AlibabacloudStackSdkGoERROR) } return nil } func resourceAlibabacloudStackLogAlertDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) logService := LogService{client} parts, err := ParseResourceId(d.Id(), 2) if err != nil { return errmsgs.WrapError(err) } var requestInfo *sls.Client err = resource.Retry(3*time.Minute, func() *resource.RetryError { raw, err := client.WithSlsDataClient(func(slsClient *sls.Client) (interface{}, error) { requestInfo = slsClient return nil, slsClient.DeleteAlert(parts[0], parts[1]) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{errmsgs.LogClientTimeout}) { time.Sleep(5 * time.Second) return resource.RetryableError(err) } return resource.NonRetryableError(err) } if debugOn() { addDebug("DeleteAlert", raw, requestInfo, map[string]interface{}{ "project_name": parts[0], "alert": parts[1], }) } return nil }) if err != nil { return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_log_alert", "DeleteAlert", errmsgs.AlibabacloudStackSdkGoERROR) } return errmsgs.WrapError(logService.WaitForLogstoreAlert(d.Id(), Deleted, DefaultTimeout)) } func createAlertConfig(d *schema.ResourceData, project, dashboard string, client *sls.Client) *sls.AlertConfiguration { noti := []*sls.Notification{} if v, ok := d.GetOk("notification_list"); ok { for _, e := range v.([]interface{}) { noti_map := e.(map[string]interface{}) content := noti_map["content"].(string) email_list := []string{} email_list_temp := noti_map["email_list"].(*schema.Set).List() for _, v := range email_list_temp { new_v := v.(string) email_list = append(email_list, new_v) } mobile_list_temp := noti_map["mobile_list"].(*schema.Set).List() mobile_list := []string{} if len(mobile_list_temp) > 0 { for _, v := range mobile_list_temp { new_v := v.(string) mobile_list = append(mobile_list, new_v) } } if noti_map["type"].(string) == sls.NotificationTypeEmail { email := &sls.Notification{ Type: sls.NotificationTypeEmail, EmailList: email_list, Content: content, } noti = append(noti, email) } if noti_map["type"].(string) == sls.NotificationTypeSMS { sms := &sls.Notification{ Type: sls.NotificationTypeSMS, MobileList: mobile_list, Content: content, } noti = append(noti, sms) } if noti_map["type"].(string) == sls.NotificationTypeDingTalk { ding := &sls.Notification{ Type: sls.NotificationTypeDingTalk, ServiceUri: noti_map["service_uri"].(string), Content: content, } noti = append(noti, ding) } if noti_map["type"].(string) == sls.NotificationTypeMessageCenter { messageCenter := &sls.Notification{ Type: sls.NotificationTypeMessageCenter, Content: content, } noti = append(noti, messageCenter) } } } queryList := []*sls.AlertQuery{} if v, ok := d.GetOk("query_list"); ok { for _, e := range v.([]interface{}) { query_map := e.(map[string]interface{}) query := &sls.AlertQuery{ ChartTitle: GetCharTitile(project, dashboard, query_map["chart_title"].(string), client), LogStore: query_map["logstore"].(string), Query: query_map["query"].(string), Start: query_map["start"].(string), End: query_map["end"].(string), TimeSpanType: query_map["time_span_type"].(string), } queryList = append(queryList, query) } } var mute_until int64 if v, ok := d.GetOk("mute_until"); ok { mute_until = int64(v.(float64)) } else { mute_until = time.Now().Unix() } config := &sls.AlertConfiguration{ Condition: d.Get("condition").(string), Dashboard: d.Get("dashboard").(string), QueryList: queryList, MuteUntil: mute_until, NotificationList: noti, Throttling: d.Get("throttling").(string), NotifyThreshold: int32(d.Get("notify_threshold").(int)), } return config } func getNotiMap(v *sls.Notification) map[string]interface{} { mapping := make(map[string]interface{}) mapping["content"] = v.Content if v.Type == sls.NotificationTypeSMS { mapping["type"] = sls.NotificationTypeSMS mapping["mobile_list"] = v.MobileList } if v.Type == sls.NotificationTypeEmail { mapping["type"] = sls.NotificationTypeEmail mapping["email_list"] = v.EmailList } if v.Type == sls.NotificationTypeDingTalk { mapping["type"] = sls.NotificationTypeDingTalk mapping["service_uri"] = v.ServiceUri } if v.Type == sls.NotificationTypeMessageCenter { mapping["type"] = sls.NotificationTypeMessageCenter } return mapping }