diff --git a/pkg/rulefmt/rulefmt.go b/pkg/rulefmt/rulefmt.go index 920c7a203..b670032f0 100644 --- a/pkg/rulefmt/rulefmt.go +++ b/pkg/rulefmt/rulefmt.go @@ -239,6 +239,7 @@ func testTemplateParsing(rl *RuleNode) (errs []error) { model.Time(timestamp.FromTime(time.Now())), nil, nil, + nil, ) return tmpl.ParseTest() } diff --git a/rules/alerting.go b/rules/alerting.go index 15cd1cf60..d1fb1cc75 100644 --- a/rules/alerting.go +++ b/rules/alerting.go @@ -338,6 +338,7 @@ func (r *AlertingRule) Eval(ctx context.Context, ts time.Time, query QueryFunc, model.Time(timestamp.FromTime(ts)), template.QueryFunc(query), externalURL, + nil, ) result, err := tmpl.Expand() if err != nil { diff --git a/template/template.go b/template/template.go index b0d8f5cc0..dca5aa432 100644 --- a/template/template.go +++ b/template/template.go @@ -115,6 +115,7 @@ type Expander struct { name string data interface{} funcMap text_template.FuncMap + options []string } // NewTemplateExpander returns a template expander ready to use. @@ -126,7 +127,11 @@ func NewTemplateExpander( timestamp model.Time, queryFunc QueryFunc, externalURL *url.URL, + options []string, ) *Expander { + if options == nil { + options = []string{"missingkey=zero"} + } return &Expander{ text: text, name: name, @@ -291,6 +296,7 @@ func NewTemplateExpander( return externalURL.String() }, }, + options: options, } } @@ -336,7 +342,9 @@ func (te Expander) Expand() (result string, resultErr error) { templateTextExpansionTotal.Inc() - tmpl, err := text_template.New(te.name).Funcs(te.funcMap).Option("missingkey=zero").Parse(te.text) + tmpl := text_template.New(te.name).Funcs(te.funcMap) + tmpl.Option(te.options...) + tmpl, err := tmpl.Parse(te.text) if err != nil { return "", errors.Wrapf(err, "error parsing template %v", te.name) } @@ -361,7 +369,7 @@ func (te Expander) ExpandHTML(templateFiles []string) (result string, resultErr }() tmpl := html_template.New(te.name).Funcs(html_template.FuncMap(te.funcMap)) - tmpl.Option("missingkey=zero") + tmpl.Option(te.options...) tmpl.Funcs(html_template.FuncMap{ "tmpl": func(name string, data interface{}) (html_template.HTML, error) { var buffer bytes.Buffer diff --git a/template/template_test.go b/template/template_test.go index 55b6a4598..6c67789ad 100644 --- a/template/template_test.go +++ b/template/template_test.go @@ -31,6 +31,7 @@ func TestTemplateExpansion(t *testing.T) { text string output string input interface{} + options []string queryResult promql.Vector shouldFail bool html bool @@ -153,6 +154,45 @@ func TestTemplateExpansion(t *testing.T) { }}, output: "a:11: b:21: ", }, + { + // Missing value is no value for nil options. + text: "{{ .Foo }}", + output: "", + }, + { + // Missing value is no value for no options. + text: "{{ .Foo }}", + options: make([]string, 0), + output: "", + }, + { + // Assert that missing value returns error with missingkey=error. + text: "{{ .Foo }}", + options: []string{"missingkey=error"}, + shouldFail: true, + errorMsg: `error executing template test: template: test:1:3: executing "test" at <.Foo>: nil data; no entry for key "Foo"`, + }, + { + // Missing value is "" for nil options in ExpandHTML. + text: "{{ .Foo }}", + output: "", + html: true, + }, + { + // Missing value is "" for no options in ExpandHTML. + text: "{{ .Foo }}", + options: make([]string, 0), + output: "", + html: true, + }, + { + // Assert that missing value returns error with missingkey=error in ExpandHTML. + text: "{{ .Foo }}", + options: []string{"missingkey=error"}, + shouldFail: true, + errorMsg: `error executing template test: template: test:1:3: executing "test" at <.Foo>: nil data; no entry for key "Foo"`, + html: true, + }, { // Unparsable template. text: "{{", @@ -341,7 +381,7 @@ func TestTemplateExpansion(t *testing.T) { } var result string var err error - expander := NewTemplateExpander(context.Background(), s.text, "test", s.input, 0, queryFunc, extURL) + expander := NewTemplateExpander(context.Background(), s.text, "test", s.input, 0, queryFunc, extURL, s.options) if s.html { result, err = expander.ExpandHTML(nil) } else { @@ -356,7 +396,7 @@ func TestTemplateExpansion(t *testing.T) { require.NoError(t, err) if err == nil { - require.Equal(t, result, s.output) + require.Equal(t, s.output, result) } } } diff --git a/web/web.go b/web/web.go index 26ed3cf18..c5e2a2216 100644 --- a/web/web.go +++ b/web/web.go @@ -709,6 +709,7 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) { h.now(), template.QueryFunc(rules.EngineQueryFunc(h.queryEngine, h.storage)), h.options.ExternalURL, + nil, ) filenames, err := filepath.Glob(h.options.ConsoleLibrariesPath + "/*.lib") if err != nil { @@ -1113,6 +1114,7 @@ func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data inter h.now(), template.QueryFunc(rules.EngineQueryFunc(h.queryEngine, h.storage)), h.options.ExternalURL, + nil, ) tmpl.Funcs(tmplFuncs(h.consolesPath(), h.options))