diff --git a/pkg/services/ngalert/api/api_alertmanager_guards.go b/pkg/services/ngalert/api/api_alertmanager_guards.go index d619b22b8d5..735b823a6f5 100644 --- a/pkg/services/ngalert/api/api_alertmanager_guards.go +++ b/pkg/services/ngalert/api/api_alertmanager_guards.go @@ -1,15 +1,17 @@ package api import ( + "encoding/json" "fmt" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + amConfig "github.com/prometheus/alertmanager/config" + "github.com/prometheus/alertmanager/pkg/labels" + apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/util/cmputil" - amConfig "github.com/prometheus/alertmanager/config" - "github.com/prometheus/alertmanager/pkg/labels" ) func (srv AlertmanagerSrv) provenanceGuard(currentConfig apimodels.GettableUserConfig, newConfig apimodels.PostableUserConfig) error { @@ -96,11 +98,16 @@ func checkContactPoints(currReceivers []*apimodels.GettableApiReceiver, newRecei return editErr } } - existingSettings, err := contactPoint.Settings.Map() + existingSettings := map[string]interface{}{} + err := json.Unmarshal(contactPoint.Settings, &existingSettings) + if err != nil { + return err + } + newSettings := map[string]interface{}{} + err = json.Unmarshal(contactPoint.Settings, &newSettings) if err != nil { return err } - newSettings, err := postedContactPoint.Settings.Map() if err != nil { return err } diff --git a/pkg/services/ngalert/api/api_alertmanager_guards_test.go b/pkg/services/ngalert/api/api_alertmanager_guards_test.go index a87733d1c3a..a4a43b01182 100644 --- a/pkg/services/ngalert/api/api_alertmanager_guards_test.go +++ b/pkg/services/ngalert/api/api_alertmanager_guards_test.go @@ -3,14 +3,14 @@ package api import ( "testing" - "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" - "github.com/grafana/grafana/pkg/services/ngalert/models" amConfig "github.com/prometheus/alertmanager/config" "github.com/prometheus/alertmanager/pkg/labels" "github.com/prometheus/alertmanager/timeinterval" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" + "github.com/grafana/grafana/pkg/services/ngalert/models" ) func TestCheckRoute(t *testing.T) { @@ -319,9 +319,9 @@ func defaultGettableReceiver(t *testing.T, uid string, provenance models.Provena SecureFields: map[string]bool{ "url": true, }, - Settings: simplejson.NewFromAny(map[string]interface{}{ - "hello": "world", - }), + Settings: definitions.RawMessage(`{ + "hello": "world" + }`), }, }, }, @@ -338,9 +338,9 @@ func defaultPostableReceiver(t *testing.T, uid string) *definitions.PostableApiR Name: "yeah", Type: "slack", DisableResolveMessage: true, - Settings: simplejson.NewFromAny(map[string]interface{}{ - "hello": "world", - }), + Settings: definitions.RawMessage(`{ + "hello": "world" + }`), }, }, }, diff --git a/pkg/services/ngalert/api/tooling/definitions/alertmanager.go b/pkg/services/ngalert/api/tooling/definitions/alertmanager.go index d0ffd5c4cae..cb2d12c08f3 100644 --- a/pkg/services/ngalert/api/tooling/definitions/alertmanager.go +++ b/pkg/services/ngalert/api/tooling/definitions/alertmanager.go @@ -17,7 +17,6 @@ import ( "github.com/prometheus/common/model" "gopkg.in/yaml.v3" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/util" @@ -964,12 +963,54 @@ func AllReceivers(route *config.Route) (res []string) { return res } +type RawMessage json.RawMessage // This type alias adds YAML marshaling to the json.RawMessage. + +// MarshalJSON returns m as the JSON encoding of m. +func (r RawMessage) MarshalJSON() ([]byte, error) { + return json.Marshal(json.RawMessage(r)) +} + +func (r *RawMessage) UnmarshalJSON(data []byte) error { + var raw json.RawMessage + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + *r = RawMessage(raw) + return nil +} + +func (r *RawMessage) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data interface{} + if err := unmarshal(&data); err != nil { + return err + } + bytes, err := json.Marshal(data) + if err != nil { + return err + } + *r = bytes + return nil +} + +func (r RawMessage) MarshalYAML() (interface{}, error) { + if r == nil { + return nil, nil + } + var d interface{} + err := json.Unmarshal(r, &d) + if err != nil { + return nil, err + } + return d, nil +} + type GettableGrafanaReceiver struct { UID string `json:"uid"` Name string `json:"name"` Type string `json:"type"` DisableResolveMessage bool `json:"disableResolveMessage"` - Settings *simplejson.Json `json:"settings"` + Settings RawMessage `json:"settings,omitempty"` SecureFields map[string]bool `json:"secureFields"` Provenance models.Provenance `json:"provenance,omitempty"` } @@ -979,7 +1020,7 @@ type PostableGrafanaReceiver struct { Name string `json:"name"` Type string `json:"type"` DisableResolveMessage bool `json:"disableResolveMessage"` - Settings *simplejson.Json `json:"settings"` + Settings RawMessage `json:"settings,omitempty"` SecureSettings map[string]string `json:"secureSettings"` } diff --git a/pkg/services/ngalert/api/tooling/definitions/alertmanager_test.go b/pkg/services/ngalert/api/tooling/definitions/alertmanager_test.go index 03c8a1ca627..2b6f1a14319 100644 --- a/pkg/services/ngalert/api/tooling/definitions/alertmanager_test.go +++ b/pkg/services/ngalert/api/tooling/definitions/alertmanager_test.go @@ -1040,3 +1040,49 @@ func Test_Marshaling_Validation(t *testing.T) { expected := []model.LabelName{"alertname"} require.Equal(t, expected, tmp.AlertmanagerConfig.Config.Route.GroupBy) } + +func Test_RawMessageMarshaling(t *testing.T) { + type Data struct { + Field RawMessage `json:"field" yaml:"field"` + } + + t.Run("should unmarshal nil", func(t *testing.T) { + v := Data{ + Field: nil, + } + data, err := json.Marshal(v) + require.NoError(t, err) + assert.JSONEq(t, `{ "field": null }`, string(data)) + + var n Data + require.NoError(t, json.Unmarshal(data, &n)) + assert.Equal(t, RawMessage("null"), n.Field) + + data, err = yaml.Marshal(&v) + require.NoError(t, err) + assert.Equal(t, "field: null\n", string(data)) + + require.NoError(t, yaml.Unmarshal(data, &n)) + assert.Nil(t, n.Field) + }) + + t.Run("should unmarshal value", func(t *testing.T) { + v := Data{ + Field: RawMessage(`{ "data": "test"}`), + } + data, err := json.Marshal(v) + require.NoError(t, err) + assert.JSONEq(t, `{"field":{"data":"test"}}`, string(data)) + + var n Data + require.NoError(t, json.Unmarshal(data, &n)) + assert.Equal(t, RawMessage(`{"data":"test"}`), n.Field) + + data, err = yaml.Marshal(&v) + require.NoError(t, err) + assert.Equal(t, "field:\n data: test\n", string(data)) + + require.NoError(t, yaml.Unmarshal(data, &n)) + assert.Equal(t, RawMessage(`{"data":"test"}`), n.Field) + }) +} diff --git a/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go b/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go index 51eca266cd1..f8decca6afd 100644 --- a/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go +++ b/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go @@ -108,8 +108,12 @@ func (e *EmbeddedContactPoint) Valid(decryptFunc channels.GetDecryptedValueFn) e if !exists { return fmt.Errorf("unknown type '%s'", e.Type) } + jsonBytes, err := e.Settings.MarshalJSON() + if err != nil { + return err + } cfg, _ := channels.NewFactoryConfig(&channels.NotificationChannelConfig{ - Settings: e.Settings, + Settings: jsonBytes, Type: e.Type, }, nil, decryptFunc, nil, nil, func(ctx ...interface{}) channels.Logger { return &channels.FakeLogger{} diff --git a/pkg/services/ngalert/notifier/alertmanager.go b/pkg/services/ngalert/notifier/alertmanager.go index 07ccc2ba35b..d0e3fc01ba0 100644 --- a/pkg/services/ngalert/notifier/alertmanager.go +++ b/pkg/services/ngalert/notifier/alertmanager.go @@ -510,7 +510,7 @@ func (am *Alertmanager) buildReceiverIntegration(r *apimodels.PostableGrafanaRec Name: r.Name, Type: r.Type, DisableResolveMessage: r.DisableResolveMessage, - Settings: r.Settings, + Settings: json.RawMessage(r.Settings), SecureSettings: secureSettings, } ) diff --git a/pkg/services/ngalert/notifier/channels/alertmanager.go b/pkg/services/ngalert/notifier/channels/alertmanager.go index 82426c19a14..80be1663e26 100644 --- a/pkg/services/ngalert/notifier/channels/alertmanager.go +++ b/pkg/services/ngalert/notifier/channels/alertmanager.go @@ -11,6 +11,8 @@ import ( "github.com/prometheus/alertmanager/template" "github.com/prometheus/alertmanager/types" "github.com/prometheus/common/model" + + "github.com/grafana/grafana/pkg/components/simplejson" ) // GetDecryptedValueFn is a function that returns the decrypted value of @@ -25,7 +27,11 @@ type AlertmanagerConfig struct { } func NewAlertmanagerConfig(config *NotificationChannelConfig, fn GetDecryptedValueFn) (*AlertmanagerConfig, error) { - urlStr := config.Settings.Get("url").MustString() + simpleConfig, err := simplejson.NewJson(config.Settings) + if err != nil { + return nil, err + } + urlStr := simpleConfig.Get("url").MustString() if urlStr == "" { return nil, errors.New("could not find url property in settings") } @@ -48,8 +54,8 @@ func NewAlertmanagerConfig(config *NotificationChannelConfig, fn GetDecryptedVal return &AlertmanagerConfig{ NotificationChannelConfig: config, URLs: urls, - BasicAuthUser: config.Settings.Get("basicAuthUser").MustString(), - BasicAuthPassword: fn(context.Background(), config.SecureSettings, "basicAuthPassword", config.Settings.Get("basicAuthPassword").MustString()), + BasicAuthUser: simpleConfig.Get("basicAuthUser").MustString(), + BasicAuthPassword: fn(context.Background(), config.SecureSettings, "basicAuthPassword", simpleConfig.Get("basicAuthPassword").MustString()), }, nil } diff --git a/pkg/services/ngalert/notifier/channels/alertmanager_test.go b/pkg/services/ngalert/notifier/channels/alertmanager_test.go index cd1cef1040d..c61a147afff 100644 --- a/pkg/services/ngalert/notifier/channels/alertmanager_test.go +++ b/pkg/services/ngalert/notifier/channels/alertmanager_test.go @@ -7,7 +7,6 @@ import ( "net/url" "testing" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -46,14 +45,12 @@ func TestNewAlertmanagerNotifier(t *testing.T) { } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) secureSettings := make(map[string][]byte) m := &NotificationChannelConfig{ Name: c.receiverName, Type: "prometheus-alertmanager", - Settings: settingsJSON, + Settings: json.RawMessage(c.settings), SecureSettings: secureSettings, } @@ -143,7 +140,7 @@ func TestAlertmanagerNotifier_Notify(t *testing.T) { } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) + settingsJSON := json.RawMessage(c.settings) require.NoError(t, err) secureSettings := make(map[string][]byte) diff --git a/pkg/services/ngalert/notifier/channels/dingding.go b/pkg/services/ngalert/notifier/channels/dingding.go index 12b00ca2067..af4648d99c6 100644 --- a/pkg/services/ngalert/notifier/channels/dingding.go +++ b/pkg/services/ngalert/notifier/channels/dingding.go @@ -9,6 +9,8 @@ import ( "github.com/prometheus/alertmanager/template" "github.com/prometheus/alertmanager/types" + + "github.com/grafana/grafana/pkg/components/simplejson" ) const defaultDingdingMsgType = "link" @@ -21,15 +23,19 @@ type dingDingSettings struct { } func buildDingDingSettings(fc FactoryConfig) (*dingDingSettings, error) { - URL := fc.Config.Settings.Get("url").MustString() + settings, err := simplejson.NewJson(fc.Config.Settings) + if err != nil { + return nil, err + } + URL := settings.Get("url").MustString() if URL == "" { return nil, errors.New("could not find url property in settings") } return &dingDingSettings{ URL: URL, - MessageType: fc.Config.Settings.Get("msgType").MustString(defaultDingdingMsgType), - Title: fc.Config.Settings.Get("title").MustString(DefaultMessageTitleEmbed), - Message: fc.Config.Settings.Get("message").MustString(DefaultMessageEmbed), + MessageType: settings.Get("msgType").MustString(defaultDingdingMsgType), + Title: settings.Get("title").MustString(DefaultMessageTitleEmbed), + Message: settings.Get("message").MustString(DefaultMessageEmbed), }, nil } diff --git a/pkg/services/ngalert/notifier/channels/dingding_test.go b/pkg/services/ngalert/notifier/channels/dingding_test.go index efbb4e140e2..f0618cf61a1 100644 --- a/pkg/services/ngalert/notifier/channels/dingding_test.go +++ b/pkg/services/ngalert/notifier/channels/dingding_test.go @@ -10,8 +10,6 @@ import ( "github.com/prometheus/alertmanager/types" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/components/simplejson" ) func TestDingdingNotifier(t *testing.T) { @@ -166,15 +164,12 @@ func TestDingdingNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) - webhookSender := mockNotificationService() fc := FactoryConfig{ Config: &NotificationChannelConfig{ Name: "dingding_testing", Type: "dingding", - Settings: settingsJSON, + Settings: json.RawMessage(c.settings), }, // TODO: allow changing the associated values for different tests. NotificationService: webhookSender, diff --git a/pkg/services/ngalert/notifier/channels/discord.go b/pkg/services/ngalert/notifier/channels/discord.go index 2b87c5b4e84..8840e340a01 100644 --- a/pkg/services/ngalert/notifier/channels/discord.go +++ b/pkg/services/ngalert/notifier/channels/discord.go @@ -59,7 +59,11 @@ func DiscordFactory(fc FactoryConfig) (NotificationChannel, error) { } func newDiscordNotifier(fc FactoryConfig) (*DiscordNotifier, error) { - dUrl := fc.Config.Settings.Get("url").MustString() + settings, err := simplejson.NewJson(fc.Config.Settings) + if err != nil { + return nil, err + } + dUrl := settings.Get("url").MustString() if dUrl == "" { return nil, errors.New("could not find webhook url property in settings") } @@ -71,11 +75,11 @@ func newDiscordNotifier(fc FactoryConfig) (*DiscordNotifier, error) { images: fc.ImageStore, tmpl: fc.Template, settings: discordSettings{ - Title: fc.Config.Settings.Get("title").MustString(DefaultMessageTitleEmbed), - Content: fc.Config.Settings.Get("message").MustString(DefaultMessageEmbed), - AvatarURL: fc.Config.Settings.Get("avatar_url").MustString(), + Title: settings.Get("title").MustString(DefaultMessageTitleEmbed), + Content: settings.Get("message").MustString(DefaultMessageEmbed), + AvatarURL: settings.Get("avatar_url").MustString(), WebhookURL: dUrl, - UseDiscordUsername: fc.Config.Settings.Get("use_discord_username").MustBool(false), + UseDiscordUsername: settings.Get("use_discord_username").MustBool(false), }, }, nil } diff --git a/pkg/services/ngalert/notifier/channels/discord_test.go b/pkg/services/ngalert/notifier/channels/discord_test.go index 8e068a5bb37..e2972182a4c 100644 --- a/pkg/services/ngalert/notifier/channels/discord_test.go +++ b/pkg/services/ngalert/notifier/channels/discord_test.go @@ -11,7 +11,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/setting" ) @@ -287,8 +286,6 @@ func TestDiscordNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJson, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) webhookSender := mockNotificationService() imageStore := &UnavailableImageStore{} @@ -296,7 +293,7 @@ func TestDiscordNotifier(t *testing.T) { Config: &NotificationChannelConfig{ Name: "discord_testing", Type: "discord", - Settings: settingsJson, + Settings: json.RawMessage(c.settings), }, ImageStore: imageStore, // TODO: allow changing the associated values for different tests. diff --git a/pkg/services/ngalert/notifier/channels/email.go b/pkg/services/ngalert/notifier/channels/email.go index 697da0ac0db..6249eaa047f 100644 --- a/pkg/services/ngalert/notifier/channels/email.go +++ b/pkg/services/ngalert/notifier/channels/email.go @@ -11,6 +11,7 @@ import ( "github.com/prometheus/alertmanager/template" "github.com/prometheus/alertmanager/types" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/util" ) @@ -48,7 +49,11 @@ func EmailFactory(fc FactoryConfig) (NotificationChannel, error) { } func NewEmailConfig(config *NotificationChannelConfig) (*EmailConfig, error) { - addressesString := config.Settings.Get("addresses").MustString() + settings, err := simplejson.NewJson(config.Settings) + if err != nil { + return nil, err + } + addressesString := settings.Get("addresses").MustString() if addressesString == "" { return nil, errors.New("could not find addresses in settings") } @@ -56,9 +61,9 @@ func NewEmailConfig(config *NotificationChannelConfig) (*EmailConfig, error) { addresses := util.SplitEmails(addressesString) return &EmailConfig{ NotificationChannelConfig: config, - SingleEmail: config.Settings.Get("singleEmail").MustBool(false), - Message: config.Settings.Get("message").MustString(), - Subject: config.Settings.Get("subject").MustString(DefaultMessageTitleEmbed), + SingleEmail: settings.Get("singleEmail").MustBool(false), + Message: settings.Get("message").MustString(), + Subject: settings.Get("subject").MustString(DefaultMessageTitleEmbed), Addresses: addresses, }, nil } diff --git a/pkg/services/ngalert/notifier/channels/email_test.go b/pkg/services/ngalert/notifier/channels/email_test.go index 767a928e3df..f4a02aad302 100644 --- a/pkg/services/ngalert/notifier/channels/email_test.go +++ b/pkg/services/ngalert/notifier/channels/email_test.go @@ -2,6 +2,7 @@ package channels import ( "context" + "encoding/json" "net/url" "testing" @@ -10,7 +11,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/notifications" ) @@ -22,9 +22,8 @@ func TestEmailNotifier(t *testing.T) { tmpl.ExternalURL = externalURL t.Run("empty settings should return error", func(t *testing.T) { - json := `{ }` - - settingsJSON, _ := simplejson.NewJson([]byte(json)) + jsonData := `{ }` + settingsJSON := json.RawMessage(jsonData) model := &NotificationChannelConfig{ Name: "ops", Type: "email", @@ -36,18 +35,16 @@ func TestEmailNotifier(t *testing.T) { }) t.Run("with the correct settings it should not fail and produce the expected command", func(t *testing.T) { - json := `{ + jsonData := `{ "addresses": "someops@example.com;somedev@example.com", "message": "{{ template \"default.title\" . }}" }` - settingsJSON, err := simplejson.NewJson([]byte(json)) - require.NoError(t, err) emailSender := mockNotificationService() cfg, err := NewEmailConfig(&NotificationChannelConfig{ Name: "ops", Type: "email", - Settings: settingsJSON, + Settings: json.RawMessage(jsonData), }) require.NoError(t, err) emailNotifier := NewEmailNotifier(cfg, &FakeLogger{}, emailSender, &UnavailableImageStore{}, tmpl) @@ -270,24 +267,23 @@ func TestEmailNotifierIntegration(t *testing.T) { func createSut(t *testing.T, messageTmpl string, subjectTmpl string, emailTmpl *template.Template, ns *emailSender) *EmailNotifier { t.Helper() - json := `{ - "addresses": "someops@example.com;somedev@example.com", - "singleEmail": true - }` - settingsJSON, err := simplejson.NewJson([]byte(json)) + jsonData := map[string]interface{}{ + "addresses": "someops@example.com;somedev@example.com", + "singleEmail": true, + } if messageTmpl != "" { - settingsJSON.Set("message", messageTmpl) + jsonData["message"] = messageTmpl } if subjectTmpl != "" { - settingsJSON.Set("subject", subjectTmpl) + jsonData["subject"] = subjectTmpl } - + bytes, err := json.Marshal(jsonData) require.NoError(t, err) cfg, err := NewEmailConfig(&NotificationChannelConfig{ Name: "ops", Type: "email", - Settings: settingsJSON, + Settings: bytes, }) require.NoError(t, err) emailNotifier := NewEmailNotifier(cfg, &FakeLogger{}, ns, &UnavailableImageStore{}, emailTmpl) diff --git a/pkg/services/ngalert/notifier/channels/googlechat.go b/pkg/services/ngalert/notifier/channels/googlechat.go index 1cda3c58210..da8d5fb0880 100644 --- a/pkg/services/ngalert/notifier/channels/googlechat.go +++ b/pkg/services/ngalert/notifier/channels/googlechat.go @@ -11,6 +11,7 @@ import ( "github.com/prometheus/alertmanager/template" "github.com/prometheus/alertmanager/types" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/setting" ) @@ -49,7 +50,11 @@ func newGoogleChatNotifier(fc FactoryConfig) (*GoogleChatNotifier, error) { return nil, fmt.Errorf("failed to unmarshal settings: %w", err) } - URL := fc.Config.Settings.Get("url").MustString() + rawsettings, err := simplejson.NewJson(fc.Config.Settings) + if err != nil { + return nil, err + } + URL := rawsettings.Get("url").MustString() if URL == "" { return nil, errors.New("could not find url property in settings") } @@ -62,8 +67,8 @@ func newGoogleChatNotifier(fc FactoryConfig) (*GoogleChatNotifier, error) { tmpl: fc.Template, settings: googleChatSettings{ URL: URL, - Title: fc.Config.Settings.Get("title").MustString(DefaultMessageTitleEmbed), - Content: fc.Config.Settings.Get("message").MustString(DefaultMessageEmbed), + Title: rawsettings.Get("title").MustString(DefaultMessageTitleEmbed), + Content: rawsettings.Get("message").MustString(DefaultMessageEmbed), }, }, nil } diff --git a/pkg/services/ngalert/notifier/channels/googlechat_test.go b/pkg/services/ngalert/notifier/channels/googlechat_test.go index 81e571de386..adae8138140 100644 --- a/pkg/services/ngalert/notifier/channels/googlechat_test.go +++ b/pkg/services/ngalert/notifier/channels/googlechat_test.go @@ -12,7 +12,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/setting" ) @@ -462,9 +461,6 @@ func TestGoogleChatNotifier(t *testing.T) { require.NoError(t, err) tmpl.ExternalURL = externalURL - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) - webhookSender := mockNotificationService() imageStore := &UnavailableImageStore{} @@ -472,7 +468,7 @@ func TestGoogleChatNotifier(t *testing.T) { Config: &NotificationChannelConfig{ Name: "googlechat_testing", Type: "googlechat", - Settings: settingsJSON, + Settings: json.RawMessage(c.settings), }, ImageStore: imageStore, NotificationService: webhookSender, diff --git a/pkg/services/ngalert/notifier/channels/kafka.go b/pkg/services/ngalert/notifier/channels/kafka.go index babfb42598c..6dad1bec1d0 100644 --- a/pkg/services/ngalert/notifier/channels/kafka.go +++ b/pkg/services/ngalert/notifier/channels/kafka.go @@ -45,16 +45,20 @@ func KafkaFactory(fc FactoryConfig) (NotificationChannel, error) { // newKafkaNotifier is the constructor function for the Kafka notifier. func newKafkaNotifier(fc FactoryConfig) (*KafkaNotifier, error) { - endpoint := fc.Config.Settings.Get("kafkaRestProxy").MustString() + settings, err := simplejson.NewJson(fc.Config.Settings) + if err != nil { + return nil, err + } + endpoint := settings.Get("kafkaRestProxy").MustString() if endpoint == "" { return nil, errors.New("could not find kafka rest proxy endpoint property in settings") } - topic := fc.Config.Settings.Get("kafkaTopic").MustString() + topic := settings.Get("kafkaTopic").MustString() if topic == "" { return nil, errors.New("could not find kafka topic property in settings") } - description := fc.Config.Settings.Get("description").MustString(DefaultMessageTitleEmbed) - details := fc.Config.Settings.Get("details").MustString(DefaultMessageEmbed) + description := settings.Get("description").MustString(DefaultMessageTitleEmbed) + details := settings.Get("details").MustString(DefaultMessageEmbed) return &KafkaNotifier{ Base: NewBase(fc.Config), diff --git a/pkg/services/ngalert/notifier/channels/kafka_test.go b/pkg/services/ngalert/notifier/channels/kafka_test.go index 32bf108b19a..a7bbd15adf4 100644 --- a/pkg/services/ngalert/notifier/channels/kafka_test.go +++ b/pkg/services/ngalert/notifier/channels/kafka_test.go @@ -2,6 +2,7 @@ package channels import ( "context" + "encoding/json" "net/url" "testing" @@ -9,8 +10,6 @@ import ( "github.com/prometheus/alertmanager/types" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/components/simplejson" ) func TestKafkaNotifier(t *testing.T) { @@ -112,16 +111,13 @@ func TestKafkaNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) - webhookSender := mockNotificationService() fc := FactoryConfig{ Config: &NotificationChannelConfig{ Name: "kafka_testing", Type: "kafka", - Settings: settingsJSON, + Settings: json.RawMessage(c.settings), }, ImageStore: images, // TODO: allow changing the associated values for different tests. diff --git a/pkg/services/ngalert/notifier/channels/line.go b/pkg/services/ngalert/notifier/channels/line.go index 46ffcc31ff8..7c9a9a7c9eb 100644 --- a/pkg/services/ngalert/notifier/channels/line.go +++ b/pkg/services/ngalert/notifier/channels/line.go @@ -9,6 +9,8 @@ import ( "github.com/prometheus/alertmanager/template" "github.com/prometheus/alertmanager/types" + + "github.com/grafana/grafana/pkg/components/simplejson" ) var ( @@ -44,12 +46,16 @@ func LineFactory(fc FactoryConfig) (NotificationChannel, error) { // newLineNotifier is the constructor for the LINE notifier func newLineNotifier(fc FactoryConfig) (*LineNotifier, error) { - token := fc.DecryptFunc(context.Background(), fc.Config.SecureSettings, "token", fc.Config.Settings.Get("token").MustString()) + settings, err := simplejson.NewJson(fc.Config.Settings) + if err != nil { + return nil, err + } + token := fc.DecryptFunc(context.Background(), fc.Config.SecureSettings, "token", settings.Get("token").MustString()) if token == "" { return nil, errors.New("could not find token in settings") } - title := fc.Config.Settings.Get("title").MustString(DefaultMessageTitleEmbed) - description := fc.Config.Settings.Get("description").MustString(DefaultMessageEmbed) + title := settings.Get("title").MustString(DefaultMessageTitleEmbed) + description := settings.Get("description").MustString(DefaultMessageEmbed) return &LineNotifier{ Base: NewBase(fc.Config), diff --git a/pkg/services/ngalert/notifier/channels/line_test.go b/pkg/services/ngalert/notifier/channels/line_test.go index 5bbe0d2381f..0f509d6fdd9 100644 --- a/pkg/services/ngalert/notifier/channels/line_test.go +++ b/pkg/services/ngalert/notifier/channels/line_test.go @@ -2,6 +2,7 @@ package channels import ( "context" + "encoding/json" "net/url" "testing" @@ -10,7 +11,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" ) @@ -96,8 +96,7 @@ func TestLineNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) webhookSender := mockNotificationService() secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) diff --git a/pkg/services/ngalert/notifier/channels/opsgenie_test.go b/pkg/services/ngalert/notifier/channels/opsgenie_test.go index bca54178e5d..dc40be38455 100644 --- a/pkg/services/ngalert/notifier/channels/opsgenie_test.go +++ b/pkg/services/ngalert/notifier/channels/opsgenie_test.go @@ -2,11 +2,11 @@ package channels import ( "context" + "encoding/json" "net/url" "testing" "time" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -230,8 +230,7 @@ func TestOpsgenieNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) webhookSender := mockNotificationService() diff --git a/pkg/services/ngalert/notifier/channels/pagerduty_test.go b/pkg/services/ngalert/notifier/channels/pagerduty_test.go index 811a5f493bc..cdc094be1f7 100644 --- a/pkg/services/ngalert/notifier/channels/pagerduty_test.go +++ b/pkg/services/ngalert/notifier/channels/pagerduty_test.go @@ -15,7 +15,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" ) @@ -276,8 +275,7 @@ func TestPagerdutyNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) webhookSender := mockNotificationService() secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) diff --git a/pkg/services/ngalert/notifier/channels/pushover_test.go b/pkg/services/ngalert/notifier/channels/pushover_test.go index 7cd5b6b1e18..16c5e1d81e1 100644 --- a/pkg/services/ngalert/notifier/channels/pushover_test.go +++ b/pkg/services/ngalert/notifier/channels/pushover_test.go @@ -3,6 +3,7 @@ package channels import ( "bytes" "context" + "encoding/json" "errors" "fmt" "io" @@ -11,7 +12,6 @@ import ( "strings" "testing" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -210,8 +210,7 @@ func TestPushoverNotifier(t *testing.T) { }) t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) webhookSender := mockNotificationService() diff --git a/pkg/services/ngalert/notifier/channels/sensugo_test.go b/pkg/services/ngalert/notifier/channels/sensugo_test.go index f032b49c9e4..7bc3b47d8a0 100644 --- a/pkg/services/ngalert/notifier/channels/sensugo_test.go +++ b/pkg/services/ngalert/notifier/channels/sensugo_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -137,8 +136,7 @@ func TestSensuGoNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) m := &NotificationChannelConfig{ diff --git a/pkg/services/ngalert/notifier/channels/slack_test.go b/pkg/services/ngalert/notifier/channels/slack_test.go index fb09cdd57e5..ebbaee10342 100644 --- a/pkg/services/ngalert/notifier/channels/slack_test.go +++ b/pkg/services/ngalert/notifier/channels/slack_test.go @@ -19,7 +19,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/setting" @@ -422,10 +421,6 @@ func setupSlackForTests(t *testing.T, settings string) (*SlackNotifier, *slackRe URL: "https://www.example.com/test.png", }}, } - - settingsJSON, err := simplejson.NewJson([]byte(settings)) - require.NoError(t, err) - secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) notificationService := mockNotificationService() @@ -433,7 +428,7 @@ func setupSlackForTests(t *testing.T, settings string) (*SlackNotifier, *slackRe Config: &NotificationChannelConfig{ Name: "slack_testing", Type: "slack", - Settings: settingsJSON, + Settings: json.RawMessage(settings), SecureSettings: make(map[string][]byte), }, ImageStore: images, diff --git a/pkg/services/ngalert/notifier/channels/teams_test.go b/pkg/services/ngalert/notifier/channels/teams_test.go index 4b544b73699..a9117911b21 100644 --- a/pkg/services/ngalert/notifier/channels/teams_test.go +++ b/pkg/services/ngalert/notifier/channels/teams_test.go @@ -11,8 +11,6 @@ import ( "github.com/prometheus/alertmanager/types" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/components/simplejson" ) func TestTeamsNotifier(t *testing.T) { @@ -249,8 +247,7 @@ func TestTeamsNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) m := &NotificationChannelConfig{ Name: "teams_testing", diff --git a/pkg/services/ngalert/notifier/channels/telegram_test.go b/pkg/services/ngalert/notifier/channels/telegram_test.go index d37fbca1b85..e59eeba1091 100644 --- a/pkg/services/ngalert/notifier/channels/telegram_test.go +++ b/pkg/services/ngalert/notifier/channels/telegram_test.go @@ -2,11 +2,11 @@ package channels import ( "context" + "encoding/json" "net/url" "strings" "testing" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -116,7 +116,7 @@ func TestTelegramNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) + settingsJSON := json.RawMessage(c.settings) require.NoError(t, err) secureSettings := make(map[string][]byte) diff --git a/pkg/services/ngalert/notifier/channels/threema_test.go b/pkg/services/ngalert/notifier/channels/threema_test.go index 8452bb9131c..46e924677af 100644 --- a/pkg/services/ngalert/notifier/channels/threema_test.go +++ b/pkg/services/ngalert/notifier/channels/threema_test.go @@ -2,10 +2,10 @@ package channels import ( "context" + "encoding/json" "net/url" "testing" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -118,8 +118,7 @@ func TestThreemaNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) webhookSender := mockNotificationService() secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) diff --git a/pkg/services/ngalert/notifier/channels/util.go b/pkg/services/ngalert/notifier/channels/util.go index 07c97d45194..8959c8af16a 100644 --- a/pkg/services/ngalert/notifier/channels/util.go +++ b/pkg/services/ngalert/notifier/channels/util.go @@ -24,8 +24,6 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/util" - - "github.com/grafana/grafana/pkg/components/simplejson" ) const ( @@ -170,20 +168,12 @@ type NotificationChannelConfig struct { Name string `json:"name"` Type string `json:"type"` DisableResolveMessage bool `json:"disableResolveMessage"` - Settings *simplejson.Json `json:"settings"` + Settings json.RawMessage `json:"settings"` SecureSettings map[string][]byte `json:"secureSettings"` } func (c NotificationChannelConfig) unmarshalSettings(v interface{}) error { - ser, err := c.Settings.Encode() - if err != nil { - return err - } - err = json.Unmarshal(ser, v) - if err != nil { - return err - } - return nil + return json.Unmarshal(c.Settings, v) } type httpCfg struct { diff --git a/pkg/services/ngalert/notifier/channels/victorops_test.go b/pkg/services/ngalert/notifier/channels/victorops_test.go index eb90d43301b..c7c4f70a359 100644 --- a/pkg/services/ngalert/notifier/channels/victorops_test.go +++ b/pkg/services/ngalert/notifier/channels/victorops_test.go @@ -11,7 +11,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/setting" ) @@ -188,8 +187,7 @@ func TestVictoropsNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) m := &NotificationChannelConfig{ Name: "victorops_testing", @@ -230,10 +228,11 @@ func TestVictoropsNotifier(t *testing.T) { require.NotEmpty(t, webhookSender.Webhook.Url) // Remove the non-constant timestamp - j, err := simplejson.NewJson([]byte(webhookSender.Webhook.Body)) + data := make(map[string]interface{}) + err = json.Unmarshal([]byte(webhookSender.Webhook.Body), &data) require.NoError(t, err) - j.Del("timestamp") - b, err := j.MarshalJSON() + delete(data, "timestamp") + b, err := json.Marshal(data) require.NoError(t, err) body := string(b) diff --git a/pkg/services/ngalert/notifier/channels/webex_test.go b/pkg/services/ngalert/notifier/channels/webex_test.go index c3806f422b2..ddccb105b99 100644 --- a/pkg/services/ngalert/notifier/channels/webex_test.go +++ b/pkg/services/ngalert/notifier/channels/webex_test.go @@ -2,12 +2,12 @@ package channels import ( "context" + "encoding/json" "fmt" "net/url" "strings" "testing" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -105,8 +105,7 @@ func TestWebexNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) diff --git a/pkg/services/ngalert/notifier/channels/webhook_test.go b/pkg/services/ngalert/notifier/channels/webhook_test.go index 353fe566efd..5b6d131fc26 100644 --- a/pkg/services/ngalert/notifier/channels/webhook_test.go +++ b/pkg/services/ngalert/notifier/channels/webhook_test.go @@ -7,7 +7,6 @@ import ( "net/url" "testing" - "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" @@ -337,8 +336,7 @@ func TestWebhookNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) secureSettings := make(map[string][]byte) m := &NotificationChannelConfig{ diff --git a/pkg/services/ngalert/notifier/channels/wecom_test.go b/pkg/services/ngalert/notifier/channels/wecom_test.go index fce2004fbd7..3f80838922e 100644 --- a/pkg/services/ngalert/notifier/channels/wecom_test.go +++ b/pkg/services/ngalert/notifier/channels/wecom_test.go @@ -19,8 +19,6 @@ import ( "github.com/prometheus/common/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/components/simplejson" ) func TestWeComNotifier(t *testing.T) { @@ -159,8 +157,7 @@ func TestWeComNotifier(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(c.settings)) - require.NoError(t, err) + settingsJSON := json.RawMessage(c.settings) m := &NotificationChannelConfig{ Name: "wecom_testing", @@ -345,13 +342,10 @@ func TestWeComNotifierAPIAPP(t *testing.T) { })) defer server.Close() - settingsJSON, err := simplejson.NewJson([]byte(tt.settings)) - require.NoError(t, err) - m := &NotificationChannelConfig{ Name: "wecom_testing", Type: "wecom", - Settings: settingsJSON, + Settings: json.RawMessage(tt.settings), } webhookSender := mockNotificationService() @@ -532,13 +526,10 @@ func TestWeComFactory(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - settingsJSON, err := simplejson.NewJson([]byte(tt.settings)) - require.NoError(t, err) - m := &NotificationChannelConfig{ Name: "wecom_testing", Type: "wecom", - Settings: settingsJSON, + Settings: json.RawMessage(tt.settings), } webhookSender := mockNotificationService() @@ -552,7 +543,7 @@ func TestWeComFactory(t *testing.T) { Logger: &FakeLogger{}, } - _, err = WeComFactory(fc) + _, err := WeComFactory(fc) if !tt.wantErr(t, err, fmt.Sprintf("WeComFactory(%v)", fc)) { return } diff --git a/pkg/services/ngalert/provisioning/contactpoints.go b/pkg/services/ngalert/provisioning/contactpoints.go index f0143c7d049..8a647384fda 100644 --- a/pkg/services/ngalert/provisioning/contactpoints.go +++ b/pkg/services/ngalert/provisioning/contactpoints.go @@ -7,12 +7,14 @@ import ( "fmt" "sort" + "github.com/prometheus/alertmanager/config" + + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/secrets" "github.com/grafana/grafana/pkg/util" - "github.com/prometheus/alertmanager/config" ) type ContactPointService struct { @@ -55,12 +57,16 @@ func (ecp *ContactPointService) GetContactPoints(ctx context.Context, q ContactP continue } + simpleJson, err := simplejson.NewJson(contactPoint.Settings) + if err != nil { + return nil, err + } embeddedContactPoint := apimodels.EmbeddedContactPoint{ UID: contactPoint.UID, Type: contactPoint.Type, Name: contactPoint.Name, DisableResolveMessage: contactPoint.DisableResolveMessage, - Settings: contactPoint.Settings, + Settings: simpleJson, } if val, exists := provenances[embeddedContactPoint.UID]; exists && val != "" { embeddedContactPoint.Provenance = string(val) @@ -96,12 +102,16 @@ func (ecp *ContactPointService) getContactPointDecrypted(ctx context.Context, or if receiver.UID != uid { continue } + simpleJson, err := simplejson.NewJson(receiver.Settings) + if err != nil { + return apimodels.EmbeddedContactPoint{}, err + } embeddedContactPoint := apimodels.EmbeddedContactPoint{ UID: receiver.UID, Type: receiver.Type, Name: receiver.Name, DisableResolveMessage: receiver.DisableResolveMessage, - Settings: receiver.Settings, + Settings: simpleJson, } for k, v := range receiver.SecureSettings { decryptedValue, err := ecp.decryptValue(v) @@ -146,12 +156,18 @@ func (ecp *ContactPointService) CreateContactPoint(ctx context.Context, orgID in if contactPoint.UID == "" { contactPoint.UID = util.GenerateShortUID() } + + jsonData, err := contactPoint.Settings.MarshalJSON() + if err != nil { + return apimodels.EmbeddedContactPoint{}, err + } + grafanaReceiver := &apimodels.PostableGrafanaReceiver{ UID: contactPoint.UID, Name: contactPoint.Name, Type: contactPoint.Type, DisableResolveMessage: contactPoint.DisableResolveMessage, - Settings: contactPoint.Settings, + Settings: jsonData, SecureSettings: extractedSecrets, } @@ -260,12 +276,17 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in } extractedSecrets[k] = encryptedValue } + + jsonData, err := contactPoint.Settings.MarshalJSON() + if err != nil { + return err + } mergedReceiver := &apimodels.PostableGrafanaReceiver{ UID: contactPoint.UID, Name: contactPoint.Name, Type: contactPoint.Type, DisableResolveMessage: contactPoint.DisableResolveMessage, - Settings: contactPoint.Settings, + Settings: jsonData, SecureSettings: extractedSecrets, } // save to store diff --git a/pkg/services/sqlstore/migrations/ualert/ualert.go b/pkg/services/sqlstore/migrations/ualert/ualert.go index 8bf0f50f980..2a346a21d46 100644 --- a/pkg/services/sqlstore/migrations/ualert/ualert.go +++ b/pkg/services/sqlstore/migrations/ualert/ualert.go @@ -470,6 +470,10 @@ func (m *migration) validateAlertmanagerConfig(orgID int64, config *PostableUser secureSettings[k] = d } + data, err := gr.Settings.MarshalJSON() + if err != nil { + return err + } var ( cfg = &channels.NotificationChannelConfig{ UID: gr.UID, @@ -477,10 +481,9 @@ func (m *migration) validateAlertmanagerConfig(orgID int64, config *PostableUser Name: gr.Name, Type: gr.Type, DisableResolveMessage: gr.DisableResolveMessage, - Settings: gr.Settings, + Settings: data, SecureSettings: secureSettings, } - err error ) // decryptFunc represents the legacy way of decrypting data. Before the migration, we don't need any new way,