mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-28 04:02:21 -04:00
Add parser options parameter to remaining parse functions
Signed-off-by: Martin Valiente Ainz <64830185+tinitiuset@users.noreply.github.com>
This commit is contained in:
parent
af16f35ad6
commit
199d85d5e4
6 changed files with 28 additions and 24 deletions
|
|
@ -873,7 +873,7 @@ func checkRulesFromStdin(ls rulesLintConfig) (bool, bool) {
|
|||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
return true, true
|
||||
}
|
||||
rgs, errs := rulefmt.Parse(data, ls.ignoreUnknownFields, ls.nameValidationScheme)
|
||||
rgs, errs := rulefmt.Parse(data, ls.ignoreUnknownFields, ls.nameValidationScheme, promtoolParserOpts)
|
||||
if errs != nil {
|
||||
failed = true
|
||||
fmt.Fprintln(os.Stderr, " FAILED:")
|
||||
|
|
@ -907,7 +907,7 @@ func checkRules(files []string, ls rulesLintConfig) (bool, bool) {
|
|||
hasErrors := false
|
||||
for _, f := range files {
|
||||
fmt.Println("Checking", f)
|
||||
rgs, errs := rulefmt.ParseFile(f, ls.ignoreUnknownFields, ls.nameValidationScheme)
|
||||
rgs, errs := rulefmt.ParseFile(f, ls.ignoreUnknownFields, ls.nameValidationScheme, promtoolParserOpts)
|
||||
if errs != nil {
|
||||
failed = true
|
||||
fmt.Fprintln(os.Stderr, " FAILED:")
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import (
|
|||
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/model/rulefmt"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"github.com/prometheus/prometheus/promql/promqltest"
|
||||
)
|
||||
|
||||
|
|
@ -187,7 +188,7 @@ func TestCheckDuplicates(t *testing.T) {
|
|||
c := test
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
rgs, err := rulefmt.ParseFile(c.ruleFile, false, model.UTF8Validation)
|
||||
rgs, err := rulefmt.ParseFile(c.ruleFile, false, model.UTF8Validation, parser.Options{})
|
||||
require.Empty(t, err)
|
||||
dups := checkDuplicates(rgs.Groups)
|
||||
require.Equal(t, c.expectedDups, dups)
|
||||
|
|
@ -196,7 +197,7 @@ func TestCheckDuplicates(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkCheckDuplicates(b *testing.B) {
|
||||
rgs, err := rulefmt.ParseFile("./testdata/rules_large.yml", false, model.UTF8Validation)
|
||||
rgs, err := rulefmt.ParseFile("./testdata/rules_large.yml", false, model.UTF8Validation, parser.Options{})
|
||||
require.Empty(b, err)
|
||||
|
||||
for b.Loop() {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ type ruleGroups struct {
|
|||
}
|
||||
|
||||
// Validate validates all rules in the rule groups.
|
||||
func (g *RuleGroups) Validate(node ruleGroups, nameValidationScheme model.ValidationScheme) (errs []error) {
|
||||
func (g *RuleGroups) Validate(node ruleGroups, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (errs []error) {
|
||||
if err := namevalidationutil.CheckNameValidationScheme(nameValidationScheme); err != nil {
|
||||
errs = append(errs, err)
|
||||
return errs
|
||||
|
|
@ -134,7 +134,7 @@ func (g *RuleGroups) Validate(node ruleGroups, nameValidationScheme model.Valida
|
|||
set[g.Name] = struct{}{}
|
||||
|
||||
for i, r := range g.Rules {
|
||||
for _, node := range r.Validate(node.Groups[j].Rules[i], nameValidationScheme) {
|
||||
for _, node := range r.Validate(node.Groups[j].Rules[i], nameValidationScheme, parserOpts) {
|
||||
var ruleName string
|
||||
if r.Alert != "" {
|
||||
ruleName = r.Alert
|
||||
|
|
@ -198,7 +198,7 @@ type RuleNode struct {
|
|||
}
|
||||
|
||||
// Validate the rule and return a list of encountered errors.
|
||||
func (r *Rule) Validate(node RuleNode, nameValidationScheme model.ValidationScheme) (nodes []WrappedError) {
|
||||
func (r *Rule) Validate(node RuleNode, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (nodes []WrappedError) {
|
||||
if r.Record != "" && r.Alert != "" {
|
||||
nodes = append(nodes, WrappedError{
|
||||
err: errors.New("only one of 'record' and 'alert' must be set"),
|
||||
|
|
@ -219,7 +219,7 @@ func (r *Rule) Validate(node RuleNode, nameValidationScheme model.ValidationSche
|
|||
err: errors.New("field 'expr' must be set in rule"),
|
||||
node: &node.Expr,
|
||||
})
|
||||
} else if _, err := parser.ParseExpr(r.Expr); err != nil {
|
||||
} else if _, err := parser.ParseExpr(r.Expr, parser.WithOptions(parserOpts)); err != nil {
|
||||
nodes = append(nodes, WrappedError{
|
||||
err: fmt.Errorf("could not parse expression: %w", err),
|
||||
node: &node.Expr,
|
||||
|
|
@ -339,7 +339,7 @@ func testTemplateParsing(rl *Rule) (errs []error) {
|
|||
}
|
||||
|
||||
// Parse parses and validates a set of rules.
|
||||
func Parse(content []byte, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*RuleGroups, []error) {
|
||||
func Parse(content []byte, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (*RuleGroups, []error) {
|
||||
var (
|
||||
groups RuleGroups
|
||||
node ruleGroups
|
||||
|
|
@ -364,16 +364,16 @@ func Parse(content []byte, ignoreUnknownFields bool, nameValidationScheme model.
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
return &groups, groups.Validate(node, nameValidationScheme)
|
||||
return &groups, groups.Validate(node, nameValidationScheme, parserOpts)
|
||||
}
|
||||
|
||||
// ParseFile reads and parses rules from a file.
|
||||
func ParseFile(file string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*RuleGroups, []error) {
|
||||
func ParseFile(file string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (*RuleGroups, []error) {
|
||||
b, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf("%s: %w", file, err)}
|
||||
}
|
||||
rgs, errs := Parse(b, ignoreUnknownFields, nameValidationScheme)
|
||||
rgs, errs := Parse(b, ignoreUnknownFields, nameValidationScheme, parserOpts)
|
||||
for i := range errs {
|
||||
errs[i] = fmt.Errorf("%s: %w", file, errs[i])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,17 +22,20 @@ import (
|
|||
"github.com/prometheus/common/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.yaml.in/yaml/v3"
|
||||
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
)
|
||||
|
||||
func TestParseFileSuccess(t *testing.T) {
|
||||
_, errs := ParseFile("testdata/test.yaml", false, model.UTF8Validation)
|
||||
opts := parser.Options{}
|
||||
_, errs := ParseFile("testdata/test.yaml", false, model.UTF8Validation, opts)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
|
||||
_, errs = ParseFile("testdata/utf-8_lname.good.yaml", false, model.UTF8Validation)
|
||||
_, errs = ParseFile("testdata/utf-8_lname.good.yaml", false, model.UTF8Validation, opts)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
_, errs = ParseFile("testdata/utf-8_annotation.good.yaml", false, model.UTF8Validation)
|
||||
_, errs = ParseFile("testdata/utf-8_annotation.good.yaml", false, model.UTF8Validation, opts)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
_, errs = ParseFile("testdata/legacy_validation_annotation.good.yaml", false, model.LegacyValidation)
|
||||
_, errs = ParseFile("testdata/legacy_validation_annotation.good.yaml", false, model.LegacyValidation, opts)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +44,7 @@ func TestParseFileSuccessWithAliases(t *testing.T) {
|
|||
/
|
||||
sum without(instance) (rate(requests_total[5m]))
|
||||
`
|
||||
rgs, errs := ParseFile("testdata/test_aliases.yaml", false, model.UTF8Validation)
|
||||
rgs, errs := ParseFile("testdata/test_aliases.yaml", false, model.UTF8Validation, parser.Options{})
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
for _, rg := range rgs.Groups {
|
||||
require.Equal(t, "HighAlert", rg.Rules[0].Alert)
|
||||
|
|
@ -119,7 +122,7 @@ func TestParseFileFailure(t *testing.T) {
|
|||
if c.nameValidationScheme == model.UnsetValidation {
|
||||
c.nameValidationScheme = model.UTF8Validation
|
||||
}
|
||||
_, errs := ParseFile(filepath.Join("testdata", c.filename), false, c.nameValidationScheme)
|
||||
_, errs := ParseFile(filepath.Join("testdata", c.filename), false, c.nameValidationScheme, parser.Options{})
|
||||
require.NotEmpty(t, errs, "Expected error parsing %s but got none", c.filename)
|
||||
require.ErrorContainsf(t, errs[0], c.errMsg, "Expected error for %s.", c.filename)
|
||||
})
|
||||
|
|
@ -215,7 +218,7 @@ groups:
|
|||
}
|
||||
|
||||
for _, tst := range tests {
|
||||
rgs, errs := Parse([]byte(tst.ruleString), false, model.UTF8Validation)
|
||||
rgs, errs := Parse([]byte(tst.ruleString), false, model.UTF8Validation, parser.Options{})
|
||||
require.NotNil(t, rgs, "Rule parsing, rule=\n"+tst.ruleString)
|
||||
passed := (tst.shouldPass && len(errs) == 0) || (!tst.shouldPass && len(errs) > 0)
|
||||
require.True(t, passed, "Rule validation failed, rule=\n"+tst.ruleString)
|
||||
|
|
@ -242,7 +245,7 @@ groups:
|
|||
annotations:
|
||||
summary: "Instance {{ $labels.instance }} up"
|
||||
`
|
||||
_, errs := Parse([]byte(group), false, model.UTF8Validation)
|
||||
_, errs := Parse([]byte(group), false, model.UTF8Validation, parser.Options{})
|
||||
require.Len(t, errs, 2, "Expected two errors")
|
||||
var err00 *Error
|
||||
require.ErrorAs(t, errs[0], &err00)
|
||||
|
|
|
|||
|
|
@ -327,8 +327,8 @@ type FileLoader struct {
|
|||
ParserOptions parser.Options
|
||||
}
|
||||
|
||||
func (FileLoader) Load(identifier string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*rulefmt.RuleGroups, []error) {
|
||||
return rulefmt.ParseFile(identifier, ignoreUnknownFields, nameValidationScheme)
|
||||
func (fl FileLoader) Load(identifier string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*rulefmt.RuleGroups, []error) {
|
||||
return rulefmt.ParseFile(identifier, ignoreUnknownFields, nameValidationScheme, fl.ParserOptions)
|
||||
}
|
||||
|
||||
func (fl FileLoader) Parse(query string) (parser.Expr, error) {
|
||||
|
|
@ -632,7 +632,7 @@ func ParseFiles(patterns []string, nameValidationScheme model.ValidationScheme)
|
|||
}
|
||||
}
|
||||
for fn, pat := range files {
|
||||
_, errs := rulefmt.ParseFile(fn, false, nameValidationScheme)
|
||||
_, errs := rulefmt.ParseFile(fn, false, nameValidationScheme, parser.Options{})
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("parse rules from file %q (pattern: %q): %w", fn, pat, errors.Join(errs...))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -809,7 +809,7 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
// Groups will be recreated if updated.
|
||||
rgs, errs := rulefmt.ParseFile("fixtures/rules.yaml", false, model.UTF8Validation)
|
||||
rgs, errs := rulefmt.ParseFile("fixtures/rules.yaml", false, model.UTF8Validation, parser.Options{})
|
||||
require.Empty(t, errs, "file parsing failures")
|
||||
|
||||
tmpFile, err := os.CreateTemp("", "rules.test.*.yaml")
|
||||
|
|
|
|||
Loading…
Reference in a new issue