Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UTF-8 not allowed in Equal field for inhibition rules #4177

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,11 @@ type InhibitRule struct {
TargetMatchers Matchers `yaml:"target_matchers,omitempty" json:"target_matchers,omitempty"`
// A set of labels that must be equal between the source and target alert
// for them to be a match.
Equal model.LabelNames `yaml:"equal,omitempty" json:"equal,omitempty"`
Equal model.LabelNames `yaml:"-" json:"-"`
// EqualStr allows us to validate the label depending on whether UTF-8 is
// enabled or disabled. It should be removed when Alertmanager is updated
// to use the validation modes in recent versions of prometheus/common.
EqualStr []string `yaml:"equal,omitempty" json:"equal,omitempty"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface for InhibitRule.
Expand All @@ -964,6 +968,14 @@ func (r *InhibitRule) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
}

for _, l := range r.EqualStr {
labelName := model.LabelName(l)
if !compat.IsValidLabelName(labelName) {
return fmt.Errorf("invalid label name %q in equal list", l)
}
r.Equal = append(r.Equal, labelName)
}

return nil
}

Expand Down
46 changes: 46 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ import (

commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"

"github.com/prometheus/alertmanager/featurecontrol"
"github.com/prometheus/alertmanager/matcher/compat"
)

func TestLoadEmptyString(t *testing.T) {
Expand Down Expand Up @@ -1387,3 +1391,45 @@ func TestNilRegexp(t *testing.T) {
})
}
}

func TestInhibitRuleEqual(t *testing.T) {
c, err := LoadFile("testdata/conf.inhibit-equal.yml")
require.NoError(t, err)

// The inhibition rule should have the expected equal labels.
require.Len(t, c.InhibitRules, 1)
r := c.InhibitRules[0]
require.Equal(t, model.LabelNames{"qux", "corge"}, r.Equal)

// Should not be able to load configuration with UTF-8 in equals list.
_, err = LoadFile("testdata/conf.inhibit-equal-utf8.yml")
require.Error(t, err)
require.Equal(t, "invalid label name \"qux🙂\" in equal list", err.Error())

// Change the mode to UTF-8 mode.
ff, err := featurecontrol.NewFlags(promslog.NewNopLogger(), featurecontrol.FeatureUTF8StrictMode)
require.NoError(t, err)
compat.InitFromFlags(promslog.NewNopLogger(), ff)

// Restore the mode to classic at the end of the test.
ff, err = featurecontrol.NewFlags(promslog.NewNopLogger(), featurecontrol.FeatureClassicMode)
require.NoError(t, err)
defer compat.InitFromFlags(promslog.NewNopLogger(), ff)

c, err = LoadFile("testdata/conf.inhibit-equal.yml")
require.NoError(t, err)

// The inhibition rule should have the expected equal labels.
require.Len(t, c.InhibitRules, 1)
r = c.InhibitRules[0]
require.Equal(t, model.LabelNames{"qux", "corge"}, r.Equal)

// Should also be able to load configuration with UTF-8 in equals list.
c, err = LoadFile("testdata/conf.inhibit-equal-utf8.yml")
require.NoError(t, err)

// The inhibition rule should have the expected equal labels.
require.Len(t, c.InhibitRules, 1)
r = c.InhibitRules[0]
require.Equal(t, model.LabelNames{"qux🙂", "corge"}, r.Equal)
}
10 changes: 10 additions & 0 deletions config/testdata/conf.inhibit-equal-utf8.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
route:
receiver: test
receivers:
- name: test
inhibit_rules:
- source_matchers:
- foo=bar
target_matchers:
- bar=baz
equal: ['qux🙂', 'corge']
10 changes: 10 additions & 0 deletions config/testdata/conf.inhibit-equal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
route:
receiver: test
receivers:
- name: test
inhibit_rules:
- source_matchers:
- foo=bar
target_matchers:
- bar=baz
equal: ['qux', 'corge']
Loading