diff --git a/README.md b/README.md index 8aedded2..fa06b637 100644 --- a/README.md +++ b/README.md @@ -442,12 +442,16 @@ endpoints: **NOTE:** Some mail servers are painfully slow. #### Configuring Google Chat alerts -| Parameter | Description | Default | -|:------------------------------------|:--------------------------------------------------------------------------------------------|:--------------| -| `alerting.googlechat` | Configuration for alerts of type `googlechat` | `{}` | -| `alerting.googlechat.webhook-url` | Google Chat Webhook URL | Required `""` | -| `alerting.googlechat.client` | Client configuration.
See [Client configuration](#client-configuration). | `{}` | -| `alerting.googlechat.default-alert` | Default alert configuration.
See [Setting a default alert](#setting-a-default-alert). | N/A | + +| Parameter | Description | Default | +|:--------------------------------------------- |:------------------------------------------------------------------------------------------- |:------------- | +| `alerting.googlechat` | Configuration for alerts of type `googlechat` | `{}` | +| `alerting.googlechat.webhook-url` | Google Chat Webhook URL | Required `""` | +| `alerting.googlechat.client` | Client configuration.
See [Client configuration](#client-configuration). | `{}` | +| `alerting.googlechat.default-alert` | Default alert configuration.
See [Setting a default alert](#setting-a-default-alert). | N/A | +| `alerting.googlechat.overrides` | List of overrides that may be prioritized over the default configuration | `[]` | +| `alerting.googlechat.overrides[].group` | Endpoint group for which the configuration will be overridden by this configuration | `""` | +| `alerting.googlechat.overrides[].webhook-url` | Teams Webhook URL | `""` | ```yaml alerting: diff --git a/alerting/provider/googlechat/googlechat.go b/alerting/provider/googlechat/googlechat.go index d6162ae4..405f41f4 100644 --- a/alerting/provider/googlechat/googlechat.go +++ b/alerting/provider/googlechat/googlechat.go @@ -20,6 +20,15 @@ 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"` + WebhookURL string `yaml:"webhook-url"` } // IsValid returns whether the provider's configuration is valid @@ -27,13 +36,24 @@ func (provider *AlertProvider) IsValid() bool { if provider.ClientConfig == nil { provider.ClientConfig = client.GetDefaultConfig() } + + registeredGroups := make(map[string]bool) + if provider.Overrides != nil { + for _, override := range provider.Overrides { + if isAlreadyRegistered := registeredGroups[override.Group]; isAlreadyRegistered || override.Group == "" || len(override.WebhookURL) == 0 { + return false + } + registeredGroups[override.Group] = true + } + } + return len(provider.WebhookURL) > 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([]byte(provider.buildRequestBody(endpoint, alert, result, resolved))) - request, err := http.NewRequest(http.MethodPost, provider.WebhookURL, buffer) + request, err := http.NewRequest(http.MethodPost, provider.getWebhookURLForGroup(endpoint.Group), buffer) if err != nil { return err } @@ -118,6 +138,18 @@ func (provider *AlertProvider) buildRequestBody(endpoint *core.Endpoint, alert * }`, endpoint.Name, endpoint.Group, message, description, results, endpoint.URL) } +// getWebhookURLForGroup returns the appropriate Webhook URL integration to for a given group +func (provider *AlertProvider) getWebhookURLForGroup(group string) string { + if provider.Overrides != nil { + for _, override := range provider.Overrides { + if group == override.Group { + return override.WebhookURL + } + } + } + return provider.WebhookURL +} + // GetDefaultAlert returns the provider's default alert configuration func (provider AlertProvider) GetDefaultAlert() *alert.Alert { return provider.DefaultAlert diff --git a/alerting/provider/googlechat/googlechat_test.go b/alerting/provider/googlechat/googlechat_test.go index 55126911..543cee61 100644 --- a/alerting/provider/googlechat/googlechat_test.go +++ b/alerting/provider/googlechat/googlechat_test.go @@ -11,7 +11,7 @@ import ( "github.com/TwiN/gatus/v3/test" ) -func TestAlertProvider_IsValid(t *testing.T) { +func TestAlertDefaultProvider_IsValid(t *testing.T) { invalidProvider := AlertProvider{WebhookURL: ""} if invalidProvider.IsValid() { t.Error("provider shouldn't have been valid") @@ -22,6 +22,43 @@ func TestAlertProvider_IsValid(t *testing.T) { } } +func TestAlertProvider_IsValidWithOverride(t *testing.T) { + providerWithInvalidOverrideGroup := AlertProvider{ + Overrides: []Override{ + { + WebhookURL: "http://example.com", + Group: "", + }, + }, + } + if providerWithInvalidOverrideGroup.IsValid() { + t.Error("provider Group shouldn't have been valid") + } + providerWithInvalidOverrideTo := AlertProvider{ + Overrides: []Override{ + { + WebhookURL: "", + Group: "group", + }, + }, + } + if providerWithInvalidOverrideTo.IsValid() { + t.Error("provider integration key shouldn't have been valid") + } + providerWithValidOverride := AlertProvider{ + WebhookURL: "http://example.com", + Overrides: []Override{ + { + WebhookURL: "http://example.com", + 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" @@ -158,3 +195,66 @@ func TestAlertProvider_GetDefaultAlert(t *testing.T) { t.Error("expected default alert to be nil") } } + +func TestAlertProvider_getWebhookURLForGroup(t *testing.T) { + tests := []struct { + Name string + Provider AlertProvider + InputGroup string + ExpectedOutput string + }{ + { + Name: "provider-no-override-specify-no-group-should-default", + Provider: AlertProvider{ + WebhookURL: "http://example.com", + Overrides: nil, + }, + InputGroup: "", + ExpectedOutput: "http://example.com", + }, + { + Name: "provider-no-override-specify-group-should-default", + Provider: AlertProvider{ + WebhookURL: "http://example.com", + Overrides: nil, + }, + InputGroup: "group", + ExpectedOutput: "http://example.com", + }, + { + Name: "provider-with-override-specify-no-group-should-default", + Provider: AlertProvider{ + WebhookURL: "http://example.com", + Overrides: []Override{ + { + Group: "group", + WebhookURL: "http://example01.com", + }, + }, + }, + InputGroup: "", + ExpectedOutput: "http://example.com", + }, + { + Name: "provider-with-override-specify-group-should-override", + Provider: AlertProvider{ + WebhookURL: "http://example.com", + Overrides: []Override{ + { + Group: "group", + WebhookURL: "http://example01.com", + }, + }, + }, + InputGroup: "group", + ExpectedOutput: "http://example01.com", + }, + } + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + if got := tt.Provider.getWebhookURLForGroup(tt.InputGroup); got != tt.ExpectedOutput { + t.Errorf("AlertProvider.getToForGroup() = %v, want %v", got, tt.ExpectedOutput) + } + }) + } +}