Encryption: Refactor securejsondata.SecureJsonData to stop relying on global functions (#38865)
* Encryption: Add support to encrypt/decrypt sjd * Add datasources.Service as a proxy to datasources db operations * Encrypt ds.SecureJsonData before calling SQLStore * Move ds cache code into ds service * Fix tlsmanager tests * Fix pluginproxy tests * Remove some securejsondata.GetEncryptedJsonData usages * Add pluginsettings.Service as a proxy for plugin settings db operations * Add AlertNotificationService as a proxy for alert notification db operations * Remove some securejsondata.GetEncryptedJsonData usages * Remove more securejsondata.GetEncryptedJsonData usages * Fix lint errors * Minor fixes * Remove encryption global functions usages from ngalert * Fix lint errors * Minor fixes * Minor fixes * Remove securejsondata.DecryptedValue usage * Refactor the refactor * Remove securejsondata.DecryptedValue usage * Move securejsondata to migrations package * Move securejsondata to migrations package * Minor fix * Fix integration test * Fix integration tests * Undo undesired changes * Fix tests * Add context.Context into encryption methods * Fix tests * Fix tests * Fix tests * Trigger CI * Fix test * Add names to params of encryption service interface * Remove bus from CacheServiceImpl * Add logging * Add keys to logger Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> * Add missing key to logger Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> * Undo changes in markdown files * Fix formatting * Add context to secrets service * Rename decryptSecureJsonData to decryptSecureJsonDataFn * Name args in GetDecryptedValueFn * Add template back to NewAlertmanagerNotifier * Copy GetDecryptedValueFn to ngalert * Add logging to pluginsettings * Fix pluginsettings test Co-authored-by: Tania B <yalyna.ts@gmail.com> Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
co-authored by
Emil Tullstedt
Tania B
parent
da813877fb
commit
722c414fef
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/encryption"
|
||||
"github.com/grafana/grafana/pkg/services/rendering"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
@@ -47,7 +48,8 @@ func (e *AlertEngine) IsDisabled() bool {
|
||||
|
||||
// ProvideAlertEngine returns a new AlertEngine.
|
||||
func ProvideAlertEngine(renderer rendering.Service, bus bus.Bus, requestValidator models.PluginRequestValidator,
|
||||
dataService plugins.DataRequestHandler, usageStatsService usagestats.Service, cfg *setting.Cfg) *AlertEngine {
|
||||
dataService plugins.DataRequestHandler, usageStatsService usagestats.Service, encryptionService encryption.Service,
|
||||
cfg *setting.Cfg) *AlertEngine {
|
||||
e := &AlertEngine{
|
||||
Cfg: cfg,
|
||||
RenderService: renderer,
|
||||
@@ -62,7 +64,7 @@ func ProvideAlertEngine(renderer rendering.Service, bus bus.Bus, requestValidato
|
||||
e.evalHandler = NewEvalHandler(e.DataService)
|
||||
e.ruleReader = newRuleReader()
|
||||
e.log = log.New("alerting.engine")
|
||||
e.resultHandler = newResultHandler(e.RenderService)
|
||||
e.resultHandler = newResultHandler(e.RenderService, encryptionService.GetDecryptedValue)
|
||||
|
||||
e.registerUsageMetrics()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
func TestEngineTimeouts(t *testing.T) {
|
||||
Convey("Alerting engine timeout tests", t, func() {
|
||||
usMock := &usagestats.UsageStatsMock{T: t}
|
||||
engine := ProvideAlertEngine(nil, nil, nil, nil, usMock, setting.NewCfg())
|
||||
engine := ProvideAlertEngine(nil, nil, nil, nil, usMock, ossencryption.ProvideService(), setting.NewCfg())
|
||||
setting.AlertingNotificationTimeout = 30 * time.Second
|
||||
setting.AlertingMaxAttempts = 3
|
||||
engine.resultHandler = &FakeResultHandler{}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
@@ -44,7 +45,7 @@ func TestEngineProcessJob(t *testing.T) {
|
||||
Convey("Alerting engine job processing", t, func() {
|
||||
bus := bus.New()
|
||||
usMock := &usagestats.UsageStatsMock{T: t}
|
||||
engine := ProvideAlertEngine(nil, bus, nil, nil, usMock, setting.NewCfg())
|
||||
engine := ProvideAlertEngine(nil, bus, nil, nil, usMock, ossencryption.ProvideService(), setting.NewCfg())
|
||||
setting.AlertingEvaluationTimeout = 30 * time.Second
|
||||
setting.AlertingNotificationTimeout = 30 * time.Second
|
||||
setting.AlertingMaxAttempts = 3
|
||||
|
||||
@@ -181,12 +181,14 @@ func TestAlertRuleExtraction(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Alert notifications are in DB", func(t *testing.T) {
|
||||
sqlstore.InitTestDB(t)
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
|
||||
firstNotification := models.CreateAlertNotificationCommand{Uid: "notifier1", OrgId: 1, Name: "1"}
|
||||
err = sqlstore.CreateAlertNotificationCommand(&firstNotification)
|
||||
err = sqlStore.CreateAlertNotificationCommand(&firstNotification)
|
||||
require.Nil(t, err)
|
||||
|
||||
secondNotification := models.CreateAlertNotificationCommand{Uid: "notifier2", OrgId: 1, Name: "2"}
|
||||
err = sqlstore.CreateAlertNotificationCommand(&secondNotification)
|
||||
err = sqlStore.CreateAlertNotificationCommand(&secondNotification)
|
||||
require.Nil(t, err)
|
||||
|
||||
json, err := ioutil.ReadFile("./testdata/influxdb-alert.json")
|
||||
|
||||
@@ -83,16 +83,18 @@ type ShowWhen struct {
|
||||
Is string `json:"is"`
|
||||
}
|
||||
|
||||
func newNotificationService(renderService rendering.Service) *notificationService {
|
||||
func newNotificationService(renderService rendering.Service, decryptFn GetDecryptedValueFn) *notificationService {
|
||||
return ¬ificationService{
|
||||
log: log.New("alerting.notifier"),
|
||||
renderService: renderService,
|
||||
decryptFn: decryptFn,
|
||||
}
|
||||
}
|
||||
|
||||
type notificationService struct {
|
||||
log log.Logger
|
||||
renderService rendering.Service
|
||||
decryptFn GetDecryptedValueFn
|
||||
}
|
||||
|
||||
func (n *notificationService) SendIfNeeded(evalCtx *EvalContext) error {
|
||||
@@ -250,7 +252,7 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [
|
||||
|
||||
var result notifierStateSlice
|
||||
for _, notification := range query.Result {
|
||||
not, err := InitNotifier(notification)
|
||||
not, err := InitNotifier(notification, n.decryptFn)
|
||||
if err != nil {
|
||||
n.log.Error("Could not create notifier", "notifier", notification.Uid, "error", err)
|
||||
continue
|
||||
@@ -280,17 +282,21 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [
|
||||
}
|
||||
|
||||
// InitNotifier instantiate a new notifier based on the model.
|
||||
func InitNotifier(model *models.AlertNotification) (Notifier, error) {
|
||||
func InitNotifier(model *models.AlertNotification, fn GetDecryptedValueFn) (Notifier, error) {
|
||||
notifierPlugin, found := notifierFactories[model.Type]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unsupported notification type %q", model.Type)
|
||||
}
|
||||
|
||||
return notifierPlugin.Factory(model)
|
||||
return notifierPlugin.Factory(model, fn)
|
||||
}
|
||||
|
||||
// GetDecryptedValueFn is a function that returns the decrypted value of
|
||||
// the given key. If the key is not present, then it returns the fallback value.
|
||||
type GetDecryptedValueFn func(ctx context.Context, sjd map[string][]byte, key string, fallback string, secret string) string
|
||||
|
||||
// NotifierFactory is a signature for creating notifiers.
|
||||
type NotifierFactory func(notification *models.AlertNotification) (Notifier, error)
|
||||
type NotifierFactory func(*models.AlertNotification, GetDecryptedValueFn) (Notifier, error)
|
||||
|
||||
var notifierFactories = make(map[string]*NotifierPlugin)
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ func notificationServiceScenario(t *testing.T, name string, evalCtx *EvalContext
|
||||
},
|
||||
}
|
||||
|
||||
scenarioCtx.notificationService = newNotificationService(renderService)
|
||||
scenarioCtx.notificationService = newNotificationService(renderService, nil)
|
||||
fn(scenarioCtx)
|
||||
})
|
||||
}
|
||||
@@ -279,7 +279,7 @@ type testNotifier struct {
|
||||
Frequency time.Duration
|
||||
}
|
||||
|
||||
func newTestNotifier(model *models.AlertNotification) (Notifier, error) {
|
||||
func newTestNotifier(model *models.AlertNotification, _ GetDecryptedValueFn) (Notifier, error) {
|
||||
uploadImage := true
|
||||
value, exist := model.Settings.CheckGet("uploadImage")
|
||||
if exist {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -49,7 +50,7 @@ func init() {
|
||||
}
|
||||
|
||||
// NewAlertmanagerNotifier returns a new Alertmanager notifier
|
||||
func NewAlertmanagerNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewAlertmanagerNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
urlString := model.Settings.Get("url").MustString()
|
||||
if urlString == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
@@ -63,7 +64,7 @@ func NewAlertmanagerNotifier(model *models.AlertNotification) (alerting.Notifier
|
||||
}
|
||||
}
|
||||
basicAuthUser := model.Settings.Get("basicAuthUser").MustString()
|
||||
basicAuthPassword := model.DecryptedValue("basicAuthPassword", model.Settings.Get("basicAuthPassword").MustString())
|
||||
basicAuthPassword := fn(context.Background(), model.SecureSettings, "basicAuthPassword", model.Settings.Get("basicAuthPassword").MustString(), setting.SecretKey)
|
||||
|
||||
return &AlertmanagerNotifier{
|
||||
NotifierBase: NewNotifierBase(model),
|
||||
|
||||
@@ -4,15 +4,14 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"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"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestReplaceIllegalCharswithUnderscore(t *testing.T) {
|
||||
@@ -93,7 +92,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewAlertmanagerNotifier(model)
|
||||
_, err := NewAlertmanagerNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -107,7 +106,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewAlertmanagerNotifier(model)
|
||||
not, err := NewAlertmanagerNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
alertmanagerNotifier := not.(*AlertmanagerNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -126,7 +125,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewAlertmanagerNotifier(model)
|
||||
not, err := NewAlertmanagerNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
alertmanagerNotifier := not.(*AlertmanagerNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -5,14 +5,12 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"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/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestShouldSendAlertNotification(t *testing.T) {
|
||||
|
||||
@@ -47,7 +47,7 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
func newDingDingNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func newDingDingNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"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/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ func TestDingDingNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := newDingDingNotifier(model)
|
||||
_, err := newDingDingNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
Convey("settings should trigger incident", func() {
|
||||
@@ -37,7 +37,7 @@ func TestDingDingNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := newDingDingNotifier(model)
|
||||
not, err := newDingDingNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
notifier := not.(*DingDingNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -51,7 +51,7 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
func newDiscordNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func newDiscordNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
avatar := model.Settings.Get("avatar_url").MustString()
|
||||
content := model.Settings.Get("content").MustString()
|
||||
url := model.Settings.Get("url").MustString()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestDiscordNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := newDiscordNotifier(model)
|
||||
_, err := newDiscordNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -40,7 +41,7 @@ func TestDiscordNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := newDiscordNotifier(model)
|
||||
not, err := newDiscordNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
discordNotifier := not.(*DiscordNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -48,7 +48,7 @@ type EmailNotifier struct {
|
||||
|
||||
// NewEmailNotifier is the constructor function
|
||||
// for the EmailNotifier.
|
||||
func NewEmailNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewEmailNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
addressesString := model.Settings.Get("addresses").MustString()
|
||||
singleEmail := model.Settings.Get("singleEmail").MustBool(false)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestEmailNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewEmailNotifier(model)
|
||||
_, err := NewEmailNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -38,7 +39,7 @@ func TestEmailNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewEmailNotifier(model)
|
||||
not, err := NewEmailNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
emailNotifier := not.(*EmailNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -62,7 +63,7 @@ func TestEmailNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewEmailNotifier(model)
|
||||
not, err := NewEmailNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
emailNotifier := not.(*EmailNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -32,7 +32,7 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
func newGoogleChatNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func newGoogleChatNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestGoogleChatNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := newGoogleChatNotifier(model)
|
||||
_, err := newGoogleChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -38,7 +39,7 @@ func TestGoogleChatNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := newGoogleChatNotifier(model)
|
||||
not, err := newGoogleChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
webhookNotifier := not.(*GoogleChatNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -53,7 +53,7 @@ const (
|
||||
|
||||
// NewHipChatNotifier is the constructor functions
|
||||
// for the HipChatNotifier
|
||||
func NewHipChatNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewHipChatNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if strings.HasSuffix(url, "/") {
|
||||
url = url[:len(url)-1]
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -22,7 +23,7 @@ func TestHipChatNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewHipChatNotifier(model)
|
||||
_, err := NewHipChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -38,7 +39,7 @@ func TestHipChatNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewHipChatNotifier(model)
|
||||
not, err := NewHipChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
hipchatNotifier := not.(*HipChatNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -64,7 +65,7 @@ func TestHipChatNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewHipChatNotifier(model)
|
||||
not, err := NewHipChatNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
hipchatNotifier := not.(*HipChatNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -41,7 +41,7 @@ func init() {
|
||||
}
|
||||
|
||||
// NewKafkaNotifier is the constructor function for the Kafka notifier.
|
||||
func NewKafkaNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewKafkaNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
endpoint := model.Settings.Get("kafkaRestProxy").MustString()
|
||||
if endpoint == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find kafka rest proxy endpoint property in settings"}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewKafkaNotifier(model)
|
||||
_, err := NewKafkaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -39,7 +40,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewKafkaNotifier(model)
|
||||
not, err := NewKafkaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
kafkaNotifier := not.(*KafkaNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
@@ -8,6 +9,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -35,8 +37,8 @@ const (
|
||||
)
|
||||
|
||||
// NewLINENotifier is the constructor for the LINE notifier
|
||||
func NewLINENotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
token := model.DecryptedValue("token", model.Settings.Get("token").MustString())
|
||||
func NewLINENotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
token := fn(context.Background(), model.SecureSettings, "token", model.Settings.Get("token").MustString(), setting.SecretKey)
|
||||
if token == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find token in settings"}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func TestLineNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewLINENotifier(model)
|
||||
_, err := NewLINENotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
Convey("settings should trigger incident", func() {
|
||||
@@ -35,7 +36,7 @@ func TestLineNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewLINENotifier(model)
|
||||
not, err := NewLINENotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
lineNotifier := not.(*LineNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -82,10 +84,10 @@ const (
|
||||
)
|
||||
|
||||
// NewOpsGenieNotifier is the constructor for OpsGenie.
|
||||
func NewOpsGenieNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewOpsGenieNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
autoClose := model.Settings.Get("autoClose").MustBool(true)
|
||||
overridePriority := model.Settings.Get("overridePriority").MustBool(true)
|
||||
apiKey := model.DecryptedValue("apiKey", model.Settings.Get("apiKey").MustString())
|
||||
apiKey := fn(context.Background(), model.SecureSettings, "apiKey", model.Settings.Get("apiKey").MustString(), setting.SecretKey)
|
||||
apiURL := model.Settings.Get("apiUrl").MustString()
|
||||
if apiKey == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find api key property in settings"}
|
||||
|
||||
@@ -4,12 +4,12 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"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/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestOpsGenieNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewOpsGenieNotifier(model)
|
||||
_, err := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestOpsGenieNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewOpsGenieNotifier(model)
|
||||
not, err := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
opsgenieNotifier := not.(*OpsGenieNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -67,7 +67,7 @@ func TestOpsGenieNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewOpsGenieNotifier(model)
|
||||
_, err := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldHaveSameTypeAs, alerting.ValidationError{})
|
||||
So(err.Error(), ShouldEndWith, "Invalid value for sendTagsAs: \"not_a_valid_value\"")
|
||||
@@ -90,7 +90,7 @@ func TestOpsGenieNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
notifier, notifierErr := NewOpsGenieNotifier(model) // unhandled error
|
||||
notifier, notifierErr := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue) // unhandled error
|
||||
|
||||
opsgenieNotifier := notifier.(*OpsGenieNotifier)
|
||||
|
||||
@@ -140,7 +140,7 @@ func TestOpsGenieNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
notifier, notifierErr := NewOpsGenieNotifier(model) // unhandled error
|
||||
notifier, notifierErr := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue) // unhandled error
|
||||
|
||||
opsgenieNotifier := notifier.(*OpsGenieNotifier)
|
||||
|
||||
@@ -190,7 +190,7 @@ func TestOpsGenieNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
notifier, notifierErr := NewOpsGenieNotifier(model) // unhandled error
|
||||
notifier, notifierErr := NewOpsGenieNotifier(model, ossencryption.ProvideService().GetDecryptedValue) // unhandled error
|
||||
|
||||
opsgenieNotifier := notifier.(*OpsGenieNotifier)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -74,10 +76,10 @@ var (
|
||||
)
|
||||
|
||||
// NewPagerdutyNotifier is the constructor for the PagerDuty notifier
|
||||
func NewPagerdutyNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewPagerdutyNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
severity := model.Settings.Get("severity").MustString("critical")
|
||||
autoResolve := model.Settings.Get("autoResolve").MustBool(false)
|
||||
key := model.DecryptedValue("integrationKey", model.Settings.Get("integrationKey").MustString())
|
||||
key := fn(context.Background(), model.SecureSettings, "integrationKey", model.Settings.Get("integrationKey").MustString(), setting.SecretKey)
|
||||
messageInDetails := model.Settings.Get("messageInDetails").MustBool(false)
|
||||
if key == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find integration key property in settings"}
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/grafana/grafana/pkg/components/null"
|
||||
"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/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewPagerdutyNotifier(model)
|
||||
_, err = NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -79,7 +79,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -106,7 +106,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -131,7 +131,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
@@ -188,7 +188,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
@@ -245,7 +245,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
@@ -315,7 +315,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
@@ -395,7 +395,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
@@ -474,7 +474,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPagerdutyNotifier(model)
|
||||
not, err := NewPagerdutyNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
pagerdutyNotifier := not.(*PagerdutyNotifier)
|
||||
|
||||
@@ -2,12 +2,15 @@ package notifiers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@@ -191,9 +194,9 @@ func init() {
|
||||
}
|
||||
|
||||
// NewPushoverNotifier is the constructor for the Pushover Notifier
|
||||
func NewPushoverNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
userKey := model.DecryptedValue("userKey", model.Settings.Get("userKey").MustString())
|
||||
APIToken := model.DecryptedValue("apiToken", model.Settings.Get("apiToken").MustString())
|
||||
func NewPushoverNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
userKey := fn(context.Background(), model.SecureSettings, "userKey", model.Settings.Get("userKey").MustString(), setting.SecretKey)
|
||||
APIToken := fn(context.Background(), model.SecureSettings, "apiToken", model.Settings.Get("apiToken").MustString(), setting.SecretKey)
|
||||
device := model.Settings.Get("device").MustString()
|
||||
alertingPriority, err := strconv.Atoi(model.Settings.Get("priority").MustString("0")) // default Normal
|
||||
if err != nil {
|
||||
|
||||
@@ -5,12 +5,11 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
|
||||
"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/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -27,7 +26,7 @@ func TestPushoverNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewPushoverNotifier(model)
|
||||
_, err := NewPushoverNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -49,7 +48,7 @@ func TestPushoverNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewPushoverNotifier(model)
|
||||
not, err := NewPushoverNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
pushoverNotifier := not.(*PushoverNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -59,7 +61,7 @@ func init() {
|
||||
}
|
||||
|
||||
// NewSensuNotifier is the constructor for the Sensu Notifier.
|
||||
func NewSensuNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewSensuNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
@@ -70,7 +72,7 @@ func NewSensuNotifier(model *models.AlertNotification) (alerting.Notifier, error
|
||||
URL: url,
|
||||
User: model.Settings.Get("username").MustString(),
|
||||
Source: model.Settings.Get("source").MustString(),
|
||||
Password: model.DecryptedValue("password", model.Settings.Get("password").MustString()),
|
||||
Password: fn(context.Background(), model.SecureSettings, "password", model.Settings.Get("password").MustString(), setting.SecretKey),
|
||||
Handler: model.Settings.Get("handler").MustString(),
|
||||
log: log.New("alerting.notifier.sensu"),
|
||||
}, nil
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestSensuNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewSensuNotifier(model)
|
||||
_, err := NewSensuNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -40,7 +41,7 @@ func TestSensuNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewSensuNotifier(model)
|
||||
not, err := NewSensuNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
sensuNotifier := not.(*SensuNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -70,9 +72,9 @@ func init() {
|
||||
}
|
||||
|
||||
// NewSensuGoNotifier is the constructor for the Sensu Go Notifier.
|
||||
func NewSensuGoNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewSensuGoNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
apikey := model.DecryptedValue("apikey", model.Settings.Get("apikey").MustString())
|
||||
apikey := fn(context.Background(), model.SecureSettings, "apikey", model.Settings.Get("apikey").MustString(), setting.SecretKey)
|
||||
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find URL property in settings"}
|
||||
|
||||
@@ -3,11 +3,11 @@ package notifiers
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSensuGoNotifier(t *testing.T) {
|
||||
@@ -21,7 +21,7 @@ func TestSensuGoNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewSensuGoNotifier(model)
|
||||
_, err = NewSensuGoNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.Error(t, err)
|
||||
|
||||
json = `
|
||||
@@ -42,7 +42,7 @@ func TestSensuGoNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewSensuGoNotifier(model)
|
||||
not, err := NewSensuGoNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.NoError(t, err)
|
||||
sensuGoNotifier := not.(*SensuGoNotifier)
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ var reRecipient *regexp.Regexp = regexp.MustCompile("^((@[a-z0-9][a-zA-Z0-9._-]*
|
||||
const slackAPIEndpoint = "https://slack.com/api/chat.postMessage"
|
||||
|
||||
// NewSlackNotifier is the constructor for the Slack notifier.
|
||||
func NewSlackNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
urlStr := model.DecryptedValue("url", model.Settings.Get("url").MustString())
|
||||
func NewSlackNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
urlStr := fn(context.Background(), model.SecureSettings, "url", model.Settings.Get("url").MustString(), setting.SecretKey)
|
||||
if urlStr == "" {
|
||||
urlStr = slackAPIEndpoint
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func NewSlackNotifier(model *models.AlertNotification) (alerting.Notifier, error
|
||||
mentionUsersStr := model.Settings.Get("mentionUsers").MustString()
|
||||
mentionGroupsStr := model.Settings.Get("mentionGroups").MustString()
|
||||
mentionChannel := model.Settings.Get("mentionChannel").MustString()
|
||||
token := model.DecryptedValue("token", model.Settings.Get("token").MustString())
|
||||
token := fn(context.Background(), model.SecureSettings, "token", model.Settings.Get("token").MustString(), setting.SecretKey)
|
||||
if token == "" && apiURL.String() == slackAPIEndpoint {
|
||||
return nil, alerting.ValidationError{
|
||||
Reason: "token must be specified when using the Slack chat API",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/securejsondata"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -22,7 +24,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewSlackNotifier(model)
|
||||
_, err = NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
assert.EqualError(t, err, "alert validation error: recipient must be specified when using the Slack chat API")
|
||||
})
|
||||
|
||||
@@ -40,7 +42,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewSlackNotifier(model)
|
||||
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.NoError(t, err)
|
||||
slackNotifier := not.(*SlackNotifier)
|
||||
assert.Equal(t, "ops", slackNotifier.Name)
|
||||
@@ -78,7 +80,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewSlackNotifier(model)
|
||||
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.NoError(t, err)
|
||||
slackNotifier := not.(*SlackNotifier)
|
||||
assert.Equal(t, "ops", slackNotifier.Name)
|
||||
@@ -110,9 +112,15 @@ func TestSlackNotifier(t *testing.T) {
|
||||
|
||||
settingsJSON, err := simplejson.NewJson([]byte(json))
|
||||
require.NoError(t, err)
|
||||
securedSettingsJSON := securejsondata.GetEncryptedJsonData(map[string]string{
|
||||
"token": "xenc-XXXXXXXX-XXXXXXXX-XXXXXXXXXX",
|
||||
})
|
||||
|
||||
encryptionService := ossencryption.ProvideService()
|
||||
securedSettingsJSON, err := encryptionService.EncryptJsonData(
|
||||
context.Background(),
|
||||
map[string]string{
|
||||
"token": "xenc-XXXXXXXX-XXXXXXXX-XXXXXXXXXX",
|
||||
}, setting.SecretKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
model := &models.AlertNotification{
|
||||
Name: "ops",
|
||||
Type: "slack",
|
||||
@@ -120,7 +128,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
SecureSettings: securedSettingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewSlackNotifier(model)
|
||||
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.NoError(t, err)
|
||||
slackNotifier := not.(*SlackNotifier)
|
||||
assert.Equal(t, "ops", slackNotifier.Name)
|
||||
@@ -151,7 +159,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewSlackNotifier(model)
|
||||
_, err = NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
assert.EqualError(t, err, "alert validation error: recipient on invalid format: \"#open tsdb\"")
|
||||
})
|
||||
|
||||
@@ -170,7 +178,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewSlackNotifier(model)
|
||||
_, err = NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
assert.EqualError(t, err, "alert validation error: recipient on invalid format: \"@user name\"")
|
||||
})
|
||||
|
||||
@@ -189,7 +197,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewSlackNotifier(model)
|
||||
_, err = NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
assert.EqualError(t, err, "alert validation error: recipient on invalid format: \"@User\"")
|
||||
})
|
||||
|
||||
@@ -208,7 +216,7 @@ func TestSlackNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewSlackNotifier(model)
|
||||
not, err := NewSlackNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.NoError(t, err)
|
||||
slackNotifier := not.(*SlackNotifier)
|
||||
assert.Equal(t, "1ABCDE", slackNotifier.recipient)
|
||||
|
||||
@@ -30,7 +30,7 @@ func init() {
|
||||
}
|
||||
|
||||
// NewTeamsNotifier is the constructor for Teams notifier.
|
||||
func NewTeamsNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewTeamsNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestTeamsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewTeamsNotifier(model)
|
||||
_, err := NewTeamsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -38,7 +39,7 @@ func TestTeamsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewTeamsNotifier(model)
|
||||
not, err := NewTeamsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
teamsNotifier := not.(*TeamsNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -60,7 +61,7 @@ func TestTeamsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewTeamsNotifier(model)
|
||||
not, err := NewTeamsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
teamsNotifier := not.(*TeamsNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -2,6 +2,7 @@ package notifiers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -61,12 +63,12 @@ type TelegramNotifier struct {
|
||||
}
|
||||
|
||||
// NewTelegramNotifier is the constructor for the Telegram notifier
|
||||
func NewTelegramNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewTelegramNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
if model.Settings == nil {
|
||||
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
|
||||
}
|
||||
|
||||
botToken := model.DecryptedValue("bottoken", model.Settings.Get("bottoken").MustString())
|
||||
botToken := fn(context.Background(), model.SecureSettings, "bottoken", model.Settings.Get("bottoken").MustString(), setting.SecretKey)
|
||||
chatID := model.Settings.Get("chatid").MustString()
|
||||
uploadImage := model.Settings.Get("uploadImage").MustBool()
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"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/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestTelegramNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewTelegramNotifier(model)
|
||||
_, err := NewTelegramNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestTelegramNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewTelegramNotifier(model)
|
||||
not, err := NewTelegramNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
telegramNotifier := not.(*TelegramNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -69,14 +71,14 @@ type ThreemaNotifier struct {
|
||||
}
|
||||
|
||||
// NewThreemaNotifier is the constructor for the Threema notifier
|
||||
func NewThreemaNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewThreemaNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
if model.Settings == nil {
|
||||
return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
|
||||
}
|
||||
|
||||
gatewayID := model.Settings.Get("gateway_id").MustString()
|
||||
recipientID := model.Settings.Get("recipient_id").MustString()
|
||||
apiSecret := model.DecryptedValue("api_secret", model.Settings.Get("api_secret").MustString())
|
||||
apiSecret := fn(context.Background(), model.SecureSettings, "api_secret", model.Settings.Get("api_secret").MustString(), setting.SecretKey)
|
||||
|
||||
// Validation
|
||||
if gatewayID == "" {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"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/services/encryption/ossencryption"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -23,7 +24,7 @@ func TestThreemaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewThreemaNotifier(model)
|
||||
_, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -42,7 +43,7 @@ func TestThreemaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewThreemaNotifier(model)
|
||||
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
threemaNotifier := not.(*ThreemaNotifier)
|
||||
|
||||
@@ -69,7 +70,7 @@ func TestThreemaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewThreemaNotifier(model)
|
||||
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(not, ShouldBeNil)
|
||||
var valErr alerting.ValidationError
|
||||
So(errors.As(err, &valErr), ShouldBeTrue)
|
||||
@@ -91,7 +92,7 @@ func TestThreemaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewThreemaNotifier(model)
|
||||
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(not, ShouldBeNil)
|
||||
var valErr alerting.ValidationError
|
||||
So(errors.As(err, &valErr), ShouldBeTrue)
|
||||
@@ -113,7 +114,7 @@ func TestThreemaNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewThreemaNotifier(model)
|
||||
not, err := NewThreemaNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(not, ShouldBeNil)
|
||||
var valErr alerting.ValidationError
|
||||
So(errors.As(err, &valErr), ShouldBeTrue)
|
||||
|
||||
@@ -47,7 +47,7 @@ func init() {
|
||||
|
||||
// NewVictoropsNotifier creates an instance of VictoropsNotifier that
|
||||
// handles posting notifications to Victorops REST API
|
||||
func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewVictoropsNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
autoResolve := model.Settings.Get("autoResolve").MustBool(true)
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
|
||||
@@ -4,12 +4,12 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"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/services/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/validations"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestVictoropsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err := NewVictoropsNotifier(model)
|
||||
_, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
@@ -52,7 +52,7 @@ func TestVictoropsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewVictoropsNotifier(model)
|
||||
not, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
victoropsNotifier := not.(*VictoropsNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
@@ -76,7 +76,7 @@ func TestVictoropsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewVictoropsNotifier(model)
|
||||
not, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
victoropsNotifier := not.(*VictoropsNotifier)
|
||||
@@ -124,7 +124,7 @@ func TestVictoropsNotifier(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewVictoropsNotifier(model)
|
||||
not, err := NewVictoropsNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
victoropsNotifier := not.(*VictoropsNotifier)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"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"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -58,13 +60,13 @@ func init() {
|
||||
|
||||
// NewWebHookNotifier is the constructor for
|
||||
// the WebHook notifier.
|
||||
func NewWebHookNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
func NewWebHookNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
}
|
||||
|
||||
password := model.DecryptedValue("password", model.Settings.Get("password").MustString())
|
||||
password := fn(context.Background(), model.SecureSettings, "password", model.Settings.Get("password").MustString(), setting.SecretKey)
|
||||
|
||||
return &WebhookNotifier{
|
||||
NotifierBase: NewNotifierBase(model),
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -21,7 +22,7 @@ func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
_, err = NewWebHookNotifier(model)
|
||||
_, err = NewWebHookNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
@@ -36,7 +37,7 @@ func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewWebHookNotifier(model)
|
||||
not, err := NewWebHookNotifier(model, ossencryption.ProvideService().GetDecryptedValue)
|
||||
require.NoError(t, err)
|
||||
webhookNotifier := not.(*WebhookNotifier)
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ type defaultResultHandler struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func newResultHandler(renderService rendering.Service) *defaultResultHandler {
|
||||
func newResultHandler(renderService rendering.Service, decryptFn GetDecryptedValueFn) *defaultResultHandler {
|
||||
return &defaultResultHandler{
|
||||
log: log.New("alerting.resultHandler"),
|
||||
notifier: newNotificationService(renderService),
|
||||
notifier: newNotificationService(renderService, decryptFn),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,16 +83,16 @@ func TestAlertRuleForParsing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAlertRuleModel(t *testing.T) {
|
||||
sqlstore.InitTestDB(t)
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
RegisterCondition("test", func(model *simplejson.Json, index int) (Condition, error) {
|
||||
return &FakeCondition{}, nil
|
||||
})
|
||||
|
||||
firstNotification := models.CreateAlertNotificationCommand{Uid: "notifier1", OrgId: 1, Name: "1"}
|
||||
err := sqlstore.CreateAlertNotificationCommand(&firstNotification)
|
||||
err := sqlStore.CreateAlertNotificationCommand(&firstNotification)
|
||||
require.Nil(t, err)
|
||||
secondNotification := models.CreateAlertNotificationCommand{Uid: "notifier2", OrgId: 1, Name: "2"}
|
||||
err = sqlstore.CreateAlertNotificationCommand(&secondNotification)
|
||||
err = sqlStore.CreateAlertNotificationCommand(&secondNotification)
|
||||
require.Nil(t, err)
|
||||
|
||||
t.Run("Testing alert rule with notification id and uid", func(t *testing.T) {
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package alerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/encryption"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type AlertNotificationService struct {
|
||||
Bus bus.Bus
|
||||
SQLStore *sqlstore.SQLStore
|
||||
EncryptionService encryption.Service
|
||||
}
|
||||
|
||||
func ProvideService(bus bus.Bus, store *sqlstore.SQLStore, encryptionService encryption.Service,
|
||||
) *AlertNotificationService {
|
||||
s := &AlertNotificationService{
|
||||
Bus: bus,
|
||||
SQLStore: store,
|
||||
EncryptionService: encryptionService,
|
||||
}
|
||||
|
||||
s.Bus.AddHandler(s.GetAlertNotifications)
|
||||
s.Bus.AddHandlerCtx(s.CreateAlertNotificationCommand)
|
||||
s.Bus.AddHandlerCtx(s.UpdateAlertNotification)
|
||||
s.Bus.AddHandler(s.DeleteAlertNotification)
|
||||
s.Bus.AddHandler(s.GetAllAlertNotifications)
|
||||
s.Bus.AddHandlerCtx(s.GetOrCreateAlertNotificationState)
|
||||
s.Bus.AddHandlerCtx(s.SetAlertNotificationStateToCompleteCommand)
|
||||
s.Bus.AddHandlerCtx(s.SetAlertNotificationStateToPendingCommand)
|
||||
s.Bus.AddHandler(s.GetAlertNotificationsWithUid)
|
||||
s.Bus.AddHandler(s.UpdateAlertNotificationWithUid)
|
||||
s.Bus.AddHandler(s.DeleteAlertNotificationWithUid)
|
||||
s.Bus.AddHandler(s.GetAlertNotificationsWithUidToSend)
|
||||
s.Bus.AddHandlerCtx(s.HandleNotificationTestCommand)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) GetAlertNotifications(query *models.GetAlertNotificationsQuery) error {
|
||||
return s.SQLStore.GetAlertNotifications(query)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) CreateAlertNotificationCommand(ctx context.Context, cmd *models.CreateAlertNotificationCommand) error {
|
||||
var err error
|
||||
cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, setting.SecretKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.SQLStore.CreateAlertNotificationCommand(cmd)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) UpdateAlertNotification(ctx context.Context, cmd *models.UpdateAlertNotificationCommand) error {
|
||||
var err error
|
||||
cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, setting.SecretKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.SQLStore.UpdateAlertNotification(cmd)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) DeleteAlertNotification(cmd *models.DeleteAlertNotificationCommand) error {
|
||||
return s.SQLStore.DeleteAlertNotification(cmd)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) GetAllAlertNotifications(query *models.GetAllAlertNotificationsQuery) error {
|
||||
return s.SQLStore.GetAllAlertNotifications(query)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) GetAlertNotificationsWithUid(query *models.GetAlertNotificationsWithUidQuery) error {
|
||||
return s.SQLStore.GetAlertNotificationsWithUid(query)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) UpdateAlertNotificationWithUid(cmd *models.UpdateAlertNotificationWithUidCommand) error {
|
||||
return s.SQLStore.UpdateAlertNotificationWithUid(cmd)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) DeleteAlertNotificationWithUid(cmd *models.DeleteAlertNotificationWithUidCommand) error {
|
||||
return s.SQLStore.DeleteAlertNotificationWithUid(cmd)
|
||||
}
|
||||
|
||||
func (s *AlertNotificationService) GetAlertNotificationsWithUidToSend(query *models.GetAlertNotificationsWithUidToSendQuery) error {
|
||||
return s.SQLStore.GetAlertNotificationsWithUidToSend(query)
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package alerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"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/encryption/ossencryption"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
|
||||
s := ProvideService(bus.New(), sqlStore, ossencryption.ProvideService())
|
||||
|
||||
origSecret := setting.SecretKey
|
||||
setting.SecretKey = "alert_notification_service_test"
|
||||
t.Cleanup(func() {
|
||||
setting.SecretKey = origSecret
|
||||
})
|
||||
|
||||
var an *models.AlertNotification
|
||||
|
||||
t.Run("create alert notification should encrypt the secure json data", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
ss := map[string]string{"password": "12345"}
|
||||
cmd := models.CreateAlertNotificationCommand{SecureSettings: ss}
|
||||
|
||||
err := s.CreateAlertNotificationCommand(ctx, &cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
an = cmd.Result
|
||||
decrypted, err := s.EncryptionService.DecryptJsonData(ctx, an.SecureSettings, setting.SecretKey)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ss, decrypted)
|
||||
})
|
||||
|
||||
t.Run("update alert notification should encrypt the secure json data", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
ss := map[string]string{"password": "678910"}
|
||||
cmd := models.UpdateAlertNotificationCommand{Id: an.Id, Settings: simplejson.New(), SecureSettings: ss}
|
||||
err := s.UpdateAlertNotification(ctx, &cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
decrypted, err := s.EncryptionService.DecryptJsonData(ctx, cmd.Result.SecureSettings, setting.SecretKey)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ss, decrypted)
|
||||
})
|
||||
}
|
||||
@@ -6,13 +6,12 @@ import (
|
||||
"math/rand"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/securejsondata"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/null"
|
||||
"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/setting"
|
||||
)
|
||||
|
||||
// NotificationTestCommand initiates an test
|
||||
@@ -31,12 +30,8 @@ var (
|
||||
logger = log.New("alerting.testnotification")
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandlerCtx("alerting", handleNotificationTestCommand)
|
||||
}
|
||||
|
||||
func handleNotificationTestCommand(ctx context.Context, cmd *NotificationTestCommand) error {
|
||||
notifier := newNotificationService(nil)
|
||||
func (s *AlertNotificationService) HandleNotificationTestCommand(ctx context.Context, cmd *NotificationTestCommand) error {
|
||||
notifier := newNotificationService(nil, nil)
|
||||
|
||||
model := &models.AlertNotification{
|
||||
Name: cmd.Name,
|
||||
@@ -56,7 +51,11 @@ func handleNotificationTestCommand(ctx context.Context, cmd *NotificationTestCom
|
||||
}
|
||||
|
||||
if query.Result.SecureSettings != nil {
|
||||
secureSettingsMap = query.Result.SecureSettings.Decrypt()
|
||||
var err error
|
||||
secureSettingsMap, err = s.EncryptionService.DecryptJsonData(ctx, query.Result.SecureSettings, setting.SecretKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +63,13 @@ func handleNotificationTestCommand(ctx context.Context, cmd *NotificationTestCom
|
||||
secureSettingsMap[k] = v
|
||||
}
|
||||
|
||||
model.SecureSettings = securejsondata.GetEncryptedJsonData(secureSettingsMap)
|
||||
|
||||
notifiers, err := InitNotifier(model)
|
||||
var err error
|
||||
model.SecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, secureSettingsMap, setting.SecretKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notifiers, err := InitNotifier(model, s.EncryptionService.GetDecryptedValue)
|
||||
if err != nil {
|
||||
logger.Error("Failed to create notifier", "error", err.Error())
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user