mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: validate mute timings in the alertmanager configuration (#42125)
* Alerting: check for uniqueness of mutetime names * add some testing * add name validation * add root route validation * add tests for validation * add check for root route mute_time_intervals * add duplicate test * remove useless yaml test * refactor table test
This commit is contained in:
parent
3e16abc939
commit
cec2d965ec
@ -746,6 +746,9 @@ func (c *Config) UnmarshalJSON(b []byte) error {
|
||||
if len(c.Route.Match) > 0 || len(c.Route.MatchRE) > 0 {
|
||||
return fmt.Errorf("root route must not have any matchers")
|
||||
}
|
||||
if len(c.Route.MuteTimeIntervals) > 0 {
|
||||
return fmt.Errorf("root route must not have any mute time intervals")
|
||||
}
|
||||
|
||||
for _, r := range c.InhibitRules {
|
||||
if err := r.UnmarshalYAML(noopUnmarshal); err != nil {
|
||||
@ -753,6 +756,33 @@ func (c *Config) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
}
|
||||
|
||||
tiNames := make(map[string]struct{})
|
||||
for _, mt := range c.MuteTimeIntervals {
|
||||
if mt.Name == "" {
|
||||
return fmt.Errorf("missing name in mute time interval")
|
||||
}
|
||||
if _, ok := tiNames[mt.Name]; ok {
|
||||
return fmt.Errorf("mute time interval %q is not unique", mt.Name)
|
||||
}
|
||||
tiNames[mt.Name] = struct{}{}
|
||||
}
|
||||
return checkTimeInterval(c.Route, tiNames)
|
||||
}
|
||||
|
||||
func checkTimeInterval(r *Route, timeIntervals map[string]struct{}) error {
|
||||
for _, sr := range r.Routes {
|
||||
if err := checkTimeInterval(sr, timeIntervals); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(r.MuteTimeIntervals) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, mt := range r.MuteTimeIntervals {
|
||||
if _, ok := timeIntervals[mt]; !ok {
|
||||
return fmt.Errorf("undefined time interval %q used in route", mt)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package definitions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -405,6 +406,283 @@ email_configs:
|
||||
}
|
||||
}
|
||||
|
||||
func Test_ConfigUnmashaling(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
desc, input string
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "empty mute time name should error",
|
||||
err: errors.New("missing name in mute time interval"),
|
||||
input: `
|
||||
{
|
||||
"route": {
|
||||
"receiver": "grafana-default-email"
|
||||
},
|
||||
"mute_time_intervals": [
|
||||
{
|
||||
"name": "",
|
||||
"time_intervals": [
|
||||
{
|
||||
"times": [
|
||||
{
|
||||
"start_time": "00:00",
|
||||
"end_time": "12:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": null,
|
||||
"receivers": [
|
||||
{
|
||||
"name": "grafana-default-email",
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"uid": "uxwfZvtnz",
|
||||
"name": "email receiver",
|
||||
"type": "email",
|
||||
"disableResolveMessage": false,
|
||||
"settings": {
|
||||
"addresses": "<example@email.com>"
|
||||
},
|
||||
"secureFields": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "not unique mute time names should error",
|
||||
err: errors.New("mute time interval \"test1\" is not unique"),
|
||||
input: `
|
||||
{
|
||||
"route": {
|
||||
"receiver": "grafana-default-email"
|
||||
},
|
||||
"mute_time_intervals": [
|
||||
{
|
||||
"name": "test1",
|
||||
"time_intervals": [
|
||||
{
|
||||
"times": [
|
||||
{
|
||||
"start_time": "00:00",
|
||||
"end_time": "12:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "test1",
|
||||
"time_intervals": [
|
||||
{
|
||||
"times": [
|
||||
{
|
||||
"start_time": "00:00",
|
||||
"end_time": "12:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": null,
|
||||
"receivers": [
|
||||
{
|
||||
"name": "grafana-default-email",
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"uid": "uxwfZvtnz",
|
||||
"name": "email receiver",
|
||||
"type": "email",
|
||||
"disableResolveMessage": false,
|
||||
"settings": {
|
||||
"addresses": "<example@email.com>"
|
||||
},
|
||||
"secureFields": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "mute time intervals on root route should error",
|
||||
err: errors.New("root route must not have any mute time intervals"),
|
||||
input: `
|
||||
{
|
||||
"route": {
|
||||
"receiver": "grafana-default-email",
|
||||
"mute_time_intervals": ["test1"]
|
||||
},
|
||||
"mute_time_intervals": [
|
||||
{
|
||||
"name": "test1",
|
||||
"time_intervals": [
|
||||
{
|
||||
"times": [
|
||||
{
|
||||
"start_time": "00:00",
|
||||
"end_time": "12:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": null,
|
||||
"receivers": [
|
||||
{
|
||||
"name": "grafana-default-email",
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"uid": "uxwfZvtnz",
|
||||
"name": "email receiver",
|
||||
"type": "email",
|
||||
"disableResolveMessage": false,
|
||||
"settings": {
|
||||
"addresses": "<example@email.com>"
|
||||
},
|
||||
"secureFields": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "undefined mute time names in routes should error",
|
||||
err: errors.New("undefined time interval \"test2\" used in route"),
|
||||
input: `
|
||||
{
|
||||
"route": {
|
||||
"receiver": "grafana-default-email",
|
||||
"routes": [
|
||||
{
|
||||
"receiver": "grafana-default-email",
|
||||
"object_matchers": [
|
||||
[
|
||||
"a",
|
||||
"=",
|
||||
"b"
|
||||
]
|
||||
],
|
||||
"mute_time_intervals": [
|
||||
"test2"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"mute_time_intervals": [
|
||||
{
|
||||
"name": "test1",
|
||||
"time_intervals": [
|
||||
{
|
||||
"times": [
|
||||
{
|
||||
"start_time": "00:00",
|
||||
"end_time": "12:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": null,
|
||||
"receivers": [
|
||||
{
|
||||
"name": "grafana-default-email",
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"uid": "uxwfZvtnz",
|
||||
"name": "email receiver",
|
||||
"type": "email",
|
||||
"disableResolveMessage": false,
|
||||
"settings": {
|
||||
"addresses": "<example@email.com>"
|
||||
},
|
||||
"secureFields": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "valid config should not error",
|
||||
input: `
|
||||
{
|
||||
"route": {
|
||||
"receiver": "grafana-default-email",
|
||||
"routes": [
|
||||
{
|
||||
"receiver": "grafana-default-email",
|
||||
"object_matchers": [
|
||||
[
|
||||
"a",
|
||||
"=",
|
||||
"b"
|
||||
]
|
||||
],
|
||||
"mute_time_intervals": [
|
||||
"test1"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"mute_time_intervals": [
|
||||
{
|
||||
"name": "test1",
|
||||
"time_intervals": [
|
||||
{
|
||||
"times": [
|
||||
{
|
||||
"start_time": "00:00",
|
||||
"end_time": "12:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": null,
|
||||
"receivers": [
|
||||
{
|
||||
"name": "grafana-default-email",
|
||||
"grafana_managed_receiver_configs": [
|
||||
{
|
||||
"uid": "uxwfZvtnz",
|
||||
"name": "email receiver",
|
||||
"type": "email",
|
||||
"disableResolveMessage": false,
|
||||
"settings": {
|
||||
"addresses": "<example@email.com>"
|
||||
},
|
||||
"secureFields": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
var out Config
|
||||
err := json.Unmarshal([]byte(tc.input), &out)
|
||||
require.Equal(t, tc.err, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GettableUserConfigUnmarshaling(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
desc, input string
|
||||
|
Loading…
Reference in New Issue
Block a user