diff --git a/README.md b/README.md index 54ed7906..23a2386d 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ receivers: - name: "slack" slack: token: YOUR-API-TOKEN-HERE + endpoint: YOUR-WEBHOOK-ENDPOINT-HERE channel: "@{{ .InvolvedObject.Labels.owner }}" message: "{{ .Message }}" color: # optional @@ -152,6 +153,8 @@ receivers: ``` +The bot `token` along with the `channel` field can be used for authentication. Alternatively, `endpoint` field can be used to define the webhook url for a given channel. In case both the fields `token` and `endpoint` are provided, the bot-token will be used for authentication. + ### Kinesis Kinesis is an AWS service allows to collect high throughput messages and allow it to be used in stream processing. diff --git a/pkg/sinks/slack.go b/pkg/sinks/slack.go index e23a688e..3fae85dd 100644 --- a/pkg/sinks/slack.go +++ b/pkg/sinks/slack.go @@ -2,7 +2,6 @@ package sinks import ( "context" - "github.com/opsgenie/kubernetes-event-exporter/pkg/kube" "github.com/rs/zerolog/log" "github.com/slack-go/slack" @@ -17,6 +16,7 @@ type SlackConfig struct { Title string `yaml:"title"` AuthorName string `yaml:"author_name"` Fields map[string]string `yaml:"fields"` + Endpoint string `yaml:"endpoint"` } type SlackSink struct { @@ -30,25 +30,15 @@ func NewSlackSink(cfg *SlackConfig) (Sink, error) { client: slack.New(cfg.Token), }, nil } +func (s *SlackSink) GetAttachment(ev *kube.EnhancedEvent) (slack.Attachment, error) { -func (s *SlackSink) Send(ctx context.Context, ev *kube.EnhancedEvent) error { - channel, err := GetString(ev, s.cfg.Channel) - if err != nil { - return err - } - - message, err := GetString(ev, s.cfg.Message) - if err != nil { - return err - } - - options := []slack.MsgOption{slack.MsgOptionText(message, true)} + slackAttachment := slack.Attachment{} if s.cfg.Fields != nil { fields := make([]slack.AttachmentField, 0) for k, v := range s.cfg.Fields { fieldText, err := GetString(ev, v) if err != nil { - return err + return slackAttachment, err } fields = append(fields, slack.AttachmentField{ @@ -57,9 +47,6 @@ func (s *SlackSink) Send(ctx context.Context, ev *kube.EnhancedEvent) error { Short: false, }) } - - // make slack attachment - slackAttachment := slack.Attachment{} slackAttachment.Fields = fields if s.cfg.AuthorName != "" { slackAttachment.AuthorName = s.cfg.AuthorName @@ -73,12 +60,46 @@ func (s *SlackSink) Send(ctx context.Context, ev *kube.EnhancedEvent) error { if s.cfg.Footer != "" { slackAttachment.Footer = s.cfg.Footer } + } + return slackAttachment, nil +} - options = append(options, slack.MsgOptionAttachments(slackAttachment)) +func (s *SlackSink) Send(ctx context.Context, ev *kube.EnhancedEvent) error { + message, err := GetString(ev, s.cfg.Message) + if err != nil { + return err } - _ch, _ts, _text, err := s.client.SendMessageContext(ctx, channel, options...) - log.Debug().Str("ch", _ch).Str("ts", _ts).Str("text", _text).Err(err).Msg("Slack Response") + slackAttachments, err := s.GetAttachment(ev) + if err != nil { + return err + } + // use bot token + if s.cfg.Token != "" { + channel, err := GetString(ev, s.cfg.Channel) + if err != nil { + return err + } + options := []slack.MsgOption{slack.MsgOptionText(message, true)} + options = append(options, slack.MsgOptionAttachments(slackAttachments)) + _ch, _ts, _text, err := s.client.SendMessageContext(ctx, channel, options...) + log.Debug().Str("ch", _ch).Str("ts", _ts).Str("text", _text).Err(err).Msg("Slack Response") + return err + } else { + // use webhook endpoint + endpoint, err := GetString(ev, s.cfg.Endpoint) + if err != nil { + return err + } + webhookMessage := slack.WebhookMessage{ + Text: message, + Attachments: []slack.Attachment{slackAttachments}, + } + err = slack.PostWebhook(endpoint, &webhookMessage) + if err != nil { + return err + } + } return err }