Alerting: Improve receiver initialisation errors (#36814)

* Alerting: Improve receiver initialisation errors
This commit is contained in:
Sofia Papagiannaki 2021-07-19 11:58:35 +03:00 committed by GitHub
parent 0cfc135c4b
commit f308ba91e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 189 additions and 225 deletions

View File

@ -9,7 +9,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
@ -18,12 +17,12 @@ import (
// NewAlertmanagerNotifier returns a new Alertmanager notifier.
func NewAlertmanagerNotifier(model *NotificationChannelConfig, t *template.Template) (*AlertmanagerNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No settings supplied"}
return nil, receiverInitError{Reason: "no settings supplied"}
}
urlStr := model.Settings.Get("url").MustString()
if urlStr == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
return nil, receiverInitError{Reason: "could not find url property in settings", Cfg: *model}
}
var urls []*url.URL
@ -36,7 +35,7 @@ func NewAlertmanagerNotifier(model *NotificationChannelConfig, t *template.Templ
uS = strings.TrimSuffix(uS, "/") + "/api/v1/alerts"
u, err := url.Parse(uS)
if err != nil {
return nil, alerting.ValidationError{Reason: "Invalid url property in settings"}
return nil, receiverInitError{Reason: "invalid url property in settings", Cfg: *model, Err: err}
}
urls = append(urls, u)

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestAlertmanagerNotifier(t *testing.T) {
@ -27,8 +26,8 @@ func TestAlertmanagerNotifier(t *testing.T) {
name string
settings string
alerts []*types.Alert
expInitError error
expMsgError error
expInitError string
receiverName string
}{
{
name: "Default config with one alert",
@ -41,16 +40,30 @@ func TestAlertmanagerNotifier(t *testing.T) {
},
},
},
receiverName: "Alertmanager",
},
{
name: "Default config with one alert with empty receiver name",
settings: `{"url": "https://alertmanager.com"}`,
alerts: []*types.Alert{
{
Alert: model.Alert{
Labels: model.LabelSet{"__alert_rule_uid__": "rule uid", "alertname": "alert1", "lbl1": "val1"},
Annotations: model.LabelSet{"ann1": "annv1"},
},
},
},
}, {
name: "Error in initing: missing URL",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find url property in settings"},
expInitError: `failed to validate receiver of type "alertmanager": could not find url property in settings`,
}, {
name: "Error in initing: invalid URL",
settings: `{
"url": "://alertmanager.com"
}`,
expInitError: alerting.ValidationError{Reason: "Invalid url property in settings"},
expInitError: `failed to validate receiver "Alertmanager" of type "alertmanager": invalid url property in settings: parse "://alertmanager.com/api/v1/alerts": missing protocol scheme`,
receiverName: "Alertmanager",
},
}
for _, c := range cases {
@ -59,15 +72,14 @@ func TestAlertmanagerNotifier(t *testing.T) {
require.NoError(t, err)
m := &NotificationChannelConfig{
Name: "Alertmanager",
Name: c.receiverName,
Type: "alertmanager",
Settings: settingsJSON,
}
sn, err := NewAlertmanagerNotifier(m, tmpl)
if c.expInitError != nil {
require.Error(t, err)
require.Equal(t, c.expInitError, err)
if c.expInitError != "" {
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)
@ -85,12 +97,6 @@ func TestAlertmanagerNotifier(t *testing.T) {
ctx := notify.WithGroupKey(context.Background(), "alertname")
ctx = notify.WithGroupLabels(ctx, model.LabelSet{"alertname": ""})
ok, err := sn.Notify(ctx, c.alerts...)
if c.expMsgError != nil {
require.False(t, ok)
require.Error(t, err)
require.Equal(t, c.expMsgError, err)
return
}
require.NoError(t, err)
require.True(t, ok)

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -21,12 +20,12 @@ const defaultDingdingMsgType = "link"
// NewDingDingNotifier is the constructor for the Dingding notifier
func NewDingDingNotifier(model *NotificationChannelConfig, t *template.Template) (*DingDingNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Reason: "no settings supplied", Cfg: *model}
}
url := model.Settings.Get("url").MustString()
if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
return nil, receiverInitError{Reason: "could not find url property in settings", Cfg: *model}
}
msgType := model.Settings.Get("msgType").MustString(defaultDingdingMsgType)

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestDingdingNotifier(t *testing.T) {
@ -29,7 +28,7 @@ func TestDingdingNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg map[string]interface{}
expInitError error
expInitError string
expMsgError error
}{
{
@ -51,7 +50,6 @@ func TestDingdingNotifier(t *testing.T) {
"title": "[FIRING:1] (val1)",
},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Custom config with multiple alerts",
@ -82,12 +80,11 @@ func TestDingdingNotifier(t *testing.T) {
},
"msgtype": "actionCard",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find url property in settings"},
expInitError: `failed to validate receiver "dingding_testing" of type "dingding": could not find url property in settings`,
},
}
@ -103,9 +100,8 @@ func TestDingdingNotifier(t *testing.T) {
}
pn, err := NewDingDingNotifier(m, tmpl)
if c.expInitError != nil {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
if c.expInitError != "" {
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/grafana/grafana/pkg/setting"
)
@ -29,14 +28,14 @@ type DiscordNotifier struct {
func NewDiscordNotifier(model *NotificationChannelConfig, t *template.Template) (*DiscordNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Reason: "no settings supplied", Cfg: *model}
}
avatarURL := model.Settings.Get("avatar_url").MustString()
discordURL := model.Settings.Get("url").MustString()
if discordURL == "" {
return nil, alerting.ValidationError{Reason: "Could not find webhook url property in settings"}
return nil, receiverInitError{Reason: "could not find webhook url property in settings", Cfg: *model}
}
content := model.Settings.Get("message").MustString(`{{ template "default.message" . }}`)

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestDiscordNotifier(t *testing.T) {
@ -29,7 +28,7 @@ func TestDiscordNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg map[string]interface{}
expInitError error
expInitError string
expMsgError error
}{
{
@ -57,7 +56,6 @@ func TestDiscordNotifier(t *testing.T) {
}},
"username": "Grafana",
},
expInitError: nil,
expMsgError: nil,
},
{
@ -95,13 +93,12 @@ func TestDiscordNotifier(t *testing.T) {
}},
"username": "Grafana",
},
expInitError: nil,
expMsgError: nil,
},
{
name: "Error in initialization",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find webhook url property in settings"},
expInitError: `failed to validate receiver "discord_testing" of type "discord": could not find webhook url property in settings`,
},
}
@ -117,9 +114,8 @@ func TestDiscordNotifier(t *testing.T) {
}
dn, err := NewDiscordNotifier(m, tmpl)
if c.expInitError != nil {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
if c.expInitError != "" {
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -11,7 +11,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/grafana/grafana/pkg/util"
)
@ -31,14 +30,14 @@ type EmailNotifier struct {
// for the EmailNotifier.
func NewEmailNotifier(model *NotificationChannelConfig, t *template.Template) (*EmailNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Reason: "no settings supplied", Cfg: *model}
}
addressesString := model.Settings.Get("addresses").MustString()
singleEmail := model.Settings.Get("singleEmail").MustBool(false)
if addressesString == "" {
return nil, alerting.ValidationError{Reason: "Could not find addresses in settings"}
return nil, receiverInitError{Reason: "could not find addresses in settings", Cfg: *model}
}
// split addresses with a few different ways

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/grafana/grafana/pkg/setting"
)
@ -29,7 +28,7 @@ type GoogleChatNotifier struct {
func NewGoogleChatNotifier(model *NotificationChannelConfig, t *template.Template) (*GoogleChatNotifier, error) {
url := model.Settings.Get("url").MustString()
if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find url property in settings"}
}
return &GoogleChatNotifier{

View File

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/setting"
)
@ -31,7 +30,7 @@ func TestGoogleChatNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg *outerStruct
expInitError error
expInitError string
expMsgError error
}{
{
@ -87,7 +86,6 @@ func TestGoogleChatNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Multiple alerts",
@ -146,12 +144,11 @@ func TestGoogleChatNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find url property in settings"},
expInitError: `failed to validate receiver "googlechat_testing" of type "googlechat": could not find url property in settings`,
},
}
@ -167,9 +164,9 @@ func TestGoogleChatNotifier(t *testing.T) {
}
pn, err := NewGoogleChatNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -31,11 +30,11 @@ type KafkaNotifier struct {
func NewKafkaNotifier(model *NotificationChannelConfig, t *template.Template) (*KafkaNotifier, error) {
endpoint := model.Settings.Get("kafkaRestProxy").MustString()
if endpoint == "" {
return nil, alerting.ValidationError{Reason: "Could not find kafka rest proxy endpoint property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find kafka rest proxy endpoint property in settings"}
}
topic := model.Settings.Get("kafkaTopic").MustString()
if topic == "" {
return nil, alerting.ValidationError{Reason: "Could not find kafka topic property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find kafka topic property in settings"}
}
return &KafkaNotifier{

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestKafkaNotifier(t *testing.T) {
@ -28,7 +27,7 @@ func TestKafkaNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expUrl, expMsg string
expInitError error
expInitError string
expMsgError error
}{
{
@ -60,7 +59,6 @@ func TestKafkaNotifier(t *testing.T) {
}
]
}`,
expInitError: nil,
expMsgError: nil,
}, {
name: "Multiple alerts",
@ -96,16 +94,15 @@ func TestKafkaNotifier(t *testing.T) {
}
]
}`,
expInitError: nil,
expMsgError: nil,
}, {
name: "Endpoint missing",
settings: `{"kafkaTopic": "sometopic"}`,
expInitError: alerting.ValidationError{Reason: "Could not find kafka rest proxy endpoint property in settings"},
expInitError: `failed to validate receiver "kafka_testing" of type "kafka": could not find kafka rest proxy endpoint property in settings`,
}, {
name: "Topic missing",
settings: `{"kafkaRestProxy": "http://localhost"}`,
expInitError: alerting.ValidationError{Reason: "Could not find kafka topic property in settings"},
expInitError: `failed to validate receiver "kafka_testing" of type "kafka": could not find kafka topic property in settings`,
},
}
@ -121,9 +118,9 @@ func TestKafkaNotifier(t *testing.T) {
}
pn, err := NewKafkaNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -24,7 +23,7 @@ var (
func NewLineNotifier(model *NotificationChannelConfig, t *template.Template) (*LineNotifier, error) {
token := model.DecryptedValue("token", model.Settings.Get("token").MustString())
if token == "" {
return nil, alerting.ValidationError{Reason: "Could not find token in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find token in settings"}
}
return &LineNotifier{

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestLineNotifier(t *testing.T) {
@ -29,7 +28,7 @@ func TestLineNotifier(t *testing.T) {
alerts []*types.Alert
expHeaders map[string]string
expMsg string
expInitError error
expInitError string
expMsgError error
}{
{
@ -48,7 +47,6 @@ func TestLineNotifier(t *testing.T) {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
},
expMsg: "message=%5BFIRING%3A1%5D++%28val1%29%0Ahttp%3A%2Flocalhost%2Falerting%2Flist%0A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+alert1%0A+-+lbl1+%3D+val1%0AAnnotations%3A%0A+-+ann1+%3D+annv1%0ASilence%3A+http%3A%2F%2Flocalhost%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253Dalert1%252Clbl1%253Dval1%0ADashboard%3A+http%3A%2F%2Flocalhost%2Fd%2Fabcd%0APanel%3A+http%3A%2F%2Flocalhost%2Fd%2Fabcd%3FviewPanel%3Defgh%0A",
expInitError: nil,
expMsgError: nil,
}, {
name: "Multiple alerts",
@ -71,12 +69,11 @@ func TestLineNotifier(t *testing.T) {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
},
expMsg: "message=%5BFIRING%3A2%5D++%0Ahttp%3A%2Flocalhost%2Falerting%2Flist%0A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+alert1%0A+-+lbl1+%3D+val1%0AAnnotations%3A%0A+-+ann1+%3D+annv1%0ASilence%3A+http%3A%2F%2Flocalhost%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253Dalert1%252Clbl1%253Dval1%0A%0ALabels%3A%0A+-+alertname+%3D+alert1%0A+-+lbl1+%3D+val2%0AAnnotations%3A%0A+-+ann1+%3D+annv2%0ASilence%3A+http%3A%2F%2Flocalhost%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253Dalert1%252Clbl1%253Dval2%0A",
expInitError: nil,
expMsgError: nil,
}, {
name: "Token missing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find token in settings"},
expInitError: `failed to validate receiver "line_testing" of type "line": could not find token in settings`,
},
}
@ -92,9 +89,9 @@ func TestLineNotifier(t *testing.T) {
}
pn, err := NewLineNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -16,7 +16,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -50,7 +49,7 @@ func NewOpsgenieNotifier(model *NotificationChannelConfig, t *template.Template)
apiKey := model.DecryptedValue("apiKey", model.Settings.Get("apiKey").MustString())
apiURL := model.Settings.Get("apiUrl").MustString()
if apiKey == "" {
return nil, alerting.ValidationError{Reason: "Could not find api key property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find api key property in settings"}
}
if apiURL == "" {
apiURL = OpsgenieAlertURL
@ -58,8 +57,8 @@ func NewOpsgenieNotifier(model *NotificationChannelConfig, t *template.Template)
sendTagsAs := model.Settings.Get("sendTagsAs").MustString(OpsgenieSendTags)
if sendTagsAs != OpsgenieSendTags && sendTagsAs != OpsgenieSendDetails && sendTagsAs != OpsgenieSendBoth {
return nil, alerting.ValidationError{
Reason: fmt.Sprintf("Invalid value for sendTagsAs: %q", sendTagsAs),
return nil, receiverInitError{Cfg: *model,
Reason: fmt.Sprintf("invalid value for sendTagsAs: %q", sendTagsAs),
}
}

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestOpsgenieNotifier(t *testing.T) {
@ -29,7 +28,7 @@ func TestOpsgenieNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg string
expInitError error
expInitError string
expMsgError error
}{
{
@ -136,7 +135,6 @@ func TestOpsgenieNotifier(t *testing.T) {
"source": "Grafana",
"tags": ["alertname:alert1"]
}`,
expInitError: nil,
expMsgError: nil,
},
{
@ -155,7 +153,7 @@ func TestOpsgenieNotifier(t *testing.T) {
{
name: "Error when incorrect settings",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find api key property in settings"},
expInitError: `failed to validate receiver "opsgenie_testing" of type "opsgenie": could not find api key property in settings`,
},
}
@ -171,9 +169,9 @@ func TestOpsgenieNotifier(t *testing.T) {
}
pn, err := NewOpsgenieNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -45,12 +44,12 @@ type PagerdutyNotifier struct {
// NewPagerdutyNotifier is the constructor for the PagerDuty notifier
func NewPagerdutyNotifier(model *NotificationChannelConfig, t *template.Template) (*PagerdutyNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
key := model.DecryptedValue("integrationKey", model.Settings.Get("integrationKey").MustString())
if key == "" {
return nil, alerting.ValidationError{Reason: "Could not find integration key property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find integration key property in settings"}
}
return &PagerdutyNotifier{

View File

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestPagerdutyNotifier(t *testing.T) {
@ -33,7 +32,7 @@ func TestPagerdutyNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg *pagerDutyMessage
expInitError error
expInitError string
expMsgError error
}{
{
@ -70,7 +69,6 @@ func TestPagerdutyNotifier(t *testing.T) {
ClientURL: "http://localhost",
Links: []pagerDutyLink{{HRef: "http://localhost", Text: "External URL"}},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Custom config with multiple alerts",
@ -117,12 +115,11 @@ func TestPagerdutyNotifier(t *testing.T) {
ClientURL: "http://localhost",
Links: []pagerDutyLink{{HRef: "http://localhost", Text: "External URL"}},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find integration key property in settings"},
expInitError: `failed to validate receiver "pageduty_testing" of type "pagerduty": could not find integration key property in settings`,
},
}
@ -138,9 +135,9 @@ func TestPagerdutyNotifier(t *testing.T) {
}
pn, err := NewPagerdutyNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -10,7 +10,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
@ -43,7 +42,7 @@ type PushoverNotifier struct {
// NewSlackNotifier is the constructor for the Slack notifier
func NewPushoverNotifier(model *NotificationChannelConfig, t *template.Template) (*PushoverNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No settings supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
userKey := model.DecryptedValue("userKey", model.Settings.Get("userKey").MustString())
@ -64,10 +63,10 @@ func NewPushoverNotifier(model *NotificationChannelConfig, t *template.Template)
uploadImage := model.Settings.Get("uploadImage").MustBool(true)
if userKey == "" {
return nil, alerting.ValidationError{Reason: "user key not found"}
return nil, receiverInitError{Cfg: *model, Reason: "user key not found"}
}
if APIToken == "" {
return nil, alerting.ValidationError{Reason: "API token not found"}
return nil, receiverInitError{Cfg: *model, Reason: "API token not found"}
}
return &PushoverNotifier{
NotifierBase: old_notifiers.NewNotifierBase(&models.AlertNotification{

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/types"
"github.com/prometheus/common/model"
@ -34,7 +33,7 @@ func TestPushoverNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg map[string]string
expInitError error
expInitError string
expMsgError error
}{
{
@ -62,7 +61,6 @@ func TestPushoverNotifier(t *testing.T) {
"message": "**Firing**\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
"html": "1",
},
expInitError: nil,
expMsgError: nil,
},
{
@ -106,7 +104,6 @@ func TestPushoverNotifier(t *testing.T) {
"expire": "86400",
"device": "device",
},
expInitError: nil,
expMsgError: nil,
},
{
@ -114,13 +111,13 @@ func TestPushoverNotifier(t *testing.T) {
settings: `{
"apiToken": "<apiToken>"
}`,
expInitError: alerting.ValidationError{Reason: "user key not found"},
expInitError: `failed to validate receiver "pushover_testing" of type "pushover": user key not found`,
}, {
name: "Missing api key",
settings: `{
"userKey": "<userKey>"
}`,
expInitError: alerting.ValidationError{Reason: "API token not found"},
expInitError: `failed to validate receiver "pushover_testing" of type "pushover": API token not found`,
},
}
@ -145,9 +142,9 @@ func TestPushoverNotifier(t *testing.T) {
}
pn, err := NewPushoverNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -10,7 +10,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
@ -34,17 +33,17 @@ type SensuGoNotifier struct {
// NewSensuGoNotifier is the constructor for the SensuGo notifier
func NewSensuGoNotifier(model *NotificationChannelConfig, t *template.Template) (*SensuGoNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No settings supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
url := model.Settings.Get("url").MustString()
if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find URL property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find URL property in settings"}
}
apikey := model.DecryptedValue("apikey", model.Settings.Get("apikey").MustString())
if apikey == "" {
return nil, alerting.ValidationError{Reason: "Could not find the API key property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find the API key property in settings"}
}
return &SensuGoNotifier{

View File

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestSensuGoNotifier(t *testing.T) {
@ -30,7 +29,7 @@ func TestSensuGoNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg map[string]interface{}
expInitError error
expInitError string
expMsgError error
}{
{
@ -66,7 +65,6 @@ func TestSensuGoNotifier(t *testing.T) {
},
"ruleUrl": "http://localhost/alerting/list",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Custom config with multiple alerts",
@ -114,20 +112,19 @@ func TestSensuGoNotifier(t *testing.T) {
},
"ruleUrl": "http://localhost/alerting/list",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing: missing URL",
settings: `{
"apikey": "<apikey>"
}`,
expInitError: alerting.ValidationError{Reason: "Could not find URL property in settings"},
expInitError: `failed to validate receiver "Sensu Go" of type "sensugo": could not find URL property in settings`,
}, {
name: "Error in initing: missing API key",
settings: `{
"url": "http://sensu-api.local:8080"
}`,
expInitError: alerting.ValidationError{Reason: "Could not find the API key property in settings"},
expInitError: `failed to validate receiver "Sensu Go" of type "sensugo": could not find the API key property in settings`,
},
}
@ -143,9 +140,9 @@ func TestSensuGoNotifier(t *testing.T) {
}
sn, err := NewSensuGoNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -20,7 +20,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/grafana/grafana/pkg/setting"
)
@ -52,7 +51,7 @@ var SlackAPIEndpoint = "https://slack.com/api/chat.postMessage"
// NewSlackNotifier is the constructor for the Slack notifier
func NewSlackNotifier(model *NotificationChannelConfig, t *template.Template) (*SlackNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
slackURL := model.DecryptedValue("url", model.Settings.Get("url").MustString())
@ -61,24 +60,24 @@ func NewSlackNotifier(model *NotificationChannelConfig, t *template.Template) (*
}
apiURL, err := url.Parse(slackURL)
if err != nil {
return nil, alerting.ValidationError{Reason: fmt.Sprintf("invalid URL %q: %s", slackURL, err)}
return nil, receiverInitError{Cfg: *model, Reason: fmt.Sprintf("invalid URL %q", slackURL), Err: err}
}
recipient := strings.TrimSpace(model.Settings.Get("recipient").MustString())
if recipient != "" {
if !reRecipient.MatchString(recipient) {
return nil, alerting.ValidationError{Reason: fmt.Sprintf("recipient on invalid format: %q", recipient)}
return nil, receiverInitError{Cfg: *model, Reason: fmt.Sprintf("recipient on invalid format: %q", recipient)}
}
} else if apiURL.String() == SlackAPIEndpoint {
return nil, alerting.ValidationError{
return nil, receiverInitError{Cfg: *model,
Reason: "recipient must be specified when using the Slack chat API",
}
}
mentionChannel := model.Settings.Get("mentionChannel").MustString()
if mentionChannel != "" && mentionChannel != "here" && mentionChannel != "channel" {
return nil, alerting.ValidationError{
Reason: fmt.Sprintf("Invalid value for mentionChannel: %q", mentionChannel),
return nil, receiverInitError{Cfg: *model,
Reason: fmt.Sprintf("invalid value for mentionChannel: %q", mentionChannel),
}
}
@ -102,7 +101,7 @@ func NewSlackNotifier(model *NotificationChannelConfig, t *template.Template) (*
token := model.DecryptedValue("token", model.Settings.Get("token").MustString())
if token == "" && apiURL.String() == SlackAPIEndpoint {
return nil, alerting.ValidationError{
return nil, receiverInitError{Cfg: *model,
Reason: "token must be specified when using the Slack chat API",
}
}

View File

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestSlackNotifier(t *testing.T) {
@ -30,7 +29,7 @@ func TestSlackNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg *slackMessage
expInitError error
expInitError string
expMsgError error
}{
{
@ -66,7 +65,6 @@ func TestSlackNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
},
{
@ -102,7 +100,6 @@ func TestSlackNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
},
{
@ -145,20 +142,19 @@ func TestSlackNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Missing token",
settings: `{
"recipient": "#testchannel"
}`,
expInitError: alerting.ValidationError{Reason: "token must be specified when using the Slack chat API"},
expInitError: `failed to validate receiver "slack_testing" of type "slack": token must be specified when using the Slack chat API`,
}, {
name: "Missing recipient",
settings: `{
"token": "1234"
}`,
expInitError: alerting.ValidationError{Reason: "recipient must be specified when using the Slack chat API"},
expInitError: `failed to validate receiver "slack_testing" of type "slack": recipient must be specified when using the Slack chat API`,
},
}
@ -174,9 +170,9 @@ func TestSlackNotifier(t *testing.T) {
}
pn, err := NewSlackNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -11,7 +11,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -28,12 +27,12 @@ type TeamsNotifier struct {
// NewTeamsNotifier is the constructor for Teams notifier.
func NewTeamsNotifier(model *NotificationChannelConfig, t *template.Template) (*TeamsNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
u := model.Settings.Get("url").MustString()
if u == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find url property in settings"}
}
return &TeamsNotifier{

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestTeamsNotifier(t *testing.T) {
@ -29,7 +28,7 @@ func TestTeamsNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg map[string]interface{}
expInitError error
expInitError string
expMsgError error
}{
{
@ -64,7 +63,6 @@ func TestTeamsNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Custom config with multiple alerts",
@ -106,12 +104,11 @@ func TestTeamsNotifier(t *testing.T) {
},
},
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find url property in settings"},
expInitError: `failed to validate receiver "teams_testing" of type "teams": could not find url property in settings`,
},
}
@ -127,9 +124,9 @@ func TestTeamsNotifier(t *testing.T) {
}
pn, err := NewTeamsNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -34,7 +33,7 @@ type TelegramNotifier struct {
// NewTelegramNotifier is the constructor for the Telegram notifier
func NewTelegramNotifier(model *NotificationChannelConfig, t *template.Template) (*TelegramNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
botToken := model.DecryptedValue("bottoken", model.Settings.Get("bottoken").MustString())
@ -42,11 +41,11 @@ func NewTelegramNotifier(model *NotificationChannelConfig, t *template.Template)
message := model.Settings.Get("message").MustString(`{{ template "default.message" . }}`)
if botToken == "" {
return nil, alerting.ValidationError{Reason: "Could not find Bot Token in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find Bot Token in settings"}
}
if chatID == "" {
return nil, alerting.ValidationError{Reason: "Could not find Chat Id in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find Chat Id in settings"}
}
return &TelegramNotifier{

View File

@ -11,7 +11,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestTelegramNotifier(t *testing.T) {
@ -26,7 +25,7 @@ func TestTelegramNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg map[string]string
expInitError error
expInitError string
expMsgError error
}{
{
@ -49,7 +48,6 @@ func TestTelegramNotifier(t *testing.T) {
"parse_mode": "html",
"text": "**Firing**\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSource: a URL\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Custom template with multiple alerts",
@ -77,12 +75,11 @@ func TestTelegramNotifier(t *testing.T) {
"parse_mode": "html",
"text": "__Custom Firing__\n2 Firing\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSource: a URL\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\n\nLabels:\n - alertname = alert1\n - lbl1 = val2\nAnnotations:\n - ann1 = annv2\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval2\n",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find Bot Token in settings"},
expInitError: `failed to validate receiver "telegram_testing" of type "telegram": could not find Bot Token in settings`,
},
}
@ -98,9 +95,9 @@ func TestTelegramNotifier(t *testing.T) {
}
pn, err := NewTelegramNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -36,7 +35,7 @@ type ThreemaNotifier struct {
// NewThreemaNotifier is the constructor for the Threema notifier
func NewThreemaNotifier(model *NotificationChannelConfig, t *template.Template) (*ThreemaNotifier, error) {
if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
}
gatewayID := model.Settings.Get("gateway_id").MustString()
@ -45,22 +44,22 @@ func NewThreemaNotifier(model *NotificationChannelConfig, t *template.Template)
// Validation
if gatewayID == "" {
return nil, alerting.ValidationError{Reason: "Could not find Threema Gateway ID in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find Threema Gateway ID in settings"}
}
if !strings.HasPrefix(gatewayID, "*") {
return nil, alerting.ValidationError{Reason: "Invalid Threema Gateway ID: Must start with a *"}
return nil, receiverInitError{Cfg: *model, Reason: "invalid Threema Gateway ID: Must start with a *"}
}
if len(gatewayID) != 8 {
return nil, alerting.ValidationError{Reason: "Invalid Threema Gateway ID: Must be 8 characters long"}
return nil, receiverInitError{Cfg: *model, Reason: "invalid Threema Gateway ID: Must be 8 characters long"}
}
if recipientID == "" {
return nil, alerting.ValidationError{Reason: "Could not find Threema Recipient ID in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find Threema Recipient ID in settings"}
}
if len(recipientID) != 8 {
return nil, alerting.ValidationError{Reason: "Invalid Threema Recipient ID: Must be 8 characters long"}
return nil, receiverInitError{Cfg: *model, Reason: "invalid Threema Recipient ID: Must be 8 characters long"}
}
if apiSecret == "" {
return nil, alerting.ValidationError{Reason: "Could not find Threema API secret in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find Threema API secret in settings"}
}
return &ThreemaNotifier{

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestThreemaNotifier(t *testing.T) {
@ -28,7 +27,7 @@ func TestThreemaNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg string
expInitError error
expInitError string
expMsgError error
}{
{
@ -47,7 +46,6 @@ func TestThreemaNotifier(t *testing.T) {
},
},
expMsg: "from=%2A1234567&secret=supersecret&text=%E2%9A%A0%EF%B8%8F+%5BFIRING%3A1%5D++%28val1%29%0A%0A%2AMessage%3A%2A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+alert1%0A+-+lbl1+%3D+val1%0AAnnotations%3A%0A+-+ann1+%3D+annv1%0ASilence%3A+http%3A%2F%2Flocalhost%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253Dalert1%252Clbl1%253Dval1%0ADashboard%3A+http%3A%2F%2Flocalhost%2Fd%2Fabcd%0APanel%3A+http%3A%2F%2Flocalhost%2Fd%2Fabcd%3FviewPanel%3Defgh%0A%0A%2AURL%3A%2A+http%3A%2Flocalhost%2Falerting%2Flist%0A&to=87654321",
expInitError: nil,
expMsgError: nil,
}, {
name: "Multiple alerts",
@ -70,7 +68,6 @@ func TestThreemaNotifier(t *testing.T) {
},
},
expMsg: "from=%2A1234567&secret=supersecret&text=%E2%9A%A0%EF%B8%8F+%5BFIRING%3A2%5D++%0A%0A%2AMessage%3A%2A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+alert1%0A+-+lbl1+%3D+val1%0AAnnotations%3A%0A+-+ann1+%3D+annv1%0ASilence%3A+http%3A%2F%2Flocalhost%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253Dalert1%252Clbl1%253Dval1%0A%0ALabels%3A%0A+-+alertname+%3D+alert1%0A+-+lbl1+%3D+val2%0AAnnotations%3A%0A+-+ann1+%3D+annv2%0ASilence%3A+http%3A%2F%2Flocalhost%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253Dalert1%252Clbl1%253Dval2%0A%0A%2AURL%3A%2A+http%3A%2Flocalhost%2Falerting%2Flist%0A&to=87654321",
expInitError: nil,
expMsgError: nil,
}, {
name: "Invalid gateway id",
@ -79,7 +76,7 @@ func TestThreemaNotifier(t *testing.T) {
"recipient_id": "87654321",
"api_secret": "supersecret"
}`,
expInitError: alerting.ValidationError{Reason: "Invalid Threema Gateway ID: Must start with a *"},
expInitError: `failed to validate receiver "threema_testing" of type "threema": invalid Threema Gateway ID: Must start with a *`,
}, {
name: "Invalid receipent id",
settings: `{
@ -87,14 +84,14 @@ func TestThreemaNotifier(t *testing.T) {
"recipient_id": "8765432",
"api_secret": "supersecret"
}`,
expInitError: alerting.ValidationError{Reason: "Invalid Threema Recipient ID: Must be 8 characters long"},
expInitError: `failed to validate receiver "threema_testing" of type "threema": invalid Threema Recipient ID: Must be 8 characters long`,
}, {
name: "No API secret",
settings: `{
"gateway_id": "*1234567",
"recipient_id": "87654321"
}`,
expInitError: alerting.ValidationError{Reason: "Could not find Threema API secret in settings"},
expInitError: `failed to validate receiver "threema_testing" of type "threema": could not find Threema API secret in settings`,
},
}
@ -110,9 +107,9 @@ func TestThreemaNotifier(t *testing.T) {
}
pn, err := NewThreemaNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -26,6 +26,28 @@ const (
ColorAlertResolved = "#36a64f"
)
type receiverInitError struct {
Reason string
Err error
Cfg NotificationChannelConfig
}
func (e receiverInitError) Error() string {
name := ""
if e.Cfg.Name != "" {
name = fmt.Sprintf("%q ", e.Cfg.Name)
}
s := fmt.Sprintf("failed to validate receiver %sof type %q: %s", name, e.Cfg.Type, e.Reason)
if e.Err != nil {
return fmt.Sprintf("%s: %s", s, e.Err.Error())
}
return s
}
func (e receiverInitError) Unwrap() error { return e.Err }
func getAlertStatusColor(status model.AlertStatus) string {
if status == model.AlertFiring {
return ColorAlertFiring

View File

@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
"github.com/grafana/grafana/pkg/setting"
)
@ -32,7 +31,7 @@ const (
func NewVictoropsNotifier(model *NotificationChannelConfig, t *template.Template) (*VictoropsNotifier, error) {
url := model.Settings.Get("url").MustString()
if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find victorops url property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find victorops url property in settings"}
}
return &VictoropsNotifier{

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestVictoropsNotifier(t *testing.T) {
@ -28,7 +27,7 @@ func TestVictoropsNotifier(t *testing.T) {
settings string
alerts []*types.Alert
expMsg string
expInitError error
expInitError string
expMsgError error
}{
{
@ -50,7 +49,6 @@ func TestVictoropsNotifier(t *testing.T) {
"monitoring_tool": "Grafana v",
"state_message": "**Firing**\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n"
}`,
expInitError: nil,
expMsgError: nil,
}, {
name: "Multiple alerts",
@ -76,12 +74,11 @@ func TestVictoropsNotifier(t *testing.T) {
"monitoring_tool": "Grafana v",
"state_message": "**Firing**\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\n\nLabels:\n - alertname = alert1\n - lbl1 = val2\nAnnotations:\n - ann1 = annv2\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval2\n"
}`,
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing, no URL",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find victorops url property in settings"},
expInitError: `failed to validate receiver "victorops_testing" of type "victorops": could not find victorops url property in settings`,
},
}
@ -97,9 +94,9 @@ func TestVictoropsNotifier(t *testing.T) {
}
pn, err := NewVictoropsNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -12,7 +12,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)
@ -34,7 +33,7 @@ type WebhookNotifier struct {
func NewWebHookNotifier(model *NotificationChannelConfig, t *template.Template) (*WebhookNotifier, error) {
url := model.Settings.Get("url").MustString()
if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
return nil, receiverInitError{Cfg: *model, Reason: "could not find url property in settings"}
}
return &WebhookNotifier{
NotifierBase: old_notifiers.NewNotifierBase(&models.AlertNotification{

View File

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
func TestWebhookNotifier(t *testing.T) {
@ -34,7 +33,7 @@ func TestWebhookNotifier(t *testing.T) {
expUsername string
expPassword string
expHttpMethod string
expInitError error
expInitError string
expMsgError error
}{
{
@ -88,7 +87,6 @@ func TestWebhookNotifier(t *testing.T) {
State: "alerting",
Message: "**Firing**\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Custom config with multiple alerts",
@ -166,12 +164,11 @@ func TestWebhookNotifier(t *testing.T) {
State: "alerting",
Message: "**Firing**\n\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval1\n\nLabels:\n - alertname = alert1\n - lbl1 = val2\nAnnotations:\n - ann1 = annv2\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matchers=alertname%3Dalert1%2Clbl1%3Dval2\n",
},
expInitError: nil,
expMsgError: nil,
}, {
name: "Error in initing",
settings: `{}`,
expInitError: alerting.ValidationError{Reason: "Could not find url property in settings"},
expInitError: `failed to validate receiver "webhook_testing" of type "webhook": could not find url property in settings`,
},
}
@ -187,9 +184,9 @@ func TestWebhookNotifier(t *testing.T) {
}
pn, err := NewWebHookNotifier(m, tmpl)
if c.expInitError != nil {
if c.expInitError != "" {
require.Error(t, err)
require.Equal(t, c.expInitError.Error(), err.Error())
require.Equal(t, c.expInitError, err.Error())
return
}
require.NoError(t, err)

View File

@ -61,7 +61,7 @@ func TestAlertmanagerConfigurationIsTransactional(t *testing.T) {
}
`
resp := postRequest(t, alertConfigURL, payload, http.StatusBadRequest) // nolint
require.JSONEq(t, "{\"message\":\"failed to save and apply Alertmanager configuration: alert validation error: token must be specified when using the Slack chat API\"}", getBody(t, resp.Body))
require.JSONEq(t, `{"message":"failed to save and apply Alertmanager configuration: failed to validate receiver \"slack.receiver\" of type \"slack\": token must be specified when using the Slack chat API"}`, getBody(t, resp.Body))
resp = getRequest(t, alertConfigURL, http.StatusOK) // nolint
require.JSONEq(t, defaultAlertmanagerConfigJSON, getBody(t, resp.Body))