Alerting: Allow filtering of contact points by name (#51933)

* Define query param and regenerate

* Add query struct for contact points

* Filter contact points by name in query

* Document that name filter is optional
This commit is contained in:
Alexander Weaver 2022-07-11 17:11:46 -05:00 committed by GitHub
parent 73f4d7ac05
commit 0e066dd5f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 19 deletions

View File

@ -25,7 +25,7 @@ type ProvisioningSrv struct {
} }
type ContactPointService interface { type ContactPointService interface {
GetContactPoints(ctx context.Context, orgID int64) ([]definitions.EmbeddedContactPoint, error) GetContactPoints(ctx context.Context, q provisioning.ContactPointQuery) ([]definitions.EmbeddedContactPoint, error)
CreateContactPoint(ctx context.Context, orgID int64, contactPoint definitions.EmbeddedContactPoint, p alerting_models.Provenance) (definitions.EmbeddedContactPoint, error) CreateContactPoint(ctx context.Context, orgID int64, contactPoint definitions.EmbeddedContactPoint, p alerting_models.Provenance) (definitions.EmbeddedContactPoint, error)
UpdateContactPoint(ctx context.Context, orgID int64, contactPoint definitions.EmbeddedContactPoint, p alerting_models.Provenance) error UpdateContactPoint(ctx context.Context, orgID int64, contactPoint definitions.EmbeddedContactPoint, p alerting_models.Provenance) error
DeleteContactPoint(ctx context.Context, orgID int64, uid string) error DeleteContactPoint(ctx context.Context, orgID int64, uid string) error
@ -95,7 +95,11 @@ func (srv *ProvisioningSrv) RouteResetPolicyTree(c *models.ReqContext) response.
} }
func (srv *ProvisioningSrv) RouteGetContactPoints(c *models.ReqContext) response.Response { func (srv *ProvisioningSrv) RouteGetContactPoints(c *models.ReqContext) response.Response {
cps, err := srv.contactPointService.GetContactPoints(c.Req.Context(), c.OrgId) q := provisioning.ContactPointQuery{
Name: c.Query("name"),
OrgID: c.OrgId,
}
cps, err := srv.contactPointService.GetContactPoints(c.Req.Context(), q)
if err != nil { if err != nil {
return ErrResp(http.StatusInternalServerError, err, "") return ErrResp(http.StatusInternalServerError, err, "")
} }

View File

@ -3386,6 +3386,14 @@
"/api/v1/provisioning/contact-points": { "/api/v1/provisioning/contact-points": {
"get": { "get": {
"operationId": "RouteGetContactpoints", "operationId": "RouteGetContactpoints",
"parameters": [
{
"description": "Filter by name",
"in": "query",
"name": "name",
"type": "string"
}
],
"responses": { "responses": {
"200": { "200": {
"description": "ContactPoints", "description": "ContactPoints",

View File

@ -53,6 +53,14 @@ type ContactPointUIDReference struct {
UID string UID string
} }
// swagger:parameters RouteGetContactpoints
type ContactPointParams struct {
// Filter by name
// in: query
// required: false
Name string `json:"name"`
}
// swagger:parameters RoutePostContactpoints RoutePutContactpoint // swagger:parameters RoutePostContactpoints RoutePutContactpoint
type ContactPointPayload struct { type ContactPointPayload struct {
// in:body // in:body

View File

@ -2761,7 +2761,6 @@
"type": "object" "type": "object"
}, },
"alertGroup": { "alertGroup": {
"description": "AlertGroup alert group",
"properties": { "properties": {
"alerts": { "alerts": {
"description": "alerts", "description": "alerts",
@ -2954,7 +2953,6 @@
"type": "array" "type": "array"
}, },
"gettableSilence": { "gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": { "properties": {
"comment": { "comment": {
"description": "comment", "description": "comment",
@ -5012,6 +5010,14 @@
"/api/v1/provisioning/contact-points": { "/api/v1/provisioning/contact-points": {
"get": { "get": {
"operationId": "RouteGetContactpoints", "operationId": "RouteGetContactpoints",
"parameters": [
{
"description": "Filter by name",
"in": "query",
"name": "name",
"type": "string"
}
],
"responses": { "responses": {
"200": { "200": {
"description": "ContactPoints", "description": "ContactPoints",

View File

@ -1780,6 +1780,14 @@
], ],
"summary": "Get all the contact points.", "summary": "Get all the contact points.",
"operationId": "RouteGetContactpoints", "operationId": "RouteGetContactpoints",
"parameters": [
{
"type": "string",
"description": "Filter by name",
"name": "name",
"in": "query"
}
],
"responses": { "responses": {
"200": { "200": {
"description": "ContactPoints", "description": "ContactPoints",
@ -5138,7 +5146,6 @@
} }
}, },
"alertGroup": { "alertGroup": {
"description": "AlertGroup alert group",
"type": "object", "type": "object",
"required": [ "required": [
"alerts", "alerts",
@ -5163,6 +5170,7 @@
"$ref": "#/definitions/alertGroup" "$ref": "#/definitions/alertGroup"
}, },
"alertGroups": { "alertGroups": {
"description": "AlertGroups alert groups",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/alertGroup" "$ref": "#/definitions/alertGroup"
@ -5328,6 +5336,7 @@
"$ref": "#/definitions/gettableAlert" "$ref": "#/definitions/gettableAlert"
}, },
"gettableAlerts": { "gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/gettableAlert" "$ref": "#/definitions/gettableAlert"
@ -5536,7 +5545,6 @@
"$ref": "#/definitions/postableSilence" "$ref": "#/definitions/postableSilence"
}, },
"receiver": { "receiver": {
"description": "Receiver receiver",
"type": "object", "type": "object",
"required": [ "required": [
"name" "name"

View File

@ -34,17 +34,27 @@ func NewContactPointService(store AMConfigStore, encryptionService secrets.Servi
} }
} }
func (ecp *ContactPointService) GetContactPoints(ctx context.Context, orgID int64) ([]apimodels.EmbeddedContactPoint, error) { type ContactPointQuery struct {
revision, err := getLastConfiguration(ctx, orgID, ecp.amStore) // Optionally filter by name.
Name string
OrgID int64
}
func (ecp *ContactPointService) GetContactPoints(ctx context.Context, q ContactPointQuery) ([]apimodels.EmbeddedContactPoint, error) {
revision, err := getLastConfiguration(ctx, q.OrgID, ecp.amStore)
if err != nil { if err != nil {
return nil, err return nil, err
} }
provenances, err := ecp.provenanceStore.GetProvenances(ctx, orgID, "contactPoint") provenances, err := ecp.provenanceStore.GetProvenances(ctx, q.OrgID, "contactPoint")
if err != nil { if err != nil {
return nil, err return nil, err
} }
contactPoints := []apimodels.EmbeddedContactPoint{} contactPoints := []apimodels.EmbeddedContactPoint{}
for _, contactPoint := range revision.cfg.GetGrafanaReceiverMap() { for _, contactPoint := range revision.cfg.GetGrafanaReceiverMap() {
if q.Name != "" && contactPoint.Name != q.Name {
continue
}
embeddedContactPoint := apimodels.EmbeddedContactPoint{ embeddedContactPoint := apimodels.EmbeddedContactPoint{
UID: contactPoint.UID, UID: contactPoint.UID,
Type: contactPoint.Type, Type: contactPoint.Type,
@ -66,6 +76,7 @@ func (ecp *ContactPointService) GetContactPoints(ctx context.Context, orgID int6
} }
embeddedContactPoint.Settings.Set(k, apimodels.RedactedValue) embeddedContactPoint.Settings.Set(k, apimodels.RedactedValue)
} }
contactPoints = append(contactPoints, embeddedContactPoint) contactPoints = append(contactPoints, embeddedContactPoint)
} }
sort.SliceStable(contactPoints, func(i, j int) bool { sort.SliceStable(contactPoints, func(i, j int) bool {

View File

@ -22,7 +22,24 @@ func TestContactPointService(t *testing.T) {
t.Run("service gets contact points from AM config", func(t *testing.T) { t.Run("service gets contact points from AM config", func(t *testing.T) {
sut := createContactPointServiceSut(secretsService) sut := createContactPointServiceSut(secretsService)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Len(t, cps, 1)
require.Equal(t, "email receiver", cps[0].Name)
})
t.Run("service filters contact points by name", func(t *testing.T) {
sut := createContactPointServiceSut(secretsService)
newCp := createTestContactPoint()
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
require.NoError(t, err)
q := ContactPointQuery{
OrgID: 1,
Name: "email receiver",
}
cps, err := sut.GetContactPoints(context.Background(), q)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, cps, 1) require.Len(t, cps, 1)
@ -36,7 +53,7 @@ func TestContactPointService(t *testing.T) {
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI) _, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
require.NoError(t, err) require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Len(t, cps, 2) require.Len(t, cps, 2)
require.Equal(t, "test-contact-point", cps[1].Name) require.Equal(t, "test-contact-point", cps[1].Name)
@ -52,7 +69,7 @@ func TestContactPointService(t *testing.T) {
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI) _, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
require.NoError(t, err) require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Len(t, cps, 2) require.Len(t, cps, 2)
require.Equal(t, customUID, cps[1].UID) require.Equal(t, customUID, cps[1].UID)
@ -120,7 +137,7 @@ func TestContactPointService(t *testing.T) {
t.Run("default provenance of contact points is none", func(t *testing.T) { t.Run("default provenance of contact points is none", func(t *testing.T) {
sut := createContactPointServiceSut(secretsService) sut := createContactPointServiceSut(secretsService)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, models.ProvenanceNone, models.Provenance(cps[0].Provenance)) require.Equal(t, models.ProvenanceNone, models.Provenance(cps[0].Provenance))
@ -133,7 +150,7 @@ func TestContactPointService(t *testing.T) {
newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceNone) newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceNone)
require.NoError(t, err) require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID) require.Equal(t, newCp.UID, cps[1].UID)
require.Equal(t, models.ProvenanceNone, models.Provenance(cps[1].Provenance)) require.Equal(t, models.ProvenanceNone, models.Provenance(cps[1].Provenance))
@ -141,7 +158,7 @@ func TestContactPointService(t *testing.T) {
err = sut.UpdateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI) err = sut.UpdateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
require.NoError(t, err) require.NoError(t, err)
cps, err = sut.GetContactPoints(context.Background(), 1) cps, err = sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID) require.Equal(t, newCp.UID, cps[1].UID)
require.Equal(t, models.ProvenanceAPI, models.Provenance(cps[1].Provenance)) require.Equal(t, models.ProvenanceAPI, models.Provenance(cps[1].Provenance))
@ -154,7 +171,7 @@ func TestContactPointService(t *testing.T) {
newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceNone) newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceNone)
require.NoError(t, err) require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID) require.Equal(t, newCp.UID, cps[1].UID)
require.Equal(t, models.ProvenanceNone, models.Provenance(cps[1].Provenance)) require.Equal(t, models.ProvenanceNone, models.Provenance(cps[1].Provenance))
@ -162,7 +179,7 @@ func TestContactPointService(t *testing.T) {
err = sut.UpdateContactPoint(context.Background(), 1, newCp, models.ProvenanceFile) err = sut.UpdateContactPoint(context.Background(), 1, newCp, models.ProvenanceFile)
require.NoError(t, err) require.NoError(t, err)
cps, err = sut.GetContactPoints(context.Background(), 1) cps, err = sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID) require.Equal(t, newCp.UID, cps[1].UID)
require.Equal(t, models.ProvenanceFile, models.Provenance(cps[1].Provenance)) require.Equal(t, models.ProvenanceFile, models.Provenance(cps[1].Provenance))
@ -175,7 +192,7 @@ func TestContactPointService(t *testing.T) {
newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceFile) newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceFile)
require.NoError(t, err) require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID) require.Equal(t, newCp.UID, cps[1].UID)
require.Equal(t, models.ProvenanceFile, models.Provenance(cps[1].Provenance)) require.Equal(t, models.ProvenanceFile, models.Provenance(cps[1].Provenance))
@ -191,7 +208,7 @@ func TestContactPointService(t *testing.T) {
newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI) newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
require.NoError(t, err) require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1) cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID) require.Equal(t, newCp.UID, cps[1].UID)
require.Equal(t, models.ProvenanceAPI, models.Provenance(cps[1].Provenance)) require.Equal(t, models.ProvenanceAPI, models.Provenance(cps[1].Provenance))
@ -269,6 +286,12 @@ func createTestContactPoint() definitions.EmbeddedContactPoint {
} }
} }
func cpsQuery(orgID int64) ContactPointQuery {
return ContactPointQuery{
OrgID: orgID,
}
}
func TestStitchReceivers(t *testing.T) { func TestStitchReceivers(t *testing.T) {
type testCase struct { type testCase struct {
name string name string