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  }