mirror of
https://github.com/TwiN/gatus.git
synced 2024-11-21 23:43:27 +01:00
feat(alerting): add alerting support for jetbrains space (#713)
* add alerting support for jetbrains space * readme fixes * add jetbrainsspace to provider interface compilation check * add jetbrainsspace to a couple more tests
This commit is contained in:
parent
5aa83ee274
commit
ae750aa367
BIN
.github/assets/jetbrains-space-alerts.png
vendored
Normal file
BIN
.github/assets/jetbrains-space-alerts.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
39
README.md
39
README.md
@ -55,6 +55,7 @@ Have any feedback or questions? [Create a discussion](https://github.com/TwiN/ga
|
|||||||
- [Configuring GitLab alerts](#configuring-gitlab-alerts)
|
- [Configuring GitLab alerts](#configuring-gitlab-alerts)
|
||||||
- [Configuring Google Chat alerts](#configuring-google-chat-alerts)
|
- [Configuring Google Chat alerts](#configuring-google-chat-alerts)
|
||||||
- [Configuring Gotify alerts](#configuring-gotify-alerts)
|
- [Configuring Gotify alerts](#configuring-gotify-alerts)
|
||||||
|
- [Configuring JetBrains Space alerts](#configuring-jetbrains-space-alerts)
|
||||||
- [Configuring Matrix alerts](#configuring-matrix-alerts)
|
- [Configuring Matrix alerts](#configuring-matrix-alerts)
|
||||||
- [Configuring Mattermost alerts](#configuring-mattermost-alerts)
|
- [Configuring Mattermost alerts](#configuring-mattermost-alerts)
|
||||||
- [Configuring Messagebird alerts](#configuring-messagebird-alerts)
|
- [Configuring Messagebird alerts](#configuring-messagebird-alerts)
|
||||||
@ -445,7 +446,7 @@ individual endpoints with configurable descriptions and thresholds.
|
|||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
| Parameter | Description | Default |
|
||||||
|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------|:--------|
|
|:--------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------|:--------|
|
||||||
| `alerting.custom` | Configuration for custom actions on failure or alerts. <br />See [Configuring Custom alerts](#configuring-custom-alerts). | `{}` |
|
| `alerting.custom` | Configuration for custom actions on failure or alerts. <br />See [Configuring Custom alerts](#configuring-custom-alerts). | `{}` |
|
||||||
| `alerting.discord` | Configuration for alerts of type `discord`. <br />See [Configuring Discord alerts](#configuring-discord-alerts). | `{}` |
|
| `alerting.discord` | Configuration for alerts of type `discord`. <br />See [Configuring Discord alerts](#configuring-discord-alerts). | `{}` |
|
||||||
| `alerting.email` | Configuration for alerts of type `email`. <br />See [Configuring Email alerts](#configuring-email-alerts). | `{}` |
|
| `alerting.email` | Configuration for alerts of type `email`. <br />See [Configuring Email alerts](#configuring-email-alerts). | `{}` |
|
||||||
@ -453,6 +454,7 @@ ignored.
|
|||||||
| `alerting.gitlab` | Configuration for alerts of type `gitlab`. <br />See [Configuring GitLab alerts](#configuring-gitlab-alerts). | `{}` |
|
| `alerting.gitlab` | Configuration for alerts of type `gitlab`. <br />See [Configuring GitLab alerts](#configuring-gitlab-alerts). | `{}` |
|
||||||
| `alerting.googlechat` | Configuration for alerts of type `googlechat`. <br />See [Configuring Google Chat alerts](#configuring-google-chat-alerts). | `{}` |
|
| `alerting.googlechat` | Configuration for alerts of type `googlechat`. <br />See [Configuring Google Chat alerts](#configuring-google-chat-alerts). | `{}` |
|
||||||
| `alerting.gotify` | Configuration for alerts of type `gotify`. <br />See [Configuring Gotify alerts](#configuring-gotify-alerts). | `{}` |
|
| `alerting.gotify` | Configuration for alerts of type `gotify`. <br />See [Configuring Gotify alerts](#configuring-gotify-alerts). | `{}` |
|
||||||
|
| `alerting.jetbrainsspace` | Configuration for alerts of type `jetbrainsspace`. <br />See [Configuring JetBrains Space alerts](#configuring-jetbrains-space-alerts). | `{}` |
|
||||||
| `alerting.matrix` | Configuration for alerts of type `matrix`. <br />See [Configuring Matrix alerts](#configuring-matrix-alerts). | `{}` |
|
| `alerting.matrix` | Configuration for alerts of type `matrix`. <br />See [Configuring Matrix alerts](#configuring-matrix-alerts). | `{}` |
|
||||||
| `alerting.mattermost` | Configuration for alerts of type `mattermost`. <br />See [Configuring Mattermost alerts](#configuring-mattermost-alerts). | `{}` |
|
| `alerting.mattermost` | Configuration for alerts of type `mattermost`. <br />See [Configuring Mattermost alerts](#configuring-mattermost-alerts). | `{}` |
|
||||||
| `alerting.messagebird` | Configuration for alerts of type `messagebird`. <br />See [Configuring Messagebird alerts](#configuring-messagebird-alerts). | `{}` |
|
| `alerting.messagebird` | Configuration for alerts of type `messagebird`. <br />See [Configuring Messagebird alerts](#configuring-messagebird-alerts). | `{}` |
|
||||||
@ -703,6 +705,41 @@ Here's an example of what the notifications look like:
|
|||||||
![Gotify notifications](.github/assets/gotify-alerts.png)
|
![Gotify notifications](.github/assets/gotify-alerts.png)
|
||||||
|
|
||||||
|
|
||||||
|
#### Configuring JetBrains Space alerts
|
||||||
|
| Parameter | Description | Default |
|
||||||
|
|:---------------------------------------------------|:--------------------------------------------------------------------------------------------|:-----------------------|
|
||||||
|
| `alerting.jetbrainsspace` | Configuration for alerts of type `jetbrainsspace` | `{}` |
|
||||||
|
| `alerting.jetbrainsspace.project` | JetBrains Space project name | Required `""` |
|
||||||
|
| `alerting.jetbrainsspace.channel-id` | JetBrains Space Chat Channel ID | Required `""` |
|
||||||
|
| `alerting.jetbrainsspace.token` | Token that is used for authentication. | Required `""` |
|
||||||
|
| `alerting.jetbrainsspace.default-alert` | Default alert configuration. <br />See [Setting a default alert](#setting-a-default-alert) | N/A |
|
||||||
|
| `alerting.jetbrainsspace.overrides` | List of overrides that may be prioritized over the default configuration | `[]` |
|
||||||
|
| `alerting.jetbrainsspace.overrides[].group` | Endpoint group for which the configuration will be overridden by this configuration | `""` |
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
alerting:
|
||||||
|
jetbrainsspace:
|
||||||
|
project: myproject
|
||||||
|
channel-id: ABCDE12345
|
||||||
|
token: "**************"
|
||||||
|
|
||||||
|
endpoints:
|
||||||
|
- name: website
|
||||||
|
url: "https://twin.sh/health"
|
||||||
|
interval: 5m
|
||||||
|
conditions:
|
||||||
|
- "[STATUS] == 200"
|
||||||
|
alerts:
|
||||||
|
- type: jetbrainsspace
|
||||||
|
description: "healthcheck failed"
|
||||||
|
send-on-resolved: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Here's an example of what the notifications look like:
|
||||||
|
|
||||||
|
![JetBrains Space notifications](.github/assets/jetbrains-space-alerts.png)
|
||||||
|
|
||||||
|
|
||||||
#### Configuring Matrix alerts
|
#### Configuring Matrix alerts
|
||||||
| Parameter | Description | Default |
|
| Parameter | Description | Default |
|
||||||
|:-----------------------------------------|:-------------------------------------------------------------------------------------------|:-----------------------------------|
|
|:-----------------------------------------|:-------------------------------------------------------------------------------------------|:-----------------------------------|
|
||||||
|
@ -29,6 +29,9 @@ const (
|
|||||||
// TypeGotify is the Type for the gotify alerting provider
|
// TypeGotify is the Type for the gotify alerting provider
|
||||||
TypeGotify Type = "gotify"
|
TypeGotify Type = "gotify"
|
||||||
|
|
||||||
|
// TypeJetBrainsSpace is the Type for the jetbrains alerting provider
|
||||||
|
TypeJetBrainsSpace Type = "jetbrainsspace"
|
||||||
|
|
||||||
// TypeMatrix is the Type for the matrix alerting provider
|
// TypeMatrix is the Type for the matrix alerting provider
|
||||||
TypeMatrix Type = "matrix"
|
TypeMatrix Type = "matrix"
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/TwiN/gatus/v5/alerting/provider/gitlab"
|
"github.com/TwiN/gatus/v5/alerting/provider/gitlab"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/googlechat"
|
"github.com/TwiN/gatus/v5/alerting/provider/googlechat"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/gotify"
|
"github.com/TwiN/gatus/v5/alerting/provider/gotify"
|
||||||
|
"github.com/TwiN/gatus/v5/alerting/provider/jetbrainsspace"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
||||||
@ -54,6 +55,9 @@ type Config struct {
|
|||||||
// Gotify is the configuration for the gotify alerting provider
|
// Gotify is the configuration for the gotify alerting provider
|
||||||
Gotify *gotify.AlertProvider `yaml:"gotify,omitempty"`
|
Gotify *gotify.AlertProvider `yaml:"gotify,omitempty"`
|
||||||
|
|
||||||
|
// JetBrainsSpace is the configuration for the jetbrains space alerting provider
|
||||||
|
JetBrainsSpace *jetbrainsspace.AlertProvider `yaml:"jetbrainsspace,omitempty"`
|
||||||
|
|
||||||
// Matrix is the configuration for the matrix alerting provider
|
// Matrix is the configuration for the matrix alerting provider
|
||||||
Matrix *matrix.AlertProvider `yaml:"matrix,omitempty"`
|
Matrix *matrix.AlertProvider `yaml:"matrix,omitempty"`
|
||||||
|
|
||||||
|
164
alerting/provider/jetbrainsspace/space.go
Normal file
164
alerting/provider/jetbrainsspace/space.go
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
package jetbrainsspace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/TwiN/gatus/v5/alerting/alert"
|
||||||
|
"github.com/TwiN/gatus/v5/client"
|
||||||
|
"github.com/TwiN/gatus/v5/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AlertProvider is the configuration necessary for sending an alert using JetBrains Space
|
||||||
|
type AlertProvider struct {
|
||||||
|
Project string `yaml:"project"` // JetBrains Space Project name
|
||||||
|
ChannelID string `yaml:"channel-id"` // JetBrains Space Chat Channel ID
|
||||||
|
Token string `yaml:"token"` // JetBrains Space Bearer Token
|
||||||
|
// DefaultAlert is the defarlt alert configuration to use for endpoints with an alert of the appropriate type
|
||||||
|
DefaultAlert *alert.Alert `yaml:"default-alert,omitempty"`
|
||||||
|
// Overrides is a list of Override that may be prioritized over the default configuration
|
||||||
|
Overrides []Override `yaml:"overrides,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override is a case under which the default integration is overridden
|
||||||
|
type Override struct {
|
||||||
|
Group string `yaml:"group"`
|
||||||
|
ChannelID string `yaml:"channel-id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid returns whether the provider's configuration is valid
|
||||||
|
func (provider *AlertProvider) IsValid() bool {
|
||||||
|
registeredGroups := make(map[string]bool)
|
||||||
|
if provider.Overrides != nil {
|
||||||
|
for _, override := range provider.Overrides {
|
||||||
|
if isAlreadyRegistered := registeredGroups[override.Group]; isAlreadyRegistered || override.Group == "" || len(override.ChannelID) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
registeredGroups[override.Group] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(provider.Project) > 0 && len(provider.ChannelID) > 0 && len(provider.Token) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send an alert using the provider
|
||||||
|
func (provider *AlertProvider) Send(endpoint *core.Endpoint, alert *alert.Alert, result *core.Result, resolved bool) error {
|
||||||
|
buffer := bytes.NewBuffer(provider.buildRequestBody(endpoint, alert, result, resolved))
|
||||||
|
url := fmt.Sprintf("https://%s.jetbrains.space/api/http/chats/messages/send-message", provider.Project)
|
||||||
|
request, err := http.NewRequest(http.MethodPost, url, buffer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
request.Header.Set("Authorization", "Bearer "+provider.Token)
|
||||||
|
response, err := client.GetHTTPClient(nil).Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
if response.StatusCode > 399 {
|
||||||
|
body, _ := io.ReadAll(response.Body)
|
||||||
|
return fmt.Errorf("call to provider alert returned status code %d: %s", response.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Body struct {
|
||||||
|
Channel string `json:"channel"`
|
||||||
|
Content Content `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Content struct {
|
||||||
|
ClassName string `json:"className"`
|
||||||
|
Style string `json:"style"`
|
||||||
|
Sections []Section `json:"sections"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Section struct {
|
||||||
|
ClassName string `json:"className"`
|
||||||
|
Elements []Element `json:"elements"`
|
||||||
|
Header string `json:"header"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Element struct {
|
||||||
|
ClassName string `json:"className"`
|
||||||
|
Accessory Accessory `json:"accessory"`
|
||||||
|
Style string `json:"style"`
|
||||||
|
Size string `json:"size"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Accessory struct {
|
||||||
|
ClassName string `json:"className"`
|
||||||
|
Icon Icon `json:"icon"`
|
||||||
|
Style string `json:"style"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Icon struct {
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildRequestBody builds the request body for the provider
|
||||||
|
func (provider *AlertProvider) buildRequestBody(endpoint *core.Endpoint, alert *alert.Alert, result *core.Result, resolved bool) []byte {
|
||||||
|
body := Body{
|
||||||
|
Channel: "id:" + provider.getChannelIDForGroup(endpoint.Group),
|
||||||
|
Content: Content{
|
||||||
|
ClassName: "ChatMessage.Block",
|
||||||
|
Sections: []Section{{
|
||||||
|
ClassName: "MessageSection",
|
||||||
|
Elements: []Element{},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if resolved {
|
||||||
|
body.Content.Style = "SUCCESS"
|
||||||
|
body.Content.Sections[0].Header = fmt.Sprintf("An alert for *%s* has been resolved after passing successfully %d time(s) in a row", endpoint.DisplayName(), alert.SuccessThreshold)
|
||||||
|
} else {
|
||||||
|
body.Content.Style = "WARNING"
|
||||||
|
body.Content.Sections[0].Header = fmt.Sprintf("An alert for *%s* has been triggered due to having failed %d time(s) in a row", endpoint.DisplayName(), alert.FailureThreshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, conditionResult := range result.ConditionResults {
|
||||||
|
icon := "warning"
|
||||||
|
style := "WARNING"
|
||||||
|
if conditionResult.Success {
|
||||||
|
icon = "success"
|
||||||
|
style = "SUCCESS"
|
||||||
|
}
|
||||||
|
|
||||||
|
body.Content.Sections[0].Elements = append(body.Content.Sections[0].Elements, Element{
|
||||||
|
ClassName: "MessageText",
|
||||||
|
Accessory: Accessory{
|
||||||
|
ClassName: "MessageIcon",
|
||||||
|
Icon: Icon{Icon: icon},
|
||||||
|
Style: style,
|
||||||
|
},
|
||||||
|
Style: style,
|
||||||
|
Size: "REGULAR",
|
||||||
|
Content: conditionResult.Condition,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonBody, _ := json.Marshal(body)
|
||||||
|
return jsonBody
|
||||||
|
}
|
||||||
|
|
||||||
|
// getChannelIDForGroup returns the appropriate channel ID to for a given group override
|
||||||
|
func (provider *AlertProvider) getChannelIDForGroup(group string) string {
|
||||||
|
if provider.Overrides != nil {
|
||||||
|
for _, override := range provider.Overrides {
|
||||||
|
if group == override.Group {
|
||||||
|
return override.ChannelID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return provider.ChannelID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDefaultAlert returns the provider's default alert configuration
|
||||||
|
func (provider *AlertProvider) GetDefaultAlert() *alert.Alert {
|
||||||
|
return provider.DefaultAlert
|
||||||
|
}
|
279
alerting/provider/jetbrainsspace/space_test.go
Normal file
279
alerting/provider/jetbrainsspace/space_test.go
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
package jetbrainsspace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/TwiN/gatus/v5/alerting/alert"
|
||||||
|
"github.com/TwiN/gatus/v5/client"
|
||||||
|
"github.com/TwiN/gatus/v5/core"
|
||||||
|
"github.com/TwiN/gatus/v5/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAlertDefaultProvider_IsValid(t *testing.T) {
|
||||||
|
invalidProvider := AlertProvider{Project: ""}
|
||||||
|
if invalidProvider.IsValid() {
|
||||||
|
t.Error("provider shouldn't have been valid")
|
||||||
|
}
|
||||||
|
validProvider := AlertProvider{Project: "foo", ChannelID: "bar", Token: "baz"}
|
||||||
|
if !validProvider.IsValid() {
|
||||||
|
t.Error("provider should've been valid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAlertProvider_IsValidWithOverride(t *testing.T) {
|
||||||
|
providerWithInvalidOverrideGroup := AlertProvider{
|
||||||
|
Project: "foobar",
|
||||||
|
Overrides: []Override{
|
||||||
|
{
|
||||||
|
ChannelID: "http://example.com",
|
||||||
|
Group: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if providerWithInvalidOverrideGroup.IsValid() {
|
||||||
|
t.Error("provider Group shouldn't have been valid")
|
||||||
|
}
|
||||||
|
providerWithInvalidOverrideTo := AlertProvider{
|
||||||
|
Project: "foobar",
|
||||||
|
Overrides: []Override{
|
||||||
|
{
|
||||||
|
ChannelID: "",
|
||||||
|
Group: "group",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if providerWithInvalidOverrideTo.IsValid() {
|
||||||
|
t.Error("provider integration key shouldn't have been valid")
|
||||||
|
}
|
||||||
|
providerWithValidOverride := AlertProvider{
|
||||||
|
Project: "foo",
|
||||||
|
ChannelID: "bar",
|
||||||
|
Token: "baz",
|
||||||
|
Overrides: []Override{
|
||||||
|
{
|
||||||
|
ChannelID: "foobar",
|
||||||
|
Group: "group",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !providerWithValidOverride.IsValid() {
|
||||||
|
t.Error("provider should've been valid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAlertProvider_Send(t *testing.T) {
|
||||||
|
defer client.InjectHTTPClient(nil)
|
||||||
|
firstDescription := "description-1"
|
||||||
|
secondDescription := "description-2"
|
||||||
|
scenarios := []struct {
|
||||||
|
Name string
|
||||||
|
Provider AlertProvider
|
||||||
|
Alert alert.Alert
|
||||||
|
Resolved bool
|
||||||
|
MockRoundTripper test.MockRoundTripper
|
||||||
|
ExpectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "triggered",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: false,
|
||||||
|
MockRoundTripper: test.MockRoundTripper(func(r *http.Request) *http.Response {
|
||||||
|
return &http.Response{StatusCode: http.StatusOK, Body: http.NoBody}
|
||||||
|
}),
|
||||||
|
ExpectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "triggered-error",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: false,
|
||||||
|
MockRoundTripper: test.MockRoundTripper(func(r *http.Request) *http.Response {
|
||||||
|
return &http.Response{StatusCode: http.StatusInternalServerError, Body: http.NoBody}
|
||||||
|
}),
|
||||||
|
ExpectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "resolved",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: true,
|
||||||
|
MockRoundTripper: test.MockRoundTripper(func(r *http.Request) *http.Response {
|
||||||
|
return &http.Response{StatusCode: http.StatusOK, Body: http.NoBody}
|
||||||
|
}),
|
||||||
|
ExpectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "resolved-error",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: true,
|
||||||
|
MockRoundTripper: test.MockRoundTripper(func(r *http.Request) *http.Response {
|
||||||
|
return &http.Response{StatusCode: http.StatusInternalServerError, Body: http.NoBody}
|
||||||
|
}),
|
||||||
|
ExpectedError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
t.Run(scenario.Name, func(t *testing.T) {
|
||||||
|
client.InjectHTTPClient(&http.Client{Transport: scenario.MockRoundTripper})
|
||||||
|
err := scenario.Provider.Send(
|
||||||
|
&core.Endpoint{Name: "endpoint-name"},
|
||||||
|
&scenario.Alert,
|
||||||
|
&core.Result{
|
||||||
|
ConditionResults: []*core.ConditionResult{
|
||||||
|
{Condition: "[CONNECTED] == true", Success: scenario.Resolved},
|
||||||
|
{Condition: "[STATUS] == 200", Success: scenario.Resolved},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scenario.Resolved,
|
||||||
|
)
|
||||||
|
if scenario.ExpectedError && err == nil {
|
||||||
|
t.Error("expected error, got none")
|
||||||
|
}
|
||||||
|
if !scenario.ExpectedError && err != nil {
|
||||||
|
t.Error("expected no error, got", err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAlertProvider_buildRequestBody(t *testing.T) {
|
||||||
|
firstDescription := "description-1"
|
||||||
|
secondDescription := "description-2"
|
||||||
|
scenarios := []struct {
|
||||||
|
Name string
|
||||||
|
Provider AlertProvider
|
||||||
|
Endpoint core.Endpoint
|
||||||
|
Alert alert.Alert
|
||||||
|
Resolved bool
|
||||||
|
ExpectedBody string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "triggered",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Endpoint: core.Endpoint{Name: "name"},
|
||||||
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: false,
|
||||||
|
ExpectedBody: `{"channel":"id:","content":{"className":"ChatMessage.Block","style":"WARNING","sections":[{"className":"MessageSection","elements":[{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"warning"},"style":"WARNING"},"style":"WARNING","size":"REGULAR","content":"[CONNECTED] == true"},{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"warning"},"style":"WARNING"},"style":"WARNING","size":"REGULAR","content":"[STATUS] == 200"}],"header":"An alert for *name* has been triggered due to having failed 3 time(s) in a row"}]}}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "triggered-with-group",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Endpoint: core.Endpoint{Name: "name", Group: "group"},
|
||||||
|
Alert: alert.Alert{Description: &firstDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: false,
|
||||||
|
ExpectedBody: `{"channel":"id:","content":{"className":"ChatMessage.Block","style":"WARNING","sections":[{"className":"MessageSection","elements":[{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"warning"},"style":"WARNING"},"style":"WARNING","size":"REGULAR","content":"[CONNECTED] == true"},{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"warning"},"style":"WARNING"},"style":"WARNING","size":"REGULAR","content":"[STATUS] == 200"}],"header":"An alert for *group/name* has been triggered due to having failed 3 time(s) in a row"}]}}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "resolved",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Endpoint: core.Endpoint{Name: "name"},
|
||||||
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: true,
|
||||||
|
ExpectedBody: `{"channel":"id:","content":{"className":"ChatMessage.Block","style":"SUCCESS","sections":[{"className":"MessageSection","elements":[{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"success"},"style":"SUCCESS"},"style":"SUCCESS","size":"REGULAR","content":"[CONNECTED] == true"},{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"success"},"style":"SUCCESS"},"style":"SUCCESS","size":"REGULAR","content":"[STATUS] == 200"}],"header":"An alert for *name* has been resolved after passing successfully 5 time(s) in a row"}]}}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "resolved-with-group",
|
||||||
|
Provider: AlertProvider{},
|
||||||
|
Endpoint: core.Endpoint{Name: "name", Group: "group"},
|
||||||
|
Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3},
|
||||||
|
Resolved: true,
|
||||||
|
ExpectedBody: `{"channel":"id:","content":{"className":"ChatMessage.Block","style":"SUCCESS","sections":[{"className":"MessageSection","elements":[{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"success"},"style":"SUCCESS"},"style":"SUCCESS","size":"REGULAR","content":"[CONNECTED] == true"},{"className":"MessageText","accessory":{"className":"MessageIcon","icon":{"icon":"success"},"style":"SUCCESS"},"style":"SUCCESS","size":"REGULAR","content":"[STATUS] == 200"}],"header":"An alert for *group/name* has been resolved after passing successfully 5 time(s) in a row"}]}}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
t.Run(scenario.Name, func(t *testing.T) {
|
||||||
|
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},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scenario.Resolved,
|
||||||
|
)
|
||||||
|
if string(body) != scenario.ExpectedBody {
|
||||||
|
t.Errorf("expected:\n%s\ngot:\n%s", scenario.ExpectedBody, body)
|
||||||
|
}
|
||||||
|
out := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal(body, &out); err != nil {
|
||||||
|
t.Error("expected body to be valid JSON, got error:", err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAlertProvider_GetDefaultAlert(t *testing.T) {
|
||||||
|
if (&AlertProvider{DefaultAlert: &alert.Alert{}}).GetDefaultAlert() == nil {
|
||||||
|
t.Error("expected default alert to be not nil")
|
||||||
|
}
|
||||||
|
if (&AlertProvider{DefaultAlert: nil}).GetDefaultAlert() != nil {
|
||||||
|
t.Error("expected default alert to be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAlertProvider_getChannelIDForGroup(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
Name string
|
||||||
|
Provider AlertProvider
|
||||||
|
InputGroup string
|
||||||
|
ExpectedOutput string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "provider-no-override-specify-no-group-should-default",
|
||||||
|
Provider: AlertProvider{
|
||||||
|
ChannelID: "bar",
|
||||||
|
},
|
||||||
|
InputGroup: "",
|
||||||
|
ExpectedOutput: "bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "provider-no-override-specify-group-should-default",
|
||||||
|
Provider: AlertProvider{
|
||||||
|
ChannelID: "bar",
|
||||||
|
},
|
||||||
|
InputGroup: "group",
|
||||||
|
ExpectedOutput: "bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "provider-with-override-specify-no-group-should-default",
|
||||||
|
Provider: AlertProvider{
|
||||||
|
ChannelID: "bar",
|
||||||
|
Overrides: []Override{
|
||||||
|
{
|
||||||
|
Group: "group",
|
||||||
|
ChannelID: "foobar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InputGroup: "",
|
||||||
|
ExpectedOutput: "bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "provider-with-override-specify-group-should-override",
|
||||||
|
Provider: AlertProvider{
|
||||||
|
ChannelID: "bar",
|
||||||
|
Overrides: []Override{
|
||||||
|
{
|
||||||
|
Group: "group",
|
||||||
|
ChannelID: "foobar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InputGroup: "group",
|
||||||
|
ExpectedOutput: "foobar",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.Name, func(t *testing.T) {
|
||||||
|
if got := tt.Provider.getChannelIDForGroup(tt.InputGroup); got != tt.ExpectedOutput {
|
||||||
|
t.Errorf("AlertProvider.getChannelIDForGroup() = %v, want %v", got, tt.ExpectedOutput)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/TwiN/gatus/v5/alerting/provider/github"
|
"github.com/TwiN/gatus/v5/alerting/provider/github"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/gitlab"
|
"github.com/TwiN/gatus/v5/alerting/provider/gitlab"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/googlechat"
|
"github.com/TwiN/gatus/v5/alerting/provider/googlechat"
|
||||||
|
"github.com/TwiN/gatus/v5/alerting/provider/jetbrainsspace"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
||||||
@ -66,6 +67,7 @@ var (
|
|||||||
_ AlertProvider = (*github.AlertProvider)(nil)
|
_ AlertProvider = (*github.AlertProvider)(nil)
|
||||||
_ AlertProvider = (*gitlab.AlertProvider)(nil)
|
_ AlertProvider = (*gitlab.AlertProvider)(nil)
|
||||||
_ AlertProvider = (*googlechat.AlertProvider)(nil)
|
_ AlertProvider = (*googlechat.AlertProvider)(nil)
|
||||||
|
_ AlertProvider = (*jetbrainsspace.AlertProvider)(nil)
|
||||||
_ AlertProvider = (*matrix.AlertProvider)(nil)
|
_ AlertProvider = (*matrix.AlertProvider)(nil)
|
||||||
_ AlertProvider = (*mattermost.AlertProvider)(nil)
|
_ AlertProvider = (*mattermost.AlertProvider)(nil)
|
||||||
_ AlertProvider = (*messagebird.AlertProvider)(nil)
|
_ AlertProvider = (*messagebird.AlertProvider)(nil)
|
||||||
|
@ -368,6 +368,7 @@ func validateAlertingConfig(alertingConfig *alerting.Config, endpoints []*core.E
|
|||||||
alert.TypeGitLab,
|
alert.TypeGitLab,
|
||||||
alert.TypeGoogleChat,
|
alert.TypeGoogleChat,
|
||||||
alert.TypeGotify,
|
alert.TypeGotify,
|
||||||
|
alert.TypeJetBrainsSpace,
|
||||||
alert.TypeEmail,
|
alert.TypeEmail,
|
||||||
alert.TypeMatrix,
|
alert.TypeMatrix,
|
||||||
alert.TypeMattermost,
|
alert.TypeMattermost,
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/TwiN/gatus/v5/alerting/provider/email"
|
"github.com/TwiN/gatus/v5/alerting/provider/email"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/github"
|
"github.com/TwiN/gatus/v5/alerting/provider/github"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/googlechat"
|
"github.com/TwiN/gatus/v5/alerting/provider/googlechat"
|
||||||
|
"github.com/TwiN/gatus/v5/alerting/provider/jetbrainsspace"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
||||||
@ -706,6 +707,10 @@ alerting:
|
|||||||
to: "+1-234-567-8901"
|
to: "+1-234-567-8901"
|
||||||
teams:
|
teams:
|
||||||
webhook-url: "http://example.com"
|
webhook-url: "http://example.com"
|
||||||
|
jetbrainsspace:
|
||||||
|
project: "foo"
|
||||||
|
channel-id: "bar"
|
||||||
|
token: "baz"
|
||||||
|
|
||||||
endpoints:
|
endpoints:
|
||||||
- name: website
|
- name: website
|
||||||
@ -728,6 +733,7 @@ endpoints:
|
|||||||
success-threshold: 15
|
success-threshold: 15
|
||||||
- type: teams
|
- type: teams
|
||||||
- type: pushover
|
- type: pushover
|
||||||
|
- type: jetbrainsspace
|
||||||
conditions:
|
conditions:
|
||||||
- "[STATUS] == 200"
|
- "[STATUS] == 200"
|
||||||
`))
|
`))
|
||||||
@ -754,8 +760,8 @@ endpoints:
|
|||||||
if config.Endpoints[0].Interval != 60*time.Second {
|
if config.Endpoints[0].Interval != 60*time.Second {
|
||||||
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
}
|
}
|
||||||
if len(config.Endpoints[0].Alerts) != 9 {
|
if len(config.Endpoints[0].Alerts) != 10 {
|
||||||
t.Fatal("There should've been 9 alerts configured")
|
t.Fatal("There should've been 10 alerts configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Endpoints[0].Alerts[0].Type != alert.TypeSlack {
|
if config.Endpoints[0].Alerts[0].Type != alert.TypeSlack {
|
||||||
@ -862,6 +868,12 @@ endpoints:
|
|||||||
if !config.Endpoints[0].Alerts[8].IsEnabled() {
|
if !config.Endpoints[0].Alerts[8].IsEnabled() {
|
||||||
t.Error("The alert should've been enabled")
|
t.Error("The alert should've been enabled")
|
||||||
}
|
}
|
||||||
|
if config.Endpoints[0].Alerts[9].Type != alert.TypeJetBrainsSpace {
|
||||||
|
t.Errorf("The type of the alert should've been %s, but it was %s", alert.TypeJetBrainsSpace, config.Endpoints[0].Alerts[9].Type)
|
||||||
|
}
|
||||||
|
if !config.Endpoints[0].Alerts[9].IsEnabled() {
|
||||||
|
t.Error("The alert should've been enabled")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseAndValidateConfigBytesWithAlertingAndDefaultAlert(t *testing.T) {
|
func TestParseAndValidateConfigBytesWithAlertingAndDefaultAlert(t *testing.T) {
|
||||||
@ -923,6 +935,14 @@ alerting:
|
|||||||
webhook-url: "http://example.com"
|
webhook-url: "http://example.com"
|
||||||
default-alert:
|
default-alert:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
jetbrainsspace:
|
||||||
|
project: "foo"
|
||||||
|
channel-id: "bar"
|
||||||
|
token: "baz"
|
||||||
|
default-alert:
|
||||||
|
enabled: true
|
||||||
|
failure-threshold: 5
|
||||||
|
success-threshold: 3
|
||||||
|
|
||||||
endpoints:
|
endpoints:
|
||||||
- name: website
|
- name: website
|
||||||
@ -938,6 +958,7 @@ endpoints:
|
|||||||
- type: twilio
|
- type: twilio
|
||||||
- type: teams
|
- type: teams
|
||||||
- type: pushover
|
- type: pushover
|
||||||
|
- type: jetbrainsspace
|
||||||
conditions:
|
conditions:
|
||||||
- "[STATUS] == 200"
|
- "[STATUS] == 200"
|
||||||
`))
|
`))
|
||||||
@ -1049,6 +1070,21 @@ endpoints:
|
|||||||
if config.Alerting.Teams.GetDefaultAlert() == nil {
|
if config.Alerting.Teams.GetDefaultAlert() == nil {
|
||||||
t.Fatal("Teams.GetDefaultAlert() shouldn't have returned nil")
|
t.Fatal("Teams.GetDefaultAlert() shouldn't have returned nil")
|
||||||
}
|
}
|
||||||
|
if config.Alerting.JetBrainsSpace == nil || !config.Alerting.JetBrainsSpace.IsValid() {
|
||||||
|
t.Fatal("JetBrainsSpace alerting config should've been valid")
|
||||||
|
}
|
||||||
|
if config.Alerting.JetBrainsSpace.GetDefaultAlert() == nil {
|
||||||
|
t.Fatal("JetBrainsSpace.GetDefaultAlert() shouldn't have returned nil")
|
||||||
|
}
|
||||||
|
if config.Alerting.JetBrainsSpace.Project != "foo" {
|
||||||
|
t.Errorf("JetBrainsSpace webhook should've been %s, but was %s", "foo", config.Alerting.JetBrainsSpace.Project)
|
||||||
|
}
|
||||||
|
if config.Alerting.JetBrainsSpace.ChannelID != "bar" {
|
||||||
|
t.Errorf("JetBrainsSpace webhook should've been %s, but was %s", "bar", config.Alerting.JetBrainsSpace.ChannelID)
|
||||||
|
}
|
||||||
|
if config.Alerting.JetBrainsSpace.Token != "baz" {
|
||||||
|
t.Errorf("JetBrainsSpace webhook should've been %s, but was %s", "baz", config.Alerting.JetBrainsSpace.Token)
|
||||||
|
}
|
||||||
|
|
||||||
// Endpoints
|
// Endpoints
|
||||||
if len(config.Endpoints) != 1 {
|
if len(config.Endpoints) != 1 {
|
||||||
@ -1060,8 +1096,8 @@ endpoints:
|
|||||||
if config.Endpoints[0].Interval != 60*time.Second {
|
if config.Endpoints[0].Interval != 60*time.Second {
|
||||||
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
}
|
}
|
||||||
if len(config.Endpoints[0].Alerts) != 9 {
|
if len(config.Endpoints[0].Alerts) != 10 {
|
||||||
t.Fatal("There should've been 9 alerts configured")
|
t.Fatal("There should've been 10 alerts configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Endpoints[0].Alerts[0].Type != alert.TypeSlack {
|
if config.Endpoints[0].Alerts[0].Type != alert.TypeSlack {
|
||||||
@ -1178,6 +1214,18 @@ endpoints:
|
|||||||
t.Errorf("The default success threshold of the alert should've been %d, but it was %d", 2, config.Endpoints[0].Alerts[8].SuccessThreshold)
|
t.Errorf("The default success threshold of the alert should've been %d, but it was %d", 2, config.Endpoints[0].Alerts[8].SuccessThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Endpoints[0].Alerts[9].Type != alert.TypeJetBrainsSpace {
|
||||||
|
t.Errorf("The type of the alert should've been %s, but it was %s", alert.TypeJetBrainsSpace, config.Endpoints[0].Alerts[9].Type)
|
||||||
|
}
|
||||||
|
if !config.Endpoints[0].Alerts[9].IsEnabled() {
|
||||||
|
t.Error("The alert should've been enabled")
|
||||||
|
}
|
||||||
|
if config.Endpoints[0].Alerts[9].FailureThreshold != 5 {
|
||||||
|
t.Errorf("The default failure threshold of the alert should've been %d, but it was %d", 3, config.Endpoints[0].Alerts[9].FailureThreshold)
|
||||||
|
}
|
||||||
|
if config.Endpoints[0].Alerts[9].SuccessThreshold != 3 {
|
||||||
|
t.Errorf("The default success threshold of the alert should've been %d, but it was %d", 2, config.Endpoints[0].Alerts[9].SuccessThreshold)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseAndValidateConfigBytesWithAlertingAndDefaultAlertAndMultipleAlertsOfSameTypeWithOverriddenParameters(t *testing.T) {
|
func TestParseAndValidateConfigBytesWithAlertingAndDefaultAlertAndMultipleAlertsOfSameTypeWithOverriddenParameters(t *testing.T) {
|
||||||
@ -1575,6 +1623,7 @@ func TestGetAlertingProviderByAlertType(t *testing.T) {
|
|||||||
Email: &email.AlertProvider{},
|
Email: &email.AlertProvider{},
|
||||||
GitHub: &github.AlertProvider{},
|
GitHub: &github.AlertProvider{},
|
||||||
GoogleChat: &googlechat.AlertProvider{},
|
GoogleChat: &googlechat.AlertProvider{},
|
||||||
|
JetBrainsSpace: &jetbrainsspace.AlertProvider{},
|
||||||
Matrix: &matrix.AlertProvider{},
|
Matrix: &matrix.AlertProvider{},
|
||||||
Mattermost: &mattermost.AlertProvider{},
|
Mattermost: &mattermost.AlertProvider{},
|
||||||
Messagebird: &messagebird.AlertProvider{},
|
Messagebird: &messagebird.AlertProvider{},
|
||||||
@ -1596,6 +1645,7 @@ func TestGetAlertingProviderByAlertType(t *testing.T) {
|
|||||||
{alertType: alert.TypeEmail, expected: alertingConfig.Email},
|
{alertType: alert.TypeEmail, expected: alertingConfig.Email},
|
||||||
{alertType: alert.TypeGitHub, expected: alertingConfig.GitHub},
|
{alertType: alert.TypeGitHub, expected: alertingConfig.GitHub},
|
||||||
{alertType: alert.TypeGoogleChat, expected: alertingConfig.GoogleChat},
|
{alertType: alert.TypeGoogleChat, expected: alertingConfig.GoogleChat},
|
||||||
|
{alertType: alert.TypeJetBrainsSpace, expected: alertingConfig.JetBrainsSpace},
|
||||||
{alertType: alert.TypeMatrix, expected: alertingConfig.Matrix},
|
{alertType: alert.TypeMatrix, expected: alertingConfig.Matrix},
|
||||||
{alertType: alert.TypeMattermost, expected: alertingConfig.Mattermost},
|
{alertType: alert.TypeMattermost, expected: alertingConfig.Mattermost},
|
||||||
{alertType: alert.TypeMessagebird, expected: alertingConfig.Messagebird},
|
{alertType: alert.TypeMessagebird, expected: alertingConfig.Messagebird},
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/TwiN/gatus/v5/alerting/provider/custom"
|
"github.com/TwiN/gatus/v5/alerting/provider/custom"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/discord"
|
"github.com/TwiN/gatus/v5/alerting/provider/discord"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/email"
|
"github.com/TwiN/gatus/v5/alerting/provider/email"
|
||||||
|
"github.com/TwiN/gatus/v5/alerting/provider/jetbrainsspace"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
"github.com/TwiN/gatus/v5/alerting/provider/matrix"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
"github.com/TwiN/gatus/v5/alerting/provider/mattermost"
|
||||||
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
"github.com/TwiN/gatus/v5/alerting/provider/messagebird"
|
||||||
@ -281,6 +282,17 @@ func TestHandleAlertingWithProviderThatReturnsAnError(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "jetbrainsspace",
|
||||||
|
AlertType: alert.TypeJetBrainsSpace,
|
||||||
|
AlertingConfig: &alerting.Config{
|
||||||
|
JetBrainsSpace: &jetbrainsspace.AlertProvider{
|
||||||
|
Project: "foo",
|
||||||
|
ChannelID: "bar",
|
||||||
|
Token: "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "mattermost",
|
Name: "mattermost",
|
||||||
AlertType: alert.TypeMattermost,
|
AlertType: alert.TypeMattermost,
|
||||||
|
Loading…
Reference in New Issue
Block a user