feat(alert): Add group-specific to email list (#264)

* feat(alert): Add group-specific to email list

Add group-specific to list for email alert

https://github.com/TwiN/gatus/issues/96

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* docs: update

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* Update README.md

* Update README.md

* Update README.md

* chore: update

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>

* Update README.md
This commit is contained in:
Bo-Yi Wu
2022-03-21 09:54:20 +08:00
committed by GitHub
parent bec2820969
commit a81c81e42c
3 changed files with 170 additions and 14 deletions

View File

@ -21,10 +21,29 @@ type AlertProvider struct {
// DefaultAlert is the default 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"`
To string `yaml:"to"`
}
// 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.To) == 0 {
return false
}
registeredGroups[override.Group] = true
}
}
return len(provider.From) > 0 && len(provider.Password) > 0 && len(provider.Host) > 0 && len(provider.To) > 0 && provider.Port > 0 && provider.Port < math.MaxUint16
}
@ -39,7 +58,7 @@ func (provider *AlertProvider) Send(endpoint *core.Endpoint, alert *alert.Alert,
subject, body := provider.buildMessageSubjectAndBody(endpoint, alert, result, resolved)
m := gomail.NewMessage()
m.SetHeader("From", provider.From)
m.SetHeader("To", strings.Split(provider.To, ",")...)
m.SetHeader("To", strings.Split(provider.getToForGroup(endpoint.Group), ",")...)
m.SetHeader("Subject", subject)
m.SetBody("text/plain", body)
d := gomail.NewDialer(provider.Host, provider.Port, username, provider.Password)
@ -72,6 +91,18 @@ func (provider *AlertProvider) buildMessageSubjectAndBody(endpoint *core.Endpoin
return subject, message + description + "\n\nCondition results:\n" + results
}
// getToForGroup returns the appropriate email integration to for a given group
func (provider *AlertProvider) getToForGroup(group string) string {
if provider.Overrides != nil {
for _, override := range provider.Overrides {
if group == override.Group {
return override.To
}
}
}
return provider.To
}
// GetDefaultAlert returns the provider's default alert configuration
func (provider AlertProvider) GetDefaultAlert() *alert.Alert {
return provider.DefaultAlert

View File

@ -7,7 +7,7 @@ import (
"github.com/TwiN/gatus/v3/core"
)
func TestAlertProvider_IsValid(t *testing.T) {
func TestAlertDefaultProvider_IsValid(t *testing.T) {
invalidProvider := AlertProvider{}
if invalidProvider.IsValid() {
t.Error("provider shouldn't have been valid")
@ -18,6 +18,47 @@ func TestAlertProvider_IsValid(t *testing.T) {
}
}
func TestAlertProvider_IsValidWithOverride(t *testing.T) {
providerWithInvalidOverrideGroup := AlertProvider{
Overrides: []Override{
{
To: "to@example.com",
Group: "",
},
},
}
if providerWithInvalidOverrideGroup.IsValid() {
t.Error("provider Group shouldn't have been valid")
}
providerWithInvalidOverrideTo := AlertProvider{
Overrides: []Override{
{
To: "",
Group: "group",
},
},
}
if providerWithInvalidOverrideTo.IsValid() {
t.Error("provider integration key shouldn't have been valid")
}
providerWithValidOverride := AlertProvider{
From: "from@example.com",
Password: "password",
Host: "smtp.gmail.com",
Port: 587,
To: "to@example.com",
Overrides: []Override{
{
To: "to@example.com",
Group: "group",
},
},
}
if !providerWithValidOverride.IsValid() {
t.Error("provider should've been valid")
}
}
func TestAlertProvider_buildRequestBody(t *testing.T) {
firstDescription := "description-1"
secondDescription := "description-2"
@ -77,3 +118,66 @@ func TestAlertProvider_GetDefaultAlert(t *testing.T) {
t.Error("expected default alert to be nil")
}
}
func TestAlertProvider_getToForGroup(t *testing.T) {
tests := []struct {
Name string
Provider AlertProvider
InputGroup string
ExpectedOutput string
}{
{
Name: "provider-no-override-specify-no-group-should-default",
Provider: AlertProvider{
To: "to@example.com",
Overrides: nil,
},
InputGroup: "",
ExpectedOutput: "to@example.com",
},
{
Name: "provider-no-override-specify-group-should-default",
Provider: AlertProvider{
To: "to@example.com",
Overrides: nil,
},
InputGroup: "group",
ExpectedOutput: "to@example.com",
},
{
Name: "provider-with-override-specify-no-group-should-default",
Provider: AlertProvider{
To: "to@example.com",
Overrides: []Override{
{
Group: "group",
To: "to01@example.com",
},
},
},
InputGroup: "",
ExpectedOutput: "to@example.com",
},
{
Name: "provider-with-override-specify-group-should-override",
Provider: AlertProvider{
To: "to@example.com",
Overrides: []Override{
{
Group: "group",
To: "to01@example.com",
},
},
},
InputGroup: "group",
ExpectedOutput: "to01@example.com",
},
}
for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
if got := tt.Provider.getToForGroup(tt.InputGroup); got != tt.ExpectedOutput {
t.Errorf("AlertProvider.getToForGroup() = %v, want %v", got, tt.ExpectedOutput)
}
})
}
}