Add icon support

Implements: https://todo.xenrox.net/~xenrox/ntfy-alertmanager/12
This commit is contained in:
Thorben Günther 2023-02-20 13:08:59 +01:00
parent 1daa751cb2
commit f1dfde6891
No known key found for this signature in database
GPG key ID: 415CD778D8C5AFED
4 changed files with 44 additions and 5 deletions

View file

@ -16,10 +16,11 @@ You can specify the configuration file location with the `--config` flag. By def
the configuration file will be read from `/etc/ntfy-alertmanager/config`. The format the configuration file will be read from `/etc/ntfy-alertmanager/config`. The format
of this file is [scfg]. of this file is [scfg].
ntfy-alertmanager has support for setting ntfy [priority] and [tags]. Define a ntfy-alertmanager has support for setting ntfy [priority], [tags], [icon] and [action buttons]
decreasing order of labels in the config file and map those labels to tags or priority. (which can be used to create an Alertmanager silence).
Define a decreasing order of labels in the config file and map those labels to tags, priority or an icon.
- For priority the first found value will be chosen. - For priority and icon the first found value will be chosen. An icon for "resolved" alerts will take precedence.
- Tags are added together. - Tags are added together.
Example: Example:
@ -45,6 +46,7 @@ labels {
severity "critical" { severity "critical" {
priority 5 priority 5
tags "rotating_light" tags "rotating_light"
icon "https://foo.com/critical.png"
} }
severity "info" { severity "info" {
@ -56,9 +58,10 @@ labels {
} }
} }
# Set tags for resolved alerts # Settings for resolved alerts
resolved { resolved {
tags "resolved,partying_face" tags "resolved,partying_face"
icon "https://foo.com/resolved.png"
} }
ntfy { ntfy {
@ -118,6 +121,8 @@ Report bugs on the [issue tracker].
[scfg]: https://git.sr.ht/~emersion/scfg [scfg]: https://git.sr.ht/~emersion/scfg
[priority]: https://ntfy.sh/docs/publish/#message-priority [priority]: https://ntfy.sh/docs/publish/#message-priority
[tags]: https://ntfy.sh/docs/publish/#tags-emojis [tags]: https://ntfy.sh/docs/publish/#tags-emojis
[icon]: https://docs.ntfy.sh/publish/#icons
[action buttons]: https://docs.ntfy.sh/publish/#action-buttons
[issue tracker]: https://todo.xenrox.net/~xenrox/ntfy-alertmanager [issue tracker]: https://todo.xenrox.net/~xenrox/ntfy-alertmanager
[docker image]: https://hub.docker.com/r/xenrox/ntfy-alertmanager [docker image]: https://hub.docker.com/r/xenrox/ntfy-alertmanager
[docker-compose file]: https://git.xenrox.net/~xenrox/ntfy-alertmanager/tree/master/item/docker/docker-compose.yml [docker-compose file]: https://git.xenrox.net/~xenrox/ntfy-alertmanager/tree/master/item/docker/docker-compose.yml

View file

@ -43,6 +43,7 @@ type labels struct {
type labelConfig struct { type labelConfig struct {
Priority string Priority string
Tags []string Tags []string
Icon string
} }
type cacheConfig struct { type cacheConfig struct {
@ -59,6 +60,7 @@ type alertmanagerConfig struct {
type resolvedConfig struct { type resolvedConfig struct {
Tags []string Tags []string
Icon string
} }
func readConfig(path string) (*config, error) { func readConfig(path string) (*config, error) {
@ -169,6 +171,13 @@ func readConfig(path string) (*config, error) {
labelConfig.Tags = strings.Split(tags, ",") labelConfig.Tags = strings.Split(tags, ",")
} }
d = labelDir.Children.Get("icon")
if d != nil {
if err := d.ParseParams(&labelConfig.Icon); err != nil {
return nil, err
}
}
labels[fmt.Sprintf("%s:%s", labelName, name)] = *labelConfig labels[fmt.Sprintf("%s:%s", labelName, name)] = *labelConfig
} }
} }
@ -288,6 +297,13 @@ func readConfig(path string) (*config, error) {
config.resolved.Tags = strings.Split(tags, ",") config.resolved.Tags = strings.Split(tags, ",")
} }
d = resolvedDir.Children.Get("icon")
if d != nil {
if err := d.ParseParams(&config.resolved.Icon); err != nil {
return nil, err
}
}
} }
return config, nil return config, nil

View file

@ -30,6 +30,7 @@ labels {
severity "critical" { severity "critical" {
priority 5 priority 5
tags "rotating_light" tags "rotating_light"
icon "https://foo.com/critical.png"
} }
severity "info" { severity "info" {
@ -43,6 +44,7 @@ labels {
resolved { resolved {
tags "resolved,partying_face" tags "resolved,partying_face"
icon "https://foo.com/resolved.png"
} }
ntfy { ntfy {
@ -85,7 +87,7 @@ cache {
ntfy: ntfyConfig{Topic: "https://ntfy.sh/alertmanager-alerts", User: "user", Password: "pass"}, ntfy: ntfyConfig{Topic: "https://ntfy.sh/alertmanager-alerts", User: "user", Password: "pass"},
labels: labels{Order: []string{"severity", "instance"}, labels: labels{Order: []string{"severity", "instance"},
Label: map[string]labelConfig{ Label: map[string]labelConfig{
"severity:critical": {Priority: "5", Tags: []string{"rotating_light"}}, "severity:critical": {Priority: "5", Tags: []string{"rotating_light"}, Icon: "https://foo.com/critical.png"},
"severity:info": {Priority: "1"}, "severity:info": {Priority: "1"},
"instance:example.com": {Tags: []string{"computer", "example"}}, "instance:example.com": {Tags: []string{"computer", "example"}},
}, },
@ -99,6 +101,7 @@ cache {
}, },
resolved: resolvedConfig{ resolved: resolvedConfig{
Tags: []string{"resolved", "partying_face"}, Tags: []string{"resolved", "partying_face"},
Icon: "https://foo.com/resolved.png",
}, },
} }

15
main.go
View file

@ -49,6 +49,7 @@ type notification struct {
body string body string
priority string priority string
tags string tags string
icon string
silenceBody string silenceBody string
fingerprint fingerprint fingerprint fingerprint
status string status string
@ -90,6 +91,7 @@ func (rcv *receiver) singleAlertNotifications(p *payload) []*notification {
var tags []string var tags []string
if alert.Status == "resolved" { if alert.Status == "resolved" {
tags = append(tags, rcv.cfg.resolved.Tags...) tags = append(tags, rcv.cfg.resolved.Tags...)
n.icon = rcv.cfg.resolved.Icon
} }
for _, labelName := range rcv.cfg.labels.Order { for _, labelName := range rcv.cfg.labels.Order {
@ -107,6 +109,10 @@ func (rcv *receiver) singleAlertNotifications(p *payload) []*notification {
n.priority = labelConfig.Priority n.priority = labelConfig.Priority
} }
if n.icon == "" {
n.icon = labelConfig.Icon
}
for _, val := range labelConfig.Tags { for _, val := range labelConfig.Tags {
if !sliceContains(tags, val) { if !sliceContains(tags, val) {
tags = append(tags, val) tags = append(tags, val)
@ -181,6 +187,7 @@ func (rcv *receiver) multiAlertNotification(p *payload) *notification {
var tags []string var tags []string
if p.Status == "resolved" { if p.Status == "resolved" {
tags = append(tags, rcv.cfg.resolved.Tags...) tags = append(tags, rcv.cfg.resolved.Tags...)
n.icon = rcv.cfg.resolved.Icon
} }
for _, labelName := range rcv.cfg.labels.Order { for _, labelName := range rcv.cfg.labels.Order {
@ -198,6 +205,10 @@ func (rcv *receiver) multiAlertNotification(p *payload) *notification {
priority = labelConfig.Priority priority = labelConfig.Priority
} }
if n.icon == "" {
n.icon = labelConfig.Icon
}
for _, val := range labelConfig.Tags { for _, val := range labelConfig.Tags {
if !sliceContains(tags, val) { if !sliceContains(tags, val) {
tags = append(tags, val) tags = append(tags, val)
@ -245,6 +256,10 @@ func (rcv *receiver) publish(n *notification) error {
req.Header.Set("X-Priority", n.priority) req.Header.Set("X-Priority", n.priority)
} }
if n.icon != "" {
req.Header.Set("X-Icon", n.icon)
}
if n.tags != "" { if n.tags != "" {
req.Header.Set("X-Tags", n.tags) req.Header.Set("X-Tags", n.tags)
} }