mirror of
https://github.com/prometheus/alertmanager
synced 2024-12-26 08:02:16 +00:00
api/v2: sort silences similarly to v1 api (#1786)
* api/v2: sort silences similarly to v1 api Sort the queried silences to match behaviour in the v1 api. Sort silences in-place instead of creating multiple slices. Use separate function for sorting silences for easier testing. Add unit test for sort order. Signed-off-by: Paul Gier <pgier@redhat.com>
This commit is contained in:
parent
c5e7dca3dc
commit
3ffe6cfdc8
@ -508,9 +508,49 @@ func (api *API) getSilencesHandler(params silence_ops.GetSilencesParams) middlew
|
|||||||
sils = append(sils, &silence)
|
sils = append(sils, &silence)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortSilences(sils)
|
||||||
|
|
||||||
return silence_ops.NewGetSilencesOK().WithPayload(sils)
|
return silence_ops.NewGetSilencesOK().WithPayload(sils)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
silenceStateOrder = map[types.SilenceState]int{
|
||||||
|
types.SilenceStateActive: 1,
|
||||||
|
types.SilenceStatePending: 2,
|
||||||
|
types.SilenceStateExpired: 3,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// sortSilences sorts first according to the state "active, pending, expired"
|
||||||
|
// then by end time or start time depending on the state.
|
||||||
|
// active silences should show the next to expire first
|
||||||
|
// pending silences are ordered based on which one starts next
|
||||||
|
// expired are ordered base on which one expired most recently
|
||||||
|
func sortSilences(sils open_api_models.GettableSilences) {
|
||||||
|
sort.Slice(sils, func(i, j int) bool {
|
||||||
|
state1 := types.SilenceState(*sils[i].Status.State)
|
||||||
|
state2 := types.SilenceState(*sils[j].Status.State)
|
||||||
|
if state1 != state2 {
|
||||||
|
return silenceStateOrder[state1] < silenceStateOrder[state2]
|
||||||
|
}
|
||||||
|
switch state1 {
|
||||||
|
case types.SilenceStateActive:
|
||||||
|
endsAt1 := time.Time(*sils[i].Silence.EndsAt)
|
||||||
|
endsAt2 := time.Time(*sils[j].Silence.EndsAt)
|
||||||
|
return endsAt1.Before(endsAt2)
|
||||||
|
case types.SilenceStatePending:
|
||||||
|
startsAt1 := time.Time(*sils[i].Silence.StartsAt)
|
||||||
|
startsAt2 := time.Time(*sils[j].Silence.StartsAt)
|
||||||
|
return startsAt1.Before(startsAt2)
|
||||||
|
case types.SilenceStateExpired:
|
||||||
|
endsAt1 := time.Time(*sils[i].Silence.EndsAt)
|
||||||
|
endsAt2 := time.Time(*sils[j].Silence.EndsAt)
|
||||||
|
return endsAt1.After(endsAt2)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func gettableSilenceMatchesFilterLabels(s open_api_models.GettableSilence, matchers []*labels.Matcher) bool {
|
func gettableSilenceMatchesFilterLabels(s open_api_models.GettableSilence, matchers []*labels.Matcher) bool {
|
||||||
sms := make(map[string]string)
|
sms := make(map[string]string)
|
||||||
for _, m := range s.Matchers {
|
for _, m := range s.Matchers {
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
|
||||||
|
open_api_models "github.com/prometheus/alertmanager/api/v2/models"
|
||||||
general_ops "github.com/prometheus/alertmanager/api/v2/restapi/operations/general"
|
general_ops "github.com/prometheus/alertmanager/api/v2/restapi/operations/general"
|
||||||
"github.com/prometheus/alertmanager/config"
|
"github.com/prometheus/alertmanager/config"
|
||||||
)
|
)
|
||||||
@ -48,3 +52,73 @@ func TestGetStatusHandlerWithNilPeer(t *testing.T) {
|
|||||||
t.Fatal("expected cluster name to be empty, violating the openapi specification")
|
t.Fatal("expected cluster name to be empty, violating the openapi specification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertEqualStrings(t *testing.T, expected string, actual string) {
|
||||||
|
if expected != actual {
|
||||||
|
t.Fatal("expected: ", expected, ", actual: ", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
testComment = "comment"
|
||||||
|
createdBy = "test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func gettableSilence(id string, state string,
|
||||||
|
updatedAt string, start string, end string,
|
||||||
|
) *open_api_models.GettableSilence {
|
||||||
|
|
||||||
|
updAt, err := strfmt.ParseDateTime(updatedAt)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
strAt, err := strfmt.ParseDateTime(start)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
endAt, err := strfmt.ParseDateTime(end)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return &open_api_models.GettableSilence{
|
||||||
|
Silence: open_api_models.Silence{
|
||||||
|
StartsAt: &strAt,
|
||||||
|
EndsAt: &endAt,
|
||||||
|
Comment: &testComment,
|
||||||
|
CreatedBy: &createdBy,
|
||||||
|
},
|
||||||
|
ID: &id,
|
||||||
|
UpdatedAt: &updAt,
|
||||||
|
Status: &open_api_models.SilenceStatus{
|
||||||
|
State: &state,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSilencesHandler(t *testing.T) {
|
||||||
|
|
||||||
|
updateTime := "2019-01-01T12:00:00+00:00"
|
||||||
|
silences := []*open_api_models.GettableSilence{
|
||||||
|
gettableSilence("silence-6-expired", "expired", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T11:00:00+00:00"),
|
||||||
|
gettableSilence("silence-1-active", "active", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T13:00:00+00:00"),
|
||||||
|
gettableSilence("silence-7-expired", "expired", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T10:00:00+00:00"),
|
||||||
|
gettableSilence("silence-5-expired", "expired", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T12:00:00+00:00"),
|
||||||
|
gettableSilence("silence-0-active", "active", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T12:00:00+00:00"),
|
||||||
|
gettableSilence("silence-4-pending", "pending", updateTime,
|
||||||
|
"2019-01-01T13:00:00+00:00", "2019-01-01T12:00:00+00:00"),
|
||||||
|
gettableSilence("silence-3-pending", "pending", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T12:00:00+00:00"),
|
||||||
|
gettableSilence("silence-2-active", "active", updateTime,
|
||||||
|
"2019-01-01T12:00:00+00:00", "2019-01-01T14:00:00+00:00"),
|
||||||
|
}
|
||||||
|
sortSilences(open_api_models.GettableSilences(silences))
|
||||||
|
|
||||||
|
for i, sil := range silences {
|
||||||
|
assertEqualStrings(t, "silence-"+strconv.Itoa(i)+"-"+*sil.Status.State, *sil.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user