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 {
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)
UpdateContactPoint(ctx context.Context, orgID int64, contactPoint definitions.EmbeddedContactPoint, p alerting_models.Provenance) 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 {
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 {
return ErrResp(http.StatusInternalServerError, err, "")
}

View File

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

View File

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

View File

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

View File

@ -1780,6 +1780,14 @@
],
"summary": "Get all the contact points.",
"operationId": "RouteGetContactpoints",
"parameters": [
{
"type": "string",
"description": "Filter by name",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"description": "ContactPoints",
@ -5138,7 +5146,6 @@
}
},
"alertGroup": {
"description": "AlertGroup alert group",
"type": "object",
"required": [
"alerts",
@ -5163,6 +5170,7 @@
"$ref": "#/definitions/alertGroup"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"type": "array",
"items": {
"$ref": "#/definitions/alertGroup"
@ -5328,6 +5336,7 @@
"$ref": "#/definitions/gettableAlert"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"type": "array",
"items": {
"$ref": "#/definitions/gettableAlert"
@ -5536,7 +5545,6 @@
"$ref": "#/definitions/postableSilence"
},
"receiver": {
"description": "Receiver receiver",
"type": "object",
"required": [
"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) {
revision, err := getLastConfiguration(ctx, orgID, ecp.amStore)
type ContactPointQuery struct {
// 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 {
return nil, err
}
provenances, err := ecp.provenanceStore.GetProvenances(ctx, orgID, "contactPoint")
provenances, err := ecp.provenanceStore.GetProvenances(ctx, q.OrgID, "contactPoint")
if err != nil {
return nil, err
}
contactPoints := []apimodels.EmbeddedContactPoint{}
for _, contactPoint := range revision.cfg.GetGrafanaReceiverMap() {
if q.Name != "" && contactPoint.Name != q.Name {
continue
}
embeddedContactPoint := apimodels.EmbeddedContactPoint{
UID: contactPoint.UID,
Type: contactPoint.Type,
@ -66,6 +76,7 @@ func (ecp *ContactPointService) GetContactPoints(ctx context.Context, orgID int6
}
embeddedContactPoint.Settings.Set(k, apimodels.RedactedValue)
}
contactPoints = append(contactPoints, embeddedContactPoint)
}
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) {
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.Len(t, cps, 1)
@ -36,7 +53,7 @@ func TestContactPointService(t *testing.T) {
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Len(t, cps, 2)
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)
require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Len(t, cps, 2)
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) {
sut := createContactPointServiceSut(secretsService)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
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)
require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID)
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)
require.NoError(t, err)
cps, err = sut.GetContactPoints(context.Background(), 1)
cps, err = sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID)
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)
require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID)
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)
require.NoError(t, err)
cps, err = sut.GetContactPoints(context.Background(), 1)
cps, err = sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID)
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)
require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID)
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)
require.NoError(t, err)
cps, err := sut.GetContactPoints(context.Background(), 1)
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1))
require.NoError(t, err)
require.Equal(t, newCp.UID, cps[1].UID)
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) {
type testCase struct {
name string