fix(alerting): Ensure that alerting.incident-io.url has the correct prefix (#1034)

* fix(alerting): Ensure that alerting.incident-io.url has the correct prefix

* Fix test
This commit is contained in:
TwiN 2025-03-17 19:41:50 -04:00 committed by GitHub
parent 43b0772e7d
commit 46499e13a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 27 deletions

View File

@ -942,7 +942,7 @@ endpoints:
```
In order to get the required alert source config id and authentication token, you must configure an HTTP alert source.
> **_NOTE:_** the source config id is of the form `api.incident.io/v2/alert_events/http/$ID` and the token is expected to be passed as a bearer token like so: `Authorization: Bearer $TOKEN`
> **_NOTE:_** the source config id is of the form `https://api.incident.io/v2/alert_events/http/$ID` and the token is expected to be passed as a bearer token like so: `Authorization: Bearer $TOKEN`
#### Configuring JetBrains Space alerts

View File

@ -22,9 +22,10 @@ const (
)
var (
ErrURLNotSet = errors.New("url not set")
ErrDuplicateGroupOverride = errors.New("duplicate group override")
ErrAuthTokenNotSet = errors.New("auth-token not set")
ErrURLNotSet = errors.New("url not set")
ErrURLNotPrefixedWithRestAPIURL = fmt.Errorf("url must be prefixed with %s", restAPIUrl)
ErrDuplicateGroupOverride = errors.New("duplicate group override")
ErrAuthTokenNotSet = errors.New("auth-token not set")
)
type Config struct {
@ -38,6 +39,9 @@ func (cfg *Config) Validate() error {
if len(cfg.URL) == 0 {
return ErrURLNotSet
}
if !strings.HasPrefix(cfg.URL, restAPIUrl) {
return ErrURLNotPrefixedWithRestAPIURL
}
if len(cfg.AuthToken) == 0 {
return ErrAuthTokenNotSet
}
@ -113,7 +117,7 @@ func (provider *AlertProvider) Send(ep *endpoint.Endpoint, alert *alert.Alert, r
err = json.NewDecoder(response.Body).Decode(&incidentioResponse)
if err != nil {
// Silently fail. We don't want to create tons of alerts just because we failed to parse the body.
logr.Errorf("[incident-io.Send] Ran into error decoding pagerduty response: %s", err.Error())
logr.Errorf("[incidentio.Send] Ran into error decoding pagerduty response: %s", err.Error())
}
alert.ResolveKey = incidentioResponse.DeduplicationKey
return err
@ -155,10 +159,9 @@ func (provider *AlertProvider) buildRequestBody(cfg *Config, ep *endpoint.Endpoi
if len(alert.GetDescription()) > 0 {
message += " with the following description: " + alert.GetDescription()
}
message += fmt.Sprintf(" and the following conditions: %s ", formattedConditionResults)
var body []byte
alertSourceID := strings.Split(cfg.URL, restAPIUrl)[1]
alertSourceID := strings.TrimPrefix(cfg.URL, restAPIUrl)
body, _ = json.Marshal(Body{
AlertSourceConfigID: alertSourceID,
Title: "Gatus: " + ep.DisplayName(),

View File

@ -23,12 +23,22 @@ func TestAlertProvider_Validate(t *testing.T) {
name: "valid",
provider: AlertProvider{
DefaultConfig: Config{
URL: "some-id",
URL: "https://api.incident.io/v2/alert_events/http/some-id",
AuthToken: "some-token",
},
},
expected: true,
},
{
name: "invalid-url",
provider: AlertProvider{
DefaultConfig: Config{
URL: "id-without-rest-api-url-as-prefix",
AuthToken: "some-token",
},
},
expected: false,
},
{
name: "invalid-missing-auth-token",
provider: AlertProvider{
@ -52,9 +62,9 @@ func TestAlertProvider_Validate(t *testing.T) {
provider: AlertProvider{
DefaultConfig: Config{
AuthToken: "some-token",
URL: "some-id",
URL: "https://api.incident.io/v2/alert_events/http/some-id",
},
Overrides: []Override{{Group: "core", Config: Config{URL: "another-id"}}},
Overrides: []Override{{Group: "core", Config: Config{URL: "https://api.incident.io/v2/alert_events/http/another-id"}}},
},
expected: true,
},
@ -258,67 +268,67 @@ func TestAlertProvider_GetConfig(t *testing.T) {
{
Name: "provider-no-override-specify-no-group-should-default",
Provider: AlertProvider{
DefaultConfig: Config{URL: "some-id", AuthToken: "some-token"},
DefaultConfig: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
Overrides: nil,
},
InputGroup: "",
InputAlert: alert.Alert{},
ExpectedOutput: Config{URL: "some-id", AuthToken: "some-token"},
ExpectedOutput: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
},
{
Name: "provider-no-override-specify-group-should-default",
Provider: AlertProvider{
DefaultConfig: Config{URL: "some-id", AuthToken: "some-token"},
DefaultConfig: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
Overrides: nil,
},
InputGroup: "group",
InputAlert: alert.Alert{},
ExpectedOutput: Config{URL: "some-id", AuthToken: "some-token"},
ExpectedOutput: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
},
{
Name: "provider-with-override-specify-no-group-should-default",
Provider: AlertProvider{
DefaultConfig: Config{URL: "some-id", AuthToken: "some-token"},
DefaultConfig: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
Overrides: []Override{
{
Group: "group",
Config: Config{URL: "diff-id"},
Config: Config{URL: "https://api.incident.io/v2/alert_events/http/diff-id"},
},
},
},
InputGroup: "",
InputAlert: alert.Alert{},
ExpectedOutput: Config{URL: "some-id", AuthToken: "some-token"},
ExpectedOutput: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
},
{
Name: "provider-with-override-specify-group-should-override",
Provider: AlertProvider{
DefaultConfig: Config{URL: "some-id", AuthToken: "some-token"},
DefaultConfig: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
Overrides: []Override{
{
Group: "group",
Config: Config{URL: "diff-id", AuthToken: "some-token"},
Config: Config{URL: "https://api.incident.io/v2/alert_events/http/diff-id", AuthToken: "some-token"},
},
},
},
InputGroup: "group",
InputAlert: alert.Alert{},
ExpectedOutput: Config{URL: "diff-id", AuthToken: "some-token"},
ExpectedOutput: Config{URL: "https://api.incident.io/v2/alert_events/http/diff-id", AuthToken: "some-token"},
},
{
Name: "provider-with-group-override-and-alert-override--alert-override-should-take-precedence",
Provider: AlertProvider{
DefaultConfig: Config{URL: "some-id", AuthToken: "some-token"},
DefaultConfig: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
Overrides: []Override{
{
Group: "group",
Config: Config{URL: "diff-id", AuthToken: "some-token"},
Config: Config{URL: "https://api.incident.io/v2/alert_events/http/diff-id", AuthToken: "some-token"},
},
},
},
InputGroup: "group",
InputAlert: alert.Alert{ProviderOverride: map[string]any{"url": "another-id"}},
ExpectedOutput: Config{URL: "another-id", AuthToken: "some-token"},
InputAlert: alert.Alert{ProviderOverride: map[string]any{"url": "https://api.incident.io/v2/alert_events/http/another-id"}},
ExpectedOutput: Config{URL: "https://api.incident.io/v2/alert_events/http/another-id", AuthToken: "some-token"},
},
}
for _, scenario := range scenarios {
@ -346,7 +356,7 @@ func TestAlertProvider_ValidateWithOverride(t *testing.T) {
providerWithInvalidOverrideGroup := AlertProvider{
Overrides: []Override{
{
Config: Config{URL: "some-id", AuthToken: "some-token"},
Config: Config{URL: "https://api.incident.io/v2/alert_events/http/some-id", AuthToken: "some-token"},
Group: "",
},
},
@ -366,10 +376,10 @@ func TestAlertProvider_ValidateWithOverride(t *testing.T) {
t.Error("provider integration key shouldn't have been valid")
}
providerWithValidOverride := AlertProvider{
DefaultConfig: Config{URL: "nice-id", AuthToken: "some-token"},
DefaultConfig: Config{URL: "https://api.incident.io/v2/alert_events/http/nice-id", AuthToken: "some-token"},
Overrides: []Override{
{
Config: Config{URL: "very-good-id", AuthToken: "some-token"},
Config: Config{URL: "https://api.incident.io/v2/alert_events/http/very-good-id", AuthToken: "some-token"},
Group: "group",
},
},