From 412f06255a1c09b16eed91d22edbc6464c606008 Mon Sep 17 00:00:00 2001 From: Alexander Weaver Date: Tue, 17 Oct 2023 08:45:44 -0500 Subject: [PATCH] Separate and export BuildReceiverIntegrations (#3553) * Move and export BuildReceiverIntegrations Signed-off-by: Alex Weaver --------- Signed-off-by: Alex Weaver --- cmd/alertmanager/main.go | 78 +----------------------- cmd/alertmanager/main_test.go | 68 --------------------- config/receiver/receiver.go | 100 +++++++++++++++++++++++++++++++ config/receiver/receiver_test.go | 88 +++++++++++++++++++++++++++ 4 files changed, 190 insertions(+), 144 deletions(-) create mode 100644 config/receiver/receiver.go create mode 100644 config/receiver/receiver_test.go diff --git a/cmd/alertmanager/main.go b/cmd/alertmanager/main.go index 2d4a58e254..bfb781fdea 100644 --- a/cmd/alertmanager/main.go +++ b/cmd/alertmanager/main.go @@ -45,24 +45,12 @@ import ( "github.com/prometheus/alertmanager/api" "github.com/prometheus/alertmanager/cluster" "github.com/prometheus/alertmanager/config" + "github.com/prometheus/alertmanager/config/receiver" "github.com/prometheus/alertmanager/dispatch" "github.com/prometheus/alertmanager/featurecontrol" "github.com/prometheus/alertmanager/inhibit" "github.com/prometheus/alertmanager/nflog" "github.com/prometheus/alertmanager/notify" - "github.com/prometheus/alertmanager/notify/discord" - "github.com/prometheus/alertmanager/notify/email" - "github.com/prometheus/alertmanager/notify/msteams" - "github.com/prometheus/alertmanager/notify/opsgenie" - "github.com/prometheus/alertmanager/notify/pagerduty" - "github.com/prometheus/alertmanager/notify/pushover" - "github.com/prometheus/alertmanager/notify/slack" - "github.com/prometheus/alertmanager/notify/sns" - "github.com/prometheus/alertmanager/notify/telegram" - "github.com/prometheus/alertmanager/notify/victorops" - "github.com/prometheus/alertmanager/notify/webex" - "github.com/prometheus/alertmanager/notify/webhook" - "github.com/prometheus/alertmanager/notify/wechat" "github.com/prometheus/alertmanager/provider/mem" "github.com/prometheus/alertmanager/silence" "github.com/prometheus/alertmanager/template" @@ -131,68 +119,6 @@ func instrumentHandler(handlerName string, handler http.HandlerFunc) http.Handle const defaultClusterAddr = "0.0.0.0:9094" -// buildReceiverIntegrations builds a list of integration notifiers off of a -// receiver config. -func buildReceiverIntegrations(nc config.Receiver, tmpl *template.Template, logger log.Logger) ([]notify.Integration, error) { - var ( - errs types.MultiError - integrations []notify.Integration - add = func(name string, i int, rs notify.ResolvedSender, f func(l log.Logger) (notify.Notifier, error)) { - n, err := f(log.With(logger, "integration", name)) - if err != nil { - errs.Add(err) - return - } - integrations = append(integrations, notify.NewIntegration(n, rs, name, i, nc.Name)) - } - ) - - for i, c := range nc.WebhookConfigs { - add("webhook", i, c, func(l log.Logger) (notify.Notifier, error) { return webhook.New(c, tmpl, l) }) - } - for i, c := range nc.EmailConfigs { - add("email", i, c, func(l log.Logger) (notify.Notifier, error) { return email.New(c, tmpl, l), nil }) - } - for i, c := range nc.PagerdutyConfigs { - add("pagerduty", i, c, func(l log.Logger) (notify.Notifier, error) { return pagerduty.New(c, tmpl, l) }) - } - for i, c := range nc.OpsGenieConfigs { - add("opsgenie", i, c, func(l log.Logger) (notify.Notifier, error) { return opsgenie.New(c, tmpl, l) }) - } - for i, c := range nc.WechatConfigs { - add("wechat", i, c, func(l log.Logger) (notify.Notifier, error) { return wechat.New(c, tmpl, l) }) - } - for i, c := range nc.SlackConfigs { - add("slack", i, c, func(l log.Logger) (notify.Notifier, error) { return slack.New(c, tmpl, l) }) - } - for i, c := range nc.VictorOpsConfigs { - add("victorops", i, c, func(l log.Logger) (notify.Notifier, error) { return victorops.New(c, tmpl, l) }) - } - for i, c := range nc.PushoverConfigs { - add("pushover", i, c, func(l log.Logger) (notify.Notifier, error) { return pushover.New(c, tmpl, l) }) - } - for i, c := range nc.SNSConfigs { - add("sns", i, c, func(l log.Logger) (notify.Notifier, error) { return sns.New(c, tmpl, l) }) - } - for i, c := range nc.TelegramConfigs { - add("telegram", i, c, func(l log.Logger) (notify.Notifier, error) { return telegram.New(c, tmpl, l) }) - } - for i, c := range nc.DiscordConfigs { - add("discord", i, c, func(l log.Logger) (notify.Notifier, error) { return discord.New(c, tmpl, l) }) - } - for i, c := range nc.WebexConfigs { - add("webex", i, c, func(l log.Logger) (notify.Notifier, error) { return webex.New(c, tmpl, l) }) - } - for i, c := range nc.MSTeamsConfigs { - add("msteams", i, c, func(l log.Logger) (notify.Notifier, error) { return msteams.New(c, tmpl, l) }) - } - - if errs.Len() > 0 { - return nil, &errs - } - return integrations, nil -} - func main() { os.Exit(run()) } @@ -459,7 +385,7 @@ func run() int { level.Info(configLogger).Log("msg", "skipping creation of receiver not referenced by any route", "receiver", rcv.Name) continue } - integrations, err := buildReceiverIntegrations(rcv, tmpl, logger) + integrations, err := receiver.BuildReceiverIntegrations(rcv, tmpl, logger) if err != nil { return err } diff --git a/cmd/alertmanager/main_test.go b/cmd/alertmanager/main_test.go index a45fa516f0..8939853608 100644 --- a/cmd/alertmanager/main_test.go +++ b/cmd/alertmanager/main_test.go @@ -18,77 +18,9 @@ import ( "testing" "github.com/go-kit/log" - commoncfg "github.com/prometheus/common/config" "github.com/stretchr/testify/require" - - "github.com/prometheus/alertmanager/config" - "github.com/prometheus/alertmanager/notify" ) -type sendResolved bool - -func (s sendResolved) SendResolved() bool { return bool(s) } - -func TestBuildReceiverIntegrations(t *testing.T) { - for _, tc := range []struct { - receiver config.Receiver - err bool - exp []notify.Integration - }{ - { - receiver: config.Receiver{ - Name: "foo", - WebhookConfigs: []*config.WebhookConfig{ - { - HTTPConfig: &commoncfg.HTTPClientConfig{}, - }, - { - HTTPConfig: &commoncfg.HTTPClientConfig{}, - NotifierConfig: config.NotifierConfig{ - VSendResolved: true, - }, - }, - }, - }, - exp: []notify.Integration{ - notify.NewIntegration(nil, sendResolved(false), "webhook", 0, "foo"), - notify.NewIntegration(nil, sendResolved(true), "webhook", 1, "foo"), - }, - }, - { - receiver: config.Receiver{ - Name: "foo", - WebhookConfigs: []*config.WebhookConfig{ - { - HTTPConfig: &commoncfg.HTTPClientConfig{ - TLSConfig: commoncfg.TLSConfig{ - CAFile: "not_existing", - }, - }, - }, - }, - }, - err: true, - }, - } { - tc := tc - t.Run("", func(t *testing.T) { - integrations, err := buildReceiverIntegrations(tc.receiver, nil, nil) - if tc.err { - require.Error(t, err) - return - } - require.NoError(t, err) - require.Len(t, integrations, len(tc.exp)) - for i := range tc.exp { - require.Equal(t, tc.exp[i].SendResolved(), integrations[i].SendResolved()) - require.Equal(t, tc.exp[i].Name(), integrations[i].Name()) - require.Equal(t, tc.exp[i].Index(), integrations[i].Index()) - } - }) - } -} - func TestExternalURL(t *testing.T) { hostname := "foo" for _, tc := range []struct { diff --git a/config/receiver/receiver.go b/config/receiver/receiver.go new file mode 100644 index 0000000000..9bb039ef05 --- /dev/null +++ b/config/receiver/receiver.go @@ -0,0 +1,100 @@ +// Copyright 2023 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package receiver + +import ( + "github.com/go-kit/log" + + commoncfg "github.com/prometheus/common/config" + + "github.com/prometheus/alertmanager/config" + "github.com/prometheus/alertmanager/notify" + "github.com/prometheus/alertmanager/notify/discord" + "github.com/prometheus/alertmanager/notify/email" + "github.com/prometheus/alertmanager/notify/msteams" + "github.com/prometheus/alertmanager/notify/opsgenie" + "github.com/prometheus/alertmanager/notify/pagerduty" + "github.com/prometheus/alertmanager/notify/pushover" + "github.com/prometheus/alertmanager/notify/slack" + "github.com/prometheus/alertmanager/notify/sns" + "github.com/prometheus/alertmanager/notify/telegram" + "github.com/prometheus/alertmanager/notify/victorops" + "github.com/prometheus/alertmanager/notify/webex" + "github.com/prometheus/alertmanager/notify/webhook" + "github.com/prometheus/alertmanager/notify/wechat" + "github.com/prometheus/alertmanager/template" + "github.com/prometheus/alertmanager/types" +) + +// BuildReceiverIntegrations builds a list of integration notifiers off of a +// receiver config. +func BuildReceiverIntegrations(nc config.Receiver, tmpl *template.Template, logger log.Logger, httpOpts ...commoncfg.HTTPClientOption) ([]notify.Integration, error) { + var ( + errs types.MultiError + integrations []notify.Integration + add = func(name string, i int, rs notify.ResolvedSender, f func(l log.Logger) (notify.Notifier, error)) { + n, err := f(log.With(logger, "integration", name)) + if err != nil { + errs.Add(err) + return + } + integrations = append(integrations, notify.NewIntegration(n, rs, name, i, nc.Name)) + } + ) + + for i, c := range nc.WebhookConfigs { + add("webhook", i, c, func(l log.Logger) (notify.Notifier, error) { return webhook.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.EmailConfigs { + add("email", i, c, func(l log.Logger) (notify.Notifier, error) { return email.New(c, tmpl, l), nil }) + } + for i, c := range nc.PagerdutyConfigs { + add("pagerduty", i, c, func(l log.Logger) (notify.Notifier, error) { return pagerduty.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.OpsGenieConfigs { + add("opsgenie", i, c, func(l log.Logger) (notify.Notifier, error) { return opsgenie.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.WechatConfigs { + add("wechat", i, c, func(l log.Logger) (notify.Notifier, error) { return wechat.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.SlackConfigs { + add("slack", i, c, func(l log.Logger) (notify.Notifier, error) { return slack.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.VictorOpsConfigs { + add("victorops", i, c, func(l log.Logger) (notify.Notifier, error) { return victorops.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.PushoverConfigs { + add("pushover", i, c, func(l log.Logger) (notify.Notifier, error) { return pushover.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.SNSConfigs { + add("sns", i, c, func(l log.Logger) (notify.Notifier, error) { return sns.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.TelegramConfigs { + add("telegram", i, c, func(l log.Logger) (notify.Notifier, error) { return telegram.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.DiscordConfigs { + add("discord", i, c, func(l log.Logger) (notify.Notifier, error) { return discord.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.WebexConfigs { + add("webex", i, c, func(l log.Logger) (notify.Notifier, error) { return webex.New(c, tmpl, l, httpOpts...) }) + } + for i, c := range nc.MSTeamsConfigs { + add("msteams", i, c, func(l log.Logger) (notify.Notifier, error) { return msteams.New(c, tmpl, l, httpOpts...) }) + } + + if errs.Len() > 0 { + return nil, &errs + } + return integrations, nil +} diff --git a/config/receiver/receiver_test.go b/config/receiver/receiver_test.go new file mode 100644 index 0000000000..3d146a98d0 --- /dev/null +++ b/config/receiver/receiver_test.go @@ -0,0 +1,88 @@ +// Copyright 2023 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package receiver + +import ( + "testing" + + commoncfg "github.com/prometheus/common/config" + "github.com/stretchr/testify/require" + + "github.com/prometheus/alertmanager/config" + "github.com/prometheus/alertmanager/notify" +) + +type sendResolved bool + +func (s sendResolved) SendResolved() bool { return bool(s) } + +func TestBuildReceiverIntegrations(t *testing.T) { + for _, tc := range []struct { + receiver config.Receiver + err bool + exp []notify.Integration + }{ + { + receiver: config.Receiver{ + Name: "foo", + WebhookConfigs: []*config.WebhookConfig{ + { + HTTPConfig: &commoncfg.HTTPClientConfig{}, + }, + { + HTTPConfig: &commoncfg.HTTPClientConfig{}, + NotifierConfig: config.NotifierConfig{ + VSendResolved: true, + }, + }, + }, + }, + exp: []notify.Integration{ + notify.NewIntegration(nil, sendResolved(false), "webhook", 0, "foo"), + notify.NewIntegration(nil, sendResolved(true), "webhook", 1, "foo"), + }, + }, + { + receiver: config.Receiver{ + Name: "foo", + WebhookConfigs: []*config.WebhookConfig{ + { + HTTPConfig: &commoncfg.HTTPClientConfig{ + TLSConfig: commoncfg.TLSConfig{ + CAFile: "not_existing", + }, + }, + }, + }, + }, + err: true, + }, + } { + tc := tc + t.Run("", func(t *testing.T) { + integrations, err := BuildReceiverIntegrations(tc.receiver, nil, nil) + if tc.err { + require.Error(t, err) + return + } + require.NoError(t, err) + require.Len(t, integrations, len(tc.exp)) + for i := range tc.exp { + require.Equal(t, tc.exp[i].SendResolved(), integrations[i].SendResolved()) + require.Equal(t, tc.exp[i].Name(), integrations[i].Name()) + require.Equal(t, tc.exp[i].Index(), integrations[i].Index()) + } + }) + } +}