From d32b7383266fc50cd7491affb87f7d0e4a7b5633 Mon Sep 17 00:00:00 2001 From: Sergey Wh1te <sergey.i@lido.fi> Date: Mon, 9 Dec 2024 14:17:59 +0300 Subject: [PATCH] feature: Filter only desired Findings --- Changelog.md | 3 +++ internal/env/notify_config.go | 23 +++++++++++++------ internal/pkg/consumer/consumer.go | 35 +++++++++++++++++++---------- internal/utils/registry/registry.go | 1 + notification.sample.yaml | 19 ++++++++++++++++ 5 files changed, 62 insertions(+), 19 deletions(-) diff --git a/Changelog.md b/Changelog.md index 6e44ce5..59947a9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,6 @@ +## 09.12.2024 +1. Dynamic config feature: filter only desired Findings. + ## 05.12.2024 1. Remove PublishedAlerts metrics 2. Added NotifyChannels: `forwarder_notification_channel_error_total` diff --git a/internal/env/notify_config.go b/internal/env/notify_config.go index 0fd4207..d232eba 100644 --- a/internal/env/notify_config.go +++ b/internal/env/notify_config.go @@ -42,13 +42,15 @@ type OpsGenieChannel struct { } type Consumer struct { - ConsumerName string `mapstructure:"consumerName"` - Type string `mapstructure:"type"` - ChannelID string `mapstructure:"channel_id"` - Severities []string `mapstructure:"severities"` - ByQuorum bool `mapstructure:"by_quorum"` - Subjects []string `mapstructure:"subjects"` - SeveritySet registry.FindingMapping + ConsumerName string `mapstructure:"consumerName"` + Type string `mapstructure:"type"` + ChannelID string `mapstructure:"channel_id"` + Severities []string `mapstructure:"severities"` + ByQuorum bool `mapstructure:"by_quorum"` + Subjects []string `mapstructure:"subjects"` + Filter []string `mapstructure:"filter"` + SeveritySet registry.FindingMapping + FindingFilterMap registry.FindingFilterMap } type NotificationConfig struct { @@ -150,6 +152,8 @@ func ValidateConfig(cfg *NotificationConfig) error { for _, consumer := range cfg.Consumers { severitySet := make(registry.FindingMapping) + findingFilter := make(registry.FindingFilterMap) + for _, severity := range consumer.Severities { if _, exists := validSeverities[databus.Severity(severity)]; !exists { return fmt.Errorf("consumer '%s' references an unknown severity level '%s'", consumer.ConsumerName, severity) @@ -157,7 +161,12 @@ func ValidateConfig(cfg *NotificationConfig) error { severitySet[databus.Severity(severity)] = true } + for _, alertID := range consumer.Filter { + findingFilter[alertID] = true + } + consumer.SeveritySet = severitySet + consumer.FindingFilterMap = findingFilter } for _, consumer := range cfg.Consumers { diff --git a/internal/pkg/consumer/consumer.go b/internal/pkg/consumer/consumer.go index 9356be3..c4efed0 100644 --- a/internal/pkg/consumer/consumer.go +++ b/internal/pkg/consumer/consumer.go @@ -33,12 +33,13 @@ type Consumer struct { redisClient *redis.Client repo *Repo - name string - subject string - severitySet registry.FindingMapping - byQuorum bool - quorumSize uint - notifier notifiler.FindingSender + name string + subject string + severitySet registry.FindingMapping + byQuorum bool + quorumSize uint + findingFilterMap registry.FindingFilterMap + notifier notifiler.FindingSender } func New( @@ -50,6 +51,7 @@ func New( consumerName, subject string, SeveritySet registry.FindingMapping, + findingFilterMap registry.FindingFilterMap, byQuorum bool, quorumSize uint, notifier notifiler.FindingSender, @@ -61,12 +63,13 @@ func New( redisClient: redisClient, repo: repo, - name: consumerName, - subject: subject, - severitySet: SeveritySet, - byQuorum: byQuorum, - quorumSize: quorumSize, - notifier: notifier, + name: consumerName, + subject: subject, + severitySet: SeveritySet, + findingFilterMap: findingFilterMap, + byQuorum: byQuorum, + quorumSize: quorumSize, + notifier: notifier, } } @@ -116,6 +119,7 @@ func NewConsumers(log *slog.Logger, metrics *metrics.Store, redisClient *redis.C consumerName, subject, consumerCfg.SeveritySet, + consumerCfg.FindingFilterMap, consumerCfg.ByQuorum, quorumSize, notificationChannel, @@ -172,6 +176,13 @@ func (c *Consumer) GetConsumeHandler(ctx context.Context) func(msg jetstream.Msg return } + if len(c.findingFilterMap) > 0 { + if _, ok := c.findingFilterMap[finding.AlertId]; !ok { + c.ackMessage(msg) + return + } + } + if c.byQuorum == false { if sendErr := c.notifier.SendFinding(ctx, finding); sendErr != nil { c.log.Error(fmt.Sprintf(`Could not send bot-finding: %v`, sendErr), diff --git a/internal/utils/registry/registry.go b/internal/utils/registry/registry.go index 14ba4b1..4bfa8fa 100644 --- a/internal/utils/registry/registry.go +++ b/internal/utils/registry/registry.go @@ -37,3 +37,4 @@ var CodeOwners = map[string]string{ } type FindingMapping = map[databus.Severity]bool +type FindingFilterMap = map[string]bool diff --git a/notification.sample.yaml b/notification.sample.yaml index de35daf..209b09b 100644 --- a/notification.sample.yaml +++ b/notification.sample.yaml @@ -31,6 +31,9 @@ discord_channels: - id: Discord2 description: Discord channel for all messages >= Low, no quorum webhook_url: YOUR_DISCORD_WEBHOOK_URL_2 + - id: AnalyticsSubscriber + description: "Analytics channel for getting only specific findings (filter: WITHDRAWALS-BIG-WITHDRAWAL-REQUEST-BATCH)" + webhook_url: YOUR_DISCORD_WEBHOOK_URL_2 opsgenie_channels: - id: OpsGenie1 @@ -125,3 +128,19 @@ consumers: - findings.protocol.steth - findings.protocol.arb - findings.dao.opt + + - consumerName: AnalyticsSubscriber + type: Discord + channel_id: AnalyticsSubscriber + severities: + - Low + - Info + - Medium + - High + - Critical + by_quorum: True + subjects: + - findings.protocol.steth + filter: + - WITHDRAWALS-BIG-WITHDRAWAL-REQUEST-BATCH +