diff --git a/pkg/services/ngalert/api/api_notifications.go b/pkg/services/ngalert/api/api_notifications.go index be0b10d14fa..70accedad4e 100644 --- a/pkg/services/ngalert/api/api_notifications.go +++ b/pkg/services/ngalert/api/api_notifications.go @@ -20,7 +20,7 @@ type NotificationSrv struct { type ReceiverService interface { GetReceiver(ctx context.Context, q models.GetReceiverQuery, u identity.Requester) (definitions.GettableApiReceiver, error) - GetReceivers(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) + ListReceivers(ctx context.Context, q models.ListReceiversQuery, user identity.Requester) ([]definitions.GettableApiReceiver, error) } func (srv *NotificationSrv) RouteGetTimeInterval(c *contextmodel.ReqContext, name string) response.Response { @@ -55,15 +55,14 @@ func (srv *NotificationSrv) RouteGetReceiver(c *contextmodel.ReqContext, name st } func (srv *NotificationSrv) RouteGetReceivers(c *contextmodel.ReqContext) response.Response { - q := models.GetReceiversQuery{ - OrgID: c.SignedInUser.OrgID, - Names: c.QueryStrings("names"), - Limit: c.QueryInt("limit"), - Offset: c.QueryInt("offset"), - Decrypt: c.QueryBool("decrypt"), + q := models.ListReceiversQuery{ + OrgID: c.SignedInUser.OrgID, + Names: c.QueryStrings("names"), + Limit: c.QueryInt("limit"), + Offset: c.QueryInt("offset"), } - receivers, err := srv.receiverService.GetReceivers(c.Req.Context(), q, c.SignedInUser) + receivers, err := srv.receiverService.ListReceivers(c.Req.Context(), q, c.SignedInUser) if err != nil { return response.ErrOrFallback(http.StatusInternalServerError, "failed to get receiver groups", err) } diff --git a/pkg/services/ngalert/api/api_notifications_test.go b/pkg/services/ngalert/api/api_notifications_test.go index 3e9349a1026..23eee4e38e1 100644 --- a/pkg/services/ngalert/api/api_notifications_test.go +++ b/pkg/services/ngalert/api/api_notifications_test.go @@ -120,7 +120,7 @@ func TestRouteGetReceivers(t *testing.T) { }, }, } - fakeReceiverSvc.GetReceiversFn = func(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { + fakeReceiverSvc.ListReceiversFn = func(ctx context.Context, q models.ListReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { return expected, nil } handler := NewNotificationsApi(newNotificationSrv(fakeReceiverSvc)) @@ -134,7 +134,7 @@ func TestRouteGetReceivers(t *testing.T) { }) t.Run("builds query from request context", func(t *testing.T) { - fakeReceiverSvc.GetReceiversFn = func(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { + fakeReceiverSvc.ListReceiversFn = func(ctx context.Context, q models.ListReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { return []definitions.GettableApiReceiver{}, nil } handler := NewNotificationsApi(newNotificationSrv(fakeReceiverSvc)) @@ -148,19 +148,18 @@ func TestRouteGetReceivers(t *testing.T) { require.Equal(t, http.StatusOK, resp.Status()) call := fakeReceiverSvc.PopMethodCall() - require.Equal(t, "GetReceivers", call.Method) - expectedQ := models.GetReceiversQuery{ - Names: []string{"receiver1", "receiver2"}, - Limit: 1, - Offset: 2, - Decrypt: true, - OrgID: 1, + require.Equal(t, "ListReceivers", call.Method) + expectedQ := models.ListReceiversQuery{ + Names: []string{"receiver1", "receiver2"}, + Limit: 1, + Offset: 2, + OrgID: 1, } require.Equal(t, expectedQ, call.Args[1]) }) t.Run("should pass along permission denied response", func(t *testing.T) { - fakeReceiverSvc.GetReceiversFn = func(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { + fakeReceiverSvc.ListReceiversFn = func(ctx context.Context, q models.ListReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { return nil, ac.ErrAuthorizationBase.Errorf("") } handler := NewNotificationsApi(newNotificationSrv(fakeReceiverSvc)) @@ -197,33 +196,9 @@ func TestRouteGetReceiversResponses(t *testing.T) { require.Equal(t, 200, response.Status()) }) - t.Run("decrypt true without alert.provisioning.secrets:read permissions returns 403", func(t *testing.T) { - recPermCheck := false - env := createTestEnv(t, testConfig) - env.ac = &recordingAccessControlFake{ - Callback: func(user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) { - if strings.Contains(evaluator.String(), accesscontrol.ActionAlertingReceiversReadSecrets) { - recPermCheck = true - } - return false, nil - }, - } - - sut := createNotificationSrvSutFromEnv(t, &env) - rc := createTestRequestCtx() - - rc.Context.Req.Form.Set("decrypt", "true") - - response := sut.RouteGetReceivers(&rc) - - require.True(t, recPermCheck) - require.Equal(t, 403, response.Status()) - }) t.Run("json body content is as expected", func(t *testing.T) { - expectedDecryptedResponse := `[{"name":"grafana-default-email","grafana_managed_receiver_configs":[{"uid":"ad95bd8a-49ed-4adc-bf89-1b444fa1aa5b","name":"grafana-default-email","type":"email","disableResolveMessage":false,"settings":{"addresses":"\u003cexample@email.com\u003e"},"secureFields":{}}]},{"name":"multiple integrations","grafana_managed_receiver_configs":[{"uid":"c2090fda-f824-4add-b545-5a4d5c2ef082","name":"multiple integrations","type":"prometheus-alertmanager","disableResolveMessage":true,"settings":{"basicAuthPassword":"testpass","basicAuthUser":"test","url":"http://localhost:9093"},"secureFields":{"basicAuthPassword":true}},{"uid":"c84539ec-f87e-4fc5-9a91-7a687d34bbd1","name":"multiple integrations","type":"discord","disableResolveMessage":false,"settings":{"avatar_url":"some avatar","url":"some url","use_discord_username":true},"secureFields":{}}]},{"name":"pagerduty test","grafana_managed_receiver_configs":[{"uid":"b9bf06f8-bde2-4438-9d4a-bba0522dcd4d","name":"pagerduty test","type":"pagerduty","disableResolveMessage":false,"settings":{"client":"some client","integrationKey":"some key","severity":"criticalish"},"secureFields":{"integrationKey":true}}]},{"name":"slack test","grafana_managed_receiver_configs":[{"uid":"cbfd0976-8228-4126-b672-4419f30a9e50","name":"slack test","type":"slack","disableResolveMessage":true,"settings":{"text":"title body test","title":"title test","url":"some secure slack webhook"},"secureFields":{"url":true}}]}]` - expectedRedactedResponse := `[{"name":"grafana-default-email","grafana_managed_receiver_configs":[{"uid":"ad95bd8a-49ed-4adc-bf89-1b444fa1aa5b","name":"grafana-default-email","type":"email","disableResolveMessage":false,"settings":{"addresses":"\u003cexample@email.com\u003e"},"secureFields":{}}]},{"name":"multiple integrations","grafana_managed_receiver_configs":[{"uid":"c2090fda-f824-4add-b545-5a4d5c2ef082","name":"multiple integrations","type":"prometheus-alertmanager","disableResolveMessage":true,"settings":{"basicAuthPassword":"[REDACTED]","basicAuthUser":"test","url":"http://localhost:9093"},"secureFields":{"basicAuthPassword":true}},{"uid":"c84539ec-f87e-4fc5-9a91-7a687d34bbd1","name":"multiple integrations","type":"discord","disableResolveMessage":false,"settings":{"avatar_url":"some avatar","url":"some url","use_discord_username":true},"secureFields":{}}]},{"name":"pagerduty test","grafana_managed_receiver_configs":[{"uid":"b9bf06f8-bde2-4438-9d4a-bba0522dcd4d","name":"pagerduty test","type":"pagerduty","disableResolveMessage":false,"settings":{"client":"some client","integrationKey":"[REDACTED]","severity":"criticalish"},"secureFields":{"integrationKey":true}}]},{"name":"slack test","grafana_managed_receiver_configs":[{"uid":"cbfd0976-8228-4126-b672-4419f30a9e50","name":"slack test","type":"slack","disableResolveMessage":true,"settings":{"text":"title body test","title":"title test","url":"[REDACTED]"},"secureFields":{"url":true}}]}]` - expectedListResponse := `[{"name":"grafana-default-email","grafana_managed_receiver_configs":[{"uid":"ad95bd8a-49ed-4adc-bf89-1b444fa1aa5b","name":"grafana-default-email","type":"email","disableResolveMessage":false,"secureFields":null}]},{"name":"multiple integrations","grafana_managed_receiver_configs":[{"uid":"c2090fda-f824-4add-b545-5a4d5c2ef082","name":"multiple integrations","type":"prometheus-alertmanager","disableResolveMessage":false,"secureFields":null},{"uid":"c84539ec-f87e-4fc5-9a91-7a687d34bbd1","name":"multiple integrations","type":"discord","disableResolveMessage":false,"secureFields":null}]},{"name":"pagerduty test","grafana_managed_receiver_configs":[{"uid":"b9bf06f8-bde2-4438-9d4a-bba0522dcd4d","name":"pagerduty test","type":"pagerduty","disableResolveMessage":false,"secureFields":null}]},{"name":"slack test","grafana_managed_receiver_configs":[{"uid":"cbfd0976-8228-4126-b672-4419f30a9e50","name":"slack test","type":"slack","disableResolveMessage":false,"secureFields":null}]}]` + expectedListResponse := `[{"name":"grafana-default-email","grafana_managed_receiver_configs":[{"uid":"ad95bd8a-49ed-4adc-bf89-1b444fa1aa5b","name":"grafana-default-email","type":"email","disableResolveMessage":false,"secureFields":{}}]},{"name":"multiple integrations","grafana_managed_receiver_configs":[{"uid":"c2090fda-f824-4add-b545-5a4d5c2ef082","name":"multiple integrations","type":"prometheus-alertmanager","disableResolveMessage":false,"secureFields":{}},{"uid":"c84539ec-f87e-4fc5-9a91-7a687d34bbd1","name":"multiple integrations","type":"discord","disableResolveMessage":false,"secureFields":{}}]},{"name":"pagerduty test","grafana_managed_receiver_configs":[{"uid":"b9bf06f8-bde2-4438-9d4a-bba0522dcd4d","name":"pagerduty test","type":"pagerduty","disableResolveMessage":false,"secureFields":{}}]},{"name":"slack test","grafana_managed_receiver_configs":[{"uid":"cbfd0976-8228-4126-b672-4419f30a9e50","name":"slack test","type":"slack","disableResolveMessage":false,"secureFields":{}}]}]` t.Run("limit offset", func(t *testing.T) { env := createTestEnv(t, testContactPointConfig) sut := createNotificationSrvSutFromEnv(t, &env) @@ -233,7 +208,7 @@ func TestRouteGetReceiversResponses(t *testing.T) { rc.Context.Req.Form.Set("decrypt", "false") var expected []definitions.GettableApiReceiver - err := json.Unmarshal([]byte(expectedRedactedResponse), &expected) + err := json.Unmarshal([]byte(expectedListResponse), &expected) require.NoError(t, err) type testcase struct { limit int @@ -266,7 +241,7 @@ func TestRouteGetReceiversResponses(t *testing.T) { }) } }) - t.Run("decrypt false with read permissions is redacted", func(t *testing.T) { + t.Run("decrypt false with read permissions, does not have settings", func(t *testing.T) { env := createTestEnv(t, testContactPointConfig) sut := createNotificationSrvSutFromEnv(t, &env) rc := createTestRequestCtx() @@ -277,7 +252,7 @@ func TestRouteGetReceiversResponses(t *testing.T) { response := sut.RouteGetReceivers(&rc) require.Equal(t, 200, response.Status()) - require.Equal(t, expectedRedactedResponse, string(response.Body())) // TODO: Should this endpoint ever return settings? + require.Equal(t, expectedListResponse, string(response.Body())) }) t.Run("decrypt false with only list permissions, does not have settings", func(t *testing.T) { env := createTestEnv(t, testContactPointConfig) @@ -300,7 +275,7 @@ func TestRouteGetReceiversResponses(t *testing.T) { require.Equal(t, 200, response.Status()) require.Equal(t, expectedListResponse, string(response.Body())) }) - t.Run("decrypt true with all permissions, contains decrypted settings", func(t *testing.T) { + t.Run("decrypt true with all permissions, does not have settings", func(t *testing.T) { env := createTestEnv(t, testContactPointConfig) env.ac = &recordingAccessControlFake{ Callback: func(user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) { @@ -316,7 +291,7 @@ func TestRouteGetReceiversResponses(t *testing.T) { response := sut.RouteGetReceivers(&rc) require.Equal(t, 200, response.Status()) - require.Equal(t, expectedDecryptedResponse, string(response.Body())) // TODO: Should this endpoint ever return settings? + require.Equal(t, expectedListResponse, string(response.Body())) }) }) }) diff --git a/pkg/services/ngalert/models/receivers.go b/pkg/services/ngalert/models/receivers.go index 152c7533c34..ec6b11d1363 100644 --- a/pkg/services/ngalert/models/receivers.go +++ b/pkg/services/ngalert/models/receivers.go @@ -18,6 +18,14 @@ type GetReceiversQuery struct { Decrypt bool } +// ListReceiversQuery represents a query for listing receiver groups. +type ListReceiversQuery struct { + OrgID int64 + Names []string + Limit int + Offset int +} + // Receiver is the domain model representation of a receiver / contact point. type Receiver struct { UID string diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index c86a1d00c30..b85aa73a871 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -412,7 +412,7 @@ func (ng *AlertNG) init() error { configStore := legacy_storage.NewAlertmanagerConfigStore(ng.store) receiverService := notifier.NewReceiverService( - ac.NewReceiverAccess[*models.Receiver](ng.accesscontrol, true), // TODO: Remove provisioning actions from regular API. + ac.NewReceiverAccess[*models.Receiver](ng.accesscontrol, false), configStore, ng.store, ng.SecretsService, diff --git a/pkg/services/ngalert/notifier/compat.go b/pkg/services/ngalert/notifier/compat.go index c809d927450..29db26528e6 100644 --- a/pkg/services/ngalert/notifier/compat.go +++ b/pkg/services/ngalert/notifier/compat.go @@ -48,48 +48,52 @@ func PostableApiAlertingConfigToApiReceivers(c apimodels.PostableApiAlertingConf type DecryptFn = func(value string) string -func PostableToGettableGrafanaReceiver(r *apimodels.PostableGrafanaReceiver, provenance *models.Provenance, decryptFn DecryptFn, listOnly bool) (apimodels.GettableGrafanaReceiver, error) { +func PostableToGettableGrafanaReceiver(r *apimodels.PostableGrafanaReceiver, provenance *models.Provenance, decryptFn DecryptFn) (apimodels.GettableGrafanaReceiver, error) { out := apimodels.GettableGrafanaReceiver{ - UID: r.UID, - Name: r.Name, - Type: r.Type, + UID: r.UID, + Name: r.Name, + Type: r.Type, + DisableResolveMessage: r.DisableResolveMessage, + SecureFields: make(map[string]bool, len(r.SecureSettings)), } if provenance != nil { out.Provenance = apimodels.Provenance(*provenance) } - // if we aren't only listing, include the settings in the output - if !listOnly { - secureFields := make(map[string]bool, len(r.SecureSettings)) - settings, err := simplejson.NewJson([]byte(r.Settings)) - if err != nil { - return apimodels.GettableGrafanaReceiver{}, err - } - - for k, v := range r.SecureSettings { - decryptedValue := decryptFn(v) - if decryptedValue == "" { - continue - } else { - settings.Set(k, decryptedValue) - } - secureFields[k] = true - } - - jsonBytes, err := settings.MarshalJSON() - if err != nil { - return apimodels.GettableGrafanaReceiver{}, err - } - - out.Settings = jsonBytes - out.SecureFields = secureFields - out.DisableResolveMessage = r.DisableResolveMessage + if r.Settings == nil && r.SecureSettings == nil { + return out, nil } + settings := simplejson.New() + if r.Settings != nil { + var err error + settings, err = simplejson.NewJson(r.Settings) + if err != nil { + return apimodels.GettableGrafanaReceiver{}, err + } + } + + for k, v := range r.SecureSettings { + decryptedValue := decryptFn(v) + if decryptedValue == "" { + continue + } else { + settings.Set(k, decryptedValue) + } + out.SecureFields[k] = true + } + + jsonBytes, err := settings.MarshalJSON() + if err != nil { + return apimodels.GettableGrafanaReceiver{}, err + } + + out.Settings = jsonBytes + return out, nil } -func PostableToGettableApiReceiver(r *apimodels.PostableApiReceiver, provenances map[string]models.Provenance, decryptFn DecryptFn, listOnly bool) (apimodels.GettableApiReceiver, error) { +func PostableToGettableApiReceiver(r *apimodels.PostableApiReceiver, provenances map[string]models.Provenance, decryptFn DecryptFn) (apimodels.GettableApiReceiver, error) { out := apimodels.GettableApiReceiver{ Receiver: config.Receiver{ Name: r.Receiver.Name, @@ -102,7 +106,7 @@ func PostableToGettableApiReceiver(r *apimodels.PostableApiReceiver, provenances prov = &p } - gettable, err := PostableToGettableGrafanaReceiver(gr, prov, decryptFn, listOnly) + gettable, err := PostableToGettableGrafanaReceiver(gr, prov, decryptFn) if err != nil { return apimodels.GettableApiReceiver{}, err } diff --git a/pkg/services/ngalert/notifier/receiver_svc.go b/pkg/services/ngalert/notifier/receiver_svc.go index 5c346385877..37542553251 100644 --- a/pkg/services/ngalert/notifier/receiver_svc.go +++ b/pkg/services/ngalert/notifier/receiver_svc.go @@ -107,7 +107,7 @@ func (rs *ReceiverService) GetReceiver(ctx context.Context, q models.GetReceiver return definitions.GettableApiReceiver{}, err } - return PostableToGettableApiReceiver(postable, storedProvenances, decryptFn, false) + return PostableToGettableApiReceiver(postable, storedProvenances, decryptFn) } // GetReceivers returns a list of receivers a user has access to. @@ -139,11 +139,64 @@ func (rs *ReceiverService) GetReceivers(ctx context.Context, q models.GetReceive return nil, err } + // User doesn't have any permissions on the receivers. + // This is mostly a safeguard as it should not be possible with current API endpoints + middleware authentication. + if !readRedactedAccess { + return nil, nil + } + + var output []definitions.GettableApiReceiver + for i := q.Offset; i < len(postables); i++ { + r := postables[i] + + decryptFn := rs.decryptOrRedact(ctx, decrypt, r.Name, "") + res, err := PostableToGettableApiReceiver(r, storedProvenances, decryptFn) + if err != nil { + return nil, err + } + + output = append(output, res) + // stop if we have reached the limit or we have found all the requested receivers + if (len(output) == q.Limit && q.Limit > 0) || (len(output) == len(q.Names)) { + break + } + } + + return output, nil +} + +// ListReceivers returns a list of receivers a user has access to. +// Receivers can be filtered by name. +// This offers an looser permissions compared to GetReceivers. When a user doesn't have read access it will check for list access instead of returning an empty list. +// If the users has list access, all receiver settings will be removed from the response. This option is for backwards compatibility with the v1/receivers endpoint +// and should be removed when FGAC is fully implemented. +func (rs *ReceiverService) ListReceivers(ctx context.Context, q models.ListReceiversQuery, user identity.Requester) ([]definitions.GettableApiReceiver, error) { // TODO: Remove this method with FGAC. listAccess, err := rs.authz.HasList(ctx, user) if err != nil { return nil, err } + readRedactedAccess, err := rs.authz.HasReadAll(ctx, user) + if err != nil { + return nil, err + } + + uids := make([]string, 0, len(q.Names)) + for _, name := range q.Names { + uids = append(uids, legacy_storage.NameToUid(name)) + } + + revision, err := rs.cfgStore.Get(ctx, q.OrgID) + if err != nil { + return nil, err + } + postables := revision.GetReceivers(uids) + + storedProvenances, err := rs.provisioningStore.GetProvenances(ctx, q.OrgID, (&definitions.EmbeddedContactPoint{}).ResourceType()) + if err != nil { + return nil, err + } + // User doesn't have any permissions on the receivers. // This is mostly a safeguard as it should not be possible with current API endpoints + middleware authentication. if !listAccess && !readRedactedAccess { @@ -154,14 +207,15 @@ func (rs *ReceiverService) GetReceivers(ctx context.Context, q models.GetReceive for i := q.Offset; i < len(postables); i++ { r := postables[i] - decryptFn := rs.decryptOrRedact(ctx, decrypt, r.Name, "") + // Remove settings. + for _, integration := range r.GrafanaManagedReceivers { + integration.Settings = nil + integration.SecureSettings = nil + integration.DisableResolveMessage = false + } - // Only has permission to list. This reduces from: - // - Has List permission - // - Doesn't have ReadRedacted (or ReadDecrypted permission since it's a subset). - listOnly := !readRedactedAccess - - res, err := PostableToGettableApiReceiver(r, storedProvenances, decryptFn, listOnly) + decryptFn := rs.decryptOrRedact(ctx, false, r.Name, "") + res, err := PostableToGettableApiReceiver(r, storedProvenances, decryptFn) if err != nil { return nil, err } diff --git a/pkg/services/ngalert/notifier/receiver_svc_test.go b/pkg/services/ngalert/notifier/receiver_svc_test.go index 1788788f945..38099b4355b 100644 --- a/pkg/services/ngalert/notifier/receiver_svc_test.go +++ b/pkg/services/ngalert/notifier/receiver_svc_test.go @@ -33,7 +33,7 @@ func TestReceiverService_GetReceiver(t *testing.T) { redactedUser := &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{ 1: { - accesscontrol.ActionAlertingProvisioningRead: nil, + accesscontrol.ActionAlertingNotificationsRead: nil, }, }} @@ -61,7 +61,7 @@ func TestReceiverService_GetReceivers(t *testing.T) { redactedUser := &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{ 1: { - accesscontrol.ActionAlertingProvisioningRead: nil, + accesscontrol.ActionAlertingNotificationsRead: nil, }, }} @@ -94,7 +94,7 @@ func TestReceiverService_DecryptRedact(t *testing.T) { readUser := &user.SignedInUser{ OrgID: 1, Permissions: map[int64]map[string][]string{ - 1: {accesscontrol.ActionAlertingProvisioningRead: nil}, + 1: {accesscontrol.ActionAlertingNotificationsRead: nil}, }, } @@ -102,8 +102,8 @@ func TestReceiverService_DecryptRedact(t *testing.T) { OrgID: 1, Permissions: map[int64]map[string][]string{ 1: { - accesscontrol.ActionAlertingProvisioningRead: nil, - accesscontrol.ActionAlertingProvisioningReadSecrets: nil, + accesscontrol.ActionAlertingNotificationsRead: nil, + accesscontrol.ActionAlertingReceiversReadSecrets: nil, }, }, } @@ -190,7 +190,7 @@ func createReceiverServiceSut(t *testing.T, encryptSvc secrets.Service) *Receive provisioningStore := fakes.NewFakeProvisioningStore() return NewReceiverService( - ac.NewReceiverAccess[*models.Receiver](acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), true), + ac.NewReceiverAccess[*models.Receiver](acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), false), legacy_storage.NewAlertmanagerConfigStore(store), provisioningStore, encryptSvc, diff --git a/pkg/services/ngalert/tests/fakes/receivers.go b/pkg/services/ngalert/tests/fakes/receivers.go index 8783adc0aa6..6f67b8c4ffd 100644 --- a/pkg/services/ngalert/tests/fakes/receivers.go +++ b/pkg/services/ngalert/tests/fakes/receivers.go @@ -14,15 +14,15 @@ type ReceiverServiceMethodCall struct { } type FakeReceiverService struct { - MethodCalls []ReceiverServiceMethodCall - GetReceiverFn func(ctx context.Context, q models.GetReceiverQuery, u identity.Requester) (definitions.GettableApiReceiver, error) - GetReceiversFn func(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) + MethodCalls []ReceiverServiceMethodCall + GetReceiverFn func(ctx context.Context, q models.GetReceiverQuery, u identity.Requester) (definitions.GettableApiReceiver, error) + ListReceiversFn func(ctx context.Context, q models.ListReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) } func NewFakeReceiverService() *FakeReceiverService { return &FakeReceiverService{ - GetReceiverFn: defaultReceiverFn, - GetReceiversFn: defaultReceiversFn, + GetReceiverFn: defaultReceiverFn, + ListReceiversFn: defaultReceiversFn, } } @@ -31,9 +31,9 @@ func (f *FakeReceiverService) GetReceiver(ctx context.Context, q models.GetRecei return f.GetReceiverFn(ctx, q, u) } -func (f *FakeReceiverService) GetReceivers(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { - f.MethodCalls = append(f.MethodCalls, ReceiverServiceMethodCall{Method: "GetReceivers", Args: []interface{}{ctx, q}}) - return f.GetReceiversFn(ctx, q, u) +func (f *FakeReceiverService) ListReceivers(ctx context.Context, q models.ListReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { + f.MethodCalls = append(f.MethodCalls, ReceiverServiceMethodCall{Method: "ListReceivers", Args: []interface{}{ctx, q}}) + return f.ListReceiversFn(ctx, q, u) } func (f *FakeReceiverService) PopMethodCall() ReceiverServiceMethodCall { @@ -48,13 +48,13 @@ func (f *FakeReceiverService) PopMethodCall() ReceiverServiceMethodCall { func (f *FakeReceiverService) Reset() { f.MethodCalls = nil f.GetReceiverFn = defaultReceiverFn - f.GetReceiversFn = defaultReceiversFn + f.ListReceiversFn = defaultReceiversFn } func defaultReceiverFn(ctx context.Context, q models.GetReceiverQuery, u identity.Requester) (definitions.GettableApiReceiver, error) { return definitions.GettableApiReceiver{}, nil } -func defaultReceiversFn(ctx context.Context, q models.GetReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { +func defaultReceiversFn(ctx context.Context, q models.ListReceiversQuery, u identity.Requester) ([]definitions.GettableApiReceiver, error) { return nil, nil }