Skip to content

Commit 17d6a6f

Browse files
committed
Address review comments
- Made a change to demarcate `AlertSourceToken` as required - Now error if an authorization header is set, and a alert_source_token is set - Ensure the alert source endpoint is no longer secret - Add documentation for the incidentio_config Signed-off-by: Rory Malcolm <[email protected]>
1 parent 4bc00a7 commit 17d6a6f

File tree

3 files changed

+67
-23
lines changed

3 files changed

+67
-23
lines changed

config/notifiers.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,16 +535,18 @@ type IncidentioConfig struct {
535535
HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`
536536

537537
// URL to send POST request to.
538-
URL *SecretURL `yaml:"url" json:"url"`
539-
URLFile string `yaml:"url_file" json:"url_file"`
538+
URL *URL `yaml:"url" json:"url"`
539+
URLFile string `yaml:"url_file" json:"url_file"`
540540

541541
// AlertSourceToken is the key used to authenticate with the alert source in incident.io.
542542
AlertSourceToken Secret `yaml:"alert_source_token,omitempty" json:"alert_source_token,omitempty"`
543543
AlertSourceTokenFile string `yaml:"alert_source_token_file,omitempty" json:"alert_source_token_file,omitempty"`
544544

545545
// MaxAlerts is the maximum number of alerts to be sent per incident.io message.
546546
// Alerts exceeding this threshold will be truncated. Setting this to 0
547-
// allows an unlimited number of alerts.
547+
// allows an unlimited number of alerts. Note that if the payload exceeds
548+
// incident.io's size limits, you will receive a 429 response and alerts
549+
// will not be ingested.
548550
MaxAlerts uint64 `yaml:"max_alerts" json:"max_alerts"`
549551

550552
// Timeout is the maximum time allowed to invoke incident.io. Setting this to 0
@@ -568,6 +570,12 @@ func (c *IncidentioConfig) UnmarshalYAML(unmarshal func(interface{}) error) erro
568570
if c.AlertSourceToken != "" && c.AlertSourceTokenFile != "" {
569571
return errors.New("at most one of alert_source_token & alert_source_token_file must be configured")
570572
}
573+
if c.AlertSourceToken == "" && c.AlertSourceTokenFile == "" {
574+
return errors.New("one of alert_source_token or alert_source_token_file must be configured")
575+
}
576+
if c.HTTPConfig != nil && c.HTTPConfig.Authorization != nil && (c.AlertSourceToken != "" || c.AlertSourceTokenFile != "") {
577+
return errors.New("cannot specify both alert_source_token/alert_source_token_file and http_config.authorization")
578+
}
571579
return nil
572580
}
573581

docs/configuration.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,8 @@ opsgenie_configs:
748748
[ - <opsgenie_config>, ... ]
749749
pagerduty_configs:
750750
[ - <pagerduty_config>, ... ]
751+
incidentio_configs:
752+
[ - <incidentio_config>, ... ]
751753
pushover_configs:
752754
[ - <pushover_config>, ... ]
753755
rocketchat_configs:
@@ -1673,6 +1675,40 @@ There is a list of
16731675
[integrations](https://prometheus.io/docs/operating/integrations/#alertmanager-webhook-receiver) with
16741676
this feature.
16751677

1678+
### `<incidentio_config>`
1679+
1680+
incident.io notifications are sent via the [incident.io Alert Sources API](https://incident.io/docs/api/alert-sources).
1681+
1682+
```yaml
1683+
# Whether to notify about resolved alerts.
1684+
[ send_resolved: <boolean> | default = true ]
1685+
1686+
# The HTTP client's configuration.
1687+
[ http_config: <http_config> | default = global.http_config ]
1688+
1689+
# The URL to send the incident.io alert. This would typically be provided by the
1690+
# incident.io team when setting up an alert source.
1691+
# URL and URL_file are mutually exclusive.
1692+
url: <string>
1693+
url_file: <filepath>
1694+
1695+
# The alert source token is used to authenticate with incident.io.
1696+
# alert_source_token and alert_source_token_file are mutually exclusive.
1697+
[ alert_source_token: <secret> ]
1698+
[ alert_source_token_file: <filepath> ]
1699+
1700+
# The maximum number of alerts to be sent per incident.io message.
1701+
# Alerts exceeding this threshold will be truncated. Setting this to 0
1702+
# allows an unlimited number of alerts. Note that if the payload exceeds
1703+
# incident.io's size limits, you will receive a 429 response and alerts
1704+
# will not be ingested.
1705+
[ max_alerts: <int> | default = 0 ]
1706+
1707+
# Timeout is the maximum time allowed to invoke incident.io. Setting this to 0
1708+
# does not impose a timeout.
1709+
[ timeout: <duration> | default = 0s ]
1710+
```
1711+
16761712
### `<wechat_config>`
16771713

16781714
WeChat notifications are sent via the [WeChat

notify/incidentio/incidentio.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,36 @@ type Notifier struct {
4343

4444
// New returns a new incident.io notifier.
4545
func New(conf *config.IncidentioConfig, t *template.Template, l *slog.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
46-
// If alert source token is specified, set authorization in HTTP config
46+
// Handle authentication configuration
4747
if conf.HTTPConfig == nil {
4848
conf.HTTPConfig = &commoncfg.HTTPClientConfig{}
4949
}
5050

51+
// Ensure one of AlertSourceToken or AlertSourceTokenFile is provided
52+
if conf.AlertSourceToken == "" && conf.AlertSourceTokenFile == "" {
53+
return nil, errors.New("one of alert_source_token or alert_source_token_file must be configured")
54+
}
55+
56+
// Error if authorization is already set in HTTPConfig
57+
if conf.HTTPConfig.Authorization != nil {
58+
return nil, errors.New("cannot specify both alert_source_token/alert_source_token_file and http_config.authorization")
59+
}
60+
61+
// Set authorization from token or token file
5162
if conf.AlertSourceToken != "" {
52-
if conf.HTTPConfig.Authorization == nil {
53-
conf.HTTPConfig.Authorization = &commoncfg.Authorization{
54-
Type: "Bearer",
55-
Credentials: commoncfg.Secret(conf.AlertSourceToken),
56-
}
63+
conf.HTTPConfig.Authorization = &commoncfg.Authorization{
64+
Type: "Bearer",
65+
Credentials: commoncfg.Secret(conf.AlertSourceToken),
5766
}
5867
} else if conf.AlertSourceTokenFile != "" {
5968
content, err := os.ReadFile(conf.AlertSourceTokenFile)
6069
if err != nil {
6170
return nil, fmt.Errorf("failed to read alert_source_token_file: %w", err)
6271
}
6372

64-
if conf.HTTPConfig.Authorization == nil {
65-
conf.HTTPConfig.Authorization = &commoncfg.Authorization{
66-
Type: "Bearer",
67-
Credentials: commoncfg.Secret(strings.TrimSpace(string(content))),
68-
}
73+
conf.HTTPConfig.Authorization = &commoncfg.Authorization{
74+
Type: "Bearer",
75+
Credentials: commoncfg.Secret(strings.TrimSpace(string(content))),
6976
}
7077
}
7178

@@ -83,10 +90,6 @@ func New(conf *config.IncidentioConfig, t *template.Template, l *slog.Logger, ht
8390
retrier: &notify.Retrier{
8491
RetryCodes: []int{
8592
http.StatusTooManyRequests, // 429
86-
http.StatusInternalServerError,
87-
http.StatusBadGateway,
88-
http.StatusServiceUnavailable,
89-
http.StatusGatewayTimeout,
9093
},
9194
CustomDetailsFunc: errDetails,
9295
},
@@ -124,7 +127,7 @@ func (n *Notifier) Notify(ctx context.Context, alerts ...*types.Alert) (bool, er
124127
n.logger.Debug("incident.io notification", "groupKey", groupKey)
125128

126129
msg := &Message{
127-
Version: "4",
130+
Version: "1",
128131
Data: data,
129132
GroupKey: groupKey.String(),
130133
TruncatedAlerts: numTruncated,
@@ -197,8 +200,5 @@ func errDetails(status int, body io.Reader) string {
197200
parts = append(parts, strings.Join(errorResponse.Errors, ", "))
198201
}
199202

200-
if len(parts) > 0 {
201-
return strings.Join(parts, ": ")
202-
}
203-
return ""
203+
return strings.Join(parts, ": ")
204204
}

0 commit comments

Comments
 (0)