From 6c1cc4b3fe99ab1568a1f740cbd2d8d3e29e033d Mon Sep 17 00:00:00 2001 From: Diego Bonfigli Date: Tue, 8 Aug 2023 19:29:42 +0200 Subject: [PATCH] feat(alerts): add change alert type --- sysdig/internal/client/v2/alerts_v2.go | 92 +++++ sysdig/internal/client/v2/model.go | 39 +- sysdig/provider.go | 1 + ...resource_sysdig_monitor_alert_v2_change.go | 341 ++++++++++++++++++ ...rce_sysdig_monitor_alert_v2_change_test.go | 330 +++++++++++++++++ ...resource_sysdig_monitor_alert_v2_common.go | 14 +- ...source_sysdig_monitor_alert_v2_downtime.go | 15 +- .../resource_sysdig_monitor_alert_v2_event.go | 16 +- ...resource_sysdig_monitor_alert_v2_metric.go | 15 +- ...urce_sysdig_monitor_alert_v2_prometheus.go | 16 +- website/docs/index.md | 1 + website/docs/r/monitor_alert_anomaly.md | 16 +- website/docs/r/monitor_alert_downtime.md | 16 +- website/docs/r/monitor_alert_event.md | 22 +- website/docs/r/monitor_alert_group_outlier.md | 14 +- website/docs/r/monitor_alert_metric.md | 14 +- website/docs/r/monitor_alert_promql.md | 8 +- website/docs/r/monitor_alert_v2_change.md | 133 +++++++ website/docs/r/monitor_alert_v2_downtime.md | 14 +- website/docs/r/monitor_alert_v2_event.md | 14 +- website/docs/r/monitor_alert_v2_metric.md | 14 +- website/docs/r/monitor_alert_v2_prometheus.md | 14 +- 22 files changed, 1048 insertions(+), 111 deletions(-) create mode 100644 sysdig/resource_sysdig_monitor_alert_v2_change.go create mode 100644 sysdig/resource_sysdig_monitor_alert_v2_change_test.go create mode 100644 website/docs/r/monitor_alert_v2_change.md diff --git a/sysdig/internal/client/v2/alerts_v2.go b/sysdig/internal/client/v2/alerts_v2.go index d69aff290..375774623 100644 --- a/sysdig/internal/client/v2/alerts_v2.go +++ b/sysdig/internal/client/v2/alerts_v2.go @@ -2,6 +2,7 @@ package v2 import ( "context" + "errors" "fmt" "io" "log" @@ -9,6 +10,8 @@ import ( "sync" ) +var AlertV2NotFound = errors.New("alert not found") + type AlertV2Type string type AlertV2Severity string type AlertLinkV2Type string @@ -22,6 +25,7 @@ const ( AlertV2TypePrometheus AlertV2Type = "PROMETHEUS" AlertV2TypeManual AlertV2Type = "MANUAL" AlertV2TypeEvent AlertV2Type = "EVENT" + AlertV2TypeChange AlertV2Type = "PERCENTAGE_OF_CHANGE" AlertV2SeverityHigh AlertV2Severity = "high" AlertV2SeverityMedium AlertV2Severity = "medium" @@ -43,6 +47,7 @@ type AlertV2Interface interface { AlertV2EventInterface AlertV2MetricInterface AlertV2DowntimeInterface + AlertV2ChangeInterface } type AlertV2PrometheusInterface interface { @@ -69,6 +74,14 @@ type AlertV2MetricInterface interface { DeleteAlertV2Metric(ctx context.Context, alertID int) error } +type AlertV2ChangeInterface interface { + Base + CreateAlertV2Change(ctx context.Context, alert AlertV2Change) (AlertV2Change, error) + UpdateAlertV2Change(ctx context.Context, alert AlertV2Change) (AlertV2Change, error) + GetAlertV2Change(ctx context.Context, alertID int) (AlertV2Change, error) + DeleteAlertV2Change(ctx context.Context, alertID int) error +} + type AlertV2DowntimeInterface interface { Base CreateAlertV2Downtime(ctx context.Context, alert AlertV2Downtime) (AlertV2Downtime, error) @@ -370,6 +383,82 @@ func (client *Client) DeleteAlertV2Downtime(ctx context.Context, alertID int) er return client.deleteAlertV2(ctx, alertID) } +func (client *Client) CreateAlertV2Change(ctx context.Context, alert AlertV2Change) (AlertV2Change, error) { + err := client.addNotificationChannelType(ctx, alert.NotificationChannelConfigList) + if err != nil { + return AlertV2Change{}, err + } + + err = client.translateScopeSegmentLabels(ctx, &alert.Config.ScopedSegmentedConfig) + if err != nil { + return AlertV2Change{}, err + } + + payload, err := Marshal(alertV2ChangeWrapper{Alert: alert}) + if err != nil { + return AlertV2Change{}, err + } + + body, err := client.createAlertV2(ctx, payload) + if err != nil { + return AlertV2Change{}, err + } + + wrapper, err := Unmarshal[alertV2ChangeWrapper](body) + if err != nil { + return AlertV2Change{}, err + } + + return wrapper.Alert, nil +} + +func (client *Client) UpdateAlertV2Change(ctx context.Context, alert AlertV2Change) (AlertV2Change, error) { + err := client.addNotificationChannelType(ctx, alert.NotificationChannelConfigList) + if err != nil { + return AlertV2Change{}, err + } + + err = client.translateScopeSegmentLabels(ctx, &alert.Config.ScopedSegmentedConfig) + if err != nil { + return AlertV2Change{}, err + } + + payload, err := Marshal(alertV2ChangeWrapper{Alert: alert}) + if err != nil { + return AlertV2Change{}, err + } + + body, err := client.updateAlertV2(ctx, alert.ID, payload) + if err != nil { + return AlertV2Change{}, err + } + + wrapper, err := Unmarshal[alertV2ChangeWrapper](body) + if err != nil { + return AlertV2Change{}, err + } + + return wrapper.Alert, nil +} + +func (client *Client) GetAlertV2Change(ctx context.Context, alertID int) (AlertV2Change, error) { + body, err := client.getAlertV2(ctx, alertID) + if err != nil { + return AlertV2Change{}, err + } + + wrapper, err := Unmarshal[alertV2ChangeWrapper](body) + if err != nil { + return AlertV2Change{}, err + } + + return wrapper.Alert, nil +} + +func (client *Client) DeleteAlertV2Change(ctx context.Context, alertID int) error { + return client.deleteAlertV2(ctx, alertID) +} + func (client *Client) createAlertV2(ctx context.Context, alertJson io.Reader) (io.ReadCloser, error) { response, err := client.requester.Request(ctx, http.MethodPost, client.alertsV2URL(), alertJson) if err != nil { @@ -419,6 +508,9 @@ func (client *Client) getAlertV2(ctx context.Context, alertID int) (io.ReadClose } defer response.Body.Close() + if response.StatusCode == http.StatusNotFound { + return nil, AlertV2NotFound + } if response.StatusCode != http.StatusOK { return nil, client.ErrorFromResponse(response) } diff --git a/sysdig/internal/client/v2/model.go b/sysdig/internal/client/v2/model.go index e7f5db0d1..9d516a883 100644 --- a/sysdig/internal/client/v2/model.go +++ b/sysdig/internal/client/v2/model.go @@ -495,7 +495,6 @@ type AlertV2Common struct { Version int `json:"version,omitempty"` Name string `json:"name"` Description string `json:"description,omitempty"` - DurationSec int `json:"durationSec"` Type string `json:"type"` Group string `json:"group,omitempty"` Severity string `json:"severity"` @@ -514,7 +513,8 @@ type AlertV2ConfigPrometheus struct { type AlertV2Prometheus struct { AlertV2Common - Config AlertV2ConfigPrometheus `json:"config"` + DurationSec int `json:"durationSec"` + Config AlertV2ConfigPrometheus `json:"config"` } type alertV2PrometheusWrapper struct { @@ -556,7 +556,8 @@ type AlertV2ConfigEvent struct { type AlertV2Event struct { AlertV2Common - Config AlertV2ConfigEvent `json:"config"` + DurationSec int `json:"durationSec"` + Config AlertV2ConfigEvent `json:"config"` } type alertV2EventWrapper struct { @@ -596,7 +597,8 @@ type AlertV2ConfigMetric struct { type AlertV2Metric struct { AlertV2Common - Config AlertV2ConfigMetric `json:"config"` + DurationSec int `json:"durationSec"` + Config AlertV2ConfigMetric `json:"config"` } type alertV2MetricWrapper struct { @@ -617,13 +619,40 @@ type AlertV2ConfigDowntime struct { type AlertV2Downtime struct { AlertV2Common - Config AlertV2ConfigDowntime `json:"config"` + DurationSec int `json:"durationSec"` + Config AlertV2ConfigDowntime `json:"config"` } type alertV2DowntimeWrapper struct { Alert AlertV2Downtime `json:"alert"` } +type AlertV2ConfigChange struct { + ScopedSegmentedConfig + + ConditionOperator string `json:"conditionOperator"` + Threshold float64 `json:"threshold"` + WarningConditionOperator string `json:"warningConditionOperator,omitempty"` + WarningThreshold *float64 `json:"warningThreshold,omitempty"` + + GroupAggregation string `json:"groupAggregation"` + TimeAggregation string `json:"timeAggregation"` + Metric AlertMetricDescriptorV2 `json:"metric"` + + ShorterRangeSec int `json:"shorterRangeSec"` + LongerRangeSec int `json:"longerRangeSec"` +} + +type AlertV2Change struct { + AlertV2Common + DurationSec int `json:"durationSec"` // not really used but the api want it set to 0 in POST/PUT + Config AlertV2ConfigChange `json:"config"` +} + +type alertV2ChangeWrapper struct { + Alert AlertV2Change `json:"alert"` +} + type CloudAccountCredentialsMonitor struct { AccountId string `json:"accountId"` } diff --git a/sysdig/provider.go b/sysdig/provider.go index b7fb68d4e..8e4b82d66 100644 --- a/sysdig/provider.go +++ b/sysdig/provider.go @@ -144,6 +144,7 @@ func Provider() *schema.Provider { "sysdig_monitor_alert_v2_metric": resourceSysdigMonitorAlertV2Metric(), "sysdig_monitor_alert_v2_downtime": resourceSysdigMonitorAlertV2Downtime(), "sysdig_monitor_alert_v2_prometheus": resourceSysdigMonitorAlertV2Prometheus(), + "sysdig_monitor_alert_v2_change": resourceSysdigMonitorAlertV2Change(), "sysdig_monitor_dashboard": resourceSysdigMonitorDashboard(), "sysdig_monitor_notification_channel_email": resourceSysdigMonitorNotificationChannelEmail(), "sysdig_monitor_notification_channel_opsgenie": resourceSysdigMonitorNotificationChannelOpsGenie(), diff --git a/sysdig/resource_sysdig_monitor_alert_v2_change.go b/sysdig/resource_sysdig_monitor_alert_v2_change.go new file mode 100644 index 000000000..44dfaa6e7 --- /dev/null +++ b/sysdig/resource_sysdig_monitor_alert_v2_change.go @@ -0,0 +1,341 @@ +package sysdig + +import ( + "context" + "fmt" + "sort" + "strconv" + "time" + + v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func toIntSec(t time.Duration) int { + return int(t.Seconds()) +} + +var allowedTimeRanges = map[int]map[int]struct{}{ // for each shorter time range, a set of allowed longer time ranges + toIntSec(time.Minute * 5): { + toIntSec(time.Hour): {}, + toIntSec(time.Hour * 2): {}, + toIntSec(time.Hour * 3): {}, + }, + toIntSec(time.Minute * 10): { + toIntSec(time.Hour): {}, + toIntSec(time.Hour * 2): {}, + toIntSec(time.Hour * 3): {}, + toIntSec(time.Hour * 4): {}, + toIntSec(time.Hour * 5): {}, + toIntSec(time.Hour * 6): {}, + toIntSec(time.Hour * 7): {}, + toIntSec(time.Hour * 8): {}, + }, + toIntSec(time.Hour): { + toIntSec(time.Hour * 4): {}, + toIntSec(time.Hour * 5): {}, + toIntSec(time.Hour * 6): {}, + toIntSec(time.Hour * 7): {}, + toIntSec(time.Hour * 8): {}, + toIntSec(time.Hour * 9): {}, + toIntSec(time.Hour * 10): {}, + toIntSec(time.Hour * 11): {}, + toIntSec(time.Hour * 12): {}, + toIntSec(time.Hour * 13): {}, + toIntSec(time.Hour * 14): {}, + toIntSec(time.Hour * 15): {}, + toIntSec(time.Hour * 16): {}, + toIntSec(time.Hour * 17): {}, + toIntSec(time.Hour * 18): {}, + toIntSec(time.Hour * 19): {}, + toIntSec(time.Hour * 20): {}, + toIntSec(time.Hour * 21): {}, + toIntSec(time.Hour * 22): {}, + toIntSec(time.Hour * 23): {}, + toIntSec(time.Hour * 24): {}, + }, + toIntSec(time.Hour * 4): { + toIntSec(time.Hour * 24): {}, + toIntSec(time.Hour * 24 * 2): {}, + toIntSec(time.Hour * 24 * 3): {}, + toIntSec(time.Hour * 24 * 4): {}, + toIntSec(time.Hour * 24 * 5): {}, + toIntSec(time.Hour * 24 * 6): {}, + toIntSec(time.Hour * 24 * 7): {}, + }, + toIntSec(time.Hour * 24): { + toIntSec(time.Hour * 24 * 7): {}, + }, +} + +func resourceSysdigMonitorAlertV2Change() *schema.Resource { + + timeout := 5 * time.Minute + + return &schema.Resource{ + CreateContext: resourceSysdigMonitorAlertV2ChangeCreate, + UpdateContext: resourceSysdigMonitorAlertV2ChangeUpdate, + ReadContext: resourceSysdigMonitorAlertV2ChangeRead, + DeleteContext: resourceSysdigMonitorAlertV2ChangeDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(timeout), + Update: schema.DefaultTimeout(timeout), + Read: schema.DefaultTimeout(timeout), + Delete: schema.DefaultTimeout(timeout), + }, + + Schema: createScopedSegmentedAlertV2Schema(createAlertV2Schema(map[string]*schema.Schema{ + "operator": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{">", ">=", "<", "<=", "=", "!="}, false), + }, + "threshold": { + Type: schema.TypeFloat, + Required: true, + }, + "warning_threshold": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "metric": { + Type: schema.TypeString, + Required: true, + }, + "time_aggregation": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"avg", "timeAvg", "sum", "min", "max"}, false), + }, + "group_aggregation": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"avg", "sum", "min", "max"}, false), + }, + "shorter_time_range_seconds": { + Type: schema.TypeInt, + Required: true, + }, + "longer_time_range_seconds": { + Type: schema.TypeInt, + Required: true, + }, + })), + + CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { + shorterTimeRangeSeconds := diff.Get("shorter_time_range_seconds").(int) + longerTimeRangeSeconds := diff.Get("longer_time_range_seconds").(int) + + if _, ok := allowedTimeRanges[shorterTimeRangeSeconds]; !ok { + var allowedValues []int + for k := range allowedTimeRanges { + allowedValues = append(allowedValues, k) + } + sort.Ints(allowedValues) + return fmt.Errorf("shorter_time_range_seconds can only have one of the following values: %v, provided: %v", allowedValues, shorterTimeRangeSeconds) + } + + if _, ok := allowedTimeRanges[shorterTimeRangeSeconds][longerTimeRangeSeconds]; !ok { + var allowedValues []int + for k := range allowedTimeRanges[shorterTimeRangeSeconds] { + allowedValues = append(allowedValues, k) + } + sort.Ints(allowedValues) + return fmt.Errorf("longer_time_range_seconds can only have one of the following values if shorter_time_range_seconds is %v: %v, provided: %v", shorterTimeRangeSeconds, allowedValues, longerTimeRangeSeconds) + } + + return nil + }, + } +} + +func getAlertV2ChangeClient(c SysdigClients) (v2.AlertV2ChangeInterface, error) { + return getAlertV2Client(c) +} + +func resourceSysdigMonitorAlertV2ChangeCreate(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + client, err := getAlertV2ChangeClient(i.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + a, err := buildAlertV2ChangeStruct(d) + if err != nil { + return diag.FromErr(err) + } + + aCreated, err := client.CreateAlertV2Change(ctx, *a) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(strconv.Itoa(aCreated.ID)) + + err = updateAlertV2ChangeState(d, &aCreated) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceSysdigMonitorAlertV2ChangeRead(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + client, err := getAlertV2ChangeClient(i.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + a, err := client.GetAlertV2Change(ctx, id) + if err != nil { + if err == v2.AlertV2NotFound { + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + err = updateAlertV2ChangeState(d, &a) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceSysdigMonitorAlertV2ChangeUpdate(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + client, err := getAlertV2ChangeClient(i.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + a, err := buildAlertV2ChangeStruct(d) + if err != nil { + return diag.FromErr(err) + } + + a.ID, _ = strconv.Atoi(d.Id()) + + aUpdated, err := client.UpdateAlertV2Change(ctx, *a) + if err != nil { + return diag.FromErr(err) + } + + err = updateAlertV2ChangeState(d, &aUpdated) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceSysdigMonitorAlertV2ChangeDelete(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + client, err := getAlertV2ChangeClient(i.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + err = client.DeleteAlertV2Change(ctx, id) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func buildAlertV2ChangeStruct(d *schema.ResourceData) (*v2.AlertV2Change, error) { + alertV2Common := buildAlertV2CommonStruct(d) + alertV2Common.Type = string(v2.AlertV2TypeChange) + config := v2.AlertV2ConfigChange{} + + buildScopedSegmentedConfigStruct(d, &config.ScopedSegmentedConfig) + + //ConditionOperator + config.ConditionOperator = d.Get("operator").(string) + + //threshold + config.Threshold = d.Get("threshold").(float64) + + //WarningThreshold + if warningThreshold, ok := d.GetOk("warning_threshold"); ok { + wts := warningThreshold.(string) + wt, err := strconv.ParseFloat(wts, 64) + if err != nil { + return nil, fmt.Errorf("cannot convert warning_threshold to a number: %w", err) + } + config.WarningThreshold = &wt + config.WarningConditionOperator = config.ConditionOperator + } + + //TimeAggregation + config.TimeAggregation = d.Get("time_aggregation").(string) + + //GroupAggregation + config.GroupAggregation = d.Get("group_aggregation").(string) + + //Metric + metric := d.Get("metric").(string) + config.Metric.ID = metric + + //ShorterRangeSec + config.ShorterRangeSec = d.Get("shorter_time_range_seconds").(int) + + //LongerRangeSec + config.LongerRangeSec = d.Get("longer_time_range_seconds").(int) + + alert := &v2.AlertV2Change{ + AlertV2Common: *alertV2Common, + DurationSec: 0, + Config: config, + } + return alert, nil +} + +func updateAlertV2ChangeState(d *schema.ResourceData, alert *v2.AlertV2Change) error { + err := updateAlertV2CommonState(d, &alert.AlertV2Common) + if err != nil { + return err + } + + err = updateScopedSegmentedConfigState(d, &alert.Config.ScopedSegmentedConfig) + if err != nil { + return err + } + + _ = d.Set("operator", alert.Config.ConditionOperator) + + _ = d.Set("threshold", alert.Config.Threshold) + + if alert.Config.WarningThreshold != nil { + _ = d.Set("warning_threshold", fmt.Sprintf("%v", *alert.Config.WarningThreshold)) + } + + _ = d.Set("time_aggregation", alert.Config.TimeAggregation) + + _ = d.Set("group_aggregation", alert.Config.GroupAggregation) + + _ = d.Set("metric", alert.Config.Metric.ID) + + _ = d.Set("shorter_time_range_seconds", alert.Config.ShorterRangeSec) + + _ = d.Set("longer_time_range_seconds", alert.Config.LongerRangeSec) + + return nil +} diff --git a/sysdig/resource_sysdig_monitor_alert_v2_change_test.go b/sysdig/resource_sysdig_monitor_alert_v2_change_test.go new file mode 100644 index 000000000..5986efab2 --- /dev/null +++ b/sysdig/resource_sysdig_monitor_alert_v2_change_test.go @@ -0,0 +1,330 @@ +//go:build tf_acc_sysdig_monitor || tf_acc_ibm_monitor + +package sysdig_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/draios/terraform-provider-sysdig/sysdig" +) + +func TestAccAlertV2Change(t *testing.T) { + rText := func() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: preCheckAnyEnv(t, SysdigMonitorApiTokenEnv, SysdigIBMMonitorAPIKeyEnv), + ProviderFactories: map[string]func() (*schema.Provider, error){ + "sysdig": func() (*schema.Provider, error) { + return sysdig.Provider(), nil + }, + }, + Steps: []resource.TestStep{ + { + Config: alertV2Change(rText()), + }, + { + Config: alertV2ChangeWithScope(rText()), + }, + { + Config: alertV2ChangeWithNotificationChannels(rText()), + }, + { + Config: alertV2ChangeWithDescription(rText()), + }, + { + Config: alertV2ChangeWithSeverity(rText()), + }, + { + Config: alertV2ChangeWithGroupBy(rText()), + }, + { + Config: alertV2ChangeWithGroup(rText()), + }, + { + Config: alertV2ChangeWithCustomNotifications(rText()), + }, + { + Config: alertV2ChangeWithLink(rText()), + }, + { + Config: alertV2ChangeWithEnabled(rText()), + }, + { + Config: alertV2ChangeWithWarningThreshold(rText()), + }, + { + ResourceName: "sysdig_monitor_alert_v2_change.sample", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func alertV2Change(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 +} +`, name) +} + +func alertV2ChangeWithScope(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + scope { + label = "kube_cluster_name" + operator = "in" + values = ["thom-cluster1", "demo-env-prom"] + } + scope { + label = "kube_cluster_name" + operator = "equals" + values = ["thom-cluster3"] + } +} + `, name) +} + +func alertV2ChangeWithNotificationChannels(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_notification_channel_email" "nc_email1" { + name = "%s1" + recipients = ["root@localhost.com"] +} + +resource "sysdig_monitor_notification_channel_email" "nc_email2" { + name = "%s2" + recipients = ["root@localhost.com"] +} + +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + enabled = false + notification_channels { + id = sysdig_monitor_notification_channel_email.nc_email1.id + notify_on_resolve = false + } + notification_channels { + id = sysdig_monitor_notification_channel_email.nc_email2.id + renotify_every_minutes = 30 + } +} +`, name, name, name) +} + +func alertV2ChangeWithDescription(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + description = "description" +} +`, name) +} + +func alertV2ChangeWithSeverity(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + severity = "high" +} +`, name) +} + +func alertV2ChangeWithGroupBy(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + group_by = ["kube_cluster_name", "cloud_provider_tag_Owner",] +} + `, name) +} + +func alertV2ChangeWithGroup(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + group = "customgroup" +} +`, name) +} + +func alertV2ChangeWithCustomNotifications(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + custom_notification { + subject = "test" + prepend = "pre" + append = "post" + } +} +`, name) +} + +func alertV2ChangeWithLink(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_dashboard" "dashboard" { + name = "TERRAFORM TEST - CHANGE %s" + description = "TERRAFORM TEST - CHANGE %s" + + panel { + pos_x = 0 + pos_y = 0 + width = 12 # Maximum size: 24 + height = 6 + type = "timechart" + name = "example panel" + description = "description" + + legend { + show_current = true + position = "bottom" + layout = "inline" + } + + query { + promql = "avg(avg_over_time(sysdig_host_cpu_used_percent[$__interval]))" + unit = "percent" + format { + display_format = "auto" + input_format = "0-100" + y_axis = "auto" + null_value_display_mode = "nullGap" + } + } + } +} + +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + link { + type = "runbook" + href = "http://ciao2.com" + } + link { + type = "dashboard" + id = sysdig_monitor_dashboard.dashboard.id + } +} +`, name, name, name) +} + +func alertV2ChangeWithEnabled(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + enabled = false +} +`, name) +} + +func alertV2ChangeWithWarningThreshold(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_notification_channel_email" "nc_email1" { + name = "%s1" + recipients = ["root@localhost.com"] +} + +resource "sysdig_monitor_notification_channel_email" "nc_email2" { + name = "%s2" + recipients = ["root@localhost.com"] +} + +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + enabled = false + warning_threshold = 10 + notification_channels { + id = sysdig_monitor_notification_channel_email.nc_email1.id + } + notification_channels { + id = sysdig_monitor_notification_channel_email.nc_email2.id + warning_threshold = true + } +} +`, name, name, name) +} diff --git a/sysdig/resource_sysdig_monitor_alert_v2_common.go b/sysdig/resource_sysdig_monitor_alert_v2_common.go index 7b938ec3a..3a533c563 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_common.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_common.go @@ -38,10 +38,6 @@ func createAlertV2Schema(original map[string]*schema.Schema) map[string]*schema. Default: string(v2.AlertV2SeverityLow), ValidateFunc: validation.StringInSlice(AlertV2SeverityValues(), true), }, - "trigger_after_minutes": { - Type: schema.TypeInt, - Required: true, - }, "group": { Type: schema.TypeString, Optional: true, @@ -205,11 +201,10 @@ func AlertLinkV2TypeValues() []string { func buildAlertV2CommonStruct(d *schema.ResourceData) *v2.AlertV2Common { alert := &v2.AlertV2Common{ - Name: d.Get("name").(string), - Type: "MANUAL", - DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), - Severity: d.Get("severity").(string), - Enabled: d.Get("enabled").(bool), + Name: d.Get("name").(string), + Type: "MANUAL", + Severity: d.Get("severity").(string), + Enabled: d.Get("enabled").(bool), } if description, ok := d.GetOk("description"); ok { @@ -311,7 +306,6 @@ func buildAlertV2CommonStruct(d *schema.ResourceData) *v2.AlertV2Common { func updateAlertV2CommonState(d *schema.ResourceData, alert *v2.AlertV2Common) (err error) { _ = d.Set("name", alert.Name) _ = d.Set("description", alert.Description) - _ = d.Set("trigger_after_minutes", secondsToMinutes(alert.DurationSec)) _ = d.Set("severity", alert.Severity) // optional with defaults diff --git a/sysdig/resource_sysdig_monitor_alert_v2_downtime.go b/sysdig/resource_sysdig_monitor_alert_v2_downtime.go index 54e058a9a..d77f64960 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_downtime.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_downtime.go @@ -33,6 +33,10 @@ func resourceSysdigMonitorAlertV2Downtime() *schema.Resource { }, Schema: createScopedSegmentedAlertV2Schema(createAlertV2Schema(map[string]*schema.Schema{ + "trigger_after_minutes": { + Type: schema.TypeInt, + Required: true, + }, "threshold": { Type: schema.TypeFloat, Optional: true, @@ -86,10 +90,12 @@ func resourceSysdigMonitorAlertV2DowntimeRead(ctx context.Context, d *schema.Res } a, err := client.GetAlertV2Downtime(ctx, id) - if err != nil { - d.SetId("") - return nil + if err == v2.AlertV2NotFound { + d.SetId("") + return nil + } + return diag.FromErr(err) } err = updateAlertV2DowntimeState(d, &a) @@ -169,6 +175,7 @@ func buildAlertV2DowntimeStruct(d *schema.ResourceData) *v2.AlertV2Downtime { alert := &v2.AlertV2Downtime{ AlertV2Common: *alertV2Common, + DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), Config: config, } return alert @@ -185,6 +192,8 @@ func updateAlertV2DowntimeState(d *schema.ResourceData, alert *v2.AlertV2Downtim return err } + _ = d.Set("trigger_after_minutes", secondsToMinutes(alert.DurationSec)) + _ = d.Set("threshold", (1-alert.Config.Threshold)*100) _ = d.Set("metric", alert.Config.Metric.ID) diff --git a/sysdig/resource_sysdig_monitor_alert_v2_event.go b/sysdig/resource_sysdig_monitor_alert_v2_event.go index 6f64f6012..5b45c3a4a 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_event.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_event.go @@ -34,6 +34,10 @@ func resourceSysdigMonitorAlertV2Event() *schema.Resource { }, Schema: createScopedSegmentedAlertV2Schema(createAlertV2Schema(map[string]*schema.Schema{ + "trigger_after_minutes": { + Type: schema.TypeInt, + Required: true, + }, "operator": { Type: schema.TypeString, Required: true, @@ -103,12 +107,13 @@ func resourceSysdigMonitorAlertV2EventRead(ctx context.Context, d *schema.Resour } a, err := client.GetAlertV2Event(ctx, id) - if err != nil { - d.SetId("") - return nil + if err == v2.AlertV2NotFound { + d.SetId("") + return nil + } + return diag.FromErr(err) } - err = updateAlertV2EventState(d, &a) if err != nil { return diag.FromErr(err) @@ -201,6 +206,7 @@ func buildAlertV2EventStruct(d *schema.ResourceData) (*v2.AlertV2Event, error) { alert := &v2.AlertV2Event{ AlertV2Common: *alertV2Common, + DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), Config: config, } return alert, nil @@ -217,6 +223,8 @@ func updateAlertV2EventState(d *schema.ResourceData, alert *v2.AlertV2Event) err return err } + _ = d.Set("trigger_after_minutes", secondsToMinutes(alert.DurationSec)) + _ = d.Set("operator", alert.Config.ConditionOperator) _ = d.Set("threshold", alert.Config.Threshold) diff --git a/sysdig/resource_sysdig_monitor_alert_v2_metric.go b/sysdig/resource_sysdig_monitor_alert_v2_metric.go index 9ea426939..487cf2a75 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_metric.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_metric.go @@ -34,6 +34,10 @@ func resourceSysdigMonitorAlertV2Metric() *schema.Resource { }, Schema: createScopedSegmentedAlertV2Schema(createAlertV2Schema(map[string]*schema.Schema{ + "trigger_after_minutes": { + Type: schema.TypeInt, + Required: true, + }, "operator": { Type: schema.TypeString, Required: true, @@ -114,10 +118,12 @@ func resourceSysdigMonitorAlertV2MetricRead(ctx context.Context, d *schema.Resou } a, err := client.GetAlertV2Metric(ctx, id) - if err != nil { - d.SetId("") - return nil + if err == v2.AlertV2NotFound { + d.SetId("") + return nil + } + return diag.FromErr(err) } err = updateAlertV2MetricState(d, &a) @@ -211,6 +217,7 @@ func buildAlertV2MetricStruct(d *schema.ResourceData) (*v2.AlertV2Metric, error) alert := &v2.AlertV2Metric{ AlertV2Common: *alertV2Common, + DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), Config: config, } return alert, nil @@ -227,6 +234,8 @@ func updateAlertV2MetricState(d *schema.ResourceData, alert *v2.AlertV2Metric) e return err } + _ = d.Set("trigger_after_minutes", secondsToMinutes(alert.DurationSec)) + _ = d.Set("operator", alert.Config.ConditionOperator) _ = d.Set("threshold", alert.Config.Threshold) diff --git a/sysdig/resource_sysdig_monitor_alert_v2_prometheus.go b/sysdig/resource_sysdig_monitor_alert_v2_prometheus.go index 29dd41b62..9e0b6726f 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_prometheus.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_prometheus.go @@ -32,6 +32,10 @@ func resourceSysdigMonitorAlertV2Prometheus() *schema.Resource { }, Schema: createAlertV2Schema(map[string]*schema.Schema{ + "trigger_after_minutes": { + Type: schema.TypeInt, + Required: true, + }, "query": { Type: schema.TypeString, Required: true, @@ -84,10 +88,12 @@ func resourceSysdigMonitorAlertV2PrometheusRead(ctx context.Context, d *schema.R } a, err := client.GetAlertV2Prometheus(ctx, id) - if err != nil { - d.SetId("") - return nil + if err == v2.AlertV2NotFound { + d.SetId("") + return nil + } + return diag.FromErr(err) } err = updateAlertV2PrometheusState(d, &a) @@ -153,6 +159,7 @@ func buildAlertV2PrometheusStruct(d *schema.ResourceData) *v2.AlertV2Prometheus alert := &v2.AlertV2Prometheus{ AlertV2Common: *alertV2Common, + DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), Config: config, } return alert @@ -164,7 +171,10 @@ func updateAlertV2PrometheusState(d *schema.ResourceData, alert *v2.AlertV2Prome return } + _ = d.Set("trigger_after_minutes", secondsToMinutes(alert.DurationSec)) + _ = d.Set("query", alert.Config.Query) + if alert.Config.KeepFiringForSec != nil { _ = d.Set("keep_firing_for_minutes", *alert.Config.KeepFiringForSec/60) } else { diff --git a/website/docs/index.md b/website/docs/index.md index 4df33eab9..82b47ca57 100644 --- a/website/docs/index.md +++ b/website/docs/index.md @@ -246,6 +246,7 @@ When IBM Workload Protection resources are to be created, this authentication mu > - `sysdig_monitor_alert_v2_event` > - `sysdig_monitor_alert_v2_metric` > - `sysdig_monitor_alert_v2_prometheus` +> - `sysdig_monitor_alert_v2_change` > - `sysdig_monitor_dashboard` > - `sysdig_secure_posture_zone` > diff --git a/website/docs/r/monitor_alert_anomaly.md b/website/docs/r/monitor_alert_anomaly.md index fe19de3c3..838af033c 100644 --- a/website/docs/r/monitor_alert_anomaly.md +++ b/website/docs/r/monitor_alert_anomaly.md @@ -26,9 +26,9 @@ resource "sysdig_monitor_alert_anomaly" "sample" { trigger_after_minutes = 10 - multiple_alerts_by = ["kubernetes.cluster.name", - "kubernetes.namespace.name", - "kubernetes.deployment.name", + multiple_alerts_by = ["kubernetes.cluster.name", + "kubernetes.namespace.name", + "kubernetes.deployment.name", "kubernetes.pod.name"] } ``` @@ -44,7 +44,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `severity` - (Optional) Severity of the Monitor alert. It must be a value between 0 and 7, with 0 being the most critical and 7 the less critical. Defaults to 4. * `trigger_after_minutes` - (Required) Threshold of time for the status to stabilize until the alert is fired. -* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. +* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Defaults to true. * `group_name` - (Optional) Lowercase string to group alerts in the UI * `notification_channels` - (Optional) List of notification channel IDs where an alert must be sent to once fired. @@ -62,8 +62,7 @@ Enables the creation of a capture file of the syscalls during the event. ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `title` - (Required) Sets the title of the alert. It is commonly defined as `{{__alert_name__}} is {{__alert_status__}}`. * `prepend` - (Optional) Text to add before the alert template. @@ -72,7 +71,7 @@ is fired. ### Anomaly alert arguments * `monitor` - (Required) Array of metrics to monitor and alert on. Example: `["cpu.used.percent", "cpu.cores.used", "memory.bytes.used", "fs.used.percent", "thread.count", "net.request.count.in"]`. -* `multiple_alerts_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kubernetes.cluster.name", "kubernetes.namespace.name"]`. +* `multiple_alerts_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kubernetes.cluster.name", "kubernetes.namespace.name"]`. ## Attributes Reference @@ -80,8 +79,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. diff --git a/website/docs/r/monitor_alert_downtime.md b/website/docs/r/monitor_alert_downtime.md index 8bd0a4335..9cfaf0a17 100644 --- a/website/docs/r/monitor_alert_downtime.md +++ b/website/docs/r/monitor_alert_downtime.md @@ -21,7 +21,7 @@ resource "sysdig_monitor_alert_downtime" "sample" { severity = 2 entities_to_monitor = ["kubernetes.namespace.name"] - + trigger_after_minutes = 10 trigger_after_pct = 100 } @@ -38,7 +38,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `severity` - (Optional) Severity of the Monitor alert. It must be a value between 0 and 7, with 0 being the most critical and 7 the less critical. Defaults to 4. * `trigger_after_minutes` - (Required) Threshold of time for the status to stabilize until the alert is fired. -* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. +* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Defaults to true. * `group_name` - (Optional) Lowercase string to group alerts in the UI * `notification_channels` - (Optional) List of notification channel IDs where an alert must be sent to once fired. @@ -56,8 +56,7 @@ Enables the creation of a capture file of the syscalls during the event. ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `title` - (Required) Sets the title of the alert. It is commonly defined as `{{__alert_name__}} is {{__alert_status__}}`. * `prepend` - (Optional) Text to add before the alert template. @@ -66,7 +65,7 @@ is fired. ### Downtime alert arguments * `entities_to_monitor` - (Required) List of metrics to monitor downtime and alert on. Example: `["kubernetes.namespace.name"]` to detect namespace removal or `["host.hostName"]` to detect host downtime. -* `trigger_after_pct` - (Optional) Below of this percentage of downtime the alert will be triggered. Defaults to 100. +* `trigger_after_pct` - (Optional) Below of this percentage of downtime the alert will be triggered. Defaults to 100. ## Attributes Reference @@ -74,8 +73,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -84,8 +82,8 @@ alerts in Sysdig Monitor: ## Import -Downtime Monitor alerts can be imported using the alert ID, e.g. +Downtime alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_downtime.example 12345 -``` \ No newline at end of file +``` diff --git a/website/docs/r/monitor_alert_event.md b/website/docs/r/monitor_alert_event.md index 3068ecad5..c0cc78c5e 100644 --- a/website/docs/r/monitor_alert_event.md +++ b/website/docs/r/monitor_alert_event.md @@ -8,8 +8,8 @@ description: |- # Resource: sysdig_monitor_alert_event -Creates a Sysdig Monitor Event Alert. Monitor occurrences of specific events, and alert if the total -number of occurrences violates a threshold. Useful for alerting on container, orchestration, and +Creates a Sysdig Monitor Event Alert. Monitor occurrences of specific events, and alert if the total +number of occurrences violates a threshold. Useful for alerting on container, orchestration, and service events like restarts and deployments. -> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. @@ -28,7 +28,7 @@ resource "sysdig_monitor_alert_event" "sample" { event_count = 0 multiple_alerts_by = ["kubernetes.pod.name"] - + trigger_after_minutes = 1 } ``` @@ -44,7 +44,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `severity` - (Optional) Severity of the Monitor alert. It must be a value between 0 and 7, with 0 being the most critical and 7 the less critical. Defaults to 4. * `trigger_after_minutes` - (Required) Threshold of time for the status to stabilize until the alert is fired. -* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. +* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Defaults to true. * `group_name` - (Optional) Lowercase string to group alerts in the UI * `notification_channels` - (Optional) List of notification channel IDs where an alert must be sent to once fired. @@ -62,8 +62,7 @@ Enables the creation of a capture file of the syscalls during the event. ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `title` - (Required) Sets the title of the alert. It is commonly defined as `{{__alert_name__}} is {{__alert_status__}}`. * `prepend` - (Optional) Text to add before the alert template. @@ -72,10 +71,10 @@ is fired. ### Event alert arguments * `event_name` - (Required) String that matches part of name, tag or the description of Sysdig Events. -* `source` - (Required) Source of the event. It can be `docker` or `kubernetes`. +* `source` - (Required) Source of the event. It can be `docker` or `kubernetes`. * `event_rel` - (Required) Relationship of the event count. It can be `>`, `>=`, `<`, `<=`, `=` or `!=`. * `event_count` - (Required) Number of events to match with event_rel. -* `multiple_alerts_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kubernetes.cluster.name", "kubernetes.namespace.name"]`. +* `multiple_alerts_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kubernetes.cluster.name", "kubernetes.namespace.name"]`. ## Attributes Reference @@ -83,8 +82,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -93,8 +91,8 @@ alerts in Sysdig Monitor: ## Import -Event Monitor alerts can be imported using the alert ID, e.g. +Event alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_event.example 12345 -``` \ No newline at end of file +``` diff --git a/website/docs/r/monitor_alert_group_outlier.md b/website/docs/r/monitor_alert_group_outlier.md index 0dd7b6355..6a55b51e4 100644 --- a/website/docs/r/monitor_alert_group_outlier.md +++ b/website/docs/r/monitor_alert_group_outlier.md @@ -23,7 +23,7 @@ resource "sysdig_monitor_alert_group_outlier" "sample" { severity = 6 monitor = ["cpu.used.percent"] - + trigger_after_minutes = 10 capture { @@ -44,7 +44,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `severity` - (Optional) Severity of the Monitor alert. It must be a value between 0 and 7, with 0 being the most critical and 7 the less critical. Defaults to 4. * `trigger_after_minutes` - (Required) Threshold of time for the status to stabilize until the alert is fired. -* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. +* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Defaults to true. * `group_name` - (Optional) Lowercase string to group alerts in the UI * `notification_channels` - (Optional) List of notification channel IDs where an alert must be sent to once fired. @@ -62,8 +62,7 @@ Enables the creation of a capture file of the syscalls during the event. ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `title` - (Required) Sets the title of the alert. It is commonly defined as `{{__alert_name__}} is {{__alert_status__}}`. * `prepend` - (Optional) Text to add before the alert template. @@ -71,7 +70,7 @@ is fired. ### Group Outlier alert arguments -* `monitor` - (Required) Array of metrics to monitor and alert on. Example: `["cpu.used.percent", "cpu.cores.used", "memory.bytes.used", "fs.used.percent", "thread.count", "net.request.count.in"]`. +* `monitor` - (Required) Array of metrics to monitor and alert on. Example: `["cpu.used.percent", "cpu.cores.used", "memory.bytes.used", "fs.used.percent", "thread.count", "net.request.count.in"]`. ## Attributes Reference @@ -79,8 +78,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -89,7 +87,7 @@ alerts in Sysdig Monitor: ## Import -Group Outlier Monitor alerts can be imported using the alert ID, e.g. +Group Outlier alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_group_outlier.example 12345 diff --git a/website/docs/r/monitor_alert_metric.md b/website/docs/r/monitor_alert_metric.md index 3dac150c3..fd5c3a68f 100644 --- a/website/docs/r/monitor_alert_metric.md +++ b/website/docs/r/monitor_alert_metric.md @@ -46,7 +46,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `severity` - (Optional) Severity of the Monitor alert. It must be a value between 0 and 7, with 0 being the most critical and 7 the less critical. Defaults to 4. * `trigger_after_minutes` - (Required) Threshold of time for the status to stabilize until the alert is fired. -* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. +* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Defaults to true. * `group_name` - (Optional) Lowercase string to group alerts in the UI * `notification_channels` - (Optional) List of notification channel IDs where an alert must be sent to once fired. @@ -64,8 +64,7 @@ Enables the creation of a capture file of the syscalls during the event. ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `title` - (Required) Sets the title of the alert. It is commonly defined as `{{__alert_name__}} is {{__alert_status__}}`. * `prepend` - (Optional) Text to add before the alert template. @@ -74,7 +73,7 @@ is fired. ### Metric alert arguments * `metric` - (Required) Metric to monitor and alert on. Example: `sum(timeAvg(kubernetes.pod.restart.count)) > 2` or `avg(avg(cpu.used.percent)) > 50`. -* `multiple_alerts_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kubernetes.cluster.name", "kubernetes.namespace.name"]`. +* `multiple_alerts_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kubernetes.cluster.name", "kubernetes.namespace.name"]`. ## Attributes Reference @@ -82,8 +81,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -92,8 +90,8 @@ alerts in Sysdig Monitor: ## Import -Metric Monitor alerts can be imported using the alert ID, e.g. +Metric alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_metric.example 12345 -``` \ No newline at end of file +``` diff --git a/website/docs/r/monitor_alert_promql.md b/website/docs/r/monitor_alert_promql.md index d5333a4f2..b0fe85a9e 100644 --- a/website/docs/r/monitor_alert_promql.md +++ b/website/docs/r/monitor_alert_promql.md @@ -44,8 +44,7 @@ These arguments are common to all alerts in Sysdig Monitor. ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `title` - (Required) Sets the title of the alert. It is commonly defined as `{{__alert_name__}} is {{__alert_status__}}`. * `prepend` - (Optional) Text to add before the alert template. @@ -61,8 +60,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -71,7 +69,7 @@ alerts in Sysdig Monitor: ## Import -PromQL Monitor alerts can be imported using the alert ID, e.g. +PromQL alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_promql.example 12345 diff --git a/website/docs/r/monitor_alert_v2_change.md b/website/docs/r/monitor_alert_v2_change.md new file mode 100644 index 000000000..806704a76 --- /dev/null +++ b/website/docs/r/monitor_alert_v2_change.md @@ -0,0 +1,133 @@ +--- +subcategory: "Sysdig Monitor" +layout: "sysdig" +page_title: "Sysdig: sysdig_monitor_alert_v2_change" +description: |- + Creates a Sysdig Monitor Change Alert with AlertV2 API. +--- + +# Resource: sysdig_monitor_alert_v2_change + +Creates a Sysdig Monitor Change Alert. Change Alerts trigger when a metric value substantially deviates compared to historical values. + +-> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. + +## Example Usage + +```terraform +resource "sysdig_monitor_alert_v2_change" "sample" { + + name = "high cpu used compared to previous periods" + severity = "high" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">" + threshold = 75 + group_by = ["kube_pod_name"] + + scope { + label = "kube_cluster_name" + operator = "in" + values = ["my_cluster_1", "my_cluster_2"] + } + + scope { + label = "kube_deployment_name" + operator = "equals" + values = ["my_deployment"] + } + + notification_channels { + id = 1234 + renotify_every_minutes = 60 + } + + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + +} + +``` + +## Argument Reference + +### Common alert arguments + +These arguments are common to all alerts in Sysdig Monitor. + +* `name` - (Required) The name of the Monitor alert. It must be unique. +* `description` - (Optional) The description of Monitor alert. +* `group` - (Optional) Lowercase string to group alerts in the UI. +* `severity` - (Optional) Severity of the Monitor alert. It must be `high`, `medium`, `low` or `info`. Default: `low`. +* `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Default: `true`. +* `notification_channels` - (Optional) List of notification channel configurations. +* `custom_notification` - (Optional) Allows to define a custom notification title, prepend and append text. +* `link` - (Optional) List of links to add to notifications. + +### `notification_channels` + +By defining this field, the user can choose to which notification channels send the events when the alert fires. + +It is a list of objects with the following fields: +* `id` - (Required) The ID of the notification channel. +* `renotify_every_minutes` - (Optional) the amount of minutes to wait before re sending the notification to this channel. `0` means no renotification enabled. Default: `0`. +* `notify_on_resolve` - (Optional) Wether to send a notification when the alert is resolved. Default: `true`. +* `main_threshold` - (Optional) Whether this notification channel is used for the main threshold of the alert. Default: `true`. +* `warning_threshold` - (Optional) Whether this notification channel is used for the warning threshold of the alert. Default: `false`. + +### `custom_notification` + +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. + +* `subject` - (Optional) Sets the title of the alert. +* `prepend` - (Optional) Text to add before the alert template. +* `append` - (Optional) Text to add after the alert template. + +### `link` + +By defining this field, the user can add link to notifications. + +* `type` - (Required) Type of link. Must be `runbook`, for generic links, or `dashboard`, for internal links to existing dashboards. +* `href` - (Optional) When using `runbook` type, url of the external resource. +* `id` - (Optional) When using `dashboard` type, dashboard id. + +### Change alert arguments + +* `scope` - (Optional) Part of the infrastructure where the alert is valid. Defaults to the entire infrastructure. Can be repeated. +* `group_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kube_cluster_name", "kube_pod_name"]`. +* `metric` - (Required) Metric the alert will act upon. +* `time_aggregation` - (Required) time aggregation function for data. It can be `avg`, `timeAvg`, `sum`, `min`, `max`. +* `group_aggregation` - (Required) group aggregation function for data. It can be `avg`, `sum`, `min`, `max`. +* `operator` - (Required) Operator for the condition to alert on. It can be `>`, `>=`, `<`, `<=`, `=` or `!=`. +* `threshold` - (Required) Threshold used together with `op` to trigger the alert if crossed. +* `warning_threshold` - (Optional) Warning threshold used together with `op` to trigger the alert if crossed. Must be a number lower than `threshold`. +* `shorter_time_range_seconds` - (Required) Time range for which data is compared to a longer, previous period. Can be one of `300` (5 minutes), `600` (10 minutes), `3600` (1 hour), `14400` (4 hours), `86400` (1 day). +* `longer_time_range_seconds` - (Required) Time range for which data will be used as baseline for comparisons with data in the time range defined in `shorter_time_range_seconds`. Possible values depend on `shorter_time_range_seconds`: for a shorter time range of 5 minutes, longer time range can be 1, 2 or 3 hours, for a shorter time range or 10 minutes, it can be from 1 to 8 hours, for a shorter time range or one hour, it can be from 4 to 24 hours, for a shorter time range of 4 hours, it can be from 1 to 7 days, for a shorter time range of one day, it can only be 7 days. + +### `scope` + +* `label` - (Required) Label in prometheus notation to select a part of the infrastructure. +* `operator` - (Required) Operator to match the label. It can be `equals`, `notEquals`, `in`, `notIn`, `contains`, `notContains`, `startsWith`. +* `values` - (Required) List of values to match the scope. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +### Common alert attributes + +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: + +* `id` - ID of the alert created. +* `version` - Current version of the resource in Sysdig Monitor. +* `team` - Team ID that owns the alert. + + +## Import + +Change alerts can be imported using the alert ID, e.g. + +``` +$ terraform import sysdig_monitor_alert_v2_change.example 12345 +``` diff --git a/website/docs/r/monitor_alert_v2_downtime.md b/website/docs/r/monitor_alert_v2_downtime.md index 03e124801..c568eb269 100644 --- a/website/docs/r/monitor_alert_v2_downtime.md +++ b/website/docs/r/monitor_alert_v2_downtime.md @@ -51,7 +51,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `group` - (Optional) Lowercase string to group alerts in the UI. * `severity` - (Optional) Severity of the Monitor alert. It must be `high`, `medium`, `low` or `info`. Default: `low`. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Default: `true`. -* `notification_channels` - (Optional) List of notification channel configuration +* `notification_channels` - (Optional) List of notification channel configurations. * `custom_notification` - (Optional) Allows to define a custom notification title, prepend and append text. * `link` - (Optional) List of links to add to notifications. @@ -66,8 +66,7 @@ It is a list of objects with the following fields: ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `subject` - (Optional) Sets the title of the alert. * `prepend` - (Optional) Text to add before the alert template. @@ -75,11 +74,11 @@ is fired. ### `link` -By defining this field, the user can add link to notificatons. +By defining this field, the user can add link to notifications. * `type` - (Required) Type of link. Must be `runbook`, for generic links, or `dashboard`, for internal links to existing dashboards. * `href` - (Optional) When using `runbook` type, url of the external resource. -* `id` - (Optional) When using `dashboard` type, dasboard id. +* `id` - (Optional) When using `dashboard` type, dashboard id. ### `capture` @@ -110,8 +109,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -119,7 +117,7 @@ alerts in Sysdig Monitor: ## Import -Prometheus Monitor alerts can be imported using the alert ID, e.g. +Downtime alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_v2_downtime.example 12345 diff --git a/website/docs/r/monitor_alert_v2_event.md b/website/docs/r/monitor_alert_v2_event.md index 4e78a5880..1909b24f5 100644 --- a/website/docs/r/monitor_alert_v2_event.md +++ b/website/docs/r/monitor_alert_v2_event.md @@ -63,7 +63,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `group` - (Optional) Lowercase string to group alerts in the UI. * `severity` - (Optional) Severity of the Monitor alert. It must be `high`, `medium`, `low` or `info`. Default: `low`. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Default: `true`. -* `notification_channels` - (Optional) List of notification channel configuration +* `notification_channels` - (Optional) List of notification channel configurations. * `custom_notification` - (Optional) Allows to define a custom notification title, prepend and append text. * `link` - (Optional) List of links to add to notifications. @@ -80,8 +80,7 @@ It is a list of objects with the following fields: ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `subject` - (Optional) Sets the title of the alert. * `prepend` - (Optional) Text to add before the alert template. @@ -89,11 +88,11 @@ is fired. ### `link` -By defining this field, the user can add link to notificatons. +By defining this field, the user can add link to notifications. * `type` - (Required) Type of link. Must be `runbook`, for generic links, or `dashboard`, for internal links to existing dashboards. * `href` - (Optional) When using `runbook` type, url of the external resource. -* `id` - (Optional) When using `dashboard` type, dasboard id. +* `id` - (Optional) When using `dashboard` type, dashboard id. ### `capture` @@ -127,8 +126,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -137,7 +135,7 @@ alerts in Sysdig Monitor: ## Import -Prometheus Monitor alerts can be imported using the alert ID, e.g. +Event alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_v2_event.example 12345 diff --git a/website/docs/r/monitor_alert_v2_metric.md b/website/docs/r/monitor_alert_v2_metric.md index b13a8684b..7504332b9 100644 --- a/website/docs/r/monitor_alert_v2_metric.md +++ b/website/docs/r/monitor_alert_v2_metric.md @@ -61,7 +61,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `group` - (Optional) Lowercase string to group alerts in the UI. * `severity` - (Optional) Severity of the Monitor alert. It must be `high`, `medium`, `low` or `info`. Default: `low`. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Default: `true`. -* `notification_channels` - (Optional) List of notification channel configuration +* `notification_channels` - (Optional) List of notification channel configurations. * `custom_notification` - (Optional) Allows to define a custom notification title, prepend and append text. * `link` - (Optional) List of links to add to notifications. @@ -78,8 +78,7 @@ It is a list of objects with the following fields: ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `subject` - (Optional) Sets the title of the alert. * `prepend` - (Optional) Text to add before the alert template. @@ -87,11 +86,11 @@ is fired. ### `link` -By defining this field, the user can add link to notificatons. +By defining this field, the user can add link to notifications. * `type` - (Required) Type of link. Must be `runbook`, for generic links, or `dashboard`, for internal links to existing dashboards. * `href` - (Optional) When using `runbook` type, url of the external resource. -* `id` - (Optional) When using `dashboard` type, dasboard id. +* `id` - (Optional) When using `dashboard` type, dashboard id. ### `capture` @@ -127,8 +126,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -137,7 +135,7 @@ alerts in Sysdig Monitor: ## Import -Prometheus Monitor alerts can be imported using the alert ID, e.g. +Metric alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_v2_metric.example 12345 diff --git a/website/docs/r/monitor_alert_v2_prometheus.md b/website/docs/r/monitor_alert_v2_prometheus.md index 1a87c5308..b41e0115a 100644 --- a/website/docs/r/monitor_alert_v2_prometheus.md +++ b/website/docs/r/monitor_alert_v2_prometheus.md @@ -40,7 +40,7 @@ These arguments are common to all alerts in Sysdig Monitor. * `group` - (Optional) Lowercase string to group alerts in the UI. * `severity` - (Optional) Severity of the Monitor alert. It must be `high`, `medium`, `low` or `info`. Default: `low`. * `enabled` - (Optional) Boolean that defines if the alert is enabled or not. Default: `true`. -* `notification_channels` - (Optional) List of notification channel configuration. +* `notification_channels` - (Optional) List of notification channel configurations. * `custom_notification` - (Optional) Allows to define a custom notification title, prepend and append text. * `link` - (Optional) List of links to add to notifications. @@ -55,8 +55,7 @@ It is a list of objects with the following fields: ### `custom_notification` -By defining this field, the user can modify the title and the body of the message sent when the alert -is fired. +By defining this field, the user can modify the title and the body of the message sent when the alert is fired. * `subject` - (Optional) Sets the title of the alert. * `prepend` - (Optional) Text to add before the alert template. @@ -64,11 +63,11 @@ is fired. ### `link` -By defining this field, the user can add link to notificatons. +By defining this field, the user can add link to notifications. * `type` - (Required) Type of link. Must be `runbook`, for generic links, or `dashboard`, for internal links to existing dashboards. * `href` - (Optional) When using `runbook` type, url of the external resource. -* `id` - (Optional) When using `dashboard` type, dasboard id. +* `id` - (Optional) When using `dashboard` type, dashboard id. ### Prometheus alert arguments @@ -81,8 +80,7 @@ In addition to all arguments above, the following attributes are exported: ### Common alert attributes -In addition to all arguments above, the following attributes are exported, which are common to all the -alerts in Sysdig Monitor: +In addition to all arguments above, the following attributes are exported, which are common to all the alerts in Sysdig Monitor: * `id` - ID of the alert created. * `version` - Current version of the resource in Sysdig Monitor. @@ -90,7 +88,7 @@ alerts in Sysdig Monitor: ## Import -Prometheus Monitor alerts can be imported using the alert ID, e.g. +Prometheus alerts can be imported using the alert ID, e.g. ``` $ terraform import sysdig_monitor_alert_v2_prometheus.example 12345