Merge pull request #85 from roberth1988/ISSUE73-ALERT_TRIGGERED_OR_RESOLVED-Placeholder

Make ALERT_TRIGGERED_OR_RESOLVED placeholder values configurable
This commit is contained in:
Chris C 2021-02-18 22:28:14 -05:00 committed by GitHub
commit c74472d332
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 9 deletions

View File

@ -16,11 +16,12 @@ import (
// AlertProvider is the configuration necessary for sending an alert using a custom HTTP request // AlertProvider is the configuration necessary for sending an alert using a custom HTTP request
// Technically, all alert providers should be reachable using the custom alert provider // Technically, all alert providers should be reachable using the custom alert provider
type AlertProvider struct { type AlertProvider struct {
URL string `yaml:"url"` URL string `yaml:"url"`
Method string `yaml:"method,omitempty"` Method string `yaml:"method,omitempty"`
Insecure bool `yaml:"insecure,omitempty"` Insecure bool `yaml:"insecure,omitempty"`
Body string `yaml:"body,omitempty"` Body string `yaml:"body,omitempty"`
Headers map[string]string `yaml:"headers,omitempty"` Headers map[string]string `yaml:"headers,omitempty"`
Placeholders map[string]map[string]string `yaml:"placeholders,omitempty"`
} }
// IsValid returns whether the provider's configuration is valid // IsValid returns whether the provider's configuration is valid
@ -33,10 +34,31 @@ func (provider *AlertProvider) ToCustomAlertProvider(service *core.Service, aler
return provider return provider
} }
// GetPlaceholderValue returns the Placeholder value for ALERT_TRIGGERED_OR_RESOLVED if configured
func (provider *AlertProvider) GetAlertStatePlaceholderValue(resolved bool) string {
status := "triggered"
if resolved {
status = "resolved"
}
if _, ok := provider.Placeholders["ALERT_TRIGGERED_OR_RESOLVED"]; ok {
if val, ok := provider.Placeholders["ALERT_TRIGGERED_OR_RESOLVED"][status]; ok {
return val
}
}
if resolved {
return "RESOLVED"
}
return "TRIGGERED"
}
func (provider *AlertProvider) buildHTTPRequest(serviceName, alertDescription string, resolved bool) *http.Request { func (provider *AlertProvider) buildHTTPRequest(serviceName, alertDescription string, resolved bool) *http.Request {
body := provider.Body body := provider.Body
providerURL := provider.URL providerURL := provider.URL
method := provider.Method method := provider.Method
if strings.Contains(body, "[ALERT_DESCRIPTION]") { if strings.Contains(body, "[ALERT_DESCRIPTION]") {
body = strings.ReplaceAll(body, "[ALERT_DESCRIPTION]", alertDescription) body = strings.ReplaceAll(body, "[ALERT_DESCRIPTION]", alertDescription)
} }
@ -45,9 +67,9 @@ func (provider *AlertProvider) buildHTTPRequest(serviceName, alertDescription st
} }
if strings.Contains(body, "[ALERT_TRIGGERED_OR_RESOLVED]") { if strings.Contains(body, "[ALERT_TRIGGERED_OR_RESOLVED]") {
if resolved { if resolved {
body = strings.ReplaceAll(body, "[ALERT_TRIGGERED_OR_RESOLVED]", "RESOLVED") body = strings.ReplaceAll(body, "[ALERT_TRIGGERED_OR_RESOLVED]", provider.GetAlertStatePlaceholderValue(true))
} else { } else {
body = strings.ReplaceAll(body, "[ALERT_TRIGGERED_OR_RESOLVED]", "TRIGGERED") body = strings.ReplaceAll(body, "[ALERT_TRIGGERED_OR_RESOLVED]", provider.GetAlertStatePlaceholderValue(false))
} }
} }
if strings.Contains(providerURL, "[ALERT_DESCRIPTION]") { if strings.Contains(providerURL, "[ALERT_DESCRIPTION]") {
@ -58,9 +80,9 @@ func (provider *AlertProvider) buildHTTPRequest(serviceName, alertDescription st
} }
if strings.Contains(providerURL, "[ALERT_TRIGGERED_OR_RESOLVED]") { if strings.Contains(providerURL, "[ALERT_TRIGGERED_OR_RESOLVED]") {
if resolved { if resolved {
providerURL = strings.ReplaceAll(providerURL, "[ALERT_TRIGGERED_OR_RESOLVED]", "RESOLVED") providerURL = strings.ReplaceAll(providerURL, "[ALERT_TRIGGERED_OR_RESOLVED]", provider.GetAlertStatePlaceholderValue(true))
} else { } else {
providerURL = strings.ReplaceAll(providerURL, "[ALERT_TRIGGERED_OR_RESOLVED]", "TRIGGERED") providerURL = strings.ReplaceAll(providerURL, "[ALERT_TRIGGERED_OR_RESOLVED]", provider.GetAlertStatePlaceholderValue(false))
} }
} }
if len(method) == 0 { if len(method) == 0 {

View File

@ -68,3 +68,45 @@ func TestAlertProvider_ToCustomAlertProvider(t *testing.T) {
t.Error("customAlertProvider should've been equal to customAlertProvider") t.Error("customAlertProvider should've been equal to customAlertProvider")
} }
} }
func TestAlertProvider_buildHTTPRequestWithCustomPlaceholder(t *testing.T) {
const (
ExpectedURL = "http://example.com/service-name?event=MYTEST&description=alert-description"
ExpectedBody = "service-name,alert-description,MYTEST"
)
customAlertProvider := &AlertProvider{
URL: "http://example.com/[SERVICE_NAME]?event=[ALERT_TRIGGERED_OR_RESOLVED]&description=[ALERT_DESCRIPTION]",
Body: "[SERVICE_NAME],[ALERT_DESCRIPTION],[ALERT_TRIGGERED_OR_RESOLVED]",
Headers: nil,
Placeholders: map[string]map[string]string{
"ALERT_TRIGGERED_OR_RESOLVED": {
"resolved": "MYTEST",
},
},
}
request := customAlertProvider.buildHTTPRequest("service-name", "alert-description", true)
if request.URL.String() != ExpectedURL {
t.Error("expected URL to be", ExpectedURL, "was", request.URL.String())
}
body, _ := ioutil.ReadAll(request.Body)
if string(body) != ExpectedBody {
t.Error("expected body to be", ExpectedBody, "was", string(body))
}
}
func TestAlertProvider_GetAlertStatePlaceholderValueDefaults(t *testing.T) {
customAlertProvider := &AlertProvider{
URL: "http://example.com/[SERVICE_NAME]?event=[ALERT_TRIGGERED_OR_RESOLVED]&description=[ALERT_DESCRIPTION]",
Body: "[SERVICE_NAME],[ALERT_DESCRIPTION],[ALERT_TRIGGERED_OR_RESOLVED]",
Headers: nil,
Placeholders: nil,
}
if customAlertProvider.GetAlertStatePlaceholderValue(true) != "RESOLVED" {
t.Error("expected here actually RESOLVED")
}
if customAlertProvider.GetAlertStatePlaceholderValue(false) != "TRIGGERED" {
t.Error("expected here actually TRIGGERED")
}
}

View File

@ -344,6 +344,11 @@ alerting:
access-key: "1" access-key: "1"
originator: "31619191918" originator: "31619191918"
recipients: "31619191919" recipients: "31619191919"
custom:
placeholders:
ALERT_TRIGGERED_OR_RESOLVED:
triggered: "partial_outage"
resolved: "operational"
services: services:
- name: twinnation - name: twinnation
url: https://twinnation.org/health url: https://twinnation.org/health
@ -396,6 +401,12 @@ services:
if config.Alerting.Messagebird.Recipients != "31619191919" { if config.Alerting.Messagebird.Recipients != "31619191919" {
t.Errorf("Messagebird to recipients should've been %s, but was %s", "31619191919", config.Alerting.Messagebird.Recipients) t.Errorf("Messagebird to recipients should've been %s, but was %s", "31619191919", config.Alerting.Messagebird.Recipients)
} }
if config.Alerting.Custom == nil {
t.Fatal("config.Alerting. Custom shouldn't have been nil")
}
if config.Alerting.Custom.Placeholders == nil {
t.Fatal("config.Alerting.Custom.Placeholders shouldn't have been nil")
}
if len(config.Services) != 1 { if len(config.Services) != 1 {
t.Error("There should've been 1 service") t.Error("There should've been 1 service")
} }