diff --git a/cmd/karma/views.go b/cmd/karma/views.go index e9dec4d23..29219b69c 100644 --- a/cmd/karma/views.go +++ b/cmd/karma/views.go @@ -245,6 +245,25 @@ func alerts(c *gin.Context) { if !validFilters || (slices.BoolInSlice(results, true) && !slices.BoolInSlice(results, false)) { matches++ + blockedAMs := map[string]bool{} + for _, am := range alert.Alertmanager { + for _, filter := range matchFilters { + if filter.GetIsValid() && filter.GetIsAlertmanagerFilter() && !filter.MatchAlertmanager(&am) { + blockedAMs[am.Name] = true + } + } + } + if len(blockedAMs) > 0 { + ams := []models.AlertmanagerInstance{} + for _, am := range alert.Alertmanager { + _, found := blockedAMs[am.Name] + if !found { + ams = append(ams, am) + } + } + alert.Alertmanager = ams + } + alertGridLabelValues := map[string]bool{} switch gridLabel { case "@receiver": diff --git a/internal/filters/filter.go b/internal/filters/filter.go index aec5a5bac..71f24b41c 100644 --- a/internal/filters/filter.go +++ b/internal/filters/filter.go @@ -12,22 +12,25 @@ import ( type FilterT interface { init(name string, matcher *matcherT, rawText string, isValid bool, value string) Match(alert *models.Alert, matches int) bool + MatchAlertmanager(am *models.AlertmanagerInstance) bool GetRawText() string GetHits() int GetIsValid() bool GetName() string GetMatcher() string GetValue() string + GetIsAlertmanagerFilter() bool } type alertFilter struct { FilterT - Matched string - Matcher matcherT - RawText string - Value interface{} - IsValid bool - Hits int + Matched string + Matcher matcherT + RawText string + Value interface{} + IsValid bool + Hits int + IsAlertmanagerFilter bool } func (filter *alertFilter) init(name string, matcher *matcherT, rawText string, isValid bool, value string) { @@ -67,6 +70,10 @@ func (filter *alertFilter) GetValue() string { return fmt.Sprintf("%s", filter.Value) } +func (filter *alertFilter) GetIsAlertmanagerFilter() bool { + return filter.IsAlertmanagerFilter +} + type newFilterFactory func() FilterT // NewFilter creates new filter object from filter expression like "key=value" diff --git a/internal/filters/filter_alertmanager.go b/internal/filters/filter_alertmanager.go index 8d38fe669..93a69ae7a 100644 --- a/internal/filters/filter_alertmanager.go +++ b/internal/filters/filter_alertmanager.go @@ -28,8 +28,17 @@ func (filter *alertmanagerInstanceFilter) Match(alert *models.Alert, matches int panic(e) } +func (filter *alertmanagerInstanceFilter) MatchAlertmanager(am *models.AlertmanagerInstance) bool { + if filter.IsValid { + return filter.Matcher.Compare(am.Name, filter.Value) + } + e := fmt.Sprintf("MatchAlertmanager() called on invalid filter %#v", filter) + panic(e) +} + func newAlertmanagerInstanceFilter() FilterT { f := alertmanagerInstanceFilter{} + f.IsAlertmanagerFilter = true return &f } diff --git a/internal/filters/filter_cluster.go b/internal/filters/filter_cluster.go index b09346025..b2809893f 100644 --- a/internal/filters/filter_cluster.go +++ b/internal/filters/filter_cluster.go @@ -28,8 +28,17 @@ func (filter *alertmanagerClusterFilter) Match(alert *models.Alert, matches int) panic(e) } +func (filter *alertmanagerClusterFilter) MatchAlertmanager(am *models.AlertmanagerInstance) bool { + if filter.IsValid { + return filter.Matcher.Compare(am.Cluster, filter.Value) + } + e := fmt.Sprintf("MatchAlertmanager() called on invalid filter %#v", filter) + panic(e) +} + func newAlertmanagerClusterFilter() FilterT { f := alertmanagerClusterFilter{} + f.IsAlertmanagerFilter = true return &f }