mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 05:04:05 -08:00
Support customization of template options in TemplateExpander (#9290)
Signed-off-by: George Robinson <george.robinson@grafana.com>
This commit is contained in:
parent
46286cb6ab
commit
049b4f4f13
|
@ -239,6 +239,7 @@ func testTemplateParsing(rl *RuleNode) (errs []error) {
|
||||||
model.Time(timestamp.FromTime(time.Now())),
|
model.Time(timestamp.FromTime(time.Now())),
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
return tmpl.ParseTest()
|
return tmpl.ParseTest()
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,6 +338,7 @@ func (r *AlertingRule) Eval(ctx context.Context, ts time.Time, query QueryFunc,
|
||||||
model.Time(timestamp.FromTime(ts)),
|
model.Time(timestamp.FromTime(ts)),
|
||||||
template.QueryFunc(query),
|
template.QueryFunc(query),
|
||||||
externalURL,
|
externalURL,
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
result, err := tmpl.Expand()
|
result, err := tmpl.Expand()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -115,6 +115,7 @@ type Expander struct {
|
||||||
name string
|
name string
|
||||||
data interface{}
|
data interface{}
|
||||||
funcMap text_template.FuncMap
|
funcMap text_template.FuncMap
|
||||||
|
options []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTemplateExpander returns a template expander ready to use.
|
// NewTemplateExpander returns a template expander ready to use.
|
||||||
|
@ -126,7 +127,11 @@ func NewTemplateExpander(
|
||||||
timestamp model.Time,
|
timestamp model.Time,
|
||||||
queryFunc QueryFunc,
|
queryFunc QueryFunc,
|
||||||
externalURL *url.URL,
|
externalURL *url.URL,
|
||||||
|
options []string,
|
||||||
) *Expander {
|
) *Expander {
|
||||||
|
if options == nil {
|
||||||
|
options = []string{"missingkey=zero"}
|
||||||
|
}
|
||||||
return &Expander{
|
return &Expander{
|
||||||
text: text,
|
text: text,
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -291,6 +296,7 @@ func NewTemplateExpander(
|
||||||
return externalURL.String()
|
return externalURL.String()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
options: options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +342,9 @@ func (te Expander) Expand() (result string, resultErr error) {
|
||||||
|
|
||||||
templateTextExpansionTotal.Inc()
|
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 {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "error parsing template %v", te.name)
|
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 := 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.Funcs(html_template.FuncMap{
|
||||||
"tmpl": func(name string, data interface{}) (html_template.HTML, error) {
|
"tmpl": func(name string, data interface{}) (html_template.HTML, error) {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
|
@ -31,6 +31,7 @@ func TestTemplateExpansion(t *testing.T) {
|
||||||
text string
|
text string
|
||||||
output string
|
output string
|
||||||
input interface{}
|
input interface{}
|
||||||
|
options []string
|
||||||
queryResult promql.Vector
|
queryResult promql.Vector
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
html bool
|
html bool
|
||||||
|
@ -153,6 +154,45 @@ func TestTemplateExpansion(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
output: "a:11: b:21: ",
|
output: "a:11: b:21: ",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Missing value is no value for nil options.
|
||||||
|
text: "{{ .Foo }}",
|
||||||
|
output: "<no value>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Missing value is no value for no options.
|
||||||
|
text: "{{ .Foo }}",
|
||||||
|
options: make([]string, 0),
|
||||||
|
output: "<no value>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 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.
|
// Unparsable template.
|
||||||
text: "{{",
|
text: "{{",
|
||||||
|
@ -341,7 +381,7 @@ func TestTemplateExpansion(t *testing.T) {
|
||||||
}
|
}
|
||||||
var result string
|
var result string
|
||||||
var err error
|
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 {
|
if s.html {
|
||||||
result, err = expander.ExpandHTML(nil)
|
result, err = expander.ExpandHTML(nil)
|
||||||
} else {
|
} else {
|
||||||
|
@ -356,7 +396,7 @@ func TestTemplateExpansion(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
require.Equal(t, result, s.output)
|
require.Equal(t, s.output, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -709,6 +709,7 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
||||||
h.now(),
|
h.now(),
|
||||||
template.QueryFunc(rules.EngineQueryFunc(h.queryEngine, h.storage)),
|
template.QueryFunc(rules.EngineQueryFunc(h.queryEngine, h.storage)),
|
||||||
h.options.ExternalURL,
|
h.options.ExternalURL,
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
filenames, err := filepath.Glob(h.options.ConsoleLibrariesPath + "/*.lib")
|
filenames, err := filepath.Glob(h.options.ConsoleLibrariesPath + "/*.lib")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1113,6 +1114,7 @@ func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data inter
|
||||||
h.now(),
|
h.now(),
|
||||||
template.QueryFunc(rules.EngineQueryFunc(h.queryEngine, h.storage)),
|
template.QueryFunc(rules.EngineQueryFunc(h.queryEngine, h.storage)),
|
||||||
h.options.ExternalURL,
|
h.options.ExternalURL,
|
||||||
|
nil,
|
||||||
)
|
)
|
||||||
tmpl.Funcs(tmplFuncs(h.consolesPath(), h.options))
|
tmpl.Funcs(tmplFuncs(h.consolesPath(), h.options))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue