mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Unified Alerting: Validate PostableSilence API. (#46892)
Invalid PostableSilences could be passed to the Alerting API - if they are passed all the way down into the alertmanager data layer, they can cause a panic. This change adds validation to avoid a panic in the alertmanager.
This commit is contained in:
parent
7798b08b1e
commit
103087a1a5
@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/grafana/grafana/pkg/api/response"
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
@ -50,6 +51,12 @@ func (srv AlertmanagerSrv) RouteGetAMStatus(c *models.ReqContext) response.Respo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (srv AlertmanagerSrv) RouteCreateSilence(c *models.ReqContext, postableSilence apimodels.PostableSilence) response.Response {
|
func (srv AlertmanagerSrv) RouteCreateSilence(c *models.ReqContext, postableSilence apimodels.PostableSilence) response.Response {
|
||||||
|
err := postableSilence.Validate(strfmt.Default)
|
||||||
|
if err != nil {
|
||||||
|
srv.log.Error("silence failed validation", "err", err)
|
||||||
|
return ErrResp(http.StatusBadRequest, err, "silence failed validation")
|
||||||
|
}
|
||||||
|
|
||||||
am, errResp := srv.AlertmanagerFor(c.OrgId)
|
am, errResp := srv.AlertmanagerFor(c.OrgId)
|
||||||
if errResp != nil {
|
if errResp != nil {
|
||||||
return errResp
|
return errResp
|
||||||
|
@ -239,6 +239,66 @@ func TestAlertmanagerConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSilenceCreate(t *testing.T) {
|
||||||
|
makeSilence := func(comment string, createdBy string,
|
||||||
|
startsAt, endsAt strfmt.DateTime, matchers amv2.Matchers) amv2.Silence {
|
||||||
|
return amv2.Silence{
|
||||||
|
Comment: &comment,
|
||||||
|
CreatedBy: &createdBy,
|
||||||
|
StartsAt: &startsAt,
|
||||||
|
EndsAt: &endsAt,
|
||||||
|
Matchers: matchers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
dt := func(t time.Time) strfmt.DateTime { return strfmt.DateTime(t) }
|
||||||
|
tru := true
|
||||||
|
testString := "testName"
|
||||||
|
matchers := amv2.Matchers{&amv2.Matcher{Name: &testString, IsEqual: &tru, IsRegex: &tru, Value: &testString}}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
silence amv2.Silence
|
||||||
|
status int
|
||||||
|
}{
|
||||||
|
{"Valid Silence",
|
||||||
|
makeSilence("", "tests", dt(now), dt(now.Add(1*time.Second)), matchers),
|
||||||
|
http.StatusAccepted,
|
||||||
|
},
|
||||||
|
{"No Comment Silence",
|
||||||
|
func() amv2.Silence {
|
||||||
|
s := makeSilence("", "tests", dt(now), dt(now.Add(1*time.Second)), matchers)
|
||||||
|
s.Comment = nil
|
||||||
|
return s
|
||||||
|
}(),
|
||||||
|
http.StatusBadRequest,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cas := range cases {
|
||||||
|
t.Run(cas.name, func(t *testing.T) {
|
||||||
|
rc := models.ReqContext{
|
||||||
|
Context: &web.Context{
|
||||||
|
Req: &http.Request{},
|
||||||
|
},
|
||||||
|
SignedInUser: &models.SignedInUser{
|
||||||
|
OrgRole: models.ROLE_EDITOR,
|
||||||
|
OrgId: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
srv := createSut(t, nil)
|
||||||
|
|
||||||
|
resp := srv.RouteCreateSilence(&rc, amv2.PostableSilence{
|
||||||
|
ID: "",
|
||||||
|
Silence: cas.silence,
|
||||||
|
})
|
||||||
|
require.Equal(t, cas.status, resp.Status())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRouteCreateSilence(t *testing.T) {
|
func TestRouteCreateSilence(t *testing.T) {
|
||||||
tesCases := []struct {
|
tesCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
Loading…
Reference in New Issue
Block a user