1
2
3
4
5
6
7
8
9
10
11
12
13
14 package cli
15
16 import (
17 "context"
18 "encoding/json"
19 "fmt"
20 "io"
21 "os"
22 "time"
23
24 "gopkg.in/alecthomas/kingpin.v2"
25
26 "github.com/prometheus/alertmanager/template"
27 )
28
29 var defaultData = template.Data{
30 Receiver: "receiver",
31 Status: "alertstatus",
32 Alerts: template.Alerts{
33 template.Alert{
34 Status: "alertstatus",
35 Labels: template.KV{
36 "label1": "value1",
37 "label2": "value2",
38 "instance": "foo.bar:1234",
39 "commonlabelkey1": "commonlabelvalue1",
40 "commonlabelkey2": "commonlabelvalue2",
41 },
42 Annotations: template.KV{
43 "annotation1": "value1",
44 "annotation2": "value2",
45 "commonannotationkey1": "commonannotationvalue1",
46 "commonannotationkey2": "commonannotationvalue2",
47 },
48 StartsAt: time.Now().Add(-5 * time.Minute),
49 EndsAt: time.Now(),
50 GeneratorURL: "https://generatorurl.com",
51 Fingerprint: "fingerprint1",
52 },
53 template.Alert{
54 Status: "alertstatus",
55 Labels: template.KV{
56 "foo": "bar",
57 "baz": "qux",
58 "commonlabelkey1": "commonlabelvalue1",
59 "commonlabelkey2": "commonlabelvalue2",
60 },
61 Annotations: template.KV{
62 "aaa": "bbb",
63 "ccc": "ddd",
64 "commonannotationkey1": "commonannotationvalue1",
65 "commonannotationkey2": "commonannotationvalue2",
66 },
67 StartsAt: time.Now().Add(-10 * time.Minute),
68 EndsAt: time.Now(),
69 GeneratorURL: "https://generatorurl.com",
70 Fingerprint: "fingerprint2",
71 },
72 },
73 GroupLabels: template.KV{
74 "grouplabelkey1": "grouplabelvalue1",
75 "grouplabelkey2": "grouplabelvalue2",
76 },
77 CommonLabels: template.KV{
78 "commonlabelkey1": "commonlabelvalue1",
79 "commonlabelkey2": "commonlabelvalue2",
80 },
81 CommonAnnotations: template.KV{
82 "commonannotationkey1": "commonannotationvalue1",
83 "commonannotationkey2": "commonannotationvalue2",
84 },
85 ExternalURL: "https://example.com",
86 }
87
88 type templateRenderCmd struct {
89 templateFilesGlobs []string
90 templateType string
91 templateText string
92 templateData *os.File
93 }
94
95 func configureTemplateRenderCmd(cc *kingpin.CmdClause) {
96 var (
97 c = &templateRenderCmd{}
98 renderCmd = cc.Command("render", "Render a given definition in a template file to standard output.")
99 )
100
101 renderCmd.Flag("template.glob", "Glob of paths that will be expanded and used for rendering.").Required().StringsVar(&c.templateFilesGlobs)
102 renderCmd.Flag("template.text", "The template that will be rendered.").Required().StringVar(&c.templateText)
103 renderCmd.Flag("template.type", "The type of the template. Can be either text (default) or html.").EnumVar(&c.templateType, "html", "text")
104 renderCmd.Flag("template.data", "Full path to a file which contains the data of the alert(-s) with which the --template.text will be rendered. Must be in JSON. File must be formatted according to the following layout: https://pkg.go.dev/github.com/prometheus/alertmanager/template#Data. If none has been specified then a predefined, simple alert will be used for rendering.").FileVar(&c.templateData)
105
106 renderCmd.Action(execWithTimeout(c.render))
107 }
108
109 func (c *templateRenderCmd) render(ctx context.Context, _ *kingpin.ParseContext) error {
110 tmpl, err := template.FromGlobs(c.templateFilesGlobs...)
111 if err != nil {
112 return err
113 }
114
115 f := tmpl.ExecuteTextString
116 if c.templateType == "html" {
117 f = tmpl.ExecuteHTMLString
118 }
119
120 var data template.Data
121 if c.templateData == nil {
122 data = defaultData
123 } else {
124 content, err := io.ReadAll(c.templateData)
125 if err != nil {
126 return err
127 }
128 if err := json.Unmarshal(content, &data); err != nil {
129 return err
130 }
131 }
132
133 rendered, err := f(c.templateText, data)
134 if err != nil {
135 return err
136 }
137
138 fmt.Print(rendered)
139 return nil
140 }
141
View as plain text