mirror of https://github.com/grafana/grafana.git
Alerting: Update alerting module + refactor (#111761)
* update alerting module * replace compat with ones from alerting * update type references Receiver and Integration to *Status * update route in provisioning test that is invalid after recent change * use right type for LINE ingtegration
This commit is contained in:
parent
cca9e0d55f
commit
d0f79ee60d
|
@ -201,7 +201,7 @@ require (
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||||
github.com/gorilla/mux v1.8.1 // indirect
|
github.com/gorilla/mux v1.8.1 // indirect
|
||||||
github.com/grafana/alerting v0.0.0-20250925200825-7a889aa4934d // indirect
|
github.com/grafana/alerting v0.0.0-20251002001425-eeed80da0165 // indirect
|
||||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect
|
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect
|
||||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 // indirect
|
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 // indirect
|
||||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||||
|
|
|
@ -721,8 +721,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||||
github.com/grafana/alerting v0.0.0-20250925200825-7a889aa4934d h1:zzEty7HgfXbQ/RiBCJFMqaZiJlqiXuz/Zbc6/H6ksuM=
|
github.com/grafana/alerting v0.0.0-20251002001425-eeed80da0165 h1:wfehM99Xlpltl9MQx8SITkgFgHmPGqrXoBCVLk/Q6NA=
|
||||||
github.com/grafana/alerting v0.0.0-20250925200825-7a889aa4934d/go.mod h1:T5sitas9VhVj8/S9LeRLy6H75kTBdh/sCCqHo7gaQI8=
|
github.com/grafana/alerting v0.0.0-20251002001425-eeed80da0165/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
||||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
|
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
|
||||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 h1:qEwZ+7MbPjzRvTi31iT9w7NBhKIpKwZrFbYmOZLqkwA=
|
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 h1:qEwZ+7MbPjzRvTi31iT9w7NBhKIpKwZrFbYmOZLqkwA=
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -86,7 +86,7 @@ require (
|
||||||
github.com/googleapis/gax-go/v2 v2.14.2 // @grafana/grafana-backend-group
|
github.com/googleapis/gax-go/v2 v2.14.2 // @grafana/grafana-backend-group
|
||||||
github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
|
github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad
|
||||||
github.com/grafana/alerting v0.0.0-20250925200825-7a889aa4934d // @grafana/alerting-backend
|
github.com/grafana/alerting v0.0.0-20251002001425-eeed80da0165 // @grafana/alerting-backend
|
||||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // @grafana/identity-access-team
|
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // @grafana/identity-access-team
|
||||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 // @grafana/identity-access-team
|
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 // @grafana/identity-access-team
|
||||||
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
|
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1585,8 +1585,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg
|
||||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||||
github.com/grafana/alerting v0.0.0-20250925200825-7a889aa4934d h1:zzEty7HgfXbQ/RiBCJFMqaZiJlqiXuz/Zbc6/H6ksuM=
|
github.com/grafana/alerting v0.0.0-20251002001425-eeed80da0165 h1:wfehM99Xlpltl9MQx8SITkgFgHmPGqrXoBCVLk/Q6NA=
|
||||||
github.com/grafana/alerting v0.0.0-20250925200825-7a889aa4934d/go.mod h1:T5sitas9VhVj8/S9LeRLy6H75kTBdh/sCCqHo7gaQI8=
|
github.com/grafana/alerting v0.0.0-20251002001425-eeed80da0165/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
||||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
|
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
|
||||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 h1:qEwZ+7MbPjzRvTi31iT9w7NBhKIpKwZrFbYmOZLqkwA=
|
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 h1:qEwZ+7MbPjzRvTi31iT9w7NBhKIpKwZrFbYmOZLqkwA=
|
||||||
|
|
|
@ -14,8 +14,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
|
||||||
prometheus "github.com/prometheus/alertmanager/config"
|
prometheus "github.com/prometheus/alertmanager/config"
|
||||||
"github.com/prometheus/alertmanager/pkg/labels"
|
"github.com/prometheus/alertmanager/pkg/labels"
|
||||||
"github.com/prometheus/alertmanager/timeinterval"
|
"github.com/prometheus/alertmanager/timeinterval"
|
||||||
|
@ -2033,12 +2032,12 @@ func TestApiContactPointExportSnapshot(t *testing.T) {
|
||||||
t.Run(fmt.Sprintf("exportType=%s", exportType), func(t *testing.T) {
|
t.Run(fmt.Sprintf("exportType=%s", exportType), func(t *testing.T) {
|
||||||
for _, redacted := range []bool{true, false} {
|
for _, redacted := range []bool{true, false} {
|
||||||
t.Run(fmt.Sprintf("redacted=%t", redacted), func(t *testing.T) {
|
t.Run(fmt.Sprintf("redacted=%t", redacted), func(t *testing.T) {
|
||||||
allIntegrations := make([]models.Integration, 0, len(alertingNotify.AllKnownConfigsForTesting))
|
allIntegrations := make([]models.Integration, 0, len(notifytest.AllKnownV1ConfigsForTesting))
|
||||||
for integrationType := range alertingNotify.AllKnownConfigsForTesting {
|
for integrationType := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
integration := models.IntegrationGen(
|
integration := models.IntegrationGen(
|
||||||
models.IntegrationMuts.WithName(allIntegrationsName),
|
models.IntegrationMuts.WithName(allIntegrationsName),
|
||||||
models.IntegrationMuts.WithUID(fmt.Sprintf("%s-uid", integrationType)),
|
models.IntegrationMuts.WithUID(fmt.Sprintf("%s-uid", strings.ToLower(string(integrationType)))),
|
||||||
models.IntegrationMuts.WithValidConfig(schema.IntegrationType(integrationType)),
|
models.IntegrationMuts.WithValidConfig(integrationType),
|
||||||
)()
|
)()
|
||||||
integration.DisableResolveMessage = redacted
|
integration.DisableResolveMessage = redacted
|
||||||
allIntegrations = append(allIntegrations, integration)
|
allIntegrations = append(allIntegrations, integration)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
alertingModels "github.com/grafana/alerting/models"
|
||||||
"github.com/grafana/alerting/notify"
|
"github.com/grafana/alerting/notify"
|
||||||
"github.com/grafana/alerting/receivers"
|
"github.com/grafana/alerting/receivers"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
@ -53,7 +54,7 @@ func ContactPointToContactPointExport(cp definitions.ContactPoint) (notify.APIRe
|
||||||
len(cp.Threema) + len(cp.Victorops) + len(cp.Webhook) + len(cp.Wecom) +
|
len(cp.Threema) + len(cp.Victorops) + len(cp.Webhook) + len(cp.Wecom) +
|
||||||
len(cp.Webex) + len(cp.Mqtt)
|
len(cp.Webex) + len(cp.Mqtt)
|
||||||
|
|
||||||
integration := make([]*notify.GrafanaIntegrationConfig, 0, contactPointsLength)
|
integration := make([]*alertingModels.IntegrationConfig, 0, contactPointsLength)
|
||||||
|
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, i := range cp.Alertmanager {
|
for _, i := range cp.Alertmanager {
|
||||||
|
@ -223,19 +224,19 @@ func ContactPointToContactPointExport(cp definitions.ContactPoint) (notify.APIRe
|
||||||
}
|
}
|
||||||
contactPoint := notify.APIReceiver{
|
contactPoint := notify.APIReceiver{
|
||||||
ConfigReceiver: notify.ConfigReceiver{Name: cp.Name},
|
ConfigReceiver: notify.ConfigReceiver{Name: cp.Name},
|
||||||
GrafanaIntegrations: notify.GrafanaIntegrations{Integrations: integration},
|
ReceiverConfig: alertingModels.ReceiverConfig{Integrations: integration},
|
||||||
}
|
}
|
||||||
return contactPoint, nil
|
return contactPoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshallIntegration converts the API model integration to the storage model that contains settings in the JSON format.
|
// marshallIntegration converts the API model integration to the storage model that contains settings in the JSON format.
|
||||||
// The secret fields are not encrypted.
|
// The secret fields are not encrypted.
|
||||||
func marshallIntegration(json jsoniter.API, integrationType string, integration interface{}, disableResolveMessage *bool) (*notify.GrafanaIntegrationConfig, error) {
|
func marshallIntegration(json jsoniter.API, integrationType string, integration interface{}, disableResolveMessage *bool) (*alertingModels.IntegrationConfig, error) {
|
||||||
data, err := json.Marshal(integration)
|
data, err := json.Marshal(integration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to marshall integration '%s' to JSON: %w", integrationType, err)
|
return nil, fmt.Errorf("failed to marshall integration '%s' to JSON: %w", integrationType, err)
|
||||||
}
|
}
|
||||||
e := ¬ify.GrafanaIntegrationConfig{
|
e := &alertingModels.IntegrationConfig{
|
||||||
Type: integrationType,
|
Type: integrationType,
|
||||||
Settings: data,
|
Settings: data,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
alertingmodels "github.com/grafana/alerting/models"
|
||||||
"github.com/grafana/alerting/notify"
|
"github.com/grafana/alerting/notify"
|
||||||
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
|
"github.com/grafana/alerting/receivers/line"
|
||||||
receiversTesting "github.com/grafana/alerting/receivers/testing"
|
receiversTesting "github.com/grafana/alerting/receivers/testing"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
apicompat "github.com/grafana/grafana/pkg/services/ngalert/api/compat"
|
apicompat "github.com/grafana/grafana/pkg/services/ngalert/api/compat"
|
||||||
|
@ -53,12 +57,12 @@ func TestContactPointFromContactPointExports(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the configs for testing because they have all fields supported by integrations
|
// use the configs for testing because they have all fields supported by integrations
|
||||||
for integrationType, cfg := range notify.AllKnownConfigsForTesting {
|
for integrationType, cfg := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
t.Run(integrationType, func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
recCfg := ¬ify.APIReceiver{
|
recCfg := ¬ify.APIReceiver{
|
||||||
ConfigReceiver: notify.ConfigReceiver{Name: "test-receiver"},
|
ConfigReceiver: notify.ConfigReceiver{Name: "test-receiver"},
|
||||||
GrafanaIntegrations: notify.GrafanaIntegrations{
|
ReceiverConfig: alertingmodels.ReceiverConfig{
|
||||||
Integrations: []*notify.GrafanaIntegrationConfig{
|
Integrations: []*alertingmodels.IntegrationConfig{
|
||||||
cfg.GetRawNotifierConfig("test"),
|
cfg.GetRawNotifierConfig("test"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -87,9 +91,15 @@ func TestContactPointFromContactPointExports(t *testing.T) {
|
||||||
}
|
}
|
||||||
if integrationType != "webhook" {
|
if integrationType != "webhook" {
|
||||||
// Many notifiers now support HTTPClientConfig but only Webhook currently has it enabled in schema.
|
// Many notifiers now support HTTPClientConfig but only Webhook currently has it enabled in schema.
|
||||||
//TODO: Remove this once HTTPClientConfig is added to other schemas.
|
// TODO: Remove this once HTTPClientConfig is added to other schemas.
|
||||||
pathFilters = append(pathFilters, "HTTPClientConfig")
|
pathFilters = append(pathFilters, "HTTPClientConfig")
|
||||||
}
|
}
|
||||||
|
if integrationType == line.Type {
|
||||||
|
for _, l := range actual.LineConfigs {
|
||||||
|
assert.Equal(t, "line", l.Type)
|
||||||
|
l.Type = string(line.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
pathFilter := cmp.FilterPath(func(path cmp.Path) bool {
|
pathFilter := cmp.FilterPath(func(path cmp.Path) bool {
|
||||||
for _, filter := range pathFilters {
|
for _, filter := range pathFilters {
|
||||||
if strings.Contains(path.String(), filter) {
|
if strings.Contains(path.String(), filter) {
|
||||||
|
|
|
@ -603,15 +603,15 @@ type AlertGroups = amv2.AlertGroups
|
||||||
|
|
||||||
type AlertGroup = amv2.AlertGroup
|
type AlertGroup = amv2.AlertGroup
|
||||||
|
|
||||||
type Receiver = alertingmodels.Receiver
|
type Receiver = alertingmodels.ReceiverStatus
|
||||||
|
|
||||||
// swagger:response receiversResponse
|
// swagger:response receiversResponse
|
||||||
type ReceiversResponse struct {
|
type ReceiversResponse struct {
|
||||||
// in:body
|
// in:body
|
||||||
Body []alertingmodels.Receiver
|
Body []alertingmodels.ReceiverStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
type Integration = alertingmodels.Integration
|
type Integration = alertingmodels.IntegrationStatus
|
||||||
|
|
||||||
// swagger:parameters RouteGetAMAlerts RouteGetAMAlertGroups RouteGetGrafanaAMAlerts RouteGetGrafanaAMAlertGroups
|
// swagger:parameters RouteGetAMAlerts RouteGetAMAlertGroups RouteGetGrafanaAMAlerts RouteGetGrafanaAMAlertGroups
|
||||||
type AlertsParams struct {
|
type AlertsParams struct {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/grafana/alerting/models"
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
"github.com/grafana/alerting/receivers/schema"
|
||||||
)
|
)
|
||||||
|
@ -572,7 +573,7 @@ func (integration *Integration) Validate(decryptFn DecryptFn) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ValidateIntegration(context.Background(), alertingNotify.GrafanaIntegrationConfig{
|
return ValidateIntegration(context.Background(), models.IntegrationConfig{
|
||||||
UID: decrypted.UID,
|
UID: decrypted.UID,
|
||||||
Name: decrypted.Name,
|
Name: decrypted.Name,
|
||||||
Type: decrypted.Config.Type,
|
Type: decrypted.Config.Type,
|
||||||
|
@ -582,7 +583,7 @@ func (integration *Integration) Validate(decryptFn DecryptFn) error {
|
||||||
}, alertingNotify.NoopDecrypt)
|
}, alertingNotify.NoopDecrypt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateIntegration(ctx context.Context, integration alertingNotify.GrafanaIntegrationConfig, decryptFunc alertingNotify.GetDecryptedValueFn) error {
|
func ValidateIntegration(ctx context.Context, integration models.IntegrationConfig, decryptFunc alertingNotify.GetDecryptedValueFn) error {
|
||||||
if integration.Type == "" {
|
if integration.Type == "" {
|
||||||
return fmt.Errorf("type should not be an empty string")
|
return fmt.Errorf("type should not be an empty string")
|
||||||
}
|
}
|
||||||
|
@ -591,8 +592,8 @@ func ValidateIntegration(ctx context.Context, integration alertingNotify.Grafana
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := alertingNotify.BuildReceiverConfiguration(ctx, &alertingNotify.APIReceiver{
|
_, err := alertingNotify.BuildReceiverConfiguration(ctx, &alertingNotify.APIReceiver{
|
||||||
GrafanaIntegrations: alertingNotify.GrafanaIntegrations{
|
ReceiverConfig: models.ReceiverConfig{
|
||||||
Integrations: []*alertingNotify.GrafanaIntegrationConfig{&integration},
|
Integrations: []*models.IntegrationConfig{&integration},
|
||||||
},
|
},
|
||||||
}, alertingNotify.DecodeSecretsFromBase64, decryptFunc)
|
}, alertingNotify.DecodeSecretsFromBase64, decryptFunc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
"github.com/grafana/alerting/receivers/schema"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -40,8 +41,7 @@ func TestReceiver_EncryptDecrypt(t *testing.T) {
|
||||||
encryptFn := Base64Enrypt
|
encryptFn := Base64Enrypt
|
||||||
decryptnFn := Base64Decrypt
|
decryptnFn := Base64Decrypt
|
||||||
// Test that all known integration types encrypt and decrypt their secrets.
|
// Test that all known integration types encrypt and decrypt their secrets.
|
||||||
for it := range alertingNotify.AllKnownConfigsForTesting {
|
for integrationType := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
integrationType := schema.IntegrationType(it)
|
|
||||||
t.Run(string(integrationType), func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
decrypedIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
decrypedIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
||||||
encrypted := decrypedIntegration.Clone()
|
encrypted := decrypedIntegration.Clone()
|
||||||
|
@ -76,8 +76,7 @@ func TestIntegration_Redact(t *testing.T) {
|
||||||
return "TESTREDACTED"
|
return "TESTREDACTED"
|
||||||
}
|
}
|
||||||
// Test that all known integration types redact their secrets.
|
// Test that all known integration types redact their secrets.
|
||||||
for it := range alertingNotify.AllKnownConfigsForTesting {
|
for integrationType := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
integrationType := schema.IntegrationType(it)
|
|
||||||
t.Run(string(integrationType), func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
validIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
validIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
||||||
|
|
||||||
|
@ -106,8 +105,7 @@ func TestIntegration_Validate(t *testing.T) {
|
||||||
testutil.SkipIntegrationTestInShortMode(t)
|
testutil.SkipIntegrationTestInShortMode(t)
|
||||||
|
|
||||||
// Test that all known integration types are valid.
|
// Test that all known integration types are valid.
|
||||||
for it := range alertingNotify.AllKnownConfigsForTesting {
|
for integrationType := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
integrationType := schema.IntegrationType(it)
|
|
||||||
t.Run(string(integrationType), func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
validIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
validIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
||||||
assert.NoError(t, validIntegration.Encrypt(Base64Enrypt))
|
assert.NoError(t, validIntegration.Encrypt(Base64Enrypt))
|
||||||
|
@ -242,8 +240,7 @@ func TestIntegration_WithExistingSecureFields(t *testing.T) {
|
||||||
|
|
||||||
func TestSecretsIntegrationConfig(t *testing.T) {
|
func TestSecretsIntegrationConfig(t *testing.T) {
|
||||||
// Test that all known integration types have a config and correctly mark their secrets as secure.
|
// Test that all known integration types have a config and correctly mark their secrets as secure.
|
||||||
for it := range alertingNotify.AllKnownConfigsForTesting {
|
for integrationType := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
integrationType := schema.IntegrationType(it)
|
|
||||||
t.Run(string(integrationType), func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
schemaType, ok := alertingNotify.GetSchemaForIntegration(integrationType)
|
schemaType, ok := alertingNotify.GetSchemaForIntegration(integrationType)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
|
@ -272,8 +269,8 @@ func TestSecretsIntegrationConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("Unknown version returns error", func(t *testing.T) {
|
t.Run("Unknown version returns error", func(t *testing.T) {
|
||||||
for s := range maps.Keys(alertingNotify.AllKnownConfigsForTesting) {
|
for s := range maps.Keys(notifytest.AllKnownV1ConfigsForTesting) {
|
||||||
schemaType, _ := alertingNotify.GetSchemaForIntegration(schema.IntegrationType(s))
|
schemaType, _ := alertingNotify.GetSchemaForIntegration(s)
|
||||||
_, err := IntegrationConfigFromSchema(schemaType, "unknown")
|
_, err := IntegrationConfigFromSchema(schemaType, "unknown")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
return
|
return
|
||||||
|
@ -285,8 +282,8 @@ func TestIntegration_SecureFields(t *testing.T) {
|
||||||
testutil.SkipIntegrationTestInShortMode(t)
|
testutil.SkipIntegrationTestInShortMode(t)
|
||||||
|
|
||||||
// Test that all known integration types have a config and correctly mark their secrets as secure.
|
// Test that all known integration types have a config and correctly mark their secrets as secure.
|
||||||
for it := range alertingNotify.AllKnownConfigsForTesting {
|
for it := range notifytest.AllKnownV1ConfigsForTesting {
|
||||||
integrationType := schema.IntegrationType(it)
|
integrationType := it
|
||||||
t.Run(string(integrationType), func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
t.Run("contains SecureSettings", func(t *testing.T) {
|
t.Run("contains SecureSettings", func(t *testing.T) {
|
||||||
validIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
validIntegration := IntegrationGen(IntegrationMuts.WithValidConfig(integrationType))()
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
"github.com/grafana/alerting/receivers/schema"
|
||||||
"github.com/grafana/alerting/receivers/webex"
|
"github.com/grafana/alerting/receivers/webex"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
|
@ -1270,7 +1271,7 @@ func CopyIntegrationWith(r Integration, mutators ...Mutator[Integration]) Integr
|
||||||
func IntegrationGen(mutators ...Mutator[Integration]) func() Integration {
|
func IntegrationGen(mutators ...Mutator[Integration]) func() Integration {
|
||||||
return func() Integration {
|
return func() Integration {
|
||||||
name := util.GenerateShortUID()
|
name := util.GenerateShortUID()
|
||||||
randomIntegrationType, _ := randomMapKey(alertingNotify.AllKnownConfigsForTesting)
|
randomIntegrationType, _ := randomMapKey(notifytest.AllKnownV1ConfigsForTesting)
|
||||||
|
|
||||||
c := Integration{
|
c := Integration{
|
||||||
UID: util.GenerateShortUID(),
|
UID: util.GenerateShortUID(),
|
||||||
|
@ -1280,7 +1281,7 @@ func IntegrationGen(mutators ...Mutator[Integration]) func() Integration {
|
||||||
SecureSettings: make(map[string]string),
|
SecureSettings: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
||||||
IntegrationMuts.WithValidConfig(schema.IntegrationType(randomIntegrationType))(&c)
|
IntegrationMuts.WithValidConfig(randomIntegrationType)(&c)
|
||||||
|
|
||||||
for _, mutator := range mutators {
|
for _, mutator := range mutators {
|
||||||
mutator(&c)
|
mutator(&c)
|
||||||
|
@ -1317,7 +1318,11 @@ func (n IntegrationMutators) WithName(name string) Mutator[Integration] {
|
||||||
func (n IntegrationMutators) WithValidConfig(integrationType schema.IntegrationType) Mutator[Integration] {
|
func (n IntegrationMutators) WithValidConfig(integrationType schema.IntegrationType) Mutator[Integration] {
|
||||||
return func(c *Integration) {
|
return func(c *Integration) {
|
||||||
// TODO add support for v0 integrations
|
// TODO add support for v0 integrations
|
||||||
config := alertingNotify.AllKnownConfigsForTesting[string(integrationType)].GetRawNotifierConfig(c.Name)
|
ncfg, ok := notifytest.AllKnownV1ConfigsForTesting[integrationType]
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("unknown integration type: %s", integrationType))
|
||||||
|
}
|
||||||
|
config := ncfg.GetRawNotifierConfig(c.Name)
|
||||||
typeSchema, _ := alertingNotify.GetSchemaForIntegration(integrationType)
|
typeSchema, _ := alertingNotify.GetSchemaForIntegration(integrationType)
|
||||||
integrationConfig, _ := IntegrationConfigFromSchema(typeSchema, schema.V1)
|
integrationConfig, _ := IntegrationConfigFromSchema(typeSchema, schema.V1)
|
||||||
c.Config = integrationConfig
|
c.Config = integrationConfig
|
||||||
|
@ -1337,7 +1342,10 @@ func (n IntegrationMutators) WithValidConfig(integrationType schema.IntegrationT
|
||||||
|
|
||||||
func (n IntegrationMutators) WithInvalidConfig(integrationType schema.IntegrationType) Mutator[Integration] {
|
func (n IntegrationMutators) WithInvalidConfig(integrationType schema.IntegrationType) Mutator[Integration] {
|
||||||
return func(c *Integration) {
|
return func(c *Integration) {
|
||||||
typeSchema, _ := alertingNotify.GetSchemaForIntegration(integrationType)
|
typeSchema, ok := alertingNotify.GetSchemaForIntegration(integrationType)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("unknown integration type: %s", integrationType))
|
||||||
|
}
|
||||||
c.Config, _ = IntegrationConfigFromSchema(typeSchema, schema.V1)
|
c.Config, _ = IntegrationConfigFromSchema(typeSchema, schema.V1)
|
||||||
c.Settings = map[string]interface{}{}
|
c.Settings = map[string]interface{}{}
|
||||||
c.SecureSettings = map[string]string{}
|
c.SecureSettings = map[string]string{}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/alerting/models"
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
"github.com/grafana/alerting/notify/nfstatus"
|
"github.com/grafana/alerting/notify/nfstatus"
|
||||||
"github.com/prometheus/alertmanager/config"
|
"github.com/prometheus/alertmanager/config"
|
||||||
|
@ -365,7 +366,7 @@ func (am *alertmanager) applyConfig(ctx context.Context, cfg *apimodels.Postable
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
receivers := PostableApiAlertingConfigToApiReceivers(amConfig)
|
receivers := alertingNotify.PostableAPIReceiversToAPIReceivers(amConfig.Receivers)
|
||||||
for _, recv := range receivers {
|
for _, recv := range receivers {
|
||||||
err = patchNewSecureFields(ctx, recv, alertingNotify.DecodeSecretsFromBase64, am.decryptFn)
|
err = patchNewSecureFields(ctx, recv, alertingNotify.DecodeSecretsFromBase64, am.decryptFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -406,7 +407,7 @@ func patchNewSecureFields(ctx context.Context, api *alertingNotify.APIReceiver,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func patchSettingsFromSecureSettings(ctx context.Context, integration *alertingNotify.GrafanaIntegrationConfig, key string, decode alertingNotify.DecodeSecretsFn, decrypt alertingNotify.GetDecryptedValueFn) error {
|
func patchSettingsFromSecureSettings(ctx context.Context, integration *models.IntegrationConfig, key string, decode alertingNotify.DecodeSecretsFn, decrypt alertingNotify.GetDecryptedValueFn) error {
|
||||||
if _, ok := integration.SecureSettings[key]; !ok {
|
if _, ok := integration.SecureSettings[key]; !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,23 +309,23 @@ func (_c *AlertmanagerMock_GetAlerts_Call) RunAndReturn(run func(context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReceivers provides a mock function with given fields: ctx
|
// GetReceivers provides a mock function with given fields: ctx
|
||||||
func (_m *AlertmanagerMock) GetReceivers(ctx context.Context) ([]alertingmodels.Receiver, error) {
|
func (_m *AlertmanagerMock) GetReceivers(ctx context.Context) ([]alertingmodels.ReceiverStatus, error) {
|
||||||
ret := _m.Called(ctx)
|
ret := _m.Called(ctx)
|
||||||
|
|
||||||
if len(ret) == 0 {
|
if len(ret) == 0 {
|
||||||
panic("no return value specified for GetReceivers")
|
panic("no return value specified for GetReceivers")
|
||||||
}
|
}
|
||||||
|
|
||||||
var r0 []alertingmodels.Receiver
|
var r0 []alertingmodels.ReceiverStatus
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(0).(func(context.Context) ([]alertingmodels.Receiver, error)); ok {
|
if rf, ok := ret.Get(0).(func(context.Context) ([]alertingmodels.ReceiverStatus, error)); ok {
|
||||||
return rf(ctx)
|
return rf(ctx)
|
||||||
}
|
}
|
||||||
if rf, ok := ret.Get(0).(func(context.Context) []alertingmodels.Receiver); ok {
|
if rf, ok := ret.Get(0).(func(context.Context) []alertingmodels.ReceiverStatus); ok {
|
||||||
r0 = rf(ctx)
|
r0 = rf(ctx)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]alertingmodels.Receiver)
|
r0 = ret.Get(0).([]alertingmodels.ReceiverStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,12 +356,12 @@ func (_c *AlertmanagerMock_GetReceivers_Call) Run(run func(ctx context.Context))
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *AlertmanagerMock_GetReceivers_Call) Return(_a0 []alertingmodels.Receiver, _a1 error) *AlertmanagerMock_GetReceivers_Call {
|
func (_c *AlertmanagerMock_GetReceivers_Call) Return(_a0 []alertingmodels.ReceiverStatus, _a1 error) *AlertmanagerMock_GetReceivers_Call {
|
||||||
_c.Call.Return(_a0, _a1)
|
_c.Call.Return(_a0, _a1)
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *AlertmanagerMock_GetReceivers_Call) RunAndReturn(run func(context.Context) ([]alertingmodels.Receiver, error)) *AlertmanagerMock_GetReceivers_Call {
|
func (_c *AlertmanagerMock_GetReceivers_Call) RunAndReturn(run func(context.Context) ([]alertingmodels.ReceiverStatus, error)) *AlertmanagerMock_GetReceivers_Call {
|
||||||
_c.Call.Return(run)
|
_c.Call.Return(run)
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,11 @@
|
||||||
package notifier
|
package notifier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
|
|
||||||
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/ngalert/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PostableGrafanaReceiverToGrafanaIntegrationConfig(p *apimodels.PostableGrafanaReceiver) *alertingNotify.GrafanaIntegrationConfig {
|
|
||||||
return &alertingNotify.GrafanaIntegrationConfig{
|
|
||||||
UID: p.UID,
|
|
||||||
Name: p.Name,
|
|
||||||
Type: p.Type,
|
|
||||||
DisableResolveMessage: p.DisableResolveMessage,
|
|
||||||
Settings: json.RawMessage(p.Settings),
|
|
||||||
SecureSettings: p.SecureSettings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostableApiReceiverToApiReceiver(r *apimodels.PostableApiReceiver) *alertingNotify.APIReceiver {
|
|
||||||
integrations := alertingNotify.GrafanaIntegrations{
|
|
||||||
Integrations: make([]*alertingNotify.GrafanaIntegrationConfig, 0, len(r.GrafanaManagedReceivers)),
|
|
||||||
}
|
|
||||||
for _, cfg := range r.GrafanaManagedReceivers {
|
|
||||||
integrations.Integrations = append(integrations.Integrations, PostableGrafanaReceiverToGrafanaIntegrationConfig(cfg))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &alertingNotify.APIReceiver{
|
|
||||||
ConfigReceiver: r.Receiver,
|
|
||||||
GrafanaIntegrations: integrations,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostableApiAlertingConfigToApiReceivers(c apimodels.PostableApiAlertingConfig) []*alertingNotify.APIReceiver {
|
|
||||||
apiReceivers := make([]*alertingNotify.APIReceiver, 0, len(c.Receivers))
|
|
||||||
for _, receiver := range c.Receivers {
|
|
||||||
apiReceivers = append(apiReceivers, PostableApiReceiverToApiReceiver(receiver))
|
|
||||||
}
|
|
||||||
return apiReceivers
|
|
||||||
}
|
|
||||||
|
|
||||||
// Silence-specific compat functions to convert between grafana/alerting and model types.
|
// Silence-specific compat functions to convert between grafana/alerting and model types.
|
||||||
|
|
||||||
func GettableSilenceToSilence(s alertingNotify.GettableSilence) *models.Silence {
|
func GettableSilenceToSilence(s alertingNotify.GettableSilence) *models.Silence {
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
package notifier
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
|
||||||
"github.com/prometheus/alertmanager/config"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPostableGrafanaReceiverToGrafanaIntegrationConfig(t *testing.T) {
|
|
||||||
r := &apimodels.PostableGrafanaReceiver{
|
|
||||||
UID: "test-uid",
|
|
||||||
Name: "test-name",
|
|
||||||
Type: "slack",
|
|
||||||
DisableResolveMessage: false,
|
|
||||||
Settings: apimodels.RawMessage(`{ "data" : "test" }`),
|
|
||||||
SecureSettings: map[string]string{
|
|
||||||
"test": "data",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
actual := PostableGrafanaReceiverToGrafanaIntegrationConfig(r)
|
|
||||||
require.Equal(t, alertingNotify.GrafanaIntegrationConfig{
|
|
||||||
UID: "test-uid",
|
|
||||||
Name: "test-name",
|
|
||||||
Type: "slack",
|
|
||||||
DisableResolveMessage: false,
|
|
||||||
Settings: json.RawMessage(`{ "data" : "test" }`),
|
|
||||||
SecureSettings: map[string]string{
|
|
||||||
"test": "data",
|
|
||||||
},
|
|
||||||
}, *actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostableApiReceiverToApiReceiver(t *testing.T) {
|
|
||||||
t.Run("returns empty when no receivers", func(t *testing.T) {
|
|
||||||
r := &apimodels.PostableApiReceiver{
|
|
||||||
Receiver: config.Receiver{
|
|
||||||
Name: "test-receiver",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
actual := PostableApiReceiverToApiReceiver(r)
|
|
||||||
require.Empty(t, actual.Integrations)
|
|
||||||
require.Equal(t, r.Receiver, actual.ConfigReceiver)
|
|
||||||
})
|
|
||||||
t.Run("converts receivers", func(t *testing.T) {
|
|
||||||
r := &apimodels.PostableApiReceiver{
|
|
||||||
Receiver: config.Receiver{
|
|
||||||
Name: "test-receiver",
|
|
||||||
},
|
|
||||||
PostableGrafanaReceivers: apimodels.PostableGrafanaReceivers{
|
|
||||||
GrafanaManagedReceivers: []*apimodels.PostableGrafanaReceiver{
|
|
||||||
{
|
|
||||||
UID: "test-uid",
|
|
||||||
Name: "test-name",
|
|
||||||
Type: "slack",
|
|
||||||
DisableResolveMessage: false,
|
|
||||||
Settings: apimodels.RawMessage(`{ "data" : "test" }`),
|
|
||||||
SecureSettings: map[string]string{
|
|
||||||
"test": "data",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
UID: "test-uid2",
|
|
||||||
Name: "test-name2",
|
|
||||||
Type: "webhook",
|
|
||||||
DisableResolveMessage: false,
|
|
||||||
Settings: apimodels.RawMessage(`{ "data2" : "test2" }`),
|
|
||||||
SecureSettings: map[string]string{
|
|
||||||
"test2": "data2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
actual := PostableApiReceiverToApiReceiver(r)
|
|
||||||
require.Len(t, actual.Integrations, 2)
|
|
||||||
require.Equal(t, r.Receiver, actual.ConfigReceiver)
|
|
||||||
require.Equal(t, *PostableGrafanaReceiverToGrafanaIntegrationConfig(r.GrafanaManagedReceivers[0]), *actual.Integrations[0])
|
|
||||||
require.Equal(t, *PostableGrafanaReceiverToGrafanaIntegrationConfig(r.GrafanaManagedReceivers[1]), *actual.Integrations[1])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostableApiAlertingConfigToApiReceivers(t *testing.T) {
|
|
||||||
t.Run("returns empty when no receivers", func(t *testing.T) {
|
|
||||||
r := apimodels.PostableApiAlertingConfig{
|
|
||||||
Config: apimodels.Config{},
|
|
||||||
}
|
|
||||||
actual := PostableApiAlertingConfigToApiReceivers(r)
|
|
||||||
require.Empty(t, actual)
|
|
||||||
})
|
|
||||||
c := apimodels.PostableApiAlertingConfig{
|
|
||||||
Config: apimodels.Config{},
|
|
||||||
Receivers: []*apimodels.PostableApiReceiver{
|
|
||||||
{
|
|
||||||
Receiver: config.Receiver{
|
|
||||||
Name: "test-receiver",
|
|
||||||
},
|
|
||||||
PostableGrafanaReceivers: apimodels.PostableGrafanaReceivers{
|
|
||||||
GrafanaManagedReceivers: []*apimodels.PostableGrafanaReceiver{
|
|
||||||
{
|
|
||||||
UID: "test-uid",
|
|
||||||
Name: "test-name",
|
|
||||||
Type: "slack",
|
|
||||||
DisableResolveMessage: false,
|
|
||||||
Settings: apimodels.RawMessage(`{ "data" : "test" }`),
|
|
||||||
SecureSettings: map[string]string{
|
|
||||||
"test": "data",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Receiver: config.Receiver{
|
|
||||||
Name: "test-receiver2",
|
|
||||||
},
|
|
||||||
PostableGrafanaReceivers: apimodels.PostableGrafanaReceivers{
|
|
||||||
GrafanaManagedReceivers: []*apimodels.PostableGrafanaReceiver{
|
|
||||||
{
|
|
||||||
UID: "test-uid2",
|
|
||||||
Name: "test-name1",
|
|
||||||
Type: "slack",
|
|
||||||
DisableResolveMessage: false,
|
|
||||||
Settings: apimodels.RawMessage(`{ "data" : "test" }`),
|
|
||||||
SecureSettings: map[string]string{
|
|
||||||
"test": "data",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
actual := PostableApiAlertingConfigToApiReceivers(c)
|
|
||||||
|
|
||||||
require.Len(t, actual, 2)
|
|
||||||
require.Equal(t, PostableApiReceiverToApiReceiver(c.Receivers[0]), actual[0])
|
|
||||||
require.Equal(t, PostableApiReceiverToApiReceiver(c.Receivers[1]), actual[1])
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/grafana/alerting/definition"
|
"github.com/grafana/alerting/definition"
|
||||||
"github.com/grafana/alerting/notify"
|
"github.com/grafana/alerting/notify"
|
||||||
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
"github.com/grafana/alerting/receivers/schema"
|
||||||
"github.com/grafana/alerting/receivers/webhook"
|
"github.com/grafana/alerting/receivers/webhook"
|
||||||
"github.com/prometheus/alertmanager/config"
|
"github.com/prometheus/alertmanager/config"
|
||||||
|
@ -92,7 +93,7 @@ func TestDeleteReceiver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateReceiver(t *testing.T) {
|
func TestCreateReceiver(t *testing.T) {
|
||||||
rawCfg := notify.AllKnownConfigsForTesting[string(webhook.Type)]
|
rawCfg := notifytest.AllKnownV1ConfigsForTesting[webhook.Type]
|
||||||
typeSchema, _ := notify.GetSchemaForIntegration(webhook.Type)
|
typeSchema, _ := notify.GetSchemaForIntegration(webhook.Type)
|
||||||
cfgSchema, err := models.IntegrationConfigFromSchema(typeSchema, schema.V1)
|
cfgSchema, err := models.IntegrationConfigFromSchema(typeSchema, schema.V1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -199,7 +200,7 @@ func TestCreateReceiver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateReceiver(t *testing.T) {
|
func TestUpdateReceiver(t *testing.T) {
|
||||||
rawCfg := notify.AllKnownConfigsForTesting[string(webhook.Type)]
|
rawCfg := notifytest.AllKnownV1ConfigsForTesting[webhook.Type]
|
||||||
typeSchema, _ := notify.GetSchemaForIntegration(webhook.Type)
|
typeSchema, _ := notify.GetSchemaForIntegration(webhook.Type)
|
||||||
cfgSchema, err := models.IntegrationConfigFromSchema(typeSchema, schema.V1)
|
cfgSchema, err := models.IntegrationConfigFromSchema(typeSchema, schema.V1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -300,7 +301,7 @@ func TestUpdateReceiver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetReceiver(t *testing.T) {
|
func TestGetReceiver(t *testing.T) {
|
||||||
rawCfg := notify.AllKnownConfigsForTesting[string(webhook.Type)]
|
rawCfg := notifytest.AllKnownV1ConfigsForTesting[webhook.Type]
|
||||||
typeSchema, _ := notify.GetSchemaForIntegration(webhook.Type)
|
typeSchema, _ := notify.GetSchemaForIntegration(webhook.Type)
|
||||||
cfgSchema, err := models.IntegrationConfigFromSchema(typeSchema, schema.V1)
|
cfgSchema, err := models.IntegrationConfigFromSchema(typeSchema, schema.V1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -491,7 +492,7 @@ func getConfigRevisionForTest() *ConfigRevision {
|
||||||
{
|
{
|
||||||
UID: "integration-uid-1",
|
UID: "integration-uid-1",
|
||||||
Type: "webhook",
|
Type: "webhook",
|
||||||
Settings: definitions.RawMessage(notify.AllKnownConfigsForTesting["webhook"].Config),
|
Settings: definitions.RawMessage(notifytest.AllKnownV1ConfigsForTesting["webhook"].Config),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -503,7 +504,7 @@ func getConfigRevisionForTest() *ConfigRevision {
|
||||||
{
|
{
|
||||||
UID: "integration-uid-2",
|
UID: "integration-uid-2",
|
||||||
Type: "webhook",
|
Type: "webhook",
|
||||||
Settings: definitions.RawMessage(notify.AllKnownConfigsForTesting["webhook"].Config),
|
Settings: definitions.RawMessage(notifytest.AllKnownV1ConfigsForTesting["webhook"].Config),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -515,7 +516,7 @@ func getConfigRevisionForTest() *ConfigRevision {
|
||||||
{
|
{
|
||||||
UID: "integration-uid-3",
|
UID: "integration-uid-3",
|
||||||
Type: "email",
|
Type: "email",
|
||||||
Settings: definitions.RawMessage(notify.AllKnownConfigsForTesting["email"].Config),
|
Settings: definitions.RawMessage(notifytest.AllKnownV1ConfigsForTesting["email"].Config),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/alerting/receivers/line"
|
||||||
"github.com/prometheus/alertmanager/config"
|
"github.com/prometheus/alertmanager/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -352,7 +353,7 @@ func TestReceiverService_Create(t *testing.T) {
|
||||||
|
|
||||||
slackIntegration := models.IntegrationGen(models.IntegrationMuts.WithName("test receiver"), models.IntegrationMuts.WithValidConfig("slack"))()
|
slackIntegration := models.IntegrationGen(models.IntegrationMuts.WithName("test receiver"), models.IntegrationMuts.WithValidConfig("slack"))()
|
||||||
emailIntegration := models.IntegrationGen(models.IntegrationMuts.WithName("test receiver"), models.IntegrationMuts.WithValidConfig("email"))()
|
emailIntegration := models.IntegrationGen(models.IntegrationMuts.WithName("test receiver"), models.IntegrationMuts.WithValidConfig("email"))()
|
||||||
lineIntegration := models.IntegrationGen(models.IntegrationMuts.WithName("test receiver"), models.IntegrationMuts.WithValidConfig("line"))()
|
lineIntegration := models.IntegrationGen(models.IntegrationMuts.WithName("test receiver"), models.IntegrationMuts.WithValidConfig(line.Type))()
|
||||||
baseReceiver := models.ReceiverGen(models.ReceiverMuts.WithName("test receiver"), models.ReceiverMuts.WithIntegrations(slackIntegration))()
|
baseReceiver := models.ReceiverGen(models.ReceiverMuts.WithName("test receiver"), models.ReceiverMuts.WithIntegrations(slackIntegration))()
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/grafana/alerting/models"
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
v2 "github.com/prometheus/alertmanager/api/v2"
|
v2 "github.com/prometheus/alertmanager/api/v2"
|
||||||
|
|
||||||
|
@ -13,9 +14,9 @@ import (
|
||||||
func (am *alertmanager) TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*alertingNotify.TestReceiversResult, int, error) {
|
func (am *alertmanager) TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*alertingNotify.TestReceiversResult, int, error) {
|
||||||
receivers := make([]*alertingNotify.APIReceiver, 0, len(c.Receivers))
|
receivers := make([]*alertingNotify.APIReceiver, 0, len(c.Receivers))
|
||||||
for _, r := range c.Receivers {
|
for _, r := range c.Receivers {
|
||||||
integrations := make([]*alertingNotify.GrafanaIntegrationConfig, 0, len(r.GrafanaManagedReceivers))
|
integrations := make([]*models.IntegrationConfig, 0, len(r.GrafanaManagedReceivers))
|
||||||
for _, gr := range r.GrafanaManagedReceivers {
|
for _, gr := range r.GrafanaManagedReceivers {
|
||||||
integrations = append(integrations, &alertingNotify.GrafanaIntegrationConfig{
|
integrations = append(integrations, &models.IntegrationConfig{
|
||||||
UID: gr.UID,
|
UID: gr.UID,
|
||||||
Name: gr.Name,
|
Name: gr.Name,
|
||||||
Type: gr.Type,
|
Type: gr.Type,
|
||||||
|
@ -26,7 +27,7 @@ func (am *alertmanager) TestReceivers(ctx context.Context, c apimodels.TestRecei
|
||||||
}
|
}
|
||||||
recv := &alertingNotify.APIReceiver{
|
recv := &alertingNotify.APIReceiver{
|
||||||
ConfigReceiver: r.Receiver,
|
ConfigReceiver: r.Receiver,
|
||||||
GrafanaIntegrations: alertingNotify.GrafanaIntegrations{
|
ReceiverConfig: models.ReceiverConfig{
|
||||||
Integrations: integrations,
|
Integrations: integrations,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -52,5 +53,5 @@ func (am *alertmanager) TestReceivers(ctx context.Context, c apimodels.TestRecei
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *alertmanager) GetReceivers(_ context.Context) ([]apimodels.Receiver, error) {
|
func (am *alertmanager) GetReceivers(_ context.Context) ([]apimodels.Receiver, error) {
|
||||||
return am.Base.GetReceivers(), nil
|
return am.Base.GetReceiversStatus(), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/alerting/models"
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingNotify "github.com/grafana/alerting/notify"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInvalidReceiverError_Error(t *testing.T) {
|
func TestInvalidReceiverError_Error(t *testing.T) {
|
||||||
e := alertingNotify.IntegrationValidationError{
|
e := alertingNotify.IntegrationValidationError{
|
||||||
Integration: &alertingNotify.GrafanaIntegrationConfig{
|
Integration: &models.IntegrationConfig{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Type: "test-type",
|
Type: "test-type",
|
||||||
UID: "uid",
|
UID: "uid",
|
||||||
|
@ -24,7 +25,7 @@ func TestInvalidReceiverError_Error(t *testing.T) {
|
||||||
|
|
||||||
func TestReceiverTimeoutError_Error(t *testing.T) {
|
func TestReceiverTimeoutError_Error(t *testing.T) {
|
||||||
e := alertingNotify.IntegrationTimeoutError{
|
e := alertingNotify.IntegrationTimeoutError{
|
||||||
Integration: &alertingNotify.GrafanaIntegrationConfig{
|
Integration: &models.IntegrationConfig{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
UID: "uid",
|
UID: "uid",
|
||||||
},
|
},
|
||||||
|
@ -45,7 +46,7 @@ func (e timeoutError) Timeout() bool {
|
||||||
|
|
||||||
func TestProcessNotifierError(t *testing.T) {
|
func TestProcessNotifierError(t *testing.T) {
|
||||||
t.Run("assert ReceiverTimeoutError is returned for context deadline exceeded", func(t *testing.T) {
|
t.Run("assert ReceiverTimeoutError is returned for context deadline exceeded", func(t *testing.T) {
|
||||||
r := &alertingNotify.GrafanaIntegrationConfig{
|
r := &models.IntegrationConfig{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
UID: "uid",
|
UID: "uid",
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,7 @@ func TestProcessNotifierError(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("assert ReceiverTimeoutError is returned for *url.Error timeout", func(t *testing.T) {
|
t.Run("assert ReceiverTimeoutError is returned for *url.Error timeout", func(t *testing.T) {
|
||||||
r := &alertingNotify.GrafanaIntegrationConfig{
|
r := &models.IntegrationConfig{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
UID: "uid",
|
UID: "uid",
|
||||||
}
|
}
|
||||||
|
@ -72,7 +73,7 @@ func TestProcessNotifierError(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("assert unknown error is returned unmodified", func(t *testing.T) {
|
t.Run("assert unknown error is returned unmodified", func(t *testing.T) {
|
||||||
r := &alertingNotify.GrafanaIntegrationConfig{
|
r := &models.IntegrationConfig{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
UID: "uid",
|
UID: "uid",
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,19 @@ package provisioning
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
alertingNotify "github.com/grafana/alerting/notify"
|
alertingModels "github.com/grafana/alerting/models"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func EmbeddedContactPointToGrafanaIntegrationConfig(e definitions.EmbeddedContactPoint) (alertingNotify.GrafanaIntegrationConfig, error) {
|
func EmbeddedContactPointToGrafanaIntegrationConfig(e definitions.EmbeddedContactPoint) (alertingModels.IntegrationConfig, error) {
|
||||||
data, err := e.Settings.MarshalJSON()
|
data, err := e.Settings.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return alertingNotify.GrafanaIntegrationConfig{}, err
|
return alertingModels.IntegrationConfig{}, err
|
||||||
}
|
}
|
||||||
return alertingNotify.GrafanaIntegrationConfig{
|
return alertingModels.IntegrationConfig{
|
||||||
UID: e.UID,
|
UID: e.UID,
|
||||||
Name: e.Name,
|
Name: e.Name,
|
||||||
Type: e.Type,
|
Type: e.Type,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/alerting/notify"
|
"github.com/grafana/alerting/notify"
|
||||||
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
"github.com/grafana/alerting/receivers/schema"
|
||||||
"github.com/prometheus/alertmanager/config"
|
"github.com/prometheus/alertmanager/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -425,7 +426,7 @@ func TestIntegrationContactPointServiceDecryptRedact(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveSecretsForContactPoint(t *testing.T) {
|
func TestRemoveSecretsForContactPoint(t *testing.T) {
|
||||||
overrides := map[string]func(settings map[string]any){
|
overrides := map[schema.IntegrationType]func(settings map[string]any){
|
||||||
"webhook": func(settings map[string]any) { // add additional field to the settings because valid config does not allow it to be specified along with password
|
"webhook": func(settings map[string]any) { // add additional field to the settings because valid config does not allow it to be specified along with password
|
||||||
settings["authorization_credentials"] = "test-authz-creds"
|
settings["authorization_credentials"] = "test-authz-creds"
|
||||||
},
|
},
|
||||||
|
@ -437,23 +438,23 @@ func TestRemoveSecretsForContactPoint(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
configs := notify.AllKnownConfigsForTesting
|
configs := notifytest.AllKnownV1ConfigsForTesting
|
||||||
keys := maps.Keys(configs)
|
keys := maps.Keys(configs)
|
||||||
slices.Sort(keys)
|
slices.Sort(keys)
|
||||||
for _, integrationType := range keys {
|
for _, integrationType := range keys {
|
||||||
integration := models.IntegrationGen(models.IntegrationMuts.WithValidConfig(schema.IntegrationType(integrationType)))()
|
integration := models.IntegrationGen(models.IntegrationMuts.WithValidConfig(integrationType))()
|
||||||
if f, ok := overrides[integrationType]; ok {
|
if f, ok := overrides[integrationType]; ok {
|
||||||
f(integration.Settings)
|
f(integration.Settings)
|
||||||
}
|
}
|
||||||
settingsRaw, err := json.Marshal(integration.Settings)
|
settingsRaw, err := json.Marshal(integration.Settings)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
typeSchema, _ := notify.GetSchemaVersionForIntegration(schema.IntegrationType(integrationType), schema.V1)
|
typeSchema, _ := notify.GetSchemaVersionForIntegration(integrationType, schema.V1)
|
||||||
expectedFields := typeSchema.GetSecretFieldsPaths()
|
expectedFields := typeSchema.GetSecretFieldsPaths()
|
||||||
|
|
||||||
t.Run(integrationType, func(t *testing.T) {
|
t.Run(string(integrationType), func(t *testing.T) {
|
||||||
cp := definitions.EmbeddedContactPoint{
|
cp := definitions.EmbeddedContactPoint{
|
||||||
Name: "integration-" + integrationType,
|
Name: "integration-" + string(integrationType),
|
||||||
Type: integrationType,
|
Type: string(integrationType),
|
||||||
Settings: simplejson.MustJson(settingsRaw),
|
Settings: simplejson.MustJson(settingsRaw),
|
||||||
}
|
}
|
||||||
secureFields, err := RemoveSecretsForContactPoint(&cp)
|
secureFields, err := RemoveSecretsForContactPoint(&cp)
|
||||||
|
|
|
@ -609,10 +609,7 @@ func (am *Alertmanager) TestReceivers(ctx context.Context, c apimodels.TestRecei
|
||||||
return nil, 0, fmt.Errorf("failed to decrypt receivers: %w", err)
|
return nil, 0, fmt.Errorf("failed to decrypt receivers: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
apiReceivers := make([]*alertingNotify.APIReceiver, 0, len(c.Receivers))
|
apiReceivers := alertingNotify.PostableAPIReceiversToAPIReceivers(decryptedReceivers)
|
||||||
for _, r := range decryptedReceivers {
|
|
||||||
apiReceivers = append(apiReceivers, notifier.PostableApiReceiverToApiReceiver(r))
|
|
||||||
}
|
|
||||||
var alert *alertingNotify.TestReceiversConfigAlertParams
|
var alert *alertingNotify.TestReceiversConfigAlertParams
|
||||||
if c.Alert != nil {
|
if c.Alert != nil {
|
||||||
alert = &alertingNotify.TestReceiversConfigAlertParams{Annotations: c.Alert.Annotations, Labels: c.Alert.Labels}
|
alert = &alertingNotify.TestReceiversConfigAlertParams{Annotations: c.Alert.Annotations, Labels: c.Alert.Labels}
|
||||||
|
|
|
@ -358,23 +358,23 @@ func (_c *RemoteAlertmanagerMock_GetAlerts_Call) RunAndReturn(run func(context.C
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReceivers provides a mock function with given fields: ctx
|
// GetReceivers provides a mock function with given fields: ctx
|
||||||
func (_m *RemoteAlertmanagerMock) GetReceivers(ctx context.Context) ([]alertingmodels.Receiver, error) {
|
func (_m *RemoteAlertmanagerMock) GetReceivers(ctx context.Context) ([]alertingmodels.ReceiverStatus, error) {
|
||||||
ret := _m.Called(ctx)
|
ret := _m.Called(ctx)
|
||||||
|
|
||||||
if len(ret) == 0 {
|
if len(ret) == 0 {
|
||||||
panic("no return value specified for GetReceivers")
|
panic("no return value specified for GetReceivers")
|
||||||
}
|
}
|
||||||
|
|
||||||
var r0 []alertingmodels.Receiver
|
var r0 []alertingmodels.ReceiverStatus
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(0).(func(context.Context) ([]alertingmodels.Receiver, error)); ok {
|
if rf, ok := ret.Get(0).(func(context.Context) ([]alertingmodels.ReceiverStatus, error)); ok {
|
||||||
return rf(ctx)
|
return rf(ctx)
|
||||||
}
|
}
|
||||||
if rf, ok := ret.Get(0).(func(context.Context) []alertingmodels.Receiver); ok {
|
if rf, ok := ret.Get(0).(func(context.Context) []alertingmodels.ReceiverStatus); ok {
|
||||||
r0 = rf(ctx)
|
r0 = rf(ctx)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]alertingmodels.Receiver)
|
r0 = ret.Get(0).([]alertingmodels.ReceiverStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,12 +405,12 @@ func (_c *RemoteAlertmanagerMock_GetReceivers_Call) Run(run func(ctx context.Con
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *RemoteAlertmanagerMock_GetReceivers_Call) Return(_a0 []alertingmodels.Receiver, _a1 error) *RemoteAlertmanagerMock_GetReceivers_Call {
|
func (_c *RemoteAlertmanagerMock_GetReceivers_Call) Return(_a0 []alertingmodels.ReceiverStatus, _a1 error) *RemoteAlertmanagerMock_GetReceivers_Call {
|
||||||
_c.Call.Return(_a0, _a1)
|
_c.Call.Return(_a0, _a1)
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_c *RemoteAlertmanagerMock_GetReceivers_Call) RunAndReturn(run func(context.Context) ([]alertingmodels.Receiver, error)) *RemoteAlertmanagerMock_GetReceivers_Call {
|
func (_c *RemoteAlertmanagerMock_GetReceivers_Call) RunAndReturn(run func(context.Context) ([]alertingmodels.ReceiverStatus, error)) *RemoteAlertmanagerMock_GetReceivers_Call {
|
||||||
_c.Call.Return(run)
|
_c.Call.Return(run)
|
||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,16 +144,17 @@ policies:
|
||||||
- label_keys_not_$$escaped
|
- label_keys_not_$$escaped
|
||||||
# <list> a list of prometheus-like matchers that an alert rule has to fulfill to match the node (allowed chars
|
# <list> a list of prometheus-like matchers that an alert rule has to fulfill to match the node (allowed chars
|
||||||
# [a-zA-Z_:])
|
# [a-zA-Z_:])
|
||||||
matchers:
|
group_wait: 30s
|
||||||
|
group_interval: 5m
|
||||||
|
repeat_interval: 4h
|
||||||
|
routes:
|
||||||
|
- matchers:
|
||||||
- alertname = Watchdog
|
- alertname = Watchdog
|
||||||
- service_id_X = serviceX
|
- service_id_X = serviceX
|
||||||
- severity =~ "warning|critical"
|
- severity =~ "warning|critical"
|
||||||
# <list> a list of grafana-like matchers that an alert rule has to fulfill to match the node
|
# <list> a list of grafana-like matchers that an alert rule has to fulfill to match the node
|
||||||
object_matchers:
|
object_matchers:
|
||||||
- ["alertname", "=", "CPUUsage"]
|
- [ "alertname", "=", "CPUUsage" ]
|
||||||
- ["service_id-X", "=", "serviceX"]
|
- [ "service_id-X", "=", "serviceX" ]
|
||||||
- ["severity", "=~", "warning|critical"]
|
- [ "severity", "=~", "warning|critical" ]
|
||||||
group_wait: 30s
|
|
||||||
group_interval: 5m
|
|
||||||
repeat_interval: 4h
|
|
||||||
routes: []
|
|
||||||
|
|
|
@ -9,10 +9,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/alerting/notify/notifytest"
|
||||||
|
"github.com/grafana/alerting/receivers/line"
|
||||||
"github.com/grafana/alerting/receivers/schema"
|
"github.com/grafana/alerting/receivers/schema"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -1225,7 +1226,7 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||||
t.Run("should be able to update default receiver", func(t *testing.T) {
|
t.Run("should be able to update default receiver", func(t *testing.T) {
|
||||||
require.NotNil(t, defaultReceiver)
|
require.NotNil(t, defaultReceiver)
|
||||||
newDefault := defaultReceiver.Copy().(*v0alpha1.Receiver)
|
newDefault := defaultReceiver.Copy().(*v0alpha1.Receiver)
|
||||||
newDefault.Spec.Integrations = append(newDefault.Spec.Integrations, createIntegration(t, "line"))
|
newDefault.Spec.Integrations = append(newDefault.Spec.Integrations, createIntegration(t, line.Type))
|
||||||
|
|
||||||
updatedReceiver, err := adminClient.Update(ctx, newDefault, v1.UpdateOptions{})
|
updatedReceiver, err := adminClient.Update(ctx, newDefault, v1.UpdateOptions{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -1266,10 +1267,10 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||||
|
|
||||||
var receiver *v0alpha1.Receiver
|
var receiver *v0alpha1.Receiver
|
||||||
t.Run("should correctly persist all known integrations", func(t *testing.T) {
|
t.Run("should correctly persist all known integrations", func(t *testing.T) {
|
||||||
integrations := make([]v0alpha1.ReceiverIntegration, 0, len(notify.AllKnownConfigsForTesting))
|
integrations := make([]v0alpha1.ReceiverIntegration, 0, len(notifytest.AllKnownV1ConfigsForTesting))
|
||||||
keysIter := maps.Keys(notify.AllKnownConfigsForTesting)
|
keysIter := maps.Keys(notifytest.AllKnownV1ConfigsForTesting)
|
||||||
keys := slices.Collect(keysIter)
|
keys := slices.Collect(keysIter)
|
||||||
sort.Strings(keys)
|
slices.Sort(keys)
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
integrations = append(integrations, createIntegration(t, key))
|
integrations = append(integrations, createIntegration(t, key))
|
||||||
}
|
}
|
||||||
|
@ -1300,7 +1301,7 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||||
|
|
||||||
export := legacyCli.ExportReceiverTyped(t, receiver.Spec.Title, true)
|
export := legacyCli.ExportReceiverTyped(t, receiver.Spec.Title, true)
|
||||||
for _, integration := range export.Receivers {
|
for _, integration := range export.Receivers {
|
||||||
expected := notify.AllKnownConfigsForTesting[strings.ToLower(integration.Type)] // to lower because there is LINE that is in different casing in API
|
expected := notifytest.AllKnownV1ConfigsForTesting[schema.IntegrationType(integration.Type)]
|
||||||
assert.JSONEqf(t, expected.Config, string(integration.Settings), "integration %s", integration.Type)
|
assert.JSONEqf(t, expected.Config, string(integration.Settings), "integration %s", integration.Type)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1313,7 +1314,7 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||||
for _, integration := range get.Spec.Integrations {
|
for _, integration := range get.Spec.Integrations {
|
||||||
integrationType := schema.IntegrationType(integration.Type)
|
integrationType := schema.IntegrationType(integration.Type)
|
||||||
t.Run(integration.Type, func(t *testing.T) {
|
t.Run(integration.Type, func(t *testing.T) {
|
||||||
expected := notify.AllKnownConfigsForTesting[strings.ToLower(integration.Type)]
|
expected := notifytest.AllKnownV1ConfigsForTesting[schema.IntegrationType(integration.Type)]
|
||||||
var fields map[string]any
|
var fields map[string]any
|
||||||
require.NoError(t, json.Unmarshal([]byte(expected.Config), &fields))
|
require.NoError(t, json.Unmarshal([]byte(expected.Config), &fields))
|
||||||
typeSchema, ok := notify.GetSchemaVersionForIntegration(integrationType, schema.V1)
|
typeSchema, ok := notify.GetSchemaVersionForIntegration(integrationType, schema.V1)
|
||||||
|
@ -1336,11 +1337,11 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should fail to persist receiver with invalid config", func(t *testing.T) {
|
t.Run("should fail to persist receiver with invalid config", func(t *testing.T) {
|
||||||
keysIter := maps.Keys(notify.AllKnownConfigsForTesting)
|
keysIter := maps.Keys(notifytest.AllKnownV1ConfigsForTesting)
|
||||||
keys := slices.Collect(keysIter)
|
keys := slices.Collect(keysIter)
|
||||||
sort.Strings(keys)
|
slices.Sort(keys)
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
t.Run(key, func(t *testing.T) {
|
t.Run(string(key), func(t *testing.T) {
|
||||||
integration := createIntegration(t, key)
|
integration := createIntegration(t, key)
|
||||||
// Make the integration invalid, so it fails to create. This is usually done by sending empty settings.
|
// Make the integration invalid, so it fails to create. This is usually done by sending empty settings.
|
||||||
clear(integration.Settings)
|
clear(integration.Settings)
|
||||||
|
@ -1503,18 +1504,18 @@ func persistInitialConfig(t *testing.T, amConfig definitions.PostableUserConfig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createIntegration(t *testing.T, integrationType string) v0alpha1.ReceiverIntegration {
|
func createIntegration(t *testing.T, integrationType schema.IntegrationType) v0alpha1.ReceiverIntegration {
|
||||||
cfg, ok := notify.AllKnownConfigsForTesting[integrationType]
|
cfg, ok := notifytest.AllKnownV1ConfigsForTesting[integrationType]
|
||||||
require.Truef(t, ok, "no known config for integration type %s", integrationType)
|
require.Truef(t, ok, "no known config for integration type %s", integrationType)
|
||||||
return createIntegrationWithSettings(t, integrationType, "v1", cfg.Config)
|
return createIntegrationWithSettings(t, integrationType, schema.V1, cfg.Config)
|
||||||
}
|
}
|
||||||
func createIntegrationWithSettings(t *testing.T, integrationType string, integrationVersion string, settingsJson string) v0alpha1.ReceiverIntegration {
|
func createIntegrationWithSettings(t *testing.T, integrationType schema.IntegrationType, integrationVersion schema.Version, settingsJson string) v0alpha1.ReceiverIntegration {
|
||||||
settings := common.Unstructured{}
|
settings := common.Unstructured{}
|
||||||
require.NoError(t, settings.UnmarshalJSON([]byte(settingsJson)))
|
require.NoError(t, settings.UnmarshalJSON([]byte(settingsJson)))
|
||||||
return v0alpha1.ReceiverIntegration{
|
return v0alpha1.ReceiverIntegration{
|
||||||
Settings: settings.Object,
|
Settings: settings.Object,
|
||||||
Type: integrationType,
|
Type: string(integrationType),
|
||||||
Version: integrationVersion,
|
Version: string(integrationVersion),
|
||||||
DisableResolveMessage: util.Pointer(false),
|
DisableResolveMessage: util.Pointer(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue