Skip to content

Commit bacaeb2

Browse files
committed
feat(template): add toJson function
This change introduces a new template function called `toJson` which can convert internal Alertmanager data structures into their JSON representation. This is useful in notify integrations where JSON objects can be passed to external services. Signed-off-by: Siavash Safi <[email protected]>
1 parent e542c68 commit bacaeb2

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

template/template.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package template
1515

1616
import (
1717
"bytes"
18+
"encoding/json"
1819
tmplhtml "html/template"
1920
"io"
2021
"net/url"
@@ -213,6 +214,13 @@ var DefaultFuncs = FuncMap{
213214
},
214215
"since": time.Since,
215216
"humanizeDuration": commonTemplates.HumanizeDuration,
217+
"toJson": func(v any) (string, error) {
218+
bytes, err := json.Marshal(v)
219+
if err != nil {
220+
return "", err
221+
}
222+
return string(bytes), nil
223+
},
216224
}
217225

218226
// Pair is a key/value string pair.

template/template_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,65 @@ func TestTemplateExpansion(t *testing.T) {
401401
},
402402
exp: "[key2 key4]",
403403
},
404+
{
405+
title: "Template using toJson with string",
406+
in: `{{ "test" | toJson }}`,
407+
exp: `"test"`,
408+
},
409+
{
410+
title: "Template using toJson with number",
411+
in: `{{ 42 | toJson }}`,
412+
exp: `42`,
413+
},
414+
{
415+
title: "Template using toJson with boolean",
416+
in: `{{ true | toJson }}`,
417+
exp: `true`,
418+
},
419+
{
420+
title: "Template using toJson with map",
421+
in: `{{ . | toJson }}`,
422+
data: map[string]any{"key": "value", "number": 123},
423+
exp: `{"key":"value","number":123}`,
424+
},
425+
{
426+
title: "Template using toJson with slice",
427+
in: `{{ . | toJson }}`,
428+
data: []string{"a", "b", "c"},
429+
exp: `["a","b","c"]`,
430+
},
431+
{
432+
title: "Template using toJson with KV",
433+
in: `{{ .CommonLabels | toJson }}`,
434+
data: Data{
435+
CommonLabels: KV{"severity": "critical", "job": "foo"},
436+
},
437+
exp: `{"job":"foo","severity":"critical"}`,
438+
},
439+
{
440+
title: "Template using toJson with Alerts",
441+
in: `{{ .Alerts | toJson }}`,
442+
data: Data{
443+
Alerts: Alerts{
444+
{
445+
Status: "firing",
446+
Labels: KV{"alertname": "test"},
447+
},
448+
},
449+
},
450+
exp: `[{"status":"firing","labels":{"alertname":"test"},"annotations":null,"startsAt":"0001-01-01T00:00:00Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"","fingerprint":""}]`,
451+
},
452+
{
453+
title: "Template using toJson with Alerts.Firing()",
454+
in: `{{ .Alerts.Firing | toJson }}`,
455+
data: Data{
456+
Alerts: Alerts{
457+
{Status: "firing"},
458+
{Status: "resolved"},
459+
},
460+
},
461+
exp: `[{"status":"firing","labels":null,"annotations":null,"startsAt":"0001-01-01T00:00:00Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"","fingerprint":""}]`,
462+
},
404463
} {
405464
t.Run(tc.title, func(t *testing.T) {
406465
f := tmpl.ExecuteTextString
@@ -575,6 +634,25 @@ func TestTemplateFuncs(t *testing.T) {
575634
in: "{{ . | since | humanizeDuration }}",
576635
data: time.Now().Add(-1 * time.Hour),
577636
exp: "1h 0m 0s",
637+
}, {
638+
title: "Template using toJson with string",
639+
in: `{{ "hello" | toJson }}`,
640+
exp: `"hello"`,
641+
}, {
642+
title: "Template using toJson with map",
643+
in: `{{ . | toJson }}`,
644+
data: map[string]string{"key": "value"},
645+
exp: `{"key":"value"}`,
646+
}, {
647+
title: "Template using toJson with Alerts.Firing()",
648+
in: `{{ .Alerts.Firing | toJson }}`,
649+
data: Data{
650+
Alerts: Alerts{
651+
{Status: "firing", Labels: KV{"alertname": "test"}},
652+
{Status: "resolved"},
653+
},
654+
},
655+
exp: `[{"status":"firing","labels":{"alertname":"test"},"annotations":null,"startsAt":"0001-01-01T00:00:00Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"","fingerprint":""}]`,
578656
}} {
579657
t.Run(tc.title, func(t *testing.T) {
580658
wg := sync.WaitGroup{}

0 commit comments

Comments
 (0)