From c3e1f870487d68f3881e0bff5b507693dfc5a744 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 21 Sep 2021 23:00:15 +0300 Subject: [PATCH] lib/promrelabel: fix parsing `regex: true` in relabeling rules --- docs/CHANGELOG.md | 1 + lib/promrelabel/config.go | 43 ++++++++++++++++++++++++++-------- lib/promrelabel/config_test.go | 14 ++++++++++- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4544780674..b7d80bb60e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,6 +7,7 @@ sort: 15 ## tip * BUGFIX: vmselect: fix accessing [Graphite APIs](https://docs.victoriametrics.com/#graphite-api-usage). The access has been broken in v1.66.0, because `/graphite/*` path prefix accidentally clashed with `/graph*` path prefix used for VictoriaMetrics UI (aka `vmui`). +* BUGFIX: fix parsing `regex: ` in relabeling rules (for example, `regex: true` or `regex: 123`). The bug has been introduced in v1.66.0. ## [v1.66.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.66.0) diff --git a/lib/promrelabel/config.go b/lib/promrelabel/config.go index f3564abf42..addfca5064 100644 --- a/lib/promrelabel/config.go +++ b/lib/promrelabel/config.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "regexp" + "strconv" "strings" "github.com/VictoriaMetrics/VictoriaMetrics/lib/envtemplate" @@ -45,29 +46,51 @@ func (mlr *MultiLineRegex) UnmarshalYAML(f func(interface{}) error) error { if err := f(&v); err != nil { return err } - var a []string + s, err := stringValue(v) + if err != nil { + return err + } + mlr.s = s + return nil +} + +func stringValue(v interface{}) (string, error) { + if v == nil { + return "null", nil + } switch x := v.(type) { - case string: - a = []string{x} case []interface{}: - a = make([]string, len(x)) + a := make([]string, len(x)) for i, xx := range x { - s, ok := xx.(string) - if !ok { - return fmt.Errorf("`regex` must contain array of strings; got %T", xx) + s, err := stringValue(xx) + if err != nil { + return "", err } a[i] = s } + return strings.Join(a, "|"), nil + case string: + return x, nil + case float64: + return strconv.FormatFloat(x, 'f', -1, 64), nil + case int: + return strconv.Itoa(x), nil + case bool: + if x { + return "true", nil + } + return "false", nil default: - return fmt.Errorf("unexpected type for `regex`: %T; want string or []string", v) + return "", fmt.Errorf("unexpected type for `regex`: %T; want string or []string", v) } - mlr.s = strings.Join(a, "|") - return nil } // MarshalYAML marshals mlr to YAML. func (mlr *MultiLineRegex) MarshalYAML() (interface{}, error) { a := strings.Split(mlr.s, "|") + if len(a) == 1 { + return a[0], nil + } return a, nil } diff --git a/lib/promrelabel/config_test.go b/lib/promrelabel/config_test.go index 2f5b52a323..7b83b6aae9 100644 --- a/lib/promrelabel/config_test.go +++ b/lib/promrelabel/config_test.go @@ -26,13 +26,25 @@ func TestRelabelConfigMarshalUnmarshal(t *testing.T) { f(` - action: keep regex: foobar -`, "- regex:\n - foobar\n action: keep\n") +`, "- regex: foobar\n action: keep\n") f(` - regex: - 'fo.+' - '.*ba[r-z]a' `, "- regex:\n - fo.+\n - .*ba[r-z]a\n") f(`- regex: foo|bar`, "- regex:\n - foo\n - bar\n") + f(`- regex: True`, `- regex: "true"`+"\n") + f(`- regex: true`, `- regex: "true"`+"\n") + f(`- regex: 123`, `- regex: "123"`+"\n") + f(`- regex: 1.23`, `- regex: "1.23"`+"\n") + f(`- regex: [null]`, `- regex: "null"`+"\n") + f(` +- regex: + - -1.23 + - False + - null + - nan +`, "- regex:\n - \"-1.23\"\n - \"false\"\n - \"null\"\n - nan\n") } func TestLoadRelabelConfigsSuccess(t *testing.T) {