github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/alertmanager/merger/v2_silences.go (about)

     1  package merger
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	"github.com/go-openapi/swag"
     8  	v2 "github.com/prometheus/alertmanager/api/v2"
     9  	v2_models "github.com/prometheus/alertmanager/api/v2/models"
    10  )
    11  
    12  // V2Silences implements the Merger interface for GET /v2/silences. It returns the union of silences
    13  // over all the responses. When a silence with the same ID exists in multiple responses, the silence
    14  // most recently updated silence is returned (newest UpdatedAt timestamp).
    15  type V2Silences struct{}
    16  
    17  func (V2Silences) MergeResponses(in [][]byte) ([]byte, error) {
    18  	silences := make(v2_models.GettableSilences, 0)
    19  	for _, body := range in {
    20  		parsed := make(v2_models.GettableSilences, 0)
    21  		if err := swag.ReadJSON(body, &parsed); err != nil {
    22  			return nil, err
    23  		}
    24  		silences = append(silences, parsed...)
    25  	}
    26  
    27  	merged, err := mergeV2Silences(silences)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	return swag.WriteJSON(merged)
    33  }
    34  
    35  func mergeV2Silences(in v2_models.GettableSilences) (v2_models.GettableSilences, error) {
    36  	// Select the most recently updated silences for each silence ID.
    37  	silences := make(map[string]*v2_models.GettableSilence)
    38  	for _, silence := range in {
    39  		if silence.ID == nil {
    40  			return nil, errors.New("unexpected nil id")
    41  		}
    42  		if silence.UpdatedAt == nil {
    43  			return nil, errors.New("unexpected nil updatedAt")
    44  		}
    45  
    46  		key := *silence.ID
    47  		if current, ok := silences[key]; ok {
    48  			if time.Time(*silence.UpdatedAt).After(time.Time(*current.UpdatedAt)) {
    49  				silences[key] = silence
    50  			}
    51  		} else {
    52  			silences[key] = silence
    53  		}
    54  	}
    55  
    56  	result := make(v2_models.GettableSilences, 0, len(silences))
    57  	for _, silence := range silences {
    58  		result = append(result, silence)
    59  	}
    60  
    61  	// Re-use Alertmanager sorting for silences.
    62  	v2.SortSilences(result)
    63  
    64  	return result, nil
    65  }