-
Notifications
You must be signed in to change notification settings - Fork 569
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new command on mimirtool used to render template
- Loading branch information
Showing
14 changed files
with
373 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
package commands | ||
|
||
import ( | ||
"github.com/alecthomas/kingpin/v2" | ||
) | ||
|
||
type TemplateCommand struct{} | ||
|
||
func (cmd *TemplateCommand) Register(app *kingpin.Application, envVars EnvVarNames) { | ||
templateCmd := app.Command("template", "Render template files.") | ||
trCmd := &TemplateRenderCmd{} | ||
renderCmd := templateCmd.Command("render", "Render a given definition in a template file to standard output.").Action(trCmd.render) | ||
renderCmd.Flag("template.glob", "Glob of paths that will be expanded and used for rendering.").Required().StringsVar(&trCmd.templateFilesGlobs) | ||
renderCmd.Flag("template.text", "The template that will be rendered.").Required().StringVar(&trCmd.templateText) | ||
renderCmd.Flag("template.type", "The type of the template. Can be either text (default) or html.").EnumVar(&trCmd.templateType, "html", "text") | ||
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(&trCmd.templateData) | ||
renderCmd.Flag("id", "Basic auth username to use when contacting Prometheus or Grafana Mimir, also set as tenant ID; alternatively, set "+envVars.TenantID+"."). | ||
Envar(envVars.TenantID). | ||
Default(""). | ||
StringVar(&trCmd.tenantID) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
package commands | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"os" | ||
"time" | ||
|
||
"github.com/alecthomas/kingpin/v2" | ||
"github.com/prometheus/alertmanager/template" | ||
|
||
MimirAlertManager "github.com/grafana/mimir/pkg/alertmanager" | ||
) | ||
|
||
var defaultData = template.Data{ | ||
Receiver: "receiver", | ||
Status: "alertstatus", | ||
Alerts: template.Alerts{ | ||
template.Alert{ | ||
Status: "alertstatus", | ||
Labels: template.KV{ | ||
"label1": "value1", | ||
"label2": "value2", | ||
"instance": "foo.bar:1234", | ||
"commonlabelkey1": "commonlabelvalue1", | ||
"commonlabelkey2": "commonlabelvalue2", | ||
}, | ||
Annotations: template.KV{ | ||
"annotation1": "value1", | ||
"annotation2": "value2", | ||
"commonannotationkey1": "commonannotationvalue1", | ||
"commonannotationkey2": "commonannotationvalue2", | ||
}, | ||
StartsAt: time.Now().Add(-5 * time.Minute), | ||
EndsAt: time.Now(), | ||
GeneratorURL: "https://generatorurl.com", | ||
Fingerprint: "fingerprint1", | ||
}, | ||
template.Alert{ | ||
Status: "alertstatus", | ||
Labels: template.KV{ | ||
"foo": "bar", | ||
"baz": "qux", | ||
"commonlabelkey1": "commonlabelvalue1", | ||
"commonlabelkey2": "commonlabelvalue2", | ||
}, | ||
Annotations: template.KV{ | ||
"aaa": "bbb", | ||
"ccc": "ddd", | ||
"commonannotationkey1": "commonannotationvalue1", | ||
"commonannotationkey2": "commonannotationvalue2", | ||
}, | ||
StartsAt: time.Now().Add(-10 * time.Minute), | ||
EndsAt: time.Now(), | ||
GeneratorURL: "https://generatorurl.com", | ||
Fingerprint: "fingerprint2", | ||
}, | ||
}, | ||
GroupLabels: template.KV{ | ||
"grouplabelkey1": "grouplabelvalue1", | ||
"grouplabelkey2": "grouplabelvalue2", | ||
}, | ||
CommonLabels: template.KV{ | ||
"alertname": "AlertNameExample", | ||
"customer": "testing_purpose", | ||
"environment": "lab", | ||
"commonlabelkey1": "commonlabelvalue1", | ||
"commonlabelkey2": "commonlabelvalue2", | ||
}, | ||
CommonAnnotations: template.KV{ | ||
"commonannotationkey1": "commonannotationvalue1", | ||
"commonannotationkey2": "commonannotationvalue2", | ||
}, | ||
ExternalURL: "https://example.com", | ||
} | ||
|
||
// TemplateRenderCmd Render a given definition in a template file to standard output | ||
type TemplateRenderCmd struct { | ||
templateFilesGlobs []string | ||
templateType string | ||
templateText string | ||
templateData *os.File | ||
tenantID string // Needed in the function WithCustomFunctions | ||
} | ||
|
||
func (cmd *TemplateRenderCmd) render(_ *kingpin.ParseContext) error { | ||
rendered, err := TemplateRender(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Print(rendered) | ||
return nil | ||
} | ||
|
||
func TemplateRender(cmd *TemplateRenderCmd) (string, error) { | ||
tmpl, err := template.FromGlobs(cmd.templateFilesGlobs, MimirAlertManager.WithCustomFunctions(cmd.tenantID)) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
f := tmpl.ExecuteTextString | ||
if cmd.templateType == "html" { | ||
f = tmpl.ExecuteHTMLString | ||
} | ||
|
||
var data template.Data | ||
if cmd.templateData == nil { | ||
data = defaultData | ||
} else { | ||
content, err := io.ReadAll(cmd.templateData) | ||
if err != nil { | ||
return "", err | ||
} | ||
if err := json.Unmarshal(content, &data); err != nil { | ||
return "", err | ||
} | ||
} | ||
|
||
rendered, err := f(cmd.templateText, data) | ||
if err != nil { | ||
return "", err | ||
} | ||
return rendered, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
package commands | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// Based on https://github.com/grafana/mimir/blob/main/pkg/alertmanager/alertmanager_template_test.go | ||
func TestTemplateRender(t *testing.T) { | ||
type tc struct { | ||
name string | ||
templateOptions TemplateRenderCmd | ||
result string | ||
expectError bool | ||
} | ||
jsonFilesStr := []string{"testdata/template/alert_data1.json", "testdata/template/alert_data1.json", "testdata/template/alert_data2.json"} | ||
jsonFiles := make([]*os.File, len(jsonFilesStr)) | ||
|
||
for index, jsonFile := range jsonFilesStr { | ||
file, err := os.OpenFile(jsonFile, os.O_RDONLY, 0) | ||
assert.NoError(t, err, "Json template data doesn't exist") | ||
jsonFiles[index] = file | ||
|
||
} | ||
cases := []tc{ | ||
{ | ||
name: "testing basic message template", | ||
templateOptions: TemplateRenderCmd{ | ||
templateFilesGlobs: []string{"testdata/template/alertmanager_template1.tmpl"}, | ||
templateType: "text", | ||
templateText: `{{ template "my_message" . }}`, | ||
templateData: jsonFiles[0], | ||
tenantID: "", | ||
}, | ||
result: `[AlertNameExample | testing_purpose | lab]`, | ||
}, | ||
{ | ||
name: "testing basic description template", | ||
templateOptions: TemplateRenderCmd{ | ||
templateFilesGlobs: []string{"testdata/template/alertmanager_template1.tmpl"}, | ||
templateType: "text", | ||
templateText: `{{ template "my_description" . }}`, | ||
templateData: jsonFiles[1], | ||
tenantID: "", | ||
}, | ||
result: ` | ||
Alertname: AlertNameExample | ||
Severity: warning | ||
Details: | ||
• Customer: testing_purpose | ||
• Environment: lab | ||
• Description: blablablabla | ||
`, | ||
}, | ||
{ | ||
name: "testing custom description template", // Using Specific Mimir Template function | ||
templateOptions: TemplateRenderCmd{ | ||
templateFilesGlobs: []string{"testdata/template/alertmanager_template2.tmpl"}, | ||
templateType: "text", | ||
templateText: `{{ template "my_description" . }}`, | ||
templateData: jsonFiles[2], | ||
tenantID: "", | ||
}, | ||
result: ` | ||
Alertname: AlertNameExample2 | ||
Severity: warning | ||
Details: | ||
• Customer: testing_purpose | ||
• Environment: lab | ||
• Description: blablablabla | ||
<a href="https://foo.bar/explore?left=%7B%22range%22%3A%7B%22from%22%3A%22now-12h%22%2C%22to%22%3A%22now%22%7D%2C%22queries%22%3A%5B%7B%22datasource%22%3A%7B%22type%22%3A%22prometheus%22%2C%22uid%22%3A%22xyz%22%7D%2C%22expr%22%3A%22up%22%2C%22instant%22%3Afalse%2C%22range%22%3Atrue%2C%22refId%22%3A%22A%22%7D%5D%7D">Grafana Explorer URL</a> | ||
`, | ||
}, | ||
} | ||
|
||
for _, c := range cases { | ||
c := c | ||
t.Run(c.name, func(t *testing.T) { | ||
renderedTemplate, err := TemplateRender(&c.templateOptions) | ||
if c.expectError { | ||
assert.Error(t, err) | ||
return | ||
} | ||
assert.NoError(t, err) | ||
assert.Equal(t, c.result, renderedTemplate) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"receiver": "receiver", | ||
"status": "alertstatus", | ||
"alerts": [ | ||
{ | ||
"status": "alertstatus", | ||
"labels": { | ||
"customer": "testing_purpose", | ||
"environment": "lab", | ||
"severity": "warning", | ||
"alertname": "AlertNameExample" | ||
}, | ||
"annotations": { | ||
"description": "blablablabla" | ||
}, | ||
"startsAt": "2024-02-07T09:00:51.0982886+01:00", | ||
"endsAt": "2024-02-07T09:10:51.0982886+01:00", | ||
"generatorURL": "https://generatorurl.com/graph?g0.expr=up", | ||
"fingerprint": "fingerprint2" | ||
} | ||
], | ||
"groupLabels": { | ||
"grouplabelkey1": "grouplabelvalue1", | ||
"grouplabelkey2": "grouplabelvalue2" | ||
}, | ||
"commonLabels": { | ||
"alertname": "AlertNameExample", | ||
"customer": "testing_purpose", | ||
"environment": "lab" | ||
}, | ||
"commonAnnotations": { | ||
"commonannotationkey1": "commonannotationvalue1", | ||
"commonannotationkey2": "commonannotationvalue2" | ||
}, | ||
"externalURL": "https://example.com" | ||
} |
Oops, something went wrong.