Skip to content

Commit

Permalink
NGAlert: Add integration tests for notification channels (grafana#33431)
Browse files Browse the repository at this point in the history
* NGAlert: Add integration tests for notification channels

Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>

* Fix the failing tests

Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>

* Fix review comments

Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>

* Override creation of rule UID, remove only namespace UID

Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>
  • Loading branch information
codesome authored May 13, 2021
1 parent 1a649af commit ec3214b
Show file tree
Hide file tree
Showing 8 changed files with 1,004 additions and 15 deletions.
2 changes: 1 addition & 1 deletion pkg/services/ngalert/notifier/alertmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func (am *Alertmanager) PutAlerts(postableAlerts apimodels.PostableAlerts) error
UpdatedAt: now,
}
for k, v := range a.Labels {
if len(v) == 0 { // Skip empty labels.
if len(v) == 0 || k == ngmodels.NamespaceUIDLabel { // Skip empty and namespace UID labels.
continue
}
alert.Alert.Labels[model.LabelName(k)] = model.LabelValue(v)
Expand Down
4 changes: 2 additions & 2 deletions pkg/services/ngalert/notifier/channels/pagerduty.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
)

var (
pagerdutyEventAPIURL = "https://events.pagerduty.com/v2/enqueue"
PagerdutyEventAPIURL = "https://events.pagerduty.com/v2/enqueue"
)

// PagerdutyNotifier is responsible for sending
Expand Down Expand Up @@ -93,7 +93,7 @@ func (pn *PagerdutyNotifier) Notify(ctx context.Context, as ...*types.Alert) (bo

pn.log.Info("Notifying Pagerduty", "event_type", eventType)
cmd := &models.SendWebhookSync{
Url: pagerdutyEventAPIURL,
Url: PagerdutyEventAPIURL,
Body: string(body),
HttpMethod: "POST",
HttpHeader: map[string]string{
Expand Down
10 changes: 5 additions & 5 deletions pkg/services/ngalert/notifier/channels/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type SlackNotifier struct {

var reRecipient *regexp.Regexp = regexp.MustCompile("^((@[a-z0-9][a-zA-Z0-9._-]*)|(#[^ .A-Z]{1,79})|([a-zA-Z0-9]+))$")

const slackAPIEndpoint = "https://slack.com/api/chat.postMessage"
var SlackAPIEndpoint = "https://slack.com/api/chat.postMessage"

// NewSlackNotifier is the constructor for the Slack notifier
func NewSlackNotifier(model *models.AlertNotification, t *template.Template) (*SlackNotifier, error) {
Expand All @@ -60,7 +60,7 @@ func NewSlackNotifier(model *models.AlertNotification, t *template.Template) (*S

slackURL := model.DecryptedValue("url", model.Settings.Get("url").MustString())
if slackURL == "" {
slackURL = slackAPIEndpoint
slackURL = SlackAPIEndpoint
}
apiURL, err := url.Parse(slackURL)
if err != nil {
Expand All @@ -72,7 +72,7 @@ func NewSlackNotifier(model *models.AlertNotification, t *template.Template) (*S
if !reRecipient.MatchString(recipient) {
return nil, alerting.ValidationError{Reason: fmt.Sprintf("recipient on invalid format: %q", recipient)}
}
} else if apiURL.String() == slackAPIEndpoint {
} else if apiURL.String() == SlackAPIEndpoint {
return nil, alerting.ValidationError{
Reason: "recipient must be specified when using the Slack chat API",
}
Expand Down Expand Up @@ -104,7 +104,7 @@ func NewSlackNotifier(model *models.AlertNotification, t *template.Template) (*S
}

token := model.DecryptedValue("token", model.Settings.Get("token").MustString())
if token == "" && apiURL.String() == slackAPIEndpoint {
if token == "" && apiURL.String() == SlackAPIEndpoint {
return nil, alerting.ValidationError{
Reason: "token must be specified when using the Slack chat API",
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func (sn *SlackNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
request.Header.Set("Content-Type", "application/json")
request.Header.Set("User-Agent", "Grafana")
if sn.Token == "" {
if sn.URL.String() == slackAPIEndpoint {
if sn.URL.String() == SlackAPIEndpoint {
panic("Token should be set when using the Slack chat API")
}
} else {
Expand Down
6 changes: 3 additions & 3 deletions pkg/services/ngalert/notifier/channels/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
)

const (
telegramAPIURL = "https://api.telegram.org/bot%s/sendMessage"
var (
TelegramAPIURL = "https://api.telegram.org/bot%s/sendMessage"
)

// TelegramNotifier is responsible for sending
Expand Down Expand Up @@ -90,7 +90,7 @@ func (tn *TelegramNotifier) Notify(ctx context.Context, as ...*types.Alert) (boo

tn.log.Info("sending telegram notification", "chat_id", tn.ChatID)
cmd := &models.SendWebhookSync{
Url: fmt.Sprintf(telegramAPIURL, tn.BotToken),
Url: fmt.Sprintf(TelegramAPIURL, tn.BotToken),
Body: body.String(),
HttpMethod: "POST",
HttpHeader: map[string]string{
Expand Down
7 changes: 5 additions & 2 deletions pkg/services/ngalert/store/alert_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (st DBstore) UpsertAlertRules(rules []UpsertRule) error {
var parentVersion int64
switch r.Existing {
case nil: // new rule
uid, err := generateNewAlertRuleUID(sess, r.New.OrgID)
uid, err := GenerateNewAlertRuleUID(sess, r.New.OrgID, r.New.Title)
if err != nil {
return fmt.Errorf("failed to generate UID for alert rule %q: %w", r.New.Title, err)
}
Expand Down Expand Up @@ -411,7 +411,10 @@ func (st DBstore) GetAlertRulesForScheduling(query *ngmodels.ListAlertRulesQuery
})
}

func generateNewAlertRuleUID(sess *sqlstore.DBSession, orgID int64) (string, error) {
// GenerateNewAlertRuleUID generates a unique UID for a rule.
// This is set as a variable so that the tests can override it.
// The ruleTitle is only used by the mocked functions.
var GenerateNewAlertRuleUID = func(sess *sqlstore.DBSession, orgID int64, ruleTitle string) (string, error) {
for i := 0; i < 3; i++ {
uid := util.GenerateShortUID()

Expand Down
9 changes: 7 additions & 2 deletions pkg/tests/api/alerting/api_available_channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@ import (

"github.com/stretchr/testify/require"

"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tests/testinfra"
)

func TestAvailableChannels(t *testing.T) {
dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
EnableFeatureToggles: []string{"ngalert"},
AnonymousUserRole: models.ROLE_EDITOR,
DisableAnonymous: true,
})

store := testinfra.SetUpDatabase(t, dir)
store.Bus = bus.GetBus()
grafanaListedAddr := testinfra.StartGrafana(t, dir, path, store)

alertsURL := fmt.Sprintf("http://%s/api/alert-notifiers", grafanaListedAddr)
// Create a user to make authenticated requests
require.NoError(t, createUser(t, store, models.ROLE_EDITOR, "grafana", "password"))

alertsURL := fmt.Sprintf("http://grafana:password@%s/api/alert-notifiers", grafanaListedAddr)
// nolint:gosec
resp, err := http.Get(alertsURL)
require.NoError(t, err)
Expand Down
Loading

0 comments on commit ec3214b

Please sign in to comment.