Add support for displaying the alert's GeneratorURL
This commit is contained in:
parent
fa1a7916f0
commit
f4483532f5
5 changed files with 57 additions and 27 deletions
|
@ -19,7 +19,7 @@ of this file is [scfg] and there is an [example configuration file] in this repo
|
||||||
Furthermore you can take a look at [my deployment].
|
Furthermore you can take a look at [my deployment].
|
||||||
|
|
||||||
ntfy-alertmanager has support for setting ntfy [priority], [tags], [icon], [action buttons]
|
ntfy-alertmanager has support for setting ntfy [priority], [tags], [icon], [action buttons]
|
||||||
(which can be used to create an Alertmanager silence), [email notifications] and [phone calls].
|
(which can be used to e.g. create an Alertmanager silence or open the alert's Prometheus URL), [email notifications] and [phone calls].
|
||||||
Define a decreasing order of labels in the config file and map those labels to tags, priority, an icon or an email address.
|
Define a decreasing order of labels in the config file and map those labels to tags, priority, an icon or an email address.
|
||||||
|
|
||||||
- For priority and icon the first found value will be chosen. Settings for "resolved" alerts will take precedence.
|
- For priority and icon the first found value will be chosen. Settings for "resolved" alerts will take precedence.
|
||||||
|
|
|
@ -87,8 +87,12 @@ ntfy {
|
||||||
# Default: ""
|
# Default: ""
|
||||||
email-address foo@example.com
|
email-address foo@example.com
|
||||||
# Call the specified number for all alerts. Use `yes` to pick the first of your verified numbers.
|
# Call the specified number for all alerts. Use `yes` to pick the first of your verified numbers.
|
||||||
Default: ""
|
# Default: ""
|
||||||
call +123456789
|
call +123456789
|
||||||
|
# Add a button that will open the alert's generator/Prometheus URL with the following label.
|
||||||
|
# This only works for the "single" alert-mode.
|
||||||
|
# Default: ""
|
||||||
|
generator-url-label source
|
||||||
}
|
}
|
||||||
|
|
||||||
alertmanager {
|
alertmanager {
|
||||||
|
|
|
@ -44,6 +44,7 @@ type ntfyConfig struct {
|
||||||
CertFingerprint string
|
CertFingerprint string
|
||||||
EmailAddress string
|
EmailAddress string
|
||||||
Call string
|
Call string
|
||||||
|
GeneratorURLLabel string
|
||||||
}
|
}
|
||||||
|
|
||||||
type labels struct {
|
type labels struct {
|
||||||
|
@ -272,6 +273,13 @@ func parseBlock(block scfg.Block, config *Config) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d = ntfyDir.Children.Get("generator-url-label")
|
||||||
|
if d != nil {
|
||||||
|
if err := d.ParseParams(&config.Ntfy.GeneratorURLLabel); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheDir := block.Get("cache")
|
cacheDir := block.Get("cache")
|
||||||
|
|
|
@ -50,6 +50,7 @@ ntfy {
|
||||||
certificate-fingerprint 13:6D:2B:88:9C:57:36:D0:81:B4:B2:9C:79:09:27:62:92:CF:B8:6A:6B:D3:AD:46:35:CB:70:17:EB:99:6E:28:08:2A:B8:C6:79:4B:F6:2E:81:79:41:98:1D:53:C8:07:B3:5C:24:5F:B1:8E:B6:FB:66:B5:DD:B4:D0:5C:29:91
|
certificate-fingerprint 13:6D:2B:88:9C:57:36:D0:81:B4:B2:9C:79:09:27:62:92:CF:B8:6A:6B:D3:AD:46:35:CB:70:17:EB:99:6E:28:08:2A:B8:C6:79:4B:F6:2E:81:79:41:98:1D:53:C8:07:B3:5C:24:5F:B1:8E:B6:FB:66:B5:DD:B4:D0:5C:29:91
|
||||||
user user
|
user user
|
||||||
password pass
|
password pass
|
||||||
|
generator-url-label source
|
||||||
}
|
}
|
||||||
|
|
||||||
alertmanager {
|
alertmanager {
|
||||||
|
@ -80,6 +81,7 @@ cache {
|
||||||
User: "user",
|
User: "user",
|
||||||
Password: "pass",
|
Password: "pass",
|
||||||
CertFingerprint: "136d2b889c5736d081b4b29c7909276292cfb86a6bd3ad4635cb7017eb996e28082ab8c6794bf62e817941981d53c807b35c245fb18eb6fb66b5ddb4d05c2991",
|
CertFingerprint: "136d2b889c5736d081b4b29c7909276292cfb86a6bd3ad4635cb7017eb996e28082ab8c6794bf62e817941981d53c807b35c245fb18eb6fb66b5ddb4d05c2991",
|
||||||
|
GeneratorURLLabel: "source",
|
||||||
},
|
},
|
||||||
Labels: labels{Order: []string{"severity", "instance"},
|
Labels: labels{Order: []string{"severity", "instance"},
|
||||||
Label: map[string]labelConfig{
|
Label: map[string]labelConfig{
|
||||||
|
|
18
main.go
18
main.go
|
@ -53,6 +53,7 @@ type alert struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Labels map[string]string `json:"labels"`
|
Labels map[string]string `json:"labels"`
|
||||||
Annotations map[string]string `json:"annotations"`
|
Annotations map[string]string `json:"annotations"`
|
||||||
|
GeneratorURL string `json:"generatorURL"`
|
||||||
Fingerprint string `json:"fingerprint"`
|
Fingerprint string `json:"fingerprint"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ type notification struct {
|
||||||
silenceBody string
|
silenceBody string
|
||||||
fingerprint string
|
fingerprint string
|
||||||
status string
|
status string
|
||||||
|
generatorURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ntfyError struct {
|
type ntfyError struct {
|
||||||
|
@ -91,6 +93,7 @@ func (br *bridge) singleAlertNotifications(p *payload) []*notification {
|
||||||
n := new(notification)
|
n := new(notification)
|
||||||
n.fingerprint = alert.Fingerprint
|
n.fingerprint = alert.Fingerprint
|
||||||
n.status = alert.Status
|
n.status = alert.Status
|
||||||
|
n.generatorURL = alert.GeneratorURL
|
||||||
|
|
||||||
// create title
|
// create title
|
||||||
n.title = fmt.Sprintf("[%s]", strings.ToUpper(alert.Status))
|
n.title = fmt.Sprintf("[%s]", strings.ToUpper(alert.Status))
|
||||||
|
@ -295,6 +298,8 @@ func (br *bridge) publish(n *notification) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var actions []string
|
||||||
|
|
||||||
// ntfy authentication
|
// ntfy authentication
|
||||||
if br.cfg.Ntfy.Password != "" && br.cfg.Ntfy.User != "" {
|
if br.cfg.Ntfy.Password != "" && br.cfg.Ntfy.User != "" {
|
||||||
req.SetBasicAuth(br.cfg.Ntfy.User, br.cfg.Ntfy.Password)
|
req.SetBasicAuth(br.cfg.Ntfy.User, br.cfg.Ntfy.Password)
|
||||||
|
@ -333,9 +338,20 @@ func (br *bridge) publish(n *notification) error {
|
||||||
authString = fmt.Sprintf(", headers.Authorization=Basic %s", auth)
|
authString = fmt.Sprintf(", headers.Authorization=Basic %s", auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Actions", fmt.Sprintf("http, Silence, %s, method=POST, body=%s%s", url, n.silenceBody, authString))
|
actions = append(actions, fmt.Sprintf("http, Silence, %s, method=POST, body=%s%s", url, n.silenceBody, authString))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if br.cfg.Ntfy.GeneratorURLLabel != "" && n.generatorURL != "" {
|
||||||
|
actions = append(actions, fmt.Sprintf("view, %s, %s", br.cfg.Ntfy.GeneratorURLLabel, n.generatorURL))
|
||||||
|
}
|
||||||
|
|
||||||
|
nActions := len(actions)
|
||||||
|
if nActions > 3 {
|
||||||
|
// TODO: Limit actions to three
|
||||||
|
br.logger.Warn(fmt.Sprintf("Publish: Too many actions (%d), ntfy only supports up to three.", nActions))
|
||||||
|
}
|
||||||
|
req.Header.Set("Actions", strings.Join(actions, ";"))
|
||||||
|
|
||||||
configFingerprint := br.cfg.Ntfy.CertFingerprint
|
configFingerprint := br.cfg.Ntfy.CertFingerprint
|
||||||
if configFingerprint != "" {
|
if configFingerprint != "" {
|
||||||
tlsCfg := &tls.Config{}
|
tlsCfg := &tls.Config{}
|
||||||
|
|
Loading…
Add table
Reference in a new issue