2021-10-07 09:33:50 -05:00
|
|
|
package alerting
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-02-11 10:13:51 -06:00
|
|
|
"fmt"
|
2021-10-07 09:33:50 -05:00
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/models"
|
|
|
|
"github.com/grafana/grafana/pkg/services/encryption"
|
2022-02-03 06:26:05 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/notifications"
|
2021-10-07 09:33:50 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2022-05-24 10:02:47 -05:00
|
|
|
"github.com/grafana/grafana/pkg/util"
|
2021-10-07 09:33:50 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type AlertNotificationService struct {
|
2022-02-03 06:26:05 -06:00
|
|
|
SQLStore *sqlstore.SQLStore
|
|
|
|
EncryptionService encryption.Internal
|
|
|
|
NotificationService *notifications.NotificationService
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
2022-04-13 08:24:13 -05:00
|
|
|
func ProvideService(store *sqlstore.SQLStore, encryptionService encryption.Internal,
|
2022-02-03 06:26:05 -06:00
|
|
|
notificationService *notifications.NotificationService) *AlertNotificationService {
|
2021-10-07 09:33:50 -05:00
|
|
|
s := &AlertNotificationService{
|
2022-02-03 06:26:05 -06:00
|
|
|
SQLStore: store,
|
|
|
|
EncryptionService: encryptionService,
|
|
|
|
NotificationService: notificationService,
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) GetAlertNotifications(ctx context.Context, query *models.GetAlertNotificationsQuery) error {
|
|
|
|
return s.SQLStore.GetAlertNotifications(ctx, query)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *AlertNotificationService) CreateAlertNotificationCommand(ctx context.Context, cmd *models.CreateAlertNotificationCommand) error {
|
2022-05-24 10:02:47 -05:00
|
|
|
if util.IsShortUIDTooLong(cmd.Uid) {
|
|
|
|
return ValidationError{Reason: "Invalid UID: Must be 40 characters or less"}
|
|
|
|
}
|
|
|
|
|
2021-10-07 09:33:50 -05:00
|
|
|
var err error
|
|
|
|
cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, setting.SecretKey)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-11-02 08:11:19 -05:00
|
|
|
model := models.AlertNotification{
|
|
|
|
Name: cmd.Name,
|
|
|
|
Type: cmd.Type,
|
|
|
|
Settings: cmd.Settings,
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.validateAlertNotification(ctx, &model, cmd.SecureSettings); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
return s.SQLStore.CreateAlertNotificationCommand(ctx, cmd)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *AlertNotificationService) UpdateAlertNotification(ctx context.Context, cmd *models.UpdateAlertNotificationCommand) error {
|
2022-05-24 10:02:47 -05:00
|
|
|
if util.IsShortUIDTooLong(cmd.Uid) {
|
|
|
|
return ValidationError{Reason: "Invalid UID: Must be 40 characters or less"}
|
|
|
|
}
|
|
|
|
|
2021-10-07 09:33:50 -05:00
|
|
|
var err error
|
|
|
|
cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, setting.SecretKey)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-11-02 08:11:19 -05:00
|
|
|
model := models.AlertNotification{
|
|
|
|
Id: cmd.Id,
|
2022-02-11 10:13:51 -06:00
|
|
|
OrgId: cmd.OrgId,
|
2021-11-02 08:11:19 -05:00
|
|
|
Name: cmd.Name,
|
|
|
|
Type: cmd.Type,
|
|
|
|
Settings: cmd.Settings,
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.validateAlertNotification(ctx, &model, cmd.SecureSettings); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
return s.SQLStore.UpdateAlertNotification(ctx, cmd)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) DeleteAlertNotification(ctx context.Context, cmd *models.DeleteAlertNotificationCommand) error {
|
|
|
|
return s.SQLStore.DeleteAlertNotification(ctx, cmd)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) GetAllAlertNotifications(ctx context.Context, query *models.GetAllAlertNotificationsQuery) error {
|
|
|
|
return s.SQLStore.GetAllAlertNotifications(ctx, query)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *AlertNotificationService) GetOrCreateAlertNotificationState(ctx context.Context, cmd *models.GetOrCreateNotificationStateQuery) error {
|
|
|
|
return s.SQLStore.GetOrCreateAlertNotificationState(ctx, cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *AlertNotificationService) SetAlertNotificationStateToCompleteCommand(ctx context.Context, cmd *models.SetAlertNotificationStateToCompleteCommand) error {
|
|
|
|
return s.SQLStore.SetAlertNotificationStateToCompleteCommand(ctx, cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *AlertNotificationService) SetAlertNotificationStateToPendingCommand(ctx context.Context, cmd *models.SetAlertNotificationStateToPendingCommand) error {
|
|
|
|
return s.SQLStore.SetAlertNotificationStateToPendingCommand(ctx, cmd)
|
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) GetAlertNotificationsWithUid(ctx context.Context, query *models.GetAlertNotificationsWithUidQuery) error {
|
|
|
|
return s.SQLStore.GetAlertNotificationsWithUid(ctx, query)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) UpdateAlertNotificationWithUid(ctx context.Context, cmd *models.UpdateAlertNotificationWithUidCommand) error {
|
2022-05-24 10:02:47 -05:00
|
|
|
if util.IsShortUIDTooLong(cmd.Uid) || util.IsShortUIDTooLong(cmd.NewUid) {
|
|
|
|
return ValidationError{Reason: "Invalid UID: Must be 40 characters or less"}
|
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
return s.SQLStore.UpdateAlertNotificationWithUid(ctx, cmd)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) DeleteAlertNotificationWithUid(ctx context.Context, cmd *models.DeleteAlertNotificationWithUidCommand) error {
|
|
|
|
return s.SQLStore.DeleteAlertNotificationWithUid(ctx, cmd)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
|
|
|
|
2021-11-05 03:41:24 -05:00
|
|
|
func (s *AlertNotificationService) GetAlertNotificationsWithUidToSend(ctx context.Context, query *models.GetAlertNotificationsWithUidToSendQuery) error {
|
|
|
|
return s.SQLStore.GetAlertNotificationsWithUidToSend(ctx, query)
|
2021-10-07 09:33:50 -05:00
|
|
|
}
|
2021-11-02 08:11:19 -05:00
|
|
|
|
|
|
|
func (s *AlertNotificationService) createNotifier(ctx context.Context, model *models.AlertNotification, secureSettings map[string]string) (Notifier, error) {
|
|
|
|
secureSettingsMap := map[string]string{}
|
|
|
|
|
|
|
|
if model.Id > 0 {
|
|
|
|
query := &models.GetAlertNotificationsQuery{
|
|
|
|
OrgId: model.OrgId,
|
|
|
|
Id: model.Id,
|
|
|
|
}
|
2021-11-05 03:41:24 -05:00
|
|
|
if err := s.SQLStore.GetAlertNotifications(ctx, query); err != nil {
|
2021-11-02 08:11:19 -05:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-02-11 10:13:51 -06:00
|
|
|
if query.Result == nil {
|
|
|
|
return nil, fmt.Errorf("unable to find the alert notification")
|
|
|
|
}
|
|
|
|
|
|
|
|
if query.Result.SecureSettings != nil {
|
2021-11-02 08:11:19 -05:00
|
|
|
var err error
|
|
|
|
secureSettingsMap, err = s.EncryptionService.DecryptJsonData(ctx, query.Result.SecureSettings, setting.SecretKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, v := range secureSettings {
|
|
|
|
secureSettingsMap[k] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
model.SecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, secureSettingsMap, setting.SecretKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-02-03 06:26:05 -06:00
|
|
|
notifier, err := InitNotifier(model, s.EncryptionService.GetDecryptedValue, s.NotificationService)
|
2021-11-02 08:11:19 -05:00
|
|
|
if err != nil {
|
|
|
|
logger.Error("Failed to create notifier", "error", err.Error())
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return notifier, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *AlertNotificationService) validateAlertNotification(ctx context.Context, model *models.AlertNotification, secureSettings map[string]string) error {
|
|
|
|
_, err := s.createNotifier(ctx, model, secureSettings)
|
|
|
|
return err
|
|
|
|
}
|