mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
144 lines
3.1 KiB
Go
144 lines
3.1 KiB
Go
package models
|
|
|
|
import (
|
|
"regexp"
|
|
"time"
|
|
|
|
"github.com/go-json-experiment/json/jsontext"
|
|
|
|
"github.com/prymitive/karma/internal/regex"
|
|
)
|
|
|
|
type SilenceMatcher struct {
|
|
re *regexp.Regexp
|
|
Name string `json:"name"`
|
|
Value string `json:"value"`
|
|
IsRegex bool `json:"isRegex"`
|
|
IsEqual bool `json:"isEqual"`
|
|
}
|
|
|
|
func NewSilenceMatcher(name, value string, isRegexp, isEqual bool) SilenceMatcher {
|
|
sm := SilenceMatcher{
|
|
Name: name,
|
|
Value: value,
|
|
IsRegex: isRegexp,
|
|
IsEqual: isEqual,
|
|
}
|
|
if sm.IsRegex {
|
|
sm.re = regex.MustCompileAnchored(sm.Value)
|
|
}
|
|
return sm
|
|
}
|
|
|
|
func (sm SilenceMatcher) MarshalJSONTo(enc *jsontext.Encoder) error {
|
|
w := jsonWriter{enc: enc}
|
|
sm.marshalTo(&w)
|
|
return w.err
|
|
}
|
|
|
|
func (sm *SilenceMatcher) marshalTo(w *jsonWriter) {
|
|
w.beginObject()
|
|
w.key("name")
|
|
w.str(sm.Name)
|
|
w.key("value")
|
|
w.str(sm.Value)
|
|
w.key("isRegex")
|
|
w.boolean(sm.IsRegex)
|
|
w.key("isEqual")
|
|
w.boolean(sm.IsEqual)
|
|
w.endObject()
|
|
}
|
|
|
|
func (sm SilenceMatcher) IsMatch(labels map[string]string) bool {
|
|
v, ok := labels[sm.Name]
|
|
if !ok {
|
|
return !sm.IsEqual
|
|
}
|
|
|
|
if sm.IsRegex {
|
|
return sm.IsEqual == sm.re.MatchString(v)
|
|
}
|
|
return sm.IsEqual == (sm.Value == v)
|
|
}
|
|
|
|
// Silence is vanilla silence + some additional attributes
|
|
// karma adds JIRA support, it can extract JIRA IDs from comments
|
|
// extracted ID is used to generate link to JIRA issue
|
|
// this means karma needs to store additional fields for each silence
|
|
type Silence struct {
|
|
StartsAt time.Time `json:"startsAt"`
|
|
EndsAt time.Time `json:"endsAt"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
ID string `json:"id"`
|
|
CreatedBy string `json:"createdBy"`
|
|
Comment string `json:"comment"`
|
|
TicketID string `json:"ticketID"`
|
|
TicketURL string `json:"ticketURL"`
|
|
Matchers []SilenceMatcher `json:"matchers"`
|
|
}
|
|
|
|
func (s Silence) MarshalJSONTo(enc *jsontext.Encoder) error {
|
|
w := jsonWriter{enc: enc}
|
|
s.marshalTo(&w)
|
|
return w.err
|
|
}
|
|
|
|
func (s *Silence) marshalTo(w *jsonWriter) {
|
|
w.beginObject()
|
|
w.key("startsAt")
|
|
w.time(s.StartsAt)
|
|
w.key("endsAt")
|
|
w.time(s.EndsAt)
|
|
w.key("createdAt")
|
|
w.time(s.CreatedAt)
|
|
w.key("id")
|
|
w.str(s.ID)
|
|
w.key("createdBy")
|
|
w.str(s.CreatedBy)
|
|
w.key("comment")
|
|
w.str(s.Comment)
|
|
w.key("ticketID")
|
|
w.str(s.TicketID)
|
|
w.key("ticketURL")
|
|
w.str(s.TicketURL)
|
|
w.key("matchers")
|
|
w.beginArray()
|
|
for i := range s.Matchers {
|
|
s.Matchers[i].marshalTo(w)
|
|
}
|
|
w.endArray()
|
|
w.endObject()
|
|
}
|
|
|
|
func (s Silence) IsMatch(labels map[string]string) bool {
|
|
for _, m := range s.Matchers {
|
|
if !m.IsMatch(labels) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// ManagedSilence is a standalone silence detached from any alert
|
|
type ManagedSilence struct {
|
|
Cluster string `json:"cluster"`
|
|
Silence Silence `json:"silence"`
|
|
AlertCount int `json:"alertCount"`
|
|
IsExpired bool `json:"isExpired"`
|
|
}
|
|
|
|
func (ms ManagedSilence) MarshalJSONTo(enc *jsontext.Encoder) error {
|
|
w := jsonWriter{enc: enc}
|
|
w.beginObject()
|
|
w.key("cluster")
|
|
w.str(ms.Cluster)
|
|
w.key("silence")
|
|
ms.Silence.marshalTo(&w)
|
|
w.key("alertCount")
|
|
w.integer(ms.AlertCount)
|
|
w.key("isExpired")
|
|
w.boolean(ms.IsExpired)
|
|
w.endObject()
|
|
return w.err
|
|
}
|