diff --git a/pkg/api/alerting.go b/pkg/api/alerting.go index 285d2005a9c..de7a4955591 100644 --- a/pkg/api/alerting.go +++ b/pkg/api/alerting.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/services/ngalert/notifier/channels_config" + "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/search" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -645,7 +646,7 @@ func (hs *HTTPServer) NotificationTest(c *models.ReqContext) response.Response { } if err := hs.AlertNotificationService.HandleNotificationTestCommand(c.Req.Context(), cmd); err != nil { - if errors.Is(err, models.ErrSmtpNotEnabled) { + if errors.Is(err, notifications.ErrSmtpNotEnabled) { return response.Error(412, err.Error(), err) } var alertingErr alerting.ValidationError diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go index 5cf7b7f0706..30271ed2f55 100644 --- a/pkg/api/org_invite.go +++ b/pkg/api/org_invite.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/models" ac "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/org" tempuser "github.com/grafana/grafana/pkg/services/temp_user" "github.com/grafana/grafana/pkg/services/user" @@ -113,7 +114,7 @@ func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response { // send invite email if inviteDto.SendEmail && util.IsEmail(inviteDto.LoginOrEmail) { - emailCmd := models.SendEmailCommand{ + emailCmd := notifications.SendEmailCommand{ To: []string{inviteDto.LoginOrEmail}, Template: "new_user_invite", Data: map[string]interface{}{ @@ -126,7 +127,7 @@ func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response { } if err := hs.AlertNG.NotificationService.SendEmailCommandHandler(c.Req.Context(), &emailCmd); err != nil { - if errors.Is(err, models.ErrSmtpNotEnabled) { + if errors.Is(err, notifications.ErrSmtpNotEnabled) { return response.Error(412, err.Error(), err) } @@ -155,7 +156,7 @@ func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *user.U } if inviteDto.SendEmail && util.IsEmail(user.Email) { - emailCmd := models.SendEmailCommand{ + emailCmd := notifications.SendEmailCommand{ To: []string{user.Email}, Template: "invited_to_org", Data: map[string]interface{}{ diff --git a/pkg/api/password.go b/pkg/api/password.go index c21c30f0ae2..5d60de08254 100644 --- a/pkg/api/password.go +++ b/pkg/api/password.go @@ -9,6 +9,7 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/login" + "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -45,7 +46,7 @@ func (hs *HTTPServer) SendResetPasswordEmail(c *models.ReqContext) response.Resp } } - emailCmd := models.SendResetPasswordEmailCommand{User: usr} + emailCmd := notifications.SendResetPasswordEmailCommand{User: usr} if err := hs.NotificationService.SendResetPasswordEmail(c.Req.Context(), &emailCmd); err != nil { return response.Error(500, "Failed to send email", err) } @@ -58,7 +59,7 @@ func (hs *HTTPServer) ResetPassword(c *models.ReqContext) response.Response { if err := web.Bind(c.Req, &form); err != nil { return response.Error(http.StatusBadRequest, "bad request data", err) } - query := models.ValidateResetPasswordCodeQuery{Code: form.Code} + query := notifications.ValidateResetPasswordCodeQuery{Code: form.Code} // For now the only way to know the username to clear login attempts for is // to set it in the function provided to NotificationService @@ -71,7 +72,7 @@ func (hs *HTTPServer) ResetPassword(c *models.ReqContext) response.Response { } if err := hs.NotificationService.ValidateResetPasswordCode(c.Req.Context(), &query, getUserByLogin); err != nil { - if errors.Is(err, models.ErrInvalidEmailCode) { + if errors.Is(err, notifications.ErrInvalidEmailCode) { return response.Error(400, "Invalid or expired reset password code", nil) } return response.Error(500, "Unknown error validating email code", err) diff --git a/pkg/services/alerting/notifiers/alertmanager.go b/pkg/services/alerting/notifiers/alertmanager.go index 92876853470..274a5bb05f3 100644 --- a/pkg/services/alerting/notifiers/alertmanager.go +++ b/pkg/services/alerting/notifiers/alertmanager.go @@ -175,7 +175,7 @@ func (am *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) error errCnt := 0 for _, url := range am.URL { - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: strings.TrimSuffix(url, "/") + "/api/v1/alerts", User: am.BasicAuthUser, Password: am.BasicAuthPassword, diff --git a/pkg/services/alerting/notifiers/dingding.go b/pkg/services/alerting/notifiers/dingding.go index 7767f791df2..d88320f0d12 100644 --- a/pkg/services/alerting/notifiers/dingding.go +++ b/pkg/services/alerting/notifiers/dingding.go @@ -86,7 +86,7 @@ func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { return err } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: dd.URL, Body: string(body), } diff --git a/pkg/services/alerting/notifiers/discord.go b/pkg/services/alerting/notifiers/discord.go index f90d1e12e06..7e7ff16f1d3 100644 --- a/pkg/services/alerting/notifiers/discord.go +++ b/pkg/services/alerting/notifiers/discord.go @@ -161,7 +161,7 @@ func (dn *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { json, _ := bodyJSON.MarshalJSON() - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: dn.WebhookURL, HttpMethod: "POST", ContentType: "application/json", @@ -185,7 +185,7 @@ func (dn *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { return nil } -func (dn *DiscordNotifier) embedImage(cmd *models.SendWebhookSync, imagePath string, existingJSONBody []byte) error { +func (dn *DiscordNotifier) embedImage(cmd *notifications.SendWebhookSync, imagePath string, existingJSONBody []byte) error { // nolint:gosec // We can ignore the gosec G304 warning on this one because `imagePath` comes // from the alert `evalContext` that generates the images. diff --git a/pkg/services/alerting/notifiers/email.go b/pkg/services/alerting/notifiers/email.go index fb072d59617..69c485cfbf2 100644 --- a/pkg/services/alerting/notifiers/email.go +++ b/pkg/services/alerting/notifiers/email.go @@ -82,8 +82,8 @@ func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error { error = evalContext.Error.Error() } - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := ¬ifications.SendEmailCommandSync{ + SendEmailCommand: notifications.SendEmailCommand{ Subject: evalContext.GetNotificationTitle(), Data: map[string]interface{}{ "Title": evalContext.GetNotificationTitle(), diff --git a/pkg/services/alerting/notifiers/googlechat.go b/pkg/services/alerting/notifiers/googlechat.go index 90b2f2e1c1f..6eeeda4eb85 100644 --- a/pkg/services/alerting/notifiers/googlechat.go +++ b/pkg/services/alerting/notifiers/googlechat.go @@ -220,7 +220,7 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error { } body, _ := json.Marshal(res1D) - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: gcn.URL, HttpMethod: "POST", HttpHeader: headers, diff --git a/pkg/services/alerting/notifiers/hipchat.go b/pkg/services/alerting/notifiers/hipchat.go index c625c96bdd5..5b8757934f5 100644 --- a/pkg/services/alerting/notifiers/hipchat.go +++ b/pkg/services/alerting/notifiers/hipchat.go @@ -173,7 +173,7 @@ func (hc *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error { hipURL := fmt.Sprintf("%s/v2/room/%s/notification?auth_token=%s", hc.URL, hc.RoomID, hc.APIKey) data, _ := json.Marshal(&body) hc.log.Info("Request payload", "json", string(data)) - cmd := &models.SendWebhookSync{Url: hipURL, Body: string(data)} + cmd := ¬ifications.SendWebhookSync{Url: hipURL, Body: string(data)} if err := hc.NotificationService.SendWebhookSync(evalContext.Ctx, cmd); err != nil { hc.log.Error("Failed to send hipchat notification", "error", err, "webhook", hc.Name) diff --git a/pkg/services/alerting/notifiers/kafka.go b/pkg/services/alerting/notifiers/kafka.go index c9faaea1027..55613d17cbb 100644 --- a/pkg/services/alerting/notifiers/kafka.go +++ b/pkg/services/alerting/notifiers/kafka.go @@ -114,7 +114,7 @@ func (kn *KafkaNotifier) Notify(evalContext *alerting.EvalContext) error { topicURL := kn.Endpoint + "/topics/" + kn.Topic - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: topicURL, Body: string(body), HttpMethod: "POST", diff --git a/pkg/services/alerting/notifiers/line.go b/pkg/services/alerting/notifiers/line.go index 9e360ecfecd..7ddbb7c0465 100644 --- a/pkg/services/alerting/notifiers/line.go +++ b/pkg/services/alerting/notifiers/line.go @@ -82,7 +82,7 @@ func (ln *LineNotifier) createAlert(evalContext *alerting.EvalContext) error { form.Add("imageFullsize", evalContext.ImagePublicURL) } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: lineNotifyURL, HttpMethod: "POST", HttpHeader: map[string]string{ diff --git a/pkg/services/alerting/notifiers/opsgenie.go b/pkg/services/alerting/notifiers/opsgenie.go index 8cf3a9ebfe8..4703415f84b 100644 --- a/pkg/services/alerting/notifiers/opsgenie.go +++ b/pkg/services/alerting/notifiers/opsgenie.go @@ -195,7 +195,7 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error body, _ := bodyJSON.MarshalJSON() - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: on.APIUrl, Body: string(body), HttpMethod: "POST", @@ -219,7 +219,7 @@ func (on *OpsGenieNotifier) closeAlert(evalContext *alerting.EvalContext) error bodyJSON.Set("source", "Grafana") body, _ := bodyJSON.MarshalJSON() - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: fmt.Sprintf("%s/alertId-%d/close?identifierType=alias", on.APIUrl, evalContext.Rule.ID), Body: string(body), HttpMethod: "POST", diff --git a/pkg/services/alerting/notifiers/pagerduty.go b/pkg/services/alerting/notifiers/pagerduty.go index 358a23d14ec..7c464a668e0 100644 --- a/pkg/services/alerting/notifiers/pagerduty.go +++ b/pkg/services/alerting/notifiers/pagerduty.go @@ -231,7 +231,7 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error { return err } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: pagerdutyEventAPIURL, Body: string(body), HttpMethod: "POST", diff --git a/pkg/services/alerting/notifiers/pushover.go b/pkg/services/alerting/notifiers/pushover.go index 6a6fedce24e..322da15632b 100644 --- a/pkg/services/alerting/notifiers/pushover.go +++ b/pkg/services/alerting/notifiers/pushover.go @@ -280,7 +280,7 @@ func (pn *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error { return err } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: pushoverEndpoint, HttpMethod: "POST", HttpHeader: headers, diff --git a/pkg/services/alerting/notifiers/sensu.go b/pkg/services/alerting/notifiers/sensu.go index b41cf17ca18..655a3ec9a43 100644 --- a/pkg/services/alerting/notifiers/sensu.go +++ b/pkg/services/alerting/notifiers/sensu.go @@ -138,7 +138,7 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error { body, _ := bodyJSON.MarshalJSON() - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: sn.URL, User: sn.User, Password: sn.Password, diff --git a/pkg/services/alerting/notifiers/sensugo.go b/pkg/services/alerting/notifiers/sensugo.go index 045484be0bb..802681fd647 100644 --- a/pkg/services/alerting/notifiers/sensugo.go +++ b/pkg/services/alerting/notifiers/sensugo.go @@ -188,7 +188,7 @@ func (sn *SensuGoNotifier) Notify(evalContext *alerting.EvalContext) error { return err } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: fmt.Sprintf("%s/api/core/v2/namespaces/%s/events", strings.TrimSuffix(sn.URL, "/"), namespace), Body: string(body), HttpMethod: "POST", diff --git a/pkg/services/alerting/notifiers/slack.go b/pkg/services/alerting/notifiers/slack.go index 86f1b7a4f59..092b366b559 100644 --- a/pkg/services/alerting/notifiers/slack.go +++ b/pkg/services/alerting/notifiers/slack.go @@ -415,7 +415,7 @@ func (sn *SlackNotifier) slackFileUpload(evalContext *alerting.EvalContext, log if err != nil { return err } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: "https://slack.com/api/files.upload", Body: uploadBody.String(), HttpHeader: headers, HttpMethod: "POST", } if err := sn.NotificationService.SendWebhookSync(evalContext.Ctx, cmd); err != nil { diff --git a/pkg/services/alerting/notifiers/teams.go b/pkg/services/alerting/notifiers/teams.go index e85f4a12d82..0add355228d 100644 --- a/pkg/services/alerting/notifiers/teams.go +++ b/pkg/services/alerting/notifiers/teams.go @@ -133,7 +133,7 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { } data, _ := json.Marshal(&body) - cmd := &models.SendWebhookSync{Url: tn.URL, Body: string(data)} + cmd := ¬ifications.SendWebhookSync{Url: tn.URL, Body: string(data)} if err := tn.NotificationService.SendWebhookSync(evalContext.Ctx, cmd); err != nil { tn.log.Error("Failed to send teams notification", "error", err, "webhook", tn.Name) diff --git a/pkg/services/alerting/notifiers/telegram.go b/pkg/services/alerting/notifiers/telegram.go index d93d776b853..92b77d27a4d 100644 --- a/pkg/services/alerting/notifiers/telegram.go +++ b/pkg/services/alerting/notifiers/telegram.go @@ -89,7 +89,7 @@ func NewTelegramNotifier(model *models.AlertNotification, fn alerting.GetDecrypt }, nil } -func (tn *TelegramNotifier) buildMessage(evalContext *alerting.EvalContext, sendImageInline bool) (*models.SendWebhookSync, error) { +func (tn *TelegramNotifier) buildMessage(evalContext *alerting.EvalContext, sendImageInline bool) (*notifications.SendWebhookSync, error) { if sendImageInline { cmd, err := tn.buildMessageInlineImage(evalContext) if err == nil { @@ -102,7 +102,7 @@ func (tn *TelegramNotifier) buildMessage(evalContext *alerting.EvalContext, send return tn.buildMessageLinkedImage(evalContext) } -func (tn *TelegramNotifier) buildMessageLinkedImage(evalContext *alerting.EvalContext) (*models.SendWebhookSync, error) { +func (tn *TelegramNotifier) buildMessageLinkedImage(evalContext *alerting.EvalContext) (*notifications.SendWebhookSync, error) { message := fmt.Sprintf("%s\nState: %s\nMessage: %s\n", evalContext.GetNotificationTitle(), evalContext.Rule.Name, evalContext.Rule.Message) ruleURL, err := evalContext.GetRuleURL() @@ -132,7 +132,7 @@ func (tn *TelegramNotifier) buildMessageLinkedImage(evalContext *alerting.EvalCo }) } -func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalContext) (*models.SendWebhookSync, error) { +func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalContext) (*notifications.SendWebhookSync, error) { var imageFile *os.File var err error @@ -169,7 +169,7 @@ func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalCo }) } -func (tn *TelegramNotifier) generateTelegramCmd(message string, messageField string, apiAction string, extraConf func(writer *multipart.Writer)) (*models.SendWebhookSync, error) { +func (tn *TelegramNotifier) generateTelegramCmd(message string, messageField string, apiAction string, extraConf func(writer *multipart.Writer)) (*notifications.SendWebhookSync, error) { var body bytes.Buffer w := multipart.NewWriter(&body) defer func() { @@ -203,7 +203,7 @@ func (tn *TelegramNotifier) generateTelegramCmd(message string, messageField str tn.log.Info("Sending telegram notification", "chat_id", tn.ChatID, "bot_token", tn.BotToken, "apiAction", apiAction) url := fmt.Sprintf(telegramAPIURL, tn.BotToken, apiAction) - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: url, Body: body.String(), HttpMethod: "POST", @@ -260,7 +260,7 @@ func appendIfPossible(tlog log.Logger, message string, extra string, sizeLimit i // Notify send an alert notification to Telegram. func (tn *TelegramNotifier) Notify(evalContext *alerting.EvalContext) error { - var cmd *models.SendWebhookSync + var cmd *notifications.SendWebhookSync var err error if evalContext.ImagePublicURL == "" && tn.UploadImage { cmd, err = tn.buildMessage(evalContext, true) diff --git a/pkg/services/alerting/notifiers/threema.go b/pkg/services/alerting/notifiers/threema.go index 19b7ecd6324..07111646d45 100644 --- a/pkg/services/alerting/notifiers/threema.go +++ b/pkg/services/alerting/notifiers/threema.go @@ -152,7 +152,7 @@ func (notifier *ThreemaNotifier) Notify(evalContext *alerting.EvalContext) error headers := map[string]string{ "Content-Type": "application/x-www-form-urlencoded", } - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: url, Body: body, HttpMethod: "POST", diff --git a/pkg/services/alerting/notifiers/victorops.go b/pkg/services/alerting/notifiers/victorops.go index 9cc1416c911..f2904ca39e6 100644 --- a/pkg/services/alerting/notifiers/victorops.go +++ b/pkg/services/alerting/notifiers/victorops.go @@ -154,7 +154,7 @@ func (vn *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error { } data, _ := bodyJSON.MarshalJSON() - cmd := &models.SendWebhookSync{Url: vn.URL, Body: string(data)} + cmd := ¬ifications.SendWebhookSync{Url: vn.URL, Body: string(data)} if err := vn.NotificationService.SendWebhookSync(evalContext.Ctx, cmd); err != nil { vn.log.Error("Failed to send Victorops notification", "error", err, "webhook", vn.Name) diff --git a/pkg/services/alerting/notifiers/webhook.go b/pkg/services/alerting/notifiers/webhook.go index 5ec1659718b..4baade18f5c 100644 --- a/pkg/services/alerting/notifiers/webhook.go +++ b/pkg/services/alerting/notifiers/webhook.go @@ -145,7 +145,7 @@ func (wn *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON, _ := json.Marshal(body) - cmd := &models.SendWebhookSync{ + cmd := ¬ifications.SendWebhookSync{ Url: wn.URL, User: wn.User, Password: wn.Password, diff --git a/pkg/services/ngalert/notifier/email_test.go b/pkg/services/ngalert/notifier/email_test.go index e1428ed8c17..19c659c3fb5 100644 --- a/pkg/services/ngalert/notifier/email_test.go +++ b/pkg/services/ngalert/notifier/email_test.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/infra/tracing" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/setting" ) @@ -240,15 +239,15 @@ func (e emailSender) SendWebhook(ctx context.Context, cmd *channels.SendWebhookS } func (e emailSender) SendEmail(ctx context.Context, cmd *channels.SendEmailSettings) error { - attached := make([]*models.SendEmailAttachFile, 0, len(cmd.AttachedFiles)) + attached := make([]*notifications.SendEmailAttachFile, 0, len(cmd.AttachedFiles)) for _, file := range cmd.AttachedFiles { - attached = append(attached, &models.SendEmailAttachFile{ + attached = append(attached, ¬ifications.SendEmailAttachFile{ Name: file.Name, Content: file.Content, }) } - return e.ns.SendEmailCommandHandlerSync(ctx, &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + return e.ns.SendEmailCommandHandlerSync(ctx, ¬ifications.SendEmailCommandSync{ + SendEmailCommand: notifications.SendEmailCommand{ To: cmd.To, SingleEmail: cmd.SingleEmail, Template: cmd.Template, diff --git a/pkg/services/ngalert/notifier/sender.go b/pkg/services/ngalert/notifier/sender.go index fd53694b399..fd016cabec9 100644 --- a/pkg/services/ngalert/notifier/sender.go +++ b/pkg/services/ngalert/notifier/sender.go @@ -5,7 +5,6 @@ import ( "github.com/grafana/alerting/alerting/notifier/channels" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/notifications" ) @@ -14,7 +13,7 @@ type sender struct { } func (s sender) SendWebhook(ctx context.Context, cmd *channels.SendWebhookSettings) error { - return s.ns.SendWebhookSync(ctx, &models.SendWebhookSync{ + return s.ns.SendWebhookSync(ctx, ¬ifications.SendWebhookSync{ Url: cmd.URL, User: cmd.User, Password: cmd.Password, @@ -27,18 +26,18 @@ func (s sender) SendWebhook(ctx context.Context, cmd *channels.SendWebhookSettin } func (s sender) SendEmail(ctx context.Context, cmd *channels.SendEmailSettings) error { - var attached []*models.SendEmailAttachFile + var attached []*notifications.SendEmailAttachFile if cmd.AttachedFiles != nil { - attached = make([]*models.SendEmailAttachFile, 0, len(cmd.AttachedFiles)) + attached = make([]*notifications.SendEmailAttachFile, 0, len(cmd.AttachedFiles)) for _, file := range cmd.AttachedFiles { - attached = append(attached, &models.SendEmailAttachFile{ + attached = append(attached, ¬ifications.SendEmailAttachFile{ Name: file.Name, Content: file.Content, }) } } - return s.ns.SendEmailCommandHandlerSync(ctx, &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + return s.ns.SendEmailCommandHandlerSync(ctx, ¬ifications.SendEmailCommandSync{ + SendEmailCommand: notifications.SendEmailCommand{ To: cmd.To, SingleEmail: cmd.SingleEmail, Template: cmd.Template, diff --git a/pkg/services/notifications/mailer.go b/pkg/services/notifications/mailer.go index 1ba3b85e40a..827e2f4973e 100644 --- a/pkg/services/notifications/mailer.go +++ b/pkg/services/notifications/mailer.go @@ -10,7 +10,6 @@ import ( "html/template" "net/mail" - "github.com/grafana/grafana/pkg/models" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) @@ -54,9 +53,9 @@ func (ns *NotificationService) Send(msg *Message) (int, error) { return ns.mailer.Send(messages...) } -func (ns *NotificationService) buildEmailMessage(cmd *models.SendEmailCommand) (*Message, error) { +func (ns *NotificationService) buildEmailMessage(cmd *SendEmailCommand) (*Message, error) { if !ns.Cfg.Smtp.Enabled { - return nil, models.ErrSmtpNotEnabled + return nil, ErrSmtpNotEnabled } data := cmd.Data @@ -120,7 +119,7 @@ func (ns *NotificationService) buildEmailMessage(cmd *models.SendEmailCommand) ( // buildAttachedFiles build attached files func buildAttachedFiles( - attached []*models.SendEmailAttachFile, + attached []*SendEmailAttachFile, ) []*AttachedFile { result := make([]*AttachedFile, 0) diff --git a/pkg/services/notifications/mock.go b/pkg/services/notifications/mock.go index 14229fc797d..2e874ad6570 100644 --- a/pkg/services/notifications/mock.go +++ b/pkg/services/notifications/mock.go @@ -2,22 +2,20 @@ package notifications import ( "context" - - "github.com/grafana/grafana/pkg/models" ) type NotificationServiceMock struct { - Webhook models.SendWebhookSync - EmailSync models.SendEmailCommandSync - Email models.SendEmailCommand + Webhook SendWebhookSync + EmailSync SendEmailCommandSync + Email SendEmailCommand ShouldError error - WebhookHandler func(context.Context, *models.SendWebhookSync) error - EmailHandlerSync func(context.Context, *models.SendEmailCommandSync) error - EmailHandler func(context.Context, *models.SendEmailCommand) error + WebhookHandler func(context.Context, *SendWebhookSync) error + EmailHandlerSync func(context.Context, *SendEmailCommandSync) error + EmailHandler func(context.Context, *SendEmailCommand) error } -func (ns *NotificationServiceMock) SendWebhookSync(ctx context.Context, cmd *models.SendWebhookSync) error { +func (ns *NotificationServiceMock) SendWebhookSync(ctx context.Context, cmd *SendWebhookSync) error { ns.Webhook = *cmd if ns.WebhookHandler != nil { return ns.WebhookHandler(ctx, cmd) @@ -25,7 +23,7 @@ func (ns *NotificationServiceMock) SendWebhookSync(ctx context.Context, cmd *mod return ns.ShouldError } -func (ns *NotificationServiceMock) SendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error { +func (ns *NotificationServiceMock) SendEmailCommandHandlerSync(ctx context.Context, cmd *SendEmailCommandSync) error { ns.EmailSync = *cmd if ns.EmailHandlerSync != nil { return ns.EmailHandlerSync(ctx, cmd) @@ -33,7 +31,7 @@ func (ns *NotificationServiceMock) SendEmailCommandHandlerSync(ctx context.Conte return ns.ShouldError } -func (ns *NotificationServiceMock) SendEmailCommandHandler(ctx context.Context, cmd *models.SendEmailCommand) error { +func (ns *NotificationServiceMock) SendEmailCommandHandler(ctx context.Context, cmd *SendEmailCommand) error { ns.Email = *cmd if ns.EmailHandler != nil { return ns.EmailHandler(ctx, cmd) diff --git a/pkg/models/notifications.go b/pkg/services/notifications/models.go similarity index 98% rename from pkg/models/notifications.go rename to pkg/services/notifications/models.go index 159d6a04edb..117f354ce82 100644 --- a/pkg/models/notifications.go +++ b/pkg/services/notifications/models.go @@ -1,4 +1,4 @@ -package models +package notifications import ( "errors" diff --git a/pkg/services/notifications/notifications.go b/pkg/services/notifications/notifications.go index bca81599d79..f481f8b355d 100644 --- a/pkg/services/notifications/notifications.go +++ b/pkg/services/notifications/notifications.go @@ -10,10 +10,10 @@ import ( "strings" "github.com/Masterminds/sprig/v3" + "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/models" tempuser "github.com/grafana/grafana/pkg/services/temp_user" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" @@ -21,11 +21,11 @@ import ( ) type WebhookSender interface { - SendWebhookSync(ctx context.Context, cmd *models.SendWebhookSync) error + SendWebhookSync(ctx context.Context, cmd *SendWebhookSync) error } type EmailSender interface { - SendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error - SendEmailCommandHandler(ctx context.Context, cmd *models.SendEmailCommand) error + SendEmailCommandHandlerSync(ctx context.Context, cmd *SendEmailCommandSync) error + SendEmailCommandHandler(ctx context.Context, cmd *SendEmailCommand) error } type Service interface { WebhookSender @@ -130,7 +130,7 @@ func (ns *NotificationService) GetMailer() Mailer { return ns.mailer } -func (ns *NotificationService) SendWebhookSync(ctx context.Context, cmd *models.SendWebhookSync) error { +func (ns *NotificationService) SendWebhookSync(ctx context.Context, cmd *SendWebhookSync) error { return ns.sendWebRequestSync(ctx, &Webhook{ Url: cmd.Url, User: cmd.User, @@ -148,8 +148,8 @@ func subjectTemplateFunc(obj map[string]interface{}, value string) string { return "" } -func (ns *NotificationService) SendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error { - message, err := ns.buildEmailMessage(&models.SendEmailCommand{ +func (ns *NotificationService) SendEmailCommandHandlerSync(ctx context.Context, cmd *SendEmailCommandSync) error { + message, err := ns.buildEmailMessage(&SendEmailCommand{ Data: cmd.Data, Info: cmd.Info, Template: cmd.Template, @@ -169,7 +169,7 @@ func (ns *NotificationService) SendEmailCommandHandlerSync(ctx context.Context, return err } -func (ns *NotificationService) SendEmailCommandHandler(ctx context.Context, cmd *models.SendEmailCommand) error { +func (ns *NotificationService) SendEmailCommandHandler(ctx context.Context, cmd *SendEmailCommand) error { message, err := ns.buildEmailMessage(cmd) if err != nil { @@ -180,12 +180,12 @@ func (ns *NotificationService) SendEmailCommandHandler(ctx context.Context, cmd return nil } -func (ns *NotificationService) SendResetPasswordEmail(ctx context.Context, cmd *models.SendResetPasswordEmailCommand) error { +func (ns *NotificationService) SendResetPasswordEmail(ctx context.Context, cmd *SendResetPasswordEmailCommand) error { code, err := createUserEmailCode(ns.Cfg, cmd.User, "") if err != nil { return err } - return ns.SendEmailCommandHandler(ctx, &models.SendEmailCommand{ + return ns.SendEmailCommandHandler(ctx, &SendEmailCommand{ To: []string{cmd.User.Email}, Template: tmplResetPassword, Data: map[string]interface{}{ @@ -197,10 +197,10 @@ func (ns *NotificationService) SendResetPasswordEmail(ctx context.Context, cmd * type GetUserByLoginFunc = func(c context.Context, login string) (*user.User, error) -func (ns *NotificationService) ValidateResetPasswordCode(ctx context.Context, query *models.ValidateResetPasswordCodeQuery, userByLogin GetUserByLoginFunc) error { +func (ns *NotificationService) ValidateResetPasswordCode(ctx context.Context, query *ValidateResetPasswordCodeQuery, userByLogin GetUserByLoginFunc) error { login := getLoginForEmailCode(query.Code) if login == "" { - return models.ErrInvalidEmailCode + return ErrInvalidEmailCode } user, err := userByLogin(ctx, login) @@ -213,7 +213,7 @@ func (ns *NotificationService) ValidateResetPasswordCode(ctx context.Context, qu return err } if !validEmailCode { - return models.ErrInvalidEmailCode + return ErrInvalidEmailCode } query.Result = user @@ -231,7 +231,7 @@ func (ns *NotificationService) signUpStartedHandler(ctx context.Context, evt *ev return nil } - err := ns.SendEmailCommandHandler(ctx, &models.SendEmailCommand{ + err := ns.SendEmailCommandHandler(ctx, &SendEmailCommand{ To: []string{evt.Email}, Template: tmplSignUpStarted, Data: map[string]interface{}{ @@ -254,7 +254,7 @@ func (ns *NotificationService) signUpCompletedHandler(ctx context.Context, evt * return nil } - return ns.SendEmailCommandHandler(ctx, &models.SendEmailCommand{ + return ns.SendEmailCommandHandler(ctx, &SendEmailCommand{ To: []string{evt.Email}, Template: tmplWelcomeOnSignUp, Data: map[string]interface{}{ diff --git a/pkg/services/notifications/notifications_test.go b/pkg/services/notifications/notifications_test.go index 48ee121127d..4254a8f93a5 100644 --- a/pkg/services/notifications/notifications_test.go +++ b/pkg/services/notifications/notifications_test.go @@ -5,13 +5,13 @@ import ( "regexp" "testing" - "github.com/grafana/grafana/pkg/bus" - "github.com/grafana/grafana/pkg/infra/tracing" - "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/user" - "github.com/grafana/grafana/pkg/setting" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/services/user" + "github.com/grafana/grafana/pkg/setting" ) func newBus(t *testing.T) bus.Bus { @@ -53,8 +53,8 @@ func TestSendEmailSync(t *testing.T) { t.Run("When sending emails synchronously", func(t *testing.T) { ns, mailer := createSut(t, bus) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"asdf@grafana.com"}, SingleEmail: false, @@ -72,8 +72,8 @@ func TestSendEmailSync(t *testing.T) { t.Run("When using Single Email mode with multiple recipients", func(t *testing.T) { ns, mailer := createSut(t, bus) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: true, @@ -89,8 +89,8 @@ func TestSendEmailSync(t *testing.T) { t.Run("When using Multi Email mode with multiple recipients", func(t *testing.T) { ns, mailer := createSut(t, bus) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: false, @@ -106,13 +106,13 @@ func TestSendEmailSync(t *testing.T) { t.Run("When attaching files to emails", func(t *testing.T) { ns, mailer := createSut(t, bus) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"asdf@grafana.com"}, SingleEmail: true, Template: "welcome_on_signup", - AttachedFiles: []*models.SendEmailAttachFile{ + AttachedFiles: []*SendEmailAttachFile{ { Name: "attachment.txt", Content: []byte("text file content"), @@ -137,8 +137,8 @@ func TestSendEmailSync(t *testing.T) { cfg.Smtp.Enabled = false ns, mailer, err := createSutWithConfig(t, bus, cfg) require.NoError(t, err) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: true, @@ -148,7 +148,7 @@ func TestSendEmailSync(t *testing.T) { err = ns.SendEmailCommandHandlerSync(context.Background(), cmd) - require.ErrorIs(t, err, models.ErrSmtpNotEnabled) + require.ErrorIs(t, err, ErrSmtpNotEnabled) require.Empty(t, mailer.Sent) }) @@ -157,8 +157,8 @@ func TestSendEmailSync(t *testing.T) { cfg.Smtp.ContentTypes = append(cfg.Smtp.ContentTypes, "multipart/form-data") ns, mailer, err := createSutWithConfig(t, bus, cfg) require.NoError(t, err) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: false, @@ -174,8 +174,8 @@ func TestSendEmailSync(t *testing.T) { t.Run("When SMTP dialer is disconnected", func(t *testing.T) { ns := createDisconnectedSut(t, bus) - cmd := &models.SendEmailCommandSync{ - SendEmailCommand: models.SendEmailCommand{ + cmd := &SendEmailCommandSync{ + SendEmailCommand: SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: false, @@ -195,7 +195,7 @@ func TestSendEmailAsync(t *testing.T) { t.Run("When sending reset email password", func(t *testing.T) { sut, _ := createSut(t, bus) testuser := user.User{Email: "asd@asd.com", Login: "asd@asd.com"} - err := sut.SendResetPasswordEmail(context.Background(), &models.SendResetPasswordEmailCommand{User: &testuser}) + err := sut.SendResetPasswordEmail(context.Background(), &SendResetPasswordEmailCommand{User: &testuser}) require.NoError(t, err) @@ -212,7 +212,7 @@ func TestSendEmailAsync(t *testing.T) { code := match[len("code="):] // verify code - query := models.ValidateResetPasswordCodeQuery{Code: code} + query := ValidateResetPasswordCodeQuery{Code: code} getUserByLogin := func(ctx context.Context, login string) (*user.User, error) { return &testuser, nil } @@ -225,7 +225,7 @@ func TestSendEmailAsync(t *testing.T) { cfg.Smtp.Enabled = false ns, mailer, err := createSutWithConfig(t, bus, cfg) require.NoError(t, err) - cmd := &models.SendEmailCommand{ + cmd := &SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: true, @@ -234,7 +234,7 @@ func TestSendEmailAsync(t *testing.T) { err = ns.SendEmailCommandHandler(context.Background(), cmd) - require.ErrorIs(t, err, models.ErrSmtpNotEnabled) + require.ErrorIs(t, err, ErrSmtpNotEnabled) require.Empty(t, mailer.Sent) }) @@ -243,7 +243,7 @@ func TestSendEmailAsync(t *testing.T) { cfg.Smtp.ContentTypes = append(cfg.Smtp.ContentTypes, "multipart/form-data") ns, mailer, err := createSutWithConfig(t, bus, cfg) require.NoError(t, err) - cmd := &models.SendEmailCommand{ + cmd := &SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: false, @@ -258,7 +258,7 @@ func TestSendEmailAsync(t *testing.T) { t.Run("When SMTP dialer is disconnected", func(t *testing.T) { ns := createDisconnectedSut(t, bus) - cmd := &models.SendEmailCommand{ + cmd := &SendEmailCommand{ Subject: "subject", To: []string{"1@grafana.com", "2@grafana.com", "3@grafana.com"}, SingleEmail: false, diff --git a/pkg/services/notifications/send_email_integration_test.go b/pkg/services/notifications/send_email_integration_test.go index a33d2781fa4..99f0cee48ab 100644 --- a/pkg/services/notifications/send_email_integration_test.go +++ b/pkg/services/notifications/send_email_integration_test.go @@ -5,7 +5,6 @@ import ( "os" "testing" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" "github.com/stretchr/testify/require" @@ -28,7 +27,7 @@ func TestEmailIntegrationTest(t *testing.T) { ns.Cfg.Smtp.ContentTypes = []string{"text/html", "text/plain"} t.Run("When sending reset email password", func(t *testing.T) { - cmd := &models.SendEmailCommand{ + cmd := &SendEmailCommand{ Data: map[string]interface{}{ "Title": "[CRITICAL] Imaginary timeseries alert", diff --git a/pkg/tests/api/alerting/api_notification_channel_test.go b/pkg/tests/api/alerting/api_notification_channel_test.go index 0a90e4ec626..7396e24dbaf 100644 --- a/pkg/tests/api/alerting/api_notification_channel_test.go +++ b/pkg/tests/api/alerting/api_notification_channel_test.go @@ -22,10 +22,10 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/models" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/store" + "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" @@ -740,7 +740,7 @@ func TestIntegrationNotificationChannels(t *testing.T) { env.NotificationService.EmailHandlerSync = mockEmail.sendEmailCommandHandlerSync // As we are using a NotificationService mock here, but the test expects real NotificationService - // we try to issue a real POST request here - env.NotificationService.WebhookHandler = func(_ context.Context, cmd *models.SendWebhookSync) error { + env.NotificationService.WebhookHandler = func(_ context.Context, cmd *notifications.SendWebhookSync) error { if res, err := http.Post(cmd.Url, "", strings.NewReader(cmd.Body)); err == nil { _ = res.Body.Close() } @@ -1165,10 +1165,10 @@ func (nc *mockNotificationChannel) Close() error { } type mockEmailHandler struct { - emails []*models.SendEmailCommandSync + emails []*notifications.SendEmailCommandSync } -func (e *mockEmailHandler) sendEmailCommandHandlerSync(_ context.Context, cmd *models.SendEmailCommandSync) error { +func (e *mockEmailHandler) sendEmailCommandHandlerSync(_ context.Context, cmd *notifications.SendEmailCommandSync) error { // We 0 out the start time since that is a variable that we cannot predict. alerts := cmd.Data["Alerts"].(channels.ExtendedAlerts) for i := range alerts { @@ -1185,7 +1185,7 @@ type mockEmailHandlerWithTimeout struct { timeout time.Duration } -func (e *mockEmailHandlerWithTimeout) sendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error { +func (e *mockEmailHandlerWithTimeout) sendEmailCommandHandlerSync(ctx context.Context, cmd *notifications.SendEmailCommandSync) error { select { case <-time.After(e.timeout): return e.mockEmailHandler.sendEmailCommandHandlerSync(ctx, cmd) @@ -2280,9 +2280,9 @@ var expAlertmanagerConfigFromAPI = ` } ` -var expEmailNotifications = []*models.SendEmailCommandSync{ +var expEmailNotifications = []*notifications.SendEmailCommandSync{ { - SendEmailCommand: models.SendEmailCommand{ + SendEmailCommand: notifications.SendEmailCommand{ To: []string{"test@email.com"}, SingleEmail: true, Template: "ng_alert_notification",