mirror of
https://github.com/TwiN/gatus.git
synced 2026-02-15 16:10:05 +00:00
fix(alerting): Support custom slack title (#1079)
This commit is contained in:
@@ -1903,9 +1903,10 @@ endpoints:
|
|||||||
|
|
||||||
#### Configuring Slack alerts
|
#### Configuring Slack alerts
|
||||||
| Parameter | Description | Default |
|
| Parameter | Description | Default |
|
||||||
|:-----------------------------------|:-------------------------------------------------------------------------------------------|:--------------|
|
|:-----------------------------------|:-------------------------------------------------------------------------------------------|:------------------------------------|
|
||||||
| `alerting.slack` | Configuration for alerts of type `slack` | `{}` |
|
| `alerting.slack` | Configuration for alerts of type `slack` | `{}` |
|
||||||
| `alerting.slack.webhook-url` | Slack Webhook URL | Required `""` |
|
| `alerting.slack.webhook-url` | Slack Webhook URL | Required `""` |
|
||||||
|
| `alerting.slack.title` | Title of the notification | `":helmet_with_white_cross: Gatus"` |
|
||||||
| `alerting.slack.default-alert` | Default alert configuration. <br />See [Setting a default alert](#setting-a-default-alert) | N/A |
|
| `alerting.slack.default-alert` | Default alert configuration. <br />See [Setting a default alert](#setting-a-default-alert) | N/A |
|
||||||
| `alerting.slack.overrides` | List of overrides that may be prioritized over the default configuration | `[]` |
|
| `alerting.slack.overrides` | List of overrides that may be prioritized over the default configuration | `[]` |
|
||||||
| `alerting.slack.overrides[].group` | Endpoint group for which the configuration will be overridden by this configuration | `""` |
|
| `alerting.slack.overrides[].group` | Endpoint group for which the configuration will be overridden by this configuration | `""` |
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ var (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
WebhookURL string `yaml:"webhook-url"` // Slack webhook URL
|
WebhookURL string `yaml:"webhook-url"` // Slack webhook URL
|
||||||
|
Title string `yaml:"title,omitempty"` // Title of the message that will be sent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) Validate() error {
|
func (cfg *Config) Validate() error {
|
||||||
@@ -34,6 +35,9 @@ func (cfg *Config) Merge(override *Config) {
|
|||||||
if len(override.WebhookURL) > 0 {
|
if len(override.WebhookURL) > 0 {
|
||||||
cfg.WebhookURL = override.WebhookURL
|
cfg.WebhookURL = override.WebhookURL
|
||||||
}
|
}
|
||||||
|
if len(override.Title) > 0 {
|
||||||
|
cfg.Title = override.Title
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AlertProvider is the configuration necessary for sending an alert using Slack
|
// AlertProvider is the configuration necessary for sending an alert using Slack
|
||||||
@@ -73,7 +77,7 @@ func (provider *AlertProvider) Send(ep *endpoint.Endpoint, alert *alert.Alert, r
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buffer := bytes.NewBuffer(provider.buildRequestBody(ep, alert, result, resolved))
|
buffer := bytes.NewBuffer(provider.buildRequestBody(cfg, ep, alert, result, resolved))
|
||||||
request, err := http.NewRequest(http.MethodPost, cfg.WebhookURL, buffer)
|
request, err := http.NewRequest(http.MethodPost, cfg.WebhookURL, buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -111,7 +115,7 @@ type Field struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildRequestBody builds the request body for the provider
|
// buildRequestBody builds the request body for the provider
|
||||||
func (provider *AlertProvider) buildRequestBody(ep *endpoint.Endpoint, alert *alert.Alert, result *endpoint.Result, resolved bool) []byte {
|
func (provider *AlertProvider) buildRequestBody(cfg *Config, ep *endpoint.Endpoint, alert *alert.Alert, result *endpoint.Result, resolved bool) []byte {
|
||||||
var message, color string
|
var message, color string
|
||||||
if resolved {
|
if resolved {
|
||||||
message = fmt.Sprintf("An alert for *%s* has been resolved after passing successfully %d time(s) in a row", ep.DisplayName(), alert.SuccessThreshold)
|
message = fmt.Sprintf("An alert for *%s* has been resolved after passing successfully %d time(s) in a row", ep.DisplayName(), alert.SuccessThreshold)
|
||||||
@@ -138,13 +142,16 @@ func (provider *AlertProvider) buildRequestBody(ep *endpoint.Endpoint, alert *al
|
|||||||
Text: "",
|
Text: "",
|
||||||
Attachments: []Attachment{
|
Attachments: []Attachment{
|
||||||
{
|
{
|
||||||
Title: ":helmet_with_white_cross: Gatus",
|
Title: cfg.Title,
|
||||||
Text: message + description,
|
Text: message + description,
|
||||||
Short: false,
|
Short: false,
|
||||||
Color: color,
|
Color: color,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if len(body.Attachments[0].Title) == 0 {
|
||||||
|
body.Attachments[0].Title = ":helmet_with_white_cross: Gatus"
|
||||||
|
}
|
||||||
if len(formattedConditionResults) > 0 {
|
if len(formattedConditionResults) > 0 {
|
||||||
body.Attachments[0].Fields = append(body.Attachments[0].Fields, Field{
|
body.Attachments[0].Fields = append(body.Attachments[0].Fields, Field{
|
||||||
Title: "Condition results",
|
Title: "Condition results",
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "triggered",
|
Name: "triggered",
|
||||||
Provider: AlertProvider{},
|
Provider: AlertProvider{DefaultConfig: Config{WebhookURL: "http://example.com"}},
|
||||||
Endpoint: endpoint.Endpoint{Name: "name"},
|
Endpoint: endpoint.Endpoint{Name: "name"},
|
||||||
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
Resolved: false,
|
Resolved: false,
|
||||||
@@ -158,7 +158,7 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "triggered-with-group",
|
Name: "triggered-with-group",
|
||||||
Provider: AlertProvider{},
|
Provider: AlertProvider{DefaultConfig: Config{WebhookURL: "http://example.com"}},
|
||||||
Endpoint: endpoint.Endpoint{Name: "name", Group: "group"},
|
Endpoint: endpoint.Endpoint{Name: "name", Group: "group"},
|
||||||
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
Resolved: false,
|
Resolved: false,
|
||||||
@@ -167,7 +167,7 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "triggered-with-no-conditions",
|
Name: "triggered-with-no-conditions",
|
||||||
NoConditions: true,
|
NoConditions: true,
|
||||||
Provider: AlertProvider{},
|
Provider: AlertProvider{DefaultConfig: Config{WebhookURL: "http://example.com"}},
|
||||||
Endpoint: endpoint.Endpoint{Name: "name"},
|
Endpoint: endpoint.Endpoint{Name: "name"},
|
||||||
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
Resolved: false,
|
Resolved: false,
|
||||||
@@ -175,7 +175,7 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "resolved",
|
Name: "resolved",
|
||||||
Provider: AlertProvider{},
|
Provider: AlertProvider{DefaultConfig: Config{WebhookURL: "http://example.com"}},
|
||||||
Endpoint: endpoint.Endpoint{Name: "name"},
|
Endpoint: endpoint.Endpoint{Name: "name"},
|
||||||
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
Resolved: true,
|
Resolved: true,
|
||||||
@@ -183,12 +183,20 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "resolved-with-group",
|
Name: "resolved-with-group",
|
||||||
Provider: AlertProvider{},
|
Provider: AlertProvider{DefaultConfig: Config{WebhookURL: "http://example.com"}},
|
||||||
Endpoint: endpoint.Endpoint{Name: "name", Group: "group"},
|
Endpoint: endpoint.Endpoint{Name: "name", Group: "group"},
|
||||||
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
Resolved: true,
|
Resolved: true,
|
||||||
ExpectedBody: "{\"text\":\"\",\"attachments\":[{\"title\":\":helmet_with_white_cross: Gatus\",\"text\":\"An alert for *group/name* has been resolved after passing successfully 5 time(s) in a row:\\n\\u003e description-2\",\"short\":false,\"color\":\"#36A64F\",\"fields\":[{\"title\":\"Condition results\",\"value\":\":white_check_mark: - `[CONNECTED] == true`\\n:white_check_mark: - `[STATUS] == 200`\\n\",\"short\":false}]}]}",
|
ExpectedBody: "{\"text\":\"\",\"attachments\":[{\"title\":\":helmet_with_white_cross: Gatus\",\"text\":\"An alert for *group/name* has been resolved after passing successfully 5 time(s) in a row:\\n\\u003e description-2\",\"short\":false,\"color\":\"#36A64F\",\"fields\":[{\"title\":\"Condition results\",\"value\":\":white_check_mark: - `[CONNECTED] == true`\\n:white_check_mark: - `[STATUS] == 200`\\n\",\"short\":false}]}]}",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "resolved-with-group-and-custom-title",
|
||||||
|
Provider: AlertProvider{DefaultConfig: Config{WebhookURL: "http://example.com", Title: "custom title"}},
|
||||||
|
Endpoint: endpoint.Endpoint{Name: "name", Group: "group"},
|
||||||
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: true,
|
||||||
|
ExpectedBody: "{\"text\":\"\",\"attachments\":[{\"title\":\"custom title\",\"text\":\"An alert for *group/name* has been resolved after passing successfully 5 time(s) in a row:\\n\\u003e description-2\",\"short\":false,\"color\":\"#36A64F\",\"fields\":[{\"title\":\"Condition results\",\"value\":\":white_check_mark: - `[CONNECTED] == true`\\n:white_check_mark: - `[STATUS] == 200`\\n\",\"short\":false}]}]}",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, scenario := range scenarios {
|
for _, scenario := range scenarios {
|
||||||
t.Run(scenario.Name, func(t *testing.T) {
|
t.Run(scenario.Name, func(t *testing.T) {
|
||||||
@@ -199,7 +207,12 @@ func TestAlertProvider_buildRequestBody(t *testing.T) {
|
|||||||
{Condition: "[STATUS] == 200", Success: scenario.Resolved},
|
{Condition: "[STATUS] == 200", Success: scenario.Resolved},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cfg, err := scenario.Provider.GetConfig(scenario.Endpoint.Group, &scenario.Alert)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("couldn't get config:", err.Error())
|
||||||
|
}
|
||||||
body := scenario.Provider.buildRequestBody(
|
body := scenario.Provider.buildRequestBody(
|
||||||
|
cfg,
|
||||||
&scenario.Endpoint,
|
&scenario.Endpoint,
|
||||||
&scenario.Alert,
|
&scenario.Alert,
|
||||||
&endpoint.Result{
|
&endpoint.Result{
|
||||||
|
|||||||
Reference in New Issue
Block a user