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 }