bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/bosun/sched/silence.go (about) 1 package sched 2 3 import ( 4 "fmt" 5 "time" 6 7 "bosun.org/models" 8 "bosun.org/opentsdb" 9 "bosun.org/slog" 10 ) 11 12 type SilenceTester func(models.AlertKey) *models.Silence 13 14 // Silenced returns a function that will determine if the given alert key is silenced at the current time. 15 // A function is returned to avoid needing to enumerate all alert keys unneccesarily. 16 func (s *Schedule) Silenced() SilenceTester { 17 now := utcNow() 18 silences, err := s.DataAccess.Silence().GetActiveSilences() 19 if err != nil { 20 slog.Error("Error fetching silences.", err) 21 return nil 22 } 23 return func(ak models.AlertKey) *models.Silence { 24 var lastEnding *models.Silence 25 for _, si := range silences { 26 if !si.ActiveAt(now) { 27 continue 28 } 29 if si.Silenced(now, ak.Name(), ak.Group()) { 30 if lastEnding == nil || lastEnding.End.Before(si.End) { 31 lastEnding = si 32 } 33 } 34 } 35 return lastEnding 36 } 37 } 38 39 func (s *Schedule) AddSilence(start, end time.Time, alert, tagList string, forget, confirm bool, edit, user, message string) (map[models.AlertKey]bool, error) { 40 if start.IsZero() || end.IsZero() { 41 return nil, fmt.Errorf("both start and end must be specified") 42 } 43 if start.After(end) { 44 return nil, fmt.Errorf("start time must be before end time") 45 } 46 if time.Since(end) > 0 { 47 return nil, fmt.Errorf("end time must be in the future") 48 } 49 if alert == "" && tagList == "" { 50 return nil, fmt.Errorf("must specify either alert or tags") 51 } 52 si := &models.Silence{ 53 Start: start, 54 End: end, 55 Alert: alert, 56 Tags: make(opentsdb.TagSet), 57 Forget: forget, 58 User: user, 59 Message: message, 60 } 61 if tagList != "" { 62 tags, err := opentsdb.ParseTags(tagList) 63 if err != nil && tags == nil { 64 return nil, err 65 } 66 si.Tags = tags 67 si.TagString = tags.Tags() 68 } 69 if confirm { 70 if edit != "" { 71 if err := s.DataAccess.Silence().DeleteSilence(edit); err != nil { 72 return nil, err 73 } 74 } 75 if err := s.DataAccess.Silence().DeleteSilence(si.ID()); err != nil { 76 return nil, err 77 } 78 if err := s.DataAccess.Silence().AddSilence(si); err != nil { 79 return nil, err 80 } 81 return nil, nil 82 } 83 aks := make(map[models.AlertKey]bool) 84 open, err := s.DataAccess.State().GetAllOpenIncidents() 85 if err != nil { 86 return nil, err 87 } 88 for _, inc := range open { 89 if si.Matches(inc.Alert, inc.AlertKey.Group()) { 90 aks[inc.AlertKey] = true 91 } 92 } 93 return aks, nil 94 } 95 96 func (s *Schedule) ClearSilence(id string) error { 97 return s.DataAccess.Silence().DeleteSilence(id) 98 }