Skip to content

Commit

Permalink
feat(alerts): add group outlier alert type (#465)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbonf authored Dec 22, 2023
1 parent b17c631 commit 546f39e
Show file tree
Hide file tree
Showing 8 changed files with 1,027 additions and 0 deletions.
86 changes: 86 additions & 0 deletions sysdig/internal/client/v2/alerts_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
AlertV2TypeEvent AlertV2Type = "EVENT"
AlertV2TypeChange AlertV2Type = "PERCENTAGE_OF_CHANGE"
AlertV2TypeFormBasedPrometheus AlertV2Type = "FORM_BASED_PROMETHEUS"
AlertV2TypeGroupOutlier AlertV2Type = "GROUP_OUTLIERS"

AlertV2SeverityHigh AlertV2Severity = "high"
AlertV2SeverityMedium AlertV2Severity = "medium"
Expand All @@ -52,6 +53,7 @@ type AlertV2Interface interface {
AlertV2DowntimeInterface
AlertV2ChangeInterface
AlertV2FormBasedPrometheusInterface
AlertV2GroupOutlierInterface
}

type AlertV2PrometheusInterface interface {
Expand Down Expand Up @@ -94,6 +96,14 @@ type AlertV2FormBasedPrometheusInterface interface {
DeleteAlertV2FormBasedPrometheus(ctx context.Context, alertID int) error
}

type AlertV2GroupOutlierInterface interface {
Base
CreateAlertV2GroupOutlier(ctx context.Context, alert AlertV2GroupOutlier) (AlertV2GroupOutlier, error)
UpdateAlertV2GroupOutlier(ctx context.Context, alert AlertV2GroupOutlier) (AlertV2GroupOutlier, error)
GetAlertV2GroupOutlier(ctx context.Context, alertID int) (AlertV2GroupOutlier, error)
DeleteAlertV2GroupOutlier(ctx context.Context, alertID int) error
}

type AlertV2DowntimeInterface interface {
Base
CreateAlertV2Downtime(ctx context.Context, alert AlertV2Downtime) (AlertV2Downtime, error)
Expand Down Expand Up @@ -547,6 +557,82 @@ func (client *Client) DeleteAlertV2FormBasedPrometheus(ctx context.Context, aler
return client.deleteAlertV2(ctx, alertID)
}

func (client *Client) CreateAlertV2GroupOutlier(ctx context.Context, alert AlertV2GroupOutlier) (AlertV2GroupOutlier, error) {
err := client.addNotificationChannelType(ctx, alert.NotificationChannelConfigList)
if err != nil {
return AlertV2GroupOutlier{}, err
}

err = client.translateScopeSegmentLabels(ctx, &alert.Config.ScopedSegmentedConfig)
if err != nil {
return AlertV2GroupOutlier{}, err
}

payload, err := Marshal(alertV2GroupOutlierWrapper{Alert: alert})
if err != nil {
return AlertV2GroupOutlier{}, err
}

body, err := client.createAlertV2(ctx, payload)
if err != nil {
return AlertV2GroupOutlier{}, err
}

wrapper, err := Unmarshal[alertV2GroupOutlierWrapper](body)
if err != nil {
return AlertV2GroupOutlier{}, err
}

return wrapper.Alert, nil
}

func (client *Client) UpdateAlertV2GroupOutlier(ctx context.Context, alert AlertV2GroupOutlier) (AlertV2GroupOutlier, error) {
err := client.addNotificationChannelType(ctx, alert.NotificationChannelConfigList)
if err != nil {
return AlertV2GroupOutlier{}, err
}

err = client.translateScopeSegmentLabels(ctx, &alert.Config.ScopedSegmentedConfig)
if err != nil {
return AlertV2GroupOutlier{}, err
}

payload, err := Marshal(alertV2GroupOutlierWrapper{Alert: alert})
if err != nil {
return AlertV2GroupOutlier{}, err
}

body, err := client.updateAlertV2(ctx, alert.ID, payload)
if err != nil {
return AlertV2GroupOutlier{}, err
}

wrapper, err := Unmarshal[alertV2GroupOutlierWrapper](body)
if err != nil {
return AlertV2GroupOutlier{}, err
}

return wrapper.Alert, nil
}

func (client *Client) GetAlertV2GroupOutlier(ctx context.Context, alertID int) (AlertV2GroupOutlier, error) {
body, err := client.getAlertV2(ctx, alertID)
if err != nil {
return AlertV2GroupOutlier{}, err
}

wrapper, err := Unmarshal[alertV2GroupOutlierWrapper](body)
if err != nil {
return AlertV2GroupOutlier{}, err
}

return wrapper.Alert, nil
}

func (client *Client) DeleteAlertV2GroupOutlier(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 {
Expand Down
25 changes: 25 additions & 0 deletions sysdig/internal/client/v2/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,31 @@ type alertV2FormBasedPrometheusWrapper struct {
Alert AlertV2FormBasedPrometheus `json:"alert"`
}

type AlertV2ConfigGroupOutlier struct {
ScopedSegmentedConfig

Algorithm string `json:"algorithm"`
MadThreshold float64 `json:"madThreshold,omitempty"`
MadTolerance float64 `json:"madTolerance,omitempty"`
DbscanTolerance float64 `json:"dbscanTolerance,omitempty"`

GroupAggregation string `json:"groupAggregation"`
TimeAggregation string `json:"timeAggregation"`
Metric AlertMetricDescriptorV2 `json:"metric"`
NoDataBehaviour string `json:"noDataBehaviour"`
}

type AlertV2GroupOutlier struct {
AlertV2Common
DurationSec int `json:"durationSec"` // Observation window should be greater than or equal to 10 minutes
Config AlertV2ConfigGroupOutlier `json:"config"`
UnreportedAlertNotificationsRetentionSec *int `json:"unreportedAlertNotificationsRetentionSec"`
}

type alertV2GroupOutlierWrapper struct {
Alert AlertV2GroupOutlier `json:"alert"`
}

type AlertV2Change struct {
AlertV2Common
DurationSec int `json:"durationSec"` // not really used but the api wants it set to 0 in POST/PUT
Expand Down
1 change: 1 addition & 0 deletions sysdig/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func (p *SysdigProvider) Provider() *schema.Provider {
"sysdig_monitor_alert_v2_prometheus": resourceSysdigMonitorAlertV2Prometheus(),
"sysdig_monitor_alert_v2_change": resourceSysdigMonitorAlertV2Change(),
"sysdig_monitor_alert_v2_form_based_prometheus": resourceSysdigMonitorAlertV2FormBasedPrometheus(),
"sysdig_monitor_alert_v2_group_outlier": resourceSysdigMonitorAlertV2GroupOutlier(),
"sysdig_monitor_dashboard": resourceSysdigMonitorDashboard(),
"sysdig_monitor_notification_channel_email": resourceSysdigMonitorNotificationChannelEmail(),
"sysdig_monitor_notification_channel_opsgenie": resourceSysdigMonitorNotificationChannelOpsGenie(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ func TestAccAlertV2FormBasedPrometheusTest(t *testing.T) {
{
Config: alertV2FormBasedPrometheusTestWithEnabled(rText()),
},
{
Config: alertV2FormBasedWithUnreportedAlertNotificationsRetentionSec(rText()),
},
{
Config: alertV2FormBasedPrometheusTestWithWarningThreshold(rText()),
},
Expand Down Expand Up @@ -232,6 +235,18 @@ resource "sysdig_monitor_alert_v2_form_based_prometheus" "sample" {
`, name)
}

func alertV2FormBasedWithUnreportedAlertNotificationsRetentionSec(name string) string {
return fmt.Sprintf(`
resource "sysdig_monitor_alert_v2_form_based_prometheus" "sample" {
name = "TERRAFORM TEST - FORM BASED PROMETHEUS %s"
query = "avg_over_time(sysdig_container_cpu_used_percent{container_name=\"test\"}[59s])"
operator = ">="
threshold = 50
unreported_alert_notifications_retention_seconds = 60 * 60 * 24 * 30
}
`, name)
}

func alertV2FormBasedPrometheusTestWithWarningThreshold(name string) string {
return fmt.Sprintf(`
resource "sysdig_monitor_notification_channel_email" "nc_email_3" {
Expand Down
Loading

0 comments on commit 546f39e

Please sign in to comment.