diff --git a/alerting/config.go b/alerting/config.go index e19a465f..ef617e67 100644 --- a/alerting/config.go +++ b/alerting/config.go @@ -1,8 +1,15 @@ package alerting +import ( + "github.com/TwinProduction/gatus/alerting/provider/custom" + "github.com/TwinProduction/gatus/alerting/provider/pagerduty" + "github.com/TwinProduction/gatus/alerting/provider/slack" + "github.com/TwinProduction/gatus/alerting/provider/twilio" +) + type Config struct { - Slack *SlackAlertProvider `yaml:"slack"` - PagerDuty *PagerDutyAlertProvider `yaml:"pagerduty"` - Twilio *TwilioAlertProvider `yaml:"twilio"` - Custom *CustomAlertProvider `yaml:"custom"` + Slack *slack.AlertProvider `yaml:"slack"` + PagerDuty *pagerduty.AlertProvider `yaml:"pagerduty"` + Twilio *twilio.AlertProvider `yaml:"twilio"` + Custom *custom.AlertProvider `yaml:"custom"` } diff --git a/alerting/pagerduty_test.go b/alerting/pagerduty_test.go deleted file mode 100644 index 338926cd..00000000 --- a/alerting/pagerduty_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package alerting - -import "testing" - -func TestPagerDutyAlertProvider_IsValid(t *testing.T) { - invalidProvider := PagerDutyAlertProvider{IntegrationKey: ""} - if invalidProvider.IsValid() { - t.Error("provider shouldn't have been valid") - } - validProvider := PagerDutyAlertProvider{IntegrationKey: "00000000000000000000000000000000"} - if !validProvider.IsValid() { - t.Error("provider should've been valid") - } -} diff --git a/alerting/custom.go b/alerting/provider/custom/custom.go similarity index 87% rename from alerting/custom.go rename to alerting/provider/custom/custom.go index 313f0e28..0885a01b 100644 --- a/alerting/custom.go +++ b/alerting/provider/custom/custom.go @@ -1,4 +1,4 @@ -package alerting +package custom import ( "bytes" @@ -9,18 +9,18 @@ import ( "strings" ) -type CustomAlertProvider struct { +type AlertProvider struct { Url string `yaml:"url"` Method string `yaml:"method,omitempty"` Body string `yaml:"body,omitempty"` Headers map[string]string `yaml:"headers,omitempty"` } -func (provider *CustomAlertProvider) IsValid() bool { +func (provider *AlertProvider) IsValid() bool { return len(provider.Url) > 0 } -func (provider *CustomAlertProvider) buildRequest(serviceName, alertDescription string, resolved bool) *http.Request { +func (provider *AlertProvider) buildRequest(serviceName, alertDescription string, resolved bool) *http.Request { body := provider.Body providerUrl := provider.Url method := provider.Method @@ -62,7 +62,7 @@ func (provider *CustomAlertProvider) buildRequest(serviceName, alertDescription } // Send a request to the alert provider and return the body -func (provider *CustomAlertProvider) Send(serviceName, alertDescription string, resolved bool) ([]byte, error) { +func (provider *AlertProvider) Send(serviceName, alertDescription string, resolved bool) ([]byte, error) { request := provider.buildRequest(serviceName, alertDescription, resolved) response, err := client.GetHttpClient().Do(request) if err != nil { diff --git a/alerting/custom_test.go b/alerting/provider/custom/custom_test.go similarity index 78% rename from alerting/custom_test.go rename to alerting/provider/custom/custom_test.go index 20ca53ee..92f8c5ba 100644 --- a/alerting/custom_test.go +++ b/alerting/provider/custom/custom_test.go @@ -1,27 +1,27 @@ -package alerting +package custom import ( "io/ioutil" "testing" ) -func TestCustomAlertProvider_IsValid(t *testing.T) { - invalidProvider := CustomAlertProvider{Url: ""} +func TestAlertProvider_IsValid(t *testing.T) { + invalidProvider := AlertProvider{Url: ""} if invalidProvider.IsValid() { t.Error("provider shouldn't have been valid") } - validProvider := CustomAlertProvider{Url: "http://example.com"} + validProvider := AlertProvider{Url: "http://example.com"} if !validProvider.IsValid() { t.Error("provider should've been valid") } } -func TestCustomAlertProvider_buildRequestWhenResolved(t *testing.T) { +func TestAlertProvider_buildRequestWhenResolved(t *testing.T) { const ( ExpectedUrl = "http://example.com/service-name" ExpectedBody = "service-name,alert-description,RESOLVED" ) - customAlertProvider := &CustomAlertProvider{ + customAlertProvider := &AlertProvider{ Url: "http://example.com/[SERVICE_NAME]", Method: "GET", Body: "[SERVICE_NAME],[ALERT_DESCRIPTION],[ALERT_TRIGGERED_OR_RESOLVED]", @@ -37,12 +37,12 @@ func TestCustomAlertProvider_buildRequestWhenResolved(t *testing.T) { } } -func TestCustomAlertProvider_buildRequestWhenTriggered(t *testing.T) { +func TestAlertProvider_buildRequestWhenTriggered(t *testing.T) { const ( ExpectedUrl = "http://example.com/service-name" ExpectedBody = "service-name,alert-description,TRIGGERED" ) - customAlertProvider := &CustomAlertProvider{ + customAlertProvider := &AlertProvider{ Url: "http://example.com/[SERVICE_NAME]", Method: "GET", Body: "[SERVICE_NAME],[ALERT_DESCRIPTION],[ALERT_TRIGGERED_OR_RESOLVED]", diff --git a/alerting/pagerduty.go b/alerting/provider/pagerduty/pagerduty.go similarity index 65% rename from alerting/pagerduty.go rename to alerting/provider/pagerduty/pagerduty.go index 2657e979..d104dfbc 100644 --- a/alerting/pagerduty.go +++ b/alerting/provider/pagerduty/pagerduty.go @@ -1,21 +1,22 @@ -package alerting +package pagerduty import ( "fmt" + "github.com/TwinProduction/gatus/alerting/provider/custom" "github.com/TwinProduction/gatus/core" ) -type PagerDutyAlertProvider struct { +type AlertProvider struct { IntegrationKey string `yaml:"integration-key"` } -func (provider *PagerDutyAlertProvider) IsValid() bool { +func (provider *AlertProvider) IsValid() bool { return len(provider.IntegrationKey) == 32 } // https://developer.pagerduty.com/docs/events-api-v2/trigger-events/ -func (provider *PagerDutyAlertProvider) ToCustomAlertProvider(eventAction, resolveKey string, service *core.Service, message string) *CustomAlertProvider { - return &CustomAlertProvider{ +func (provider *AlertProvider) ToCustomAlertProvider(eventAction, resolveKey string, service *core.Service, message string) *custom.AlertProvider { + return &custom.AlertProvider{ Url: "https://events.pagerduty.com/v2/enqueue", Method: "POST", Body: fmt.Sprintf(`{ diff --git a/alerting/provider/pagerduty/pagerduty_test.go b/alerting/provider/pagerduty/pagerduty_test.go new file mode 100644 index 00000000..47765d3f --- /dev/null +++ b/alerting/provider/pagerduty/pagerduty_test.go @@ -0,0 +1,14 @@ +package pagerduty + +import "testing" + +func TestAlertProvider_IsValid(t *testing.T) { + invalidProvider := AlertProvider{IntegrationKey: ""} + if invalidProvider.IsValid() { + t.Error("provider shouldn't have been valid") + } + validProvider := AlertProvider{IntegrationKey: "00000000000000000000000000000000"} + if !validProvider.IsValid() { + t.Error("provider should've been valid") + } +} diff --git a/alerting/slack.go b/alerting/provider/slack/slack.go similarity index 79% rename from alerting/slack.go rename to alerting/provider/slack/slack.go index 4abdc361..fad3d57e 100644 --- a/alerting/slack.go +++ b/alerting/provider/slack/slack.go @@ -1,19 +1,20 @@ -package alerting +package slack import ( "fmt" + "github.com/TwinProduction/gatus/alerting/provider/custom" "github.com/TwinProduction/gatus/core" ) -type SlackAlertProvider struct { +type AlertProvider struct { WebhookUrl string `yaml:"webhook-url"` } -func (provider *SlackAlertProvider) IsValid() bool { +func (provider *AlertProvider) IsValid() bool { return len(provider.WebhookUrl) > 0 } -func (provider *SlackAlertProvider) ToCustomAlertProvider(service *core.Service, alert *core.Alert, result *core.Result, resolved bool) *CustomAlertProvider { +func (provider *AlertProvider) ToCustomAlertProvider(service *core.Service, alert *core.Alert, result *core.Result, resolved bool) *custom.AlertProvider { var message string var color string if resolved { @@ -33,7 +34,7 @@ func (provider *SlackAlertProvider) ToCustomAlertProvider(service *core.Service, } results += fmt.Sprintf("%s - `%s`\n", prefix, conditionResult.Condition) } - return &CustomAlertProvider{ + return &custom.AlertProvider{ Url: provider.WebhookUrl, Method: "POST", Body: fmt.Sprintf(`{ diff --git a/alerting/provider/slack/slack_test.go b/alerting/provider/slack/slack_test.go new file mode 100644 index 00000000..0a9af3e0 --- /dev/null +++ b/alerting/provider/slack/slack_test.go @@ -0,0 +1,14 @@ +package slack + +import "testing" + +func TestAlertProvider_IsValid(t *testing.T) { + invalidProvider := AlertProvider{WebhookUrl: ""} + if invalidProvider.IsValid() { + t.Error("provider shouldn't have been valid") + } + validProvider := AlertProvider{WebhookUrl: "http://example.com"} + if !validProvider.IsValid() { + t.Error("provider should've been valid") + } +} diff --git a/alerting/twilio.go b/alerting/provider/twilio/twilio.go similarity index 72% rename from alerting/twilio.go rename to alerting/provider/twilio/twilio.go index 933122fc..7d5c13ba 100644 --- a/alerting/twilio.go +++ b/alerting/provider/twilio/twilio.go @@ -1,24 +1,25 @@ -package alerting +package twilio import ( "encoding/base64" "fmt" + "github.com/TwinProduction/gatus/alerting/provider/custom" "net/url" ) -type TwilioAlertProvider struct { +type AlertProvider struct { SID string `yaml:"sid"` Token string `yaml:"token"` From string `yaml:"from"` To string `yaml:"to"` } -func (provider *TwilioAlertProvider) IsValid() bool { +func (provider *AlertProvider) IsValid() bool { return len(provider.Token) > 0 && len(provider.SID) > 0 && len(provider.From) > 0 && len(provider.To) > 0 } -func (provider *TwilioAlertProvider) ToCustomAlertProvider(message string) *CustomAlertProvider { - return &CustomAlertProvider{ +func (provider *AlertProvider) ToCustomAlertProvider(message string) *custom.AlertProvider { + return &custom.AlertProvider{ Url: fmt.Sprintf("https://api.twilio.com/2010-04-01/Accounts/%s/Messages.json", provider.SID), Method: "POST", Body: url.Values{ diff --git a/alerting/twilio_test.go b/alerting/provider/twilio/twilio_test.go similarity index 74% rename from alerting/twilio_test.go rename to alerting/provider/twilio/twilio_test.go index 1da7d4aa..c3613b97 100644 --- a/alerting/twilio_test.go +++ b/alerting/provider/twilio/twilio_test.go @@ -1,13 +1,13 @@ -package alerting +package twilio import "testing" func TestTwilioAlertProvider_IsValid(t *testing.T) { - invalidProvider := TwilioAlertProvider{} + invalidProvider := AlertProvider{} if invalidProvider.IsValid() { t.Error("provider shouldn't have been valid") } - validProvider := TwilioAlertProvider{ + validProvider := AlertProvider{ SID: "1", Token: "1", From: "1", diff --git a/alerting/slack_test.go b/alerting/slack_test.go deleted file mode 100644 index 8d211caa..00000000 --- a/alerting/slack_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package alerting - -import "testing" - -func TestSlackAlertProvider_IsValid(t *testing.T) { - invalidProvider := SlackAlertProvider{WebhookUrl: ""} - if invalidProvider.IsValid() { - t.Error("provider shouldn't have been valid") - } - validProvider := SlackAlertProvider{WebhookUrl: "http://example.com"} - if !validProvider.IsValid() { - t.Error("provider should've been valid") - } -} diff --git a/watchdog/alerting.go b/watchdog/alerting.go index 634408dc..00774f79 100644 --- a/watchdog/alerting.go +++ b/watchdog/alerting.go @@ -3,7 +3,7 @@ package watchdog import ( "encoding/json" "fmt" - "github.com/TwinProduction/gatus/alerting" + "github.com/TwinProduction/gatus/alerting/provider/custom" "github.com/TwinProduction/gatus/config" "github.com/TwinProduction/gatus/core" "log" @@ -36,7 +36,7 @@ func handleAlertsToTrigger(service *core.Service, result *core.Result, cfg *conf } continue } - var alertProvider *alerting.CustomAlertProvider + var alertProvider *custom.AlertProvider if alert.Type == core.SlackAlert { if cfg.Alerting.Slack != nil && cfg.Alerting.Slack.IsValid() { log.Printf("[watchdog][handleAlertsToTrigger] Sending Slack alert because alert with description='%s' has been triggered", alert.Description) @@ -103,7 +103,7 @@ func handleAlertsToResolve(service *core.Service, result *core.Result, cfg *conf if !alert.SendOnResolved { continue } - var alertProvider *alerting.CustomAlertProvider + var alertProvider *custom.AlertProvider if alert.Type == core.SlackAlert { if cfg.Alerting.Slack != nil && cfg.Alerting.Slack.IsValid() { log.Printf("[watchdog][handleAlertsToResolve] Sending Slack alert because alert with description='%s' has been resolved", alert.Description) @@ -128,7 +128,7 @@ func handleAlertsToResolve(service *core.Service, result *core.Result, cfg *conf } else if alert.Type == core.CustomAlert { if cfg.Alerting.Custom != nil && cfg.Alerting.Custom.IsValid() { log.Printf("[watchdog][handleAlertsToResolve] Sending custom alert because alert with description='%s' has been resolved", alert.Description) - alertProvider = &alerting.CustomAlertProvider{ + alertProvider = &custom.AlertProvider{ Url: cfg.Alerting.Custom.Url, Method: cfg.Alerting.Custom.Method, Body: cfg.Alerting.Custom.Body,