Alertmanager: Slack incorrect URL encoding, using " instead of %22

Created on 16 Oct 2019  Â·  5Comments  Â·  Source: prometheus/alertmanager

Alertmanager version 0.18.0
I've tested this on multiple machines, using different browsers.

I'm not sure whether this is an issue in Slack or Alertmanager, but here we go.

Description
I've created a "template to build silence URLs", for the silence button in Slack, see config below.

The silence button is properly shown and is created in Slack.

Issue
The URL redirects me to:
https://alertmanager.example.com/#/silences/new?filter=%7Bbutton_label%3D"

The page opens, but with no silencer arguments filled in, making the silencer button broken.

The issue here is that ""e;" is used for httpd encoding. This is incorrect, it should be %22 to parse quotes.

When I click on the silence button with 'open in new tab', the correct page shows, because then it directs me to: https://alertmanager.example.com/#/silences/new?filter=%7Bbutton_label%3D%22

Can someone fix this in Alertmanager or anywhere appropriate?

The alertmanager config

    # This builds the silence URL.  We exclude the alertname in the range
    # to avoid the issue of having trailing comma separator (%2C) at the end
    # of the generated URL
    {{ define "__alert_silence_link" -}}
      {{ template ".ExternalURL" }}/#/silences/new?filter=%7B
      {{- range .SortedPairs -}}
        {{- if not (eq .Name "alertname") -}}
          {{- .Name }}%3D"{{- reReplaceAll " +" "%20" .Value -}}"%2C%20
        {{- end -}}
      {{- end -}}
      alertname%3D"{{ reReplaceAll " +" "%20" .alertname }}"%7D
    {{- end }}

    {{ define "__subject" }}{{ .Alerts.Firing | len }}{{ if .CommonLabels.severity }} {{ .CommonLabels.severity }}{{ end }}{{ if gt (.Alerts.Firing | len) 1 }} alerts{{ else }} alert{{ end }}{{ end }}
    {{ define "__description" }}{{ if .Annotations.description }}*Description:* {{ .Annotations.description }}{{ else }}{{ end }}{{ end }}

    {{ define "__text_alert_list" }}{{ range . }}Labels:
    {{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
    {{ end }}Annotations:
    {{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }}
    {{ end }}Source: {{ .GeneratorURL }}
    {{ end }}{{ end }}

    {{ define "slack.default.title" }}{{ template "__subject" . }}{{ end }}
    {{ define ".ExternalURL" }}https://alertmanager.example.com{{ end }}

Most helpful comment

Not sure if Slack has fixed the issue, but after some tuning and basically replacing some double quotes with %22 I got it to work.

{{ define "__alert_silence_link" -}}
    {{ .ExternalURL }}/#/silences/new?filter=%7B
    {{- range .CommonLabels.SortedPairs -}}
        {{- if ne .Name "alertname" -}}
            {{- .Name }}%3D%22{{- reReplaceAll " +" "%20" .Value -}}%22%2C%20
        {{- end -}}
    {{- end -}}
    alertname%3D%22{{ reReplaceAll " +" "%20" .CommonLabels.alertname }}%22%7D
{{- end }}

All 5 comments

Can you share the receiver configuration? It matters whether it is a HTML
or string template as to whether the issue may be on our end.

On Wed 16 Oct 2019, 10:39 username1222, notifications@github.com wrote:

Alertmanager version 0.18.0
I've tested this on multiple machines, using different browsers.

I'm not sure whether this is an issue in Slack or Alertmanager, but here
we go.

Description
I've created a "template to build silence URLs", for the silence button in
Slack, see config below.

The silence button is properly shown and is created in Slack.

Issue
The URL redirects me to:
https://alertmanager.example.com/#/silences/new?filter=%7Bbutton_label%3D
".......

The page opens, but with no silencer arguments filled in, making the
silencer button broken.

The issue here is that ""e;" is used for httpd encoding. This is
incorrect, it should be %22 to parse quotes.

When I click on the silence button with 'open in new tab', the correct
page shows, because then it directs me to:
https://alertmanager.example.com/#/silences/new?filter=%7Bbutton_label%3D%22

Can someone fix this in the Slack API or anywhere?

The alertmanager config

# This builds the silence URL.  We exclude the alertname in the range
# to avoid the issue of having trailing comma separator (%2C) at the end
# of the generated URL
{{ define "__alert_silence_link" -}}
  {{ template ".ExternalURL" }}/#/silences/new?filter=%7B
  {{- range .SortedPairs -}}
    {{- if not (eq .Name "alertname") -}}
      {{- .Name }}%3D"{{- reReplaceAll " +" "%20" .Value -}}"%2C%20
    {{- end -}}
  {{- end -}}
  alertname%3D"{{ reReplaceAll " +" "%20" .alertname }}"%7D
{{- end }}

{{ define "__subject" }}{{ .Alerts.Firing | len }}{{ if .CommonLabels.severity }} {{ .CommonLabels.severity }}{{ end }}{{ if gt (.Alerts.Firing | len) 1 }} alerts{{ else }} alert{{ end }}{{ end }}
{{ define "__description" }}{{ if .Annotations.description }}*Description:* {{ .Annotations.description }}{{ else }}{{ end }}{{ end }}

{{ define "__text_alert_list" }}{{ range . }}Labels:
{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
{{ end }}Annotations:
{{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }}
{{ end }}Source: {{ .GeneratorURL }}
{{ end }}{{ end }}

{{ define "slack.default.title" }}{{ template "__subject" . }}{{ end }}
{{ define ".ExternalURL" }}https://alertmanager.example.com{{ end }}

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/prometheus/alertmanager/issues/2070?email_source=notifications&email_token=ABWJG5RJ6KULBRL6QROUUWDQO4RQRA5CNFSM4JBMQKXKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HSF4BYA,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABWJG5UBO3V3BBNB7TNVJR3QO4RQRANCNFSM4JBMQKXA
.

I've found this in the alertmanager.yml file;

      - match_re:
          receiver: ^(alerts-developers)$
        receiver:       alerts-developers
        group_interval: 30m
        repeat_interval: 30m

then

    - name: alerts-developers
      slack_configs:
      - channel:  '#alerts-developers'
        send_resolved: false
        link_names: true
        color: '{{ if eq .Status "firing" }}{{- if eq .CommonLabels.severity "critical" -}}danger{{ else }}#ffa500{{ end }}{{ else }}good{{ end }}'
        username: "{{ .CommonLabels.alertname }}"
        title: '{{ template "slack.default.title" . }} {{ if .CommonLabels.responsible }}<@{{ .CommonLabels.responsible }}>{{ end }}{{ if .CommonLabels.responsible_team }} <!subteam^{{ .CommonLabels.responsible_team }}>{{ end }}'
        image_url: '{{(index .Alerts 0).Annotations.image }}'
        text: |-
          {{ range .Alerts }}{{ if not .Annotations.image}}{{ .Annotations.summary }}
          {{ else }}{{ template "__description" . }}{{ end }}{{ end }}
        api_url: https://hooks.slack.com/services/<token>
        icon_url: https://some_url.png
        actions:
        - text: 'Silence {{ index (index .Alerts 0).Labels (index .Alerts 0).Labels.button_label }} :no_bell:'
          type: button
          url: '{{ template "__alert_silence_link" (index .Alerts 0).Labels }}'
        - text: '{{ if gt (.Alerts | len) 1 }}Silence {{ index (index .Alerts 1).Labels (index .Alerts 1).Labels.button_label }} :no_bell:{{ end }}'
          type: button
          url: '{{ if gt (.Alerts | len) 1 }}{{ template "__alert_silence_link" (index .Alerts 1).Labels }}{{ end }}'
        - text: '{{ if gt (.Alerts | len) 2 }}Silence {{ index (index .Alerts 2).Labels (index .Alerts 0).Labels.button_label }} :no_bell:{{ end }}'
          type: button
          url: '{{ if gt (.Alerts | len) 2 }}{{ template "__alert_silence_link" (index .Alerts 2).Labels }}{{ end }}'
        - text: '{{ if gt (.Alerts | len) 3 }}Silence {{ index (index .Alerts 3).Labels (index .Alerts 0).Labels.button_label }} :no_bell:{{ end }}'
          type: button
          url: '{{ if gt (.Alerts | len) 3 }}{{ template "__alert_silence_link" (index .Alerts 3).Labels }}{{ end }}'
        - text: '{{ if gt (.Alerts | len) 4 }}Silence {{ index (index .Alerts 4).Labels (index .Alerts 0).Labels.button_label }} :no_bell:{{ end }}'
          type: button
          url: '{{ if gt (.Alerts | len) 4 }}{{ template "__alert_silence_link" (index .Alerts 4).Labels }}{{ end }}'
        - text: '{{ if gt (.Alerts | len) 5 }}Silence {{ index (index .Alerts 5).Labels (index .Alerts 0).Labels.button_label }} :no_bell:{{ end }}'
          type: button
          url: '{{ if gt (.Alerts | len) 5 }}{{ template "__alert_silence_link" (index .Alerts 5).Labels }}{{ end }}'
        - text: '{{ if gt (.Alerts | len) 6 }}Silence {{ index (index .Alerts 6).Labels (index .Alerts 0).Labels.button_label }} :no_bell:{{ end }}'
          type: button
          url: '{{ if gt (.Alerts | len) 6 }}{{ template "__alert_silence_link" (index .Alerts 6).Labels }}{{ end }}'
        - type: button
          text: 'Show :mag:'
          url: '{{ if not (match ".*prometheus.*" (index .Alerts 0).GeneratorURL) }}http://grafana.example.com{{ (index .Alerts 0).GeneratorURL }}{{ else }}{{ (index .Alerts 0).GeneratorURL }}{{ end }}'

The Slack message is send towards the Slack Webhook API: https://viriciti.slack.com/apps/A0F7XDUAZ-incoming-webhooks?next_id=0

I've also performed a grep in the project folder to search for either %22 and &quote; but no results.

That's a text template, so the issue is likely on Slack's end.

That's what I thought. I've contacted Slack Support. Hope they will fix it.

Thanks for taking your time!

Not sure if Slack has fixed the issue, but after some tuning and basically replacing some double quotes with %22 I got it to work.

{{ define "__alert_silence_link" -}}
    {{ .ExternalURL }}/#/silences/new?filter=%7B
    {{- range .CommonLabels.SortedPairs -}}
        {{- if ne .Name "alertname" -}}
            {{- .Name }}%3D%22{{- reReplaceAll " +" "%20" .Value -}}%22%2C%20
        {{- end -}}
    {{- end -}}
    alertname%3D%22{{ reReplaceAll " +" "%20" .CommonLabels.alertname }}%22%7D
{{- end }}
Was this page helpful?
0 / 5 - 0 ratings