mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Allow querying of Alerts from notifications (#32614)
* Alerting: Allow querying of Alerts from notifications * Wire everything up * Remove unused functions * Remove duplicate line
This commit is contained in:
@@ -30,11 +30,18 @@ import (
|
||||
var timeNow = time.Now
|
||||
|
||||
type Alertmanager interface {
|
||||
// Configuration
|
||||
ApplyConfig(config *apimodels.PostableUserConfig) error
|
||||
|
||||
// Silences
|
||||
CreateSilence(ps *apimodels.PostableSilence) (string, error)
|
||||
DeleteSilence(silenceID string) error
|
||||
GetSilence(silenceID string) (apimodels.GettableSilence, error)
|
||||
ListSilences(filters []string) (apimodels.GettableSilences, error)
|
||||
ListSilences(filter []string) (apimodels.GettableSilences, error)
|
||||
|
||||
// Alerts
|
||||
GetAlerts(active, silenced, inhibited bool, filter []string, receiver string) (apimodels.GettableAlerts, error)
|
||||
GetAlertGroups(active, silenced, inhibited bool, filter []string, receiver string) (apimodels.AlertGroups, error)
|
||||
}
|
||||
|
||||
// API handlers.
|
||||
|
||||
@@ -4,11 +4,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
apimodels "github.com/grafana/alerting-api/pkg/api"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@@ -17,7 +15,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
amv2 "github.com/prometheus/alertmanager/api/v2/models"
|
||||
)
|
||||
|
||||
type AlertmanagerSrv struct {
|
||||
@@ -118,193 +115,41 @@ func (srv AlertmanagerSrv) RouteGetAlertingConfig(c *models.ReqContext) response
|
||||
}
|
||||
|
||||
func (srv AlertmanagerSrv) RouteGetAMAlertGroups(c *models.ReqContext) response.Response {
|
||||
recipient := c.Params(":Recipient")
|
||||
srv.log.Info("RouteGetAMAlertGroups: ", "Recipient", recipient)
|
||||
now := time.Now()
|
||||
result := apimodels.AlertGroups{
|
||||
&amv2.AlertGroup{
|
||||
Alerts: []*amv2.GettableAlert{
|
||||
{
|
||||
Annotations: amv2.LabelSet{
|
||||
"annotation1-1": "value1",
|
||||
"annotation1-2": "value2",
|
||||
},
|
||||
EndsAt: timePtr(strfmt.DateTime(now.Add(time.Hour))),
|
||||
Fingerprint: stringPtr("fingerprint 1"),
|
||||
Receivers: []*amv2.Receiver{
|
||||
{
|
||||
Name: stringPtr("receiver identifier 1-1"),
|
||||
},
|
||||
{
|
||||
Name: stringPtr("receiver identifier 1-2"),
|
||||
},
|
||||
},
|
||||
StartsAt: timePtr(strfmt.DateTime(now)),
|
||||
Status: &amv2.AlertStatus{
|
||||
InhibitedBy: []string{"inhibitedBy 1"},
|
||||
SilencedBy: []string{"silencedBy 1"},
|
||||
State: stringPtr(amv2.AlertStatusStateActive),
|
||||
},
|
||||
UpdatedAt: timePtr(strfmt.DateTime(now.Add(-time.Hour))),
|
||||
Alert: amv2.Alert{
|
||||
GeneratorURL: strfmt.URI("a URL"),
|
||||
Labels: amv2.LabelSet{
|
||||
"label1-1": "value1",
|
||||
"label1-2": "value2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Annotations: amv2.LabelSet{
|
||||
"annotation2-1": "value1",
|
||||
"annotation2-2": "value2",
|
||||
},
|
||||
EndsAt: timePtr(strfmt.DateTime(now.Add(time.Hour))),
|
||||
Fingerprint: stringPtr("fingerprint 2"),
|
||||
Receivers: []*amv2.Receiver{
|
||||
{
|
||||
Name: stringPtr("receiver identifier 2-1"),
|
||||
},
|
||||
{
|
||||
Name: stringPtr("receiver identifier 2-2"),
|
||||
},
|
||||
},
|
||||
StartsAt: timePtr(strfmt.DateTime(now)),
|
||||
Status: &amv2.AlertStatus{
|
||||
InhibitedBy: []string{"inhibitedBy 2"},
|
||||
SilencedBy: []string{"silencedBy 2"},
|
||||
State: stringPtr(amv2.AlertStatusStateActive),
|
||||
},
|
||||
UpdatedAt: timePtr(strfmt.DateTime(now.Add(-time.Hour))),
|
||||
Alert: amv2.Alert{
|
||||
GeneratorURL: strfmt.URI("a URL"),
|
||||
Labels: amv2.LabelSet{
|
||||
"label2-1": "value1",
|
||||
"label2-2": "value2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Labels: amv2.LabelSet{
|
||||
"label1-1": "value1",
|
||||
"label1-2": "value2",
|
||||
},
|
||||
Receiver: &amv2.Receiver{
|
||||
Name: stringPtr("receiver identifier 2-1"),
|
||||
},
|
||||
},
|
||||
&amv2.AlertGroup{
|
||||
Alerts: []*amv2.GettableAlert{
|
||||
{
|
||||
Annotations: amv2.LabelSet{
|
||||
"annotation2-1": "value1",
|
||||
"annotation2-2": "value2",
|
||||
},
|
||||
EndsAt: timePtr(strfmt.DateTime(now.Add(time.Hour))),
|
||||
Fingerprint: stringPtr("fingerprint 2"),
|
||||
Receivers: []*amv2.Receiver{
|
||||
{
|
||||
Name: stringPtr("receiver identifier 2-1"),
|
||||
},
|
||||
{
|
||||
Name: stringPtr("receiver identifier 2-2"),
|
||||
},
|
||||
},
|
||||
StartsAt: timePtr(strfmt.DateTime(now)),
|
||||
Status: &amv2.AlertStatus{
|
||||
InhibitedBy: []string{"inhibitedBy 2"},
|
||||
SilencedBy: []string{"silencedBy 2"},
|
||||
State: stringPtr(amv2.AlertStatusStateActive),
|
||||
},
|
||||
UpdatedAt: timePtr(strfmt.DateTime(now.Add(-time.Hour))),
|
||||
Alert: amv2.Alert{
|
||||
GeneratorURL: strfmt.URI("a URL"),
|
||||
Labels: amv2.LabelSet{
|
||||
"label2-1": "value1",
|
||||
"label2-2": "value2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Labels: amv2.LabelSet{
|
||||
"label2-1": "value1",
|
||||
"label2-2": "value2",
|
||||
},
|
||||
Receiver: &amv2.Receiver{
|
||||
Name: stringPtr("receiver identifier 2-1"),
|
||||
},
|
||||
},
|
||||
groups, err := srv.am.GetAlertGroups(
|
||||
c.QueryBool("active"),
|
||||
c.QueryBool("silenced"),
|
||||
c.QueryBool("inhibited"),
|
||||
c.QueryStrings("filter"),
|
||||
c.Query("receiver"),
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, notifier.ErrGetAlertGroupsBadPayload) {
|
||||
return response.Error(http.StatusBadRequest, err.Error(), nil)
|
||||
}
|
||||
// any other error here should be an unexpected failure and thus an internal error
|
||||
return response.Error(http.StatusInternalServerError, err.Error(), nil)
|
||||
}
|
||||
return response.JSON(http.StatusOK, result)
|
||||
|
||||
return response.JSON(http.StatusOK, groups)
|
||||
}
|
||||
|
||||
func (srv AlertmanagerSrv) RouteGetAMAlerts(c *models.ReqContext) response.Response {
|
||||
recipient := c.Params(":Recipient")
|
||||
srv.log.Info("RouteGetAMAlerts: ", "Recipient", recipient)
|
||||
now := time.Now()
|
||||
result := apimodels.GettableAlerts{
|
||||
&amv2.GettableAlert{
|
||||
Annotations: amv2.LabelSet{
|
||||
"annotation1-1": "value1",
|
||||
"annotation1-2": "value2",
|
||||
},
|
||||
EndsAt: timePtr(strfmt.DateTime(now.Add(time.Hour))),
|
||||
Fingerprint: stringPtr("fingerprint 1"),
|
||||
Receivers: []*amv2.Receiver{
|
||||
{
|
||||
Name: stringPtr("receiver identifier 1-1"),
|
||||
},
|
||||
{
|
||||
Name: stringPtr("receiver identifier 1-2"),
|
||||
},
|
||||
},
|
||||
StartsAt: timePtr(strfmt.DateTime(now)),
|
||||
Status: &amv2.AlertStatus{
|
||||
InhibitedBy: []string{"inhibitedBy 1"},
|
||||
SilencedBy: []string{"silencedBy 1"},
|
||||
State: stringPtr(amv2.AlertStatusStateActive),
|
||||
},
|
||||
UpdatedAt: timePtr(strfmt.DateTime(now.Add(-time.Hour))),
|
||||
Alert: amv2.Alert{
|
||||
GeneratorURL: strfmt.URI("a URL"),
|
||||
Labels: amv2.LabelSet{
|
||||
"label1-1": "value1",
|
||||
"label1-2": "value2",
|
||||
},
|
||||
},
|
||||
},
|
||||
&amv2.GettableAlert{
|
||||
Annotations: amv2.LabelSet{
|
||||
"annotation2-1": "value1",
|
||||
"annotation2-2": "value2",
|
||||
},
|
||||
EndsAt: timePtr(strfmt.DateTime(now.Add(time.Hour))),
|
||||
Fingerprint: stringPtr("fingerprint 2"),
|
||||
Receivers: []*amv2.Receiver{
|
||||
{
|
||||
Name: stringPtr("receiver identifier 2-1"),
|
||||
},
|
||||
{
|
||||
Name: stringPtr("receiver identifier 2-2"),
|
||||
},
|
||||
},
|
||||
StartsAt: timePtr(strfmt.DateTime(now)),
|
||||
Status: &amv2.AlertStatus{
|
||||
InhibitedBy: []string{"inhibitedBy 2"},
|
||||
SilencedBy: []string{"silencedBy 2"},
|
||||
State: stringPtr(amv2.AlertStatusStateActive),
|
||||
},
|
||||
UpdatedAt: timePtr(strfmt.DateTime(now.Add(-time.Hour))),
|
||||
Alert: amv2.Alert{
|
||||
GeneratorURL: strfmt.URI("a URL"),
|
||||
Labels: amv2.LabelSet{
|
||||
"label2-1": "value1",
|
||||
"label2-2": "value2",
|
||||
},
|
||||
},
|
||||
},
|
||||
alerts, err := srv.am.GetAlerts(
|
||||
c.QueryBool("active"),
|
||||
c.QueryBool("silenced"),
|
||||
c.QueryBool("inhibited"),
|
||||
c.QueryStrings("filter"),
|
||||
c.Query("receiver"),
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, notifier.ErrGetAlertsBadPayload) {
|
||||
return response.Error(http.StatusBadRequest, err.Error(), nil)
|
||||
}
|
||||
// any other error here should be an unexpected failure and thus an internal error
|
||||
return response.Error(http.StatusInternalServerError, err.Error(), nil)
|
||||
}
|
||||
return response.JSON(http.StatusOK, result)
|
||||
|
||||
return response.JSON(http.StatusOK, alerts)
|
||||
}
|
||||
|
||||
func (srv AlertmanagerSrv) RouteGetSilence(c *models.ReqContext) response.Response {
|
||||
@@ -321,8 +166,7 @@ func (srv AlertmanagerSrv) RouteGetSilence(c *models.ReqContext) response.Respon
|
||||
}
|
||||
|
||||
func (srv AlertmanagerSrv) RouteGetSilences(c *models.ReqContext) response.Response {
|
||||
filters := c.QueryStrings("Filter")
|
||||
gettableSilences, err := srv.am.ListSilences(filters)
|
||||
gettableSilences, err := srv.am.ListSilences(c.QueryStrings("filter"))
|
||||
if err != nil {
|
||||
if errors.Is(err, notifier.ErrListSilencesBadPayload) {
|
||||
return response.Error(http.StatusBadRequest, err.Error(), nil)
|
||||
|
||||
@@ -97,6 +97,10 @@ content-type: application/json
|
||||
# get AM alerts
|
||||
GET http://admin:admin@localhost:3000/api/alertmanager/{{alertManagerDatasourceID}}/api/v2/alerts
|
||||
|
||||
###
|
||||
# get AM alert groups
|
||||
GET http://admin:admin@localhost:3000/alertmanager/{{alertManagerDatasourceID}}/api/v2/alerts/groups
|
||||
|
||||
###
|
||||
# get silences - no silences
|
||||
GET http://admin:admin@localhost:3000/api/alertmanager/{{alertManagerDatasourceID}}/api/v2/silences?Filter=foo="bar"&Filter=bar="foo"
|
||||
@@ -164,4 +168,4 @@ DELETE http://admin:admin@localhost:3000/api/alertmanager/{{alertManagerDatasour
|
||||
|
||||
###
|
||||
# delete silence - unknown
|
||||
DELETE http://admin:admin@localhost:3000/api/alertmanager/{{alertManagerDatasourceID}}/api/v2/silence/unknown
|
||||
DELETE http://admin:admin@localhost:3000/api/alertmanager/{{alertManagerDatasourceID}}/api/v2/silence/unknown
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
apimodels "github.com/grafana/alerting-api/pkg/api"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@@ -30,14 +29,6 @@ func toMacaronPath(path string) string {
|
||||
}))
|
||||
}
|
||||
|
||||
func timePtr(t strfmt.DateTime) *strfmt.DateTime {
|
||||
return &t
|
||||
}
|
||||
|
||||
func stringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
func backendType(ctx *models.ReqContext, cache datasources.CacheService) (apimodels.Backend, error) {
|
||||
recipient := ctx.Params("Recipient")
|
||||
if recipient == apimodels.GrafanaBackend.String() {
|
||||
|
||||
Reference in New Issue
Block a user