fix(alerting): Support alerts with no conditions for external endpoints (#729)

This commit is contained in:
TwiN
2024-04-10 20:46:17 -04:00
committed by GitHub
parent a4bc3c4dfe
commit 241956b28c
24 changed files with 303 additions and 209 deletions

View File

@ -71,7 +71,7 @@ type Attachment struct {
Text string `json:"text"`
Short bool `json:"short"`
Color string `json:"color"`
Fields []Field `json:"fields"`
Fields []Field `json:"fields,omitempty"`
}
type Field struct {
@ -82,7 +82,7 @@ type Field struct {
// buildRequestBody builds the request body for the provider
func (provider *AlertProvider) buildRequestBody(endpoint *core.Endpoint, alert *alert.Alert, result *core.Result, resolved bool) []byte {
var message, color, results string
var message, color string
if resolved {
message = fmt.Sprintf("An alert for *%s* has been resolved after passing successfully %d time(s) in a row", endpoint.DisplayName(), alert.SuccessThreshold)
color = "#36A64F"
@ -90,6 +90,7 @@ func (provider *AlertProvider) buildRequestBody(endpoint *core.Endpoint, alert *
message = fmt.Sprintf("An alert for *%s* has been triggered due to having failed %d time(s) in a row", endpoint.DisplayName(), alert.FailureThreshold)
color = "#DD0000"
}
var formattedConditionResults string
for _, conditionResult := range result.ConditionResults {
var prefix string
if conditionResult.Success {
@ -97,13 +98,13 @@ func (provider *AlertProvider) buildRequestBody(endpoint *core.Endpoint, alert *
} else {
prefix = ":x:"
}
results += fmt.Sprintf("%s - `%s`\n", prefix, conditionResult.Condition)
formattedConditionResults += fmt.Sprintf("%s - `%s`\n", prefix, conditionResult.Condition)
}
var description string
if alertDescription := alert.GetDescription(); len(alertDescription) > 0 {
description = ":\n> " + alertDescription
}
body, _ := json.Marshal(Body{
body := Body{
Text: "",
Attachments: []Attachment{
{
@ -111,17 +112,18 @@ func (provider *AlertProvider) buildRequestBody(endpoint *core.Endpoint, alert *
Text: message + description,
Short: false,
Color: color,
Fields: []Field{
{
Title: "Condition results",
Value: results,
Short: false,
},
},
},
},
})
return body
}
if len(formattedConditionResults) > 0 {
body.Attachments[0].Fields = append(body.Attachments[0].Fields, Field{
Title: "Condition results",
Value: formattedConditionResults,
Short: false,
})
}
bodyAsJSON, _ := json.Marshal(body)
return bodyAsJSON
}
// getWebhookURLForGroup returns the appropriate Webhook URL integration to for a given group

View File

@ -144,6 +144,7 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
Provider AlertProvider
Endpoint core.Endpoint
Alert alert.Alert
NoConditions bool
Resolved bool
ExpectedBody string
}{
@ -163,6 +164,15 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
Resolved: false,
ExpectedBody: "{\"text\":\"\",\"attachments\":[{\"title\":\":helmet_with_white_cross: Gatus\",\"text\":\"An alert for *group/name* has been triggered due to having failed 3 time(s) in a row:\\n\\u003e description-1\",\"short\":false,\"color\":\"#DD0000\",\"fields\":[{\"title\":\"Condition results\",\"value\":\":x: - `[CONNECTED] == true`\\n:x: - `[STATUS] == 200`\\n\",\"short\":false}]}]}",
},
{
Name: "triggered-with-no-conditions",
NoConditions: true,
Provider: AlertProvider{},
Endpoint: core.Endpoint{Name: "name"},
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
Resolved: false,
ExpectedBody: "{\"text\":\"\",\"attachments\":[{\"title\":\":helmet_with_white_cross: Gatus\",\"text\":\"An alert for *name* has been triggered due to having failed 3 time(s) in a row:\\n\\u003e description-1\",\"short\":false,\"color\":\"#DD0000\"}]}",
},
{
Name: "resolved",
Provider: AlertProvider{},
@ -182,14 +192,18 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
}
for _, scenario := range scenarios {
t.Run(scenario.Name, func(t *testing.T) {
var conditionResults []*core.ConditionResult
if !scenario.NoConditions {
conditionResults = []*core.ConditionResult{
{Condition: "[CONNECTED] == true", Success: scenario.Resolved},
{Condition: "[STATUS] == 200", Success: scenario.Resolved},
}
}
body := scenario.Provider.buildRequestBody(
&scenario.Endpoint,
&scenario.Alert,
&core.Result{
ConditionResults: []*core.ConditionResult{
{Condition: "[CONNECTED] == true", Success: scenario.Resolved},
{Condition: "[STATUS] == 200", Success: scenario.Resolved},
},
ConditionResults: conditionResults,
},
scenario.Resolved,
)