~xenrox/ntfy-alertmanager

f1dfde68916a4223f10f8486f49e96bb194d7737 — Thorben Günther 1 year, 2 months ago 1daa751
Add icon support

Implements: https://todo.xenrox.net/~xenrox/ntfy-alertmanager/12
4 files changed, 44 insertions(+), 5 deletions(-)

M README.md
M config.go
M config_test.go
M main.go
M README.md => README.md +9 -4
@@ 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
of this file is [scfg].

ntfy-alertmanager has support for setting ntfy [priority] and [tags]. Define a
decreasing order of labels in the config file and map those labels to tags or priority.
ntfy-alertmanager has support for setting ntfy [priority], [tags], [icon] and [action buttons]
(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.

Example:


@@ 45,6 46,7 @@ labels {
    severity "critical" {
        priority 5
        tags "rotating_light"
        icon "https://foo.com/critical.png"
    }

    severity "info" {


@@ 56,9 58,10 @@ labels {
    }
}

# Set tags for resolved alerts
# Settings for resolved alerts
resolved {
    tags "resolved,partying_face"
    icon "https://foo.com/resolved.png"
}

ntfy {


@@ 118,6 121,8 @@ Report bugs on the [issue tracker].
[scfg]: https://git.sr.ht/~emersion/scfg
[priority]: https://ntfy.sh/docs/publish/#message-priority
[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
[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

M config.go => config.go +16 -0
@@ 43,6 43,7 @@ type labels struct {
type labelConfig struct {
	Priority string
	Tags     []string
	Icon     string
}

type cacheConfig struct {


@@ 59,6 60,7 @@ type alertmanagerConfig struct {

type resolvedConfig struct {
	Tags []string
	Icon string
}

func readConfig(path string) (*config, error) {


@@ 169,6 171,13 @@ func readConfig(path string) (*config, error) {
					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
			}
		}


@@ 288,6 297,13 @@ func readConfig(path string) (*config, error) {

			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

M config_test.go => config_test.go +4 -1
@@ 30,6 30,7 @@ labels {
    severity "critical" {
        priority 5
        tags "rotating_light"
        icon "https://foo.com/critical.png"
    }

    severity "info" {


@@ 43,6 44,7 @@ labels {

resolved {
    tags "resolved,partying_face"
    icon "https://foo.com/resolved.png"
}

ntfy {


@@ 85,7 87,7 @@ cache {
		ntfy:        ntfyConfig{Topic: "https://ntfy.sh/alertmanager-alerts", User: "user", Password: "pass"},
		labels: labels{Order: []string{"severity", "instance"},
			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"},
				"instance:example.com": {Tags: []string{"computer", "example"}},
			},


@@ 99,6 101,7 @@ cache {
		},
		resolved: resolvedConfig{
			Tags: []string{"resolved", "partying_face"},
			Icon: "https://foo.com/resolved.png",
		},
	}


M main.go => main.go +15 -0
@@ 49,6 49,7 @@ type notification struct {
	body        string
	priority    string
	tags        string
	icon        string
	silenceBody string
	fingerprint fingerprint
	status      string


@@ 90,6 91,7 @@ func (rcv *receiver) singleAlertNotifications(p *payload) []*notification {
		var tags []string
		if alert.Status == "resolved" {
			tags = append(tags, rcv.cfg.resolved.Tags...)
			n.icon = rcv.cfg.resolved.Icon
		}

		for _, labelName := range rcv.cfg.labels.Order {


@@ 107,6 109,10 @@ func (rcv *receiver) singleAlertNotifications(p *payload) []*notification {
				n.priority = labelConfig.Priority
			}

			if n.icon == "" {
				n.icon = labelConfig.Icon
			}

			for _, val := range labelConfig.Tags {
				if !sliceContains(tags, val) {
					tags = append(tags, val)


@@ 181,6 187,7 @@ func (rcv *receiver) multiAlertNotification(p *payload) *notification {
	var tags []string
	if p.Status == "resolved" {
		tags = append(tags, rcv.cfg.resolved.Tags...)
		n.icon = rcv.cfg.resolved.Icon
	}

	for _, labelName := range rcv.cfg.labels.Order {


@@ 198,6 205,10 @@ func (rcv *receiver) multiAlertNotification(p *payload) *notification {
			priority = labelConfig.Priority
		}

		if n.icon == "" {
			n.icon = labelConfig.Icon
		}

		for _, val := range labelConfig.Tags {
			if !sliceContains(tags, val) {
				tags = append(tags, val)


@@ 245,6 256,10 @@ func (rcv *receiver) publish(n *notification) error {
		req.Header.Set("X-Priority", n.priority)
	}

	if n.icon != "" {
		req.Header.Set("X-Icon", n.icon)
	}

	if n.tags != "" {
		req.Header.Set("X-Tags", n.tags)
	}