Remove bus from org invite api (#44530)

* Remove bus from org invite api

* Fix lint

* Remove comment
pull/44669/head
idafurjes 4 years ago committed by GitHub
parent 7ed82ac049
commit 12420260ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      pkg/api/api.go
  2. 46
      pkg/api/org_invite.go
  3. 4
      pkg/api/signup.go
  4. 10
      pkg/services/ngalert/notifier/channels/email_test.go
  5. 9
      pkg/services/ngalert/notifier/channels/testing.go
  6. 17
      pkg/services/notifications/mock.go
  7. 11
      pkg/services/notifications/notifications.go
  8. 2
      pkg/services/notifications/send_email_integration_test.go
  9. 622
      pkg/tests/api/alerting/api_notification_channel_test.go

@ -120,7 +120,7 @@ func (hs *HTTPServer) registerRoutes() {
r.Post("/api/user/signup/step2", routing.Wrap(hs.SignUpStep2))
// invited
r.Get("/api/user/invite/:code", routing.Wrap(GetInviteInfoByCode))
r.Get("/api/user/invite/:code", routing.Wrap(hs.GetInviteInfoByCode))
r.Post("/api/user/invite/complete", routing.Wrap(hs.CompleteInvite))
// reset password
@ -216,9 +216,9 @@ func (hs *HTTPServer) registerRoutes() {
orgRoute.Delete("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRemove, userIDScope)), routing.Wrap(hs.RemoveOrgUserForCurrentOrg))
// invites
orgRoute.Get("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionUsersCreate)), routing.Wrap(GetPendingOrgInvites))
orgRoute.Post("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionUsersCreate)), quota("user"), routing.Wrap(AddOrgInvite))
orgRoute.Patch("/invites/:code/revoke", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionUsersCreate)), routing.Wrap(RevokeInvite))
orgRoute.Get("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionUsersCreate)), routing.Wrap(hs.GetPendingOrgInvites))
orgRoute.Post("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionUsersCreate)), quota("user"), routing.Wrap(hs.AddOrgInvite))
orgRoute.Patch("/invites/:code/revoke", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionUsersCreate)), routing.Wrap(hs.RevokeInvite))
// prefs
orgRoute.Get("/preferences", authorize(reqOrgAdmin, ac.EvalPermission(ActionOrgsPreferencesRead)), routing.Wrap(hs.GetOrgPreferences))

@ -17,10 +17,10 @@ import (
"github.com/grafana/grafana/pkg/web"
)
func GetPendingOrgInvites(c *models.ReqContext) response.Response {
func (hs *HTTPServer) GetPendingOrgInvites(c *models.ReqContext) response.Response {
query := models.GetTempUsersQuery{OrgId: c.OrgId, Status: models.TmpUserInvitePending}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
if err := hs.SQLStore.GetTempUsersQuery(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to get invites from db", err)
}
@ -31,7 +31,7 @@ func GetPendingOrgInvites(c *models.ReqContext) response.Response {
return response.JSON(200, query.Result)
}
func AddOrgInvite(c *models.ReqContext) response.Response {
func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response {
inviteDto := dtos.AddInviteForm{}
if err := web.Bind(c.Req, &inviteDto); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
@ -42,12 +42,12 @@ func AddOrgInvite(c *models.ReqContext) response.Response {
// first try get existing user
userQuery := models.GetUserByLoginQuery{LoginOrEmail: inviteDto.LoginOrEmail}
if err := bus.Dispatch(c.Req.Context(), &userQuery); err != nil {
if err := hs.SQLStore.GetUserByLogin(c.Req.Context(), &userQuery); err != nil {
if !errors.Is(err, models.ErrUserNotFound) {
return response.Error(500, "Failed to query db for existing user check", err)
}
} else {
return inviteExistingUserToOrg(c, userQuery.Result, &inviteDto)
return hs.inviteExistingUserToOrg(c, userQuery.Result, &inviteDto)
}
if setting.DisableLoginForm {
@ -68,7 +68,7 @@ func AddOrgInvite(c *models.ReqContext) response.Response {
cmd.Role = inviteDto.Role
cmd.RemoteAddr = c.Req.RemoteAddr
if err := bus.Dispatch(c.Req.Context(), &cmd); err != nil {
if err := hs.SQLStore.CreateTempUser(c.Req.Context(), &cmd); err != nil {
return response.Error(500, "Failed to save invite to database", err)
}
@ -86,7 +86,7 @@ func AddOrgInvite(c *models.ReqContext) response.Response {
},
}
if err := bus.Dispatch(c.Req.Context(), &emailCmd); err != nil {
if err := hs.AlertNG.NotificationService.SendEmailCommandHandler(c.Req.Context(), &emailCmd); err != nil {
if errors.Is(err, models.ErrSmtpNotEnabled) {
return response.Error(412, err.Error(), err)
}
@ -95,7 +95,7 @@ func AddOrgInvite(c *models.ReqContext) response.Response {
}
emailSentCmd := models.UpdateTempUserWithEmailSentCommand{Code: cmd.Result.Code}
if err := bus.Dispatch(c.Req.Context(), &emailSentCmd); err != nil {
if err := hs.SQLStore.UpdateTempUserWithEmailSent(c.Req.Context(), &emailSentCmd); err != nil {
return response.Error(500, "Failed to update invite with email sent info", err)
}
@ -105,10 +105,10 @@ func AddOrgInvite(c *models.ReqContext) response.Response {
return response.Success(fmt.Sprintf("Created invite for %s", inviteDto.LoginOrEmail))
}
func inviteExistingUserToOrg(c *models.ReqContext, user *models.User, inviteDto *dtos.AddInviteForm) response.Response {
func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *models.User, inviteDto *dtos.AddInviteForm) response.Response {
// user exists, add org role
createOrgUserCmd := models.AddOrgUserCommand{OrgId: c.OrgId, UserId: user.Id, Role: inviteDto.Role}
if err := bus.Dispatch(c.Req.Context(), &createOrgUserCmd); err != nil {
if err := hs.SQLStore.AddOrgUser(c.Req.Context(), &createOrgUserCmd); err != nil {
if errors.Is(err, models.ErrOrgUserAlreadyAdded) {
return response.Error(412, fmt.Sprintf("User %s is already added to organization", inviteDto.LoginOrEmail), err)
}
@ -126,7 +126,7 @@ func inviteExistingUserToOrg(c *models.ReqContext, user *models.User, inviteDto
},
}
if err := bus.Dispatch(c.Req.Context(), &emailCmd); err != nil {
if err := hs.AlertNG.NotificationService.SendEmailCommandHandler(c.Req.Context(), &emailCmd); err != nil {
return response.Error(500, "Failed to send email invited_to_org", err)
}
}
@ -137,8 +137,8 @@ func inviteExistingUserToOrg(c *models.ReqContext, user *models.User, inviteDto
})
}
func RevokeInvite(c *models.ReqContext) response.Response {
if ok, rsp := updateTempUserStatus(c.Req.Context(), web.Params(c.Req)[":code"], models.TmpUserRevoked); !ok {
func (hs *HTTPServer) RevokeInvite(c *models.ReqContext) response.Response {
if ok, rsp := hs.updateTempUserStatus(c.Req.Context(), web.Params(c.Req)[":code"], models.TmpUserRevoked); !ok {
return rsp
}
@ -148,9 +148,9 @@ func RevokeInvite(c *models.ReqContext) response.Response {
// GetInviteInfoByCode gets a pending user invite corresponding to a certain code.
// A response containing an InviteInfo object is returned if the invite is found.
// If a (pending) invite is not found, 404 is returned.
func GetInviteInfoByCode(c *models.ReqContext) response.Response {
func (hs *HTTPServer) GetInviteInfoByCode(c *models.ReqContext) response.Response {
query := models.GetTempUserByCodeQuery{Code: web.Params(c.Req)[":code"]}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
if err := hs.SQLStore.GetTempUserByCode(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrTempUserNotFound) {
return response.Error(404, "Invite not found", nil)
}
@ -177,7 +177,7 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
}
query := models.GetTempUserByCodeQuery{Code: completeInvite.InviteCode}
if err := bus.Dispatch(c.Req.Context(), &query); err != nil {
if err := hs.SQLStore.GetTempUserByCode(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrTempUserNotFound) {
return response.Error(404, "Invite not found", nil)
}
@ -213,7 +213,7 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
return response.Error(500, "failed to publish event", err)
}
if ok, rsp := applyUserInvite(c.Req.Context(), user, invite, true); !ok {
if ok, rsp := hs.applyUserInvite(c.Req.Context(), user, invite, true); !ok {
return rsp
}
@ -231,33 +231,33 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
})
}
func updateTempUserStatus(ctx context.Context, code string, status models.TempUserStatus) (bool, response.Response) {
func (hs *HTTPServer) updateTempUserStatus(ctx context.Context, code string, status models.TempUserStatus) (bool, response.Response) {
// update temp user status
updateTmpUserCmd := models.UpdateTempUserStatusCommand{Code: code, Status: status}
if err := bus.Dispatch(ctx, &updateTmpUserCmd); err != nil {
if err := hs.SQLStore.UpdateTempUserStatus(ctx, &updateTmpUserCmd); err != nil {
return false, response.Error(500, "Failed to update invite status", err)
}
return true, nil
}
func applyUserInvite(ctx context.Context, user *models.User, invite *models.TempUserDTO, setActive bool) (bool, response.Response) {
func (hs *HTTPServer) applyUserInvite(ctx context.Context, user *models.User, invite *models.TempUserDTO, setActive bool) (bool, response.Response) {
// add to org
addOrgUserCmd := models.AddOrgUserCommand{OrgId: invite.OrgId, UserId: user.Id, Role: invite.Role}
if err := bus.Dispatch(ctx, &addOrgUserCmd); err != nil {
if err := hs.SQLStore.AddOrgUser(ctx, &addOrgUserCmd); err != nil {
if !errors.Is(err, models.ErrOrgUserAlreadyAdded) {
return false, response.Error(500, "Error while trying to create org user", err)
}
}
// update temp user status
if ok, rsp := updateTempUserStatus(ctx, invite.Code, models.TmpUserCompleted); !ok {
if ok, rsp := hs.updateTempUserStatus(ctx, invite.Code, models.TmpUserCompleted); !ok {
return false, rsp
}
if setActive {
// set org to active
if err := bus.Dispatch(ctx, &models.SetUsingOrgCommand{OrgId: invite.OrgId, UserId: user.Id}); err != nil {
if err := hs.SQLStore.SetUsingOrg(ctx, &models.SetUsingOrgCommand{OrgId: invite.OrgId, UserId: user.Id}); err != nil {
return false, response.Error(500, "Failed to set org as active", err)
}
}

@ -110,7 +110,7 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response {
}
// mark temp user as completed
if ok, rsp := updateTempUserStatus(c.Req.Context(), form.Code, models.TmpUserCompleted); !ok {
if ok, rsp := hs.updateTempUserStatus(c.Req.Context(), form.Code, models.TmpUserCompleted); !ok {
return rsp
}
@ -122,7 +122,7 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response {
apiResponse := util.DynMap{"message": "User sign up completed successfully", "code": "redirect-to-landing-page"}
for _, invite := range invitesQuery.Result {
if ok, rsp := applyUserInvite(c.Req.Context(), user, invite, false); !ok {
if ok, rsp := hs.applyUserInvite(c.Req.Context(), user, invite, false); !ok {
return rsp
}
apiResponse["code"] = "redirect-to-select-org"

@ -66,11 +66,11 @@ func TestEmailNotifier(t *testing.T) {
require.True(t, ok)
expected := map[string]interface{}{
"subject": emailSender.Email.Subject,
"to": emailSender.Email.To,
"single_email": emailSender.Email.SingleEmail,
"template": emailSender.Email.Template,
"data": emailSender.Email.Data,
"subject": emailSender.EmailSync.Subject,
"to": emailSender.EmailSync.To,
"single_email": emailSender.EmailSync.SingleEmail,
"template": emailSender.EmailSync.Template,
"data": emailSender.EmailSync.Data,
}
require.Equal(t, map[string]interface{}{
"subject": "[FIRING:1] (AlwaysFiring warning)",

@ -29,7 +29,8 @@ func resetTimeNow() {
type notificationServiceMock struct {
Webhook models.SendWebhookSync
Email models.SendEmailCommandSync
EmailSync models.SendEmailCommandSync
Emailx models.SendEmailCommand
ShouldError error
}
@ -38,7 +39,11 @@ func (ns *notificationServiceMock) SendWebhookSync(ctx context.Context, cmd *mod
return ns.ShouldError
}
func (ns *notificationServiceMock) SendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error {
ns.Email = *cmd
ns.EmailSync = *cmd
return ns.ShouldError
}
func (ns *notificationServiceMock) SendEmailCommandHandler(ctx context.Context, cmd *models.SendEmailCommand) error {
ns.Emailx = *cmd
return ns.ShouldError
}

@ -8,11 +8,13 @@ import (
type NotificationServiceMock struct {
Webhook models.SendWebhookSync
Email models.SendEmailCommandSync
EmailSync models.SendEmailCommandSync
Email models.SendEmailCommand
ShouldError error
WebhookHandler func(context.Context, *models.SendWebhookSync) error
EmailHandler func(context.Context, *models.SendEmailCommandSync) error
WebhookHandler func(context.Context, *models.SendWebhookSync) error
EmailHandlerSync func(context.Context, *models.SendEmailCommandSync) error
EmailHandler func(context.Context, *models.SendEmailCommand) error
}
func (ns *NotificationServiceMock) SendWebhookSync(ctx context.Context, cmd *models.SendWebhookSync) error {
@ -22,7 +24,16 @@ func (ns *NotificationServiceMock) SendWebhookSync(ctx context.Context, cmd *mod
}
return ns.ShouldError
}
func (ns *NotificationServiceMock) SendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error {
ns.EmailSync = *cmd
if ns.EmailHandlerSync != nil {
return ns.EmailHandlerSync(ctx, cmd)
}
return ns.ShouldError
}
func (ns *NotificationServiceMock) SendEmailCommandHandler(ctx context.Context, cmd *models.SendEmailCommand) error {
ns.Email = *cmd
if ns.EmailHandler != nil {
return ns.EmailHandler(ctx, cmd)

@ -22,6 +22,7 @@ type WebhookSender interface {
}
type EmailSender interface {
SendEmailCommandHandlerSync(ctx context.Context, cmd *models.SendEmailCommandSync) error
SendEmailCommandHandler(ctx context.Context, cmd *models.SendEmailCommand) error
}
type Service interface {
WebhookSender
@ -45,7 +46,7 @@ func ProvideService(bus bus.Bus, cfg *setting.Cfg, mailer Mailer) (*Notification
ns.Bus.AddHandler(ns.sendResetPasswordEmail)
ns.Bus.AddHandler(ns.validateResetPasswordCode)
ns.Bus.AddHandler(ns.sendEmailCommandHandler)
ns.Bus.AddHandler(ns.SendEmailCommandHandler)
ns.Bus.AddHandler(ns.SendEmailCommandHandlerSync)
ns.Bus.AddHandler(ns.SendWebhookSync)
@ -151,7 +152,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 *models.SendEmailCommand) error {
message, err := ns.buildEmailMessage(cmd)
if err != nil {
@ -167,7 +168,7 @@ func (ns *NotificationService) sendResetPasswordEmail(ctx context.Context, cmd *
if err != nil {
return err
}
return ns.sendEmailCommandHandler(ctx, &models.SendEmailCommand{
return ns.SendEmailCommandHandler(ctx, &models.SendEmailCommand{
To: []string{cmd.User.Email},
Template: tmplResetPassword,
Data: map[string]interface{}{
@ -211,7 +212,7 @@ func (ns *NotificationService) signUpStartedHandler(ctx context.Context, evt *ev
return nil
}
err := ns.sendEmailCommandHandler(ctx, &models.SendEmailCommand{
err := ns.SendEmailCommandHandler(ctx, &models.SendEmailCommand{
To: []string{evt.Email},
Template: tmplSignUpStarted,
Data: map[string]interface{}{
@ -234,7 +235,7 @@ func (ns *NotificationService) signUpCompletedHandler(ctx context.Context, evt *
return nil
}
return ns.sendEmailCommandHandler(ctx, &models.SendEmailCommand{
return ns.SendEmailCommandHandler(ctx, &models.SendEmailCommand{
To: []string{evt.Email},
Template: tmplWelcomeOnSignUp,
Data: map[string]interface{}{

@ -57,7 +57,7 @@ func TestEmailIntegrationTest(t *testing.T) {
Template: "alert_notification",
}
err := ns.sendEmailCommandHandler(context.Background(), cmd)
err := ns.SendEmailCommandHandler(context.Background(), cmd)
require.NoError(t, err)
sentMsg := <-ns.mailQueue

@ -53,8 +53,8 @@ func TestTestReceivers(t *testing.T) {
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
// nolint
resp := postRequest(t, testReceiversURL, `{
"receivers": []
}`, http.StatusBadRequest)
"receivers": []
}`, http.StatusBadRequest)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
@ -84,27 +84,27 @@ func TestTestReceivers(t *testing.T) {
})
mockEmails := &mockEmailHandler{}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
// nolint
resp := postRequest(t, testReceiversURL, `{
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses":"example@email.com"
},
"secureFields": {}
}
]
}]
}`, http.StatusOK)
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses":"example@email.com"
},
"secureFields": {}
}
]
}]
}`, http.StatusOK)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
@ -119,28 +119,28 @@ func TestTestReceivers(t *testing.T) {
require.Len(t, result.Receivers[0].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
require.JSONEq(t, expectedJSON, string(b))
@ -168,25 +168,25 @@ func TestTestReceivers(t *testing.T) {
})
mockEmails := &mockEmailHandler{}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
// nolint
resp := postRequest(t, testReceiversURL, `{
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {},
"secureFields": {}
}
]
}]
}`, http.StatusBadRequest)
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {},
"secureFields": {}
}
]
}]
}`, http.StatusBadRequest)
t.Cleanup(func() {
require.NoError(t, resp.Body.Close())
})
@ -200,29 +200,29 @@ func TestTestReceivers(t *testing.T) {
require.Len(t, result.Receivers[0].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "failed",
"error": "the receiver is invalid: failed to validate receiver \"receiver-1\" of type \"email\": could not find addresses in settings"
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "failed",
"error": "the receiver is invalid: failed to validate receiver \"receiver-1\" of type \"email\": could not find addresses in settings"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
require.JSONEq(t, expectedJSON, string(b))
@ -249,26 +249,26 @@ func TestTestReceivers(t *testing.T) {
mockEmails := &mockEmailHandlerWithTimeout{
timeout: 5 * time.Second,
}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
req, err := http.NewRequest(http.MethodPost, testReceiversURL, strings.NewReader(`{
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses":"example@email.com"
},
"secureFields": {}
}
]
}]
}`))
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses":"example@email.com"
},
"secureFields": {}
}
]
}]
}`))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Request-Timeout", "1")
@ -289,29 +289,29 @@ func TestTestReceivers(t *testing.T) {
require.Len(t, result.Receivers[0].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "failed",
"error": "the receiver timed out: context deadline exceeded"
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "failed",
"error": "the receiver timed out: context deadline exceeded"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
require.JSONEq(t, expectedJSON, string(b))
@ -338,38 +338,38 @@ func TestTestReceivers(t *testing.T) {
mockEmails := &mockEmailHandlerWithTimeout{
timeout: 5 * time.Second,
}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
req, err := http.NewRequest(http.MethodPost, testReceiversURL, strings.NewReader(`{
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {},
"secureFields": {}
}
]
}, {
"name":"receiver-2",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-2",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses":"example@email.com"
},
"secureFields": {}
}
]
}]
}`))
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-1",
"type": "email",
"disableResolveMessage": false,
"settings": {},
"secureFields": {}
}
]
}, {
"name":"receiver-2",
"grafana_managed_receiver_configs": [
{
"uid": "",
"name": "receiver-2",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses":"example@email.com"
},
"secureFields": {}
}
]
}]
}`))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Request-Timeout", "1")
@ -391,39 +391,39 @@ func TestTestReceivers(t *testing.T) {
require.Len(t, result.Receivers[1].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "failed",
"error": "the receiver is invalid: failed to validate receiver \"receiver-1\" of type \"email\": could not find addresses in settings"
}
]
}, {
"name":"receiver-2",
"grafana_managed_receiver_configs": [
{
"name": "receiver-2",
"uid": "%s",
"status": "failed",
"error": "the receiver timed out: context deadline exceeded"
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "failed",
"error": "the receiver is invalid: failed to validate receiver \"receiver-1\" of type \"email\": could not find addresses in settings"
}
]
}, {
"name":"receiver-2",
"grafana_managed_receiver_configs": [
{
"name": "receiver-2",
"uid": "%s",
"status": "failed",
"error": "the receiver timed out: context deadline exceeded"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.Receivers[1].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
@ -451,36 +451,36 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
})
mockEmails := &mockEmailHandler{}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
// nolint
resp := postRequest(t, testReceiversURL, `{
"alert": {
"annotations": {
"annotation1": "value1",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"label1": "value1"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid":"",
"name":"receiver-1",
"type":"email",
"disableResolveMessage":false,
"settings":{
"addresses":"example@email.com"
},
"secureFields":{}
"alert": {
"annotations": {
"annotation1": "value1",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"label1": "value1"
}
]
}]
}`, http.StatusOK)
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid":"",
"name":"receiver-1",
"type":"email",
"disableResolveMessage":false,
"settings":{
"addresses":"example@email.com"
},
"secureFields":{}
}
]
}]
}`, http.StatusOK)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
@ -495,30 +495,30 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
require.Len(t, result.Receivers[0].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"annotation1": "value1",
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana",
"label1": "value1"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
"alert": {
"annotations": {
"annotation1": "value1",
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana",
"label1": "value1"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
require.JSONEq(t, expectedJSON, string(b))
@ -546,33 +546,33 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
})
mockEmails := &mockEmailHandler{}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
// nolint
resp := postRequest(t, testReceiversURL, `{
"alert": {
"annotations": {
"summary": "This is a custom annotation",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid":"",
"name":"receiver-1",
"type":"email",
"disableResolveMessage":false,
"settings":{
"addresses":"example@email.com"
},
"secureFields":{}
"alert": {
"annotations": {
"summary": "This is a custom annotation",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
}
]
}]
}`, http.StatusOK)
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid":"",
"name":"receiver-1",
"type":"email",
"disableResolveMessage":false,
"settings":{
"addresses":"example@email.com"
},
"secureFields":{}
}
]
}]
}`, http.StatusOK)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
@ -587,28 +587,28 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
require.Len(t, result.Receivers[0].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"summary": "This is a custom annotation",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
"alert": {
"annotations": {
"summary": "This is a custom annotation",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "TestAlert",
"instance": "Grafana"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
require.JSONEq(t, expectedJSON, string(b))
@ -636,32 +636,32 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
})
mockEmails := &mockEmailHandler{}
env.NotificationService.EmailHandler = mockEmails.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmails.sendEmailCommandHandlerSync
testReceiversURL := fmt.Sprintf("http://grafana:password@%s/api/alertmanager/grafana/config/api/v1/receivers/test", grafanaListedAddr)
// nolint
resp := postRequest(t, testReceiversURL, `{
"alert": {
"labels": {
"alertname": "This is a custom label"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid":"",
"name":"receiver-1",
"type":"email",
"disableResolveMessage":false,
"settings":{
"addresses":"example@email.com"
},
"secureFields":{}
"alert": {
"labels": {
"alertname": "This is a custom label"
}
]
}]
}`, http.StatusOK)
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"uid":"",
"name":"receiver-1",
"type":"email",
"disableResolveMessage":false,
"settings":{
"addresses":"example@email.com"
},
"secureFields":{}
}
]
}]
}`, http.StatusOK)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
@ -676,28 +676,28 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
require.Len(t, result.Receivers[0].Configs, 1)
expectedJSON := fmt.Sprintf(`{
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "This is a custom label",
"instance": "Grafana"
}
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
"alert": {
"annotations": {
"summary": "Notification test",
"__value_string__": "[ metric='foo' labels={instance=bar} value=10 ]"
},
"labels": {
"alertname": "This is a custom label",
"instance": "Grafana"
}
]
}],
"notified_at": "%s"
}`,
},
"receivers": [{
"name":"receiver-1",
"grafana_managed_receiver_configs": [
{
"name": "receiver-1",
"uid": "%s",
"status": "ok"
}
]
}],
"notified_at": "%s"
}`,
result.Receivers[0].Configs[0].UID,
result.NotifiedAt.Format(time.RFC3339Nano))
require.JSONEq(t, expectedJSON, string(b))
@ -744,7 +744,7 @@ func TestNotificationChannels(t *testing.T) {
channels.ThreemaGwBaseURL = fmt.Sprintf("http://%s/threema_recv/threema_test", mockChannel.server.Addr)
channels.GetBoundary = func() string { return "abcd" }
env.NotificationService.EmailHandler = mockEmail.sendEmailCommandHandlerSync
env.NotificationService.EmailHandlerSync = mockEmail.sendEmailCommandHandlerSync
// As we are using a NotificationService mock here, but he test expects real NotificationService -
// we try to issue a real POST request here
env.NotificationService.WebhookHandler = func(_ context.Context, cmd *models.SendWebhookSync) error {

Loading…
Cancel
Save