From cf65ed343ce4f0c3ee553fc584e846e8e0936ec9 Mon Sep 17 00:00:00 2001 From: aananthraj Date: Fri, 19 Jul 2019 13:26:12 +0530 Subject: [PATCH] Enhance Notification : Brief notification type This commit, - enables sending brief event notifications to channels - adds a optional filed "notiftype" under channel config to change between default and brief notif types - adds Message() method to event object for creating brief messages (to use across handlers) --- pkg/config/config.go | 25 ++++--- pkg/events/events.go | 42 ++++++++++++ pkg/notify/mattermost.go | 123 +++++++++++++++++++--------------- pkg/notify/slack.go | 139 ++++++++++++++++++++++----------------- 4 files changed, 208 insertions(+), 121 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 6d2cd27e00..ce53acac5c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -24,6 +24,10 @@ const ( WarningEvent EventType = "warning" // AllEvent to watch all events AllEvent EventType = "all" + // DefaultNotify is the Default NotifType + DefaultNotify NotifType = "default" + // BriefNotify for short events notification + BriefNotify NotifType = " brief" ) // EventType to watch @@ -35,6 +39,9 @@ var ConfigFileName = "config.yaml" // Notify flag to toggle event notification var Notify = true +// NotifType to change notification type +type NotifType string + // Config structure of configuration yaml file type Config struct { Resources []Resource @@ -59,9 +66,10 @@ type Communications struct { // Slack configuration to authentication and send notifications type Slack struct { - Enabled bool - Channel string - Token string `yaml:",omitempty"` + Enabled bool + Channel string + NotifType string `yaml:",omitempty"` + Token string `yaml:",omitempty"` } // ElasticSearch config auth settings @@ -83,11 +91,12 @@ type Index struct { // Mattermost configuration to authentication and send notifications type Mattermost struct { - Enabled bool - URL string - Token string - Team string - Channel string + Enabled bool + URL string + Token string + Team string + Channel string + NotifType string `yaml:",omitempty"` } // Settings for multicluster support diff --git a/pkg/events/events.go b/pkg/events/events.go index 0c6048a9eb..50cb867b75 100644 --- a/pkg/events/events.go +++ b/pkg/events/events.go @@ -183,3 +183,45 @@ func New(object interface{}, eventType config.EventType, kind string) Event { return event } + +// Message returns event message in brief format. +// included as a part of event package to use across handlers. +func (event *Event) Message() (msg string) { + message := "" + if len(event.Messages) > 0 { + for _, m := range event.Messages { + message = message + m + } + } + switch event.Type { + case "create", "delete", "update": + msg = fmt.Sprintf( + "A %s `%s` in of cluster %s, namespace `%s` has been %s:\n```%s```", + event.Kind, + event.Name, + event.Cluster, + event.Namespace, + event.Type+"d", + message, + ) + case "error": + msg = fmt.Sprintf( + "Error Occurred in %s: `%s` of cluster %s, namespace `%s`:\n```%s``` ", + event.Kind, + event.Name, + event.Cluster, + event.Namespace, + message, + ) + case "warning": + msg = fmt.Sprintf( + "Warning %s: `%s` of cluster %s, namespace `%s`:\n```%s``` ", + event.Kind, + event.Name, + event.Cluster, + event.Namespace, + message, + ) + } + return msg +} diff --git a/pkg/notify/mattermost.go b/pkg/notify/mattermost.go index 0652dfa0a4..9230936b36 100644 --- a/pkg/notify/mattermost.go +++ b/pkg/notify/mattermost.go @@ -16,6 +16,7 @@ type Mattermost struct { Client *model.Client4 Channel string ClusterName string + NotifType string } // NewMattermost returns new Mattermost object @@ -44,6 +45,7 @@ func NewMattermost(c *config.Config) (Notifier, error) { Client: client, Channel: botChannel.Id, ClusterName: c.Settings.ClusterName, + NotifType: c.Communications.Mattermost.NotifType, }, nil } @@ -51,70 +53,85 @@ func NewMattermost(c *config.Config) (Notifier, error) { func (m *Mattermost) SendEvent(event events.Event) error { log.Logger.Info(fmt.Sprintf(">> Sending to Mattermost: %+v", event)) - fields := []*model.SlackAttachmentField{ - { - Title: "Kind", - Value: event.Kind, - Short: true, - }, - { - Title: "Name", - Value: event.Name, - Short: true, - }, - } + var fields []*model.SlackAttachmentField + + switch m.NotifType { + case "brief": + // set missing cluster name to event object + event.Cluster = m.ClusterName + fields = []*model.SlackAttachmentField{ + { + Title: fmt.Sprintf("%s", event.Kind+" "+string(event.Type)), + Value: event.Message(), + }, + } - if event.Namespace != "" { - fields = append(fields, &model.SlackAttachmentField{ - Title: "Namespace", - Value: event.Namespace, - Short: true, - }) - } + default: + fields = []*model.SlackAttachmentField{ + { + Title: "Kind", + Value: event.Kind, + Short: true, + }, + { + Title: "Name", + Value: event.Name, + Short: true, + }, + } - if event.Reason != "" { - fields = append(fields, &model.SlackAttachmentField{ - Title: "Reason", - Value: event.Reason, - Short: true, - }) - } + if event.Namespace != "" { + fields = append(fields, &model.SlackAttachmentField{ + Title: "Namespace", + Value: event.Namespace, + Short: true, + }) + } - if len(event.Messages) > 0 { - message := "" - for _, m := range event.Messages { - message = message + m + if event.Reason != "" { + fields = append(fields, &model.SlackAttachmentField{ + Title: "Reason", + Value: event.Reason, + Short: true, + }) } - fields = append(fields, &model.SlackAttachmentField{ - Title: "Message", - Value: message, - }) - } - if event.Action != "" { - fields = append(fields, &model.SlackAttachmentField{ - Title: "Action", - Value: event.Action, - }) - } + if len(event.Messages) > 0 { + message := "" + for _, m := range event.Messages { + message = message + m + } + fields = append(fields, &model.SlackAttachmentField{ + Title: "Message", + Value: message, + }) + } + + if event.Action != "" { + fields = append(fields, &model.SlackAttachmentField{ + Title: "Action", + Value: event.Action, + }) + } - if len(event.Recommendations) > 0 { - rec := "" - for _, r := range event.Recommendations { - rec = rec + r + if len(event.Recommendations) > 0 { + rec := "" + for _, r := range event.Recommendations { + rec = rec + r + } + fields = append(fields, &model.SlackAttachmentField{ + Title: "Recommendations", + Value: rec, + }) } + + // Add clustername in the message fields = append(fields, &model.SlackAttachmentField{ - Title: "Recommendations", - Value: rec, + Title: "Cluster", + Value: m.ClusterName, }) } - // Add clustername in the message - fields = append(fields, &model.SlackAttachmentField{ - Title: "Cluster", - Value: m.ClusterName, - }) - attachment := []*model.SlackAttachment{{ Fields: fields, Footer: "BotKube", diff --git a/pkg/notify/slack.go b/pkg/notify/slack.go index d6084e6eb4..b7b2b7cd0a 100644 --- a/pkg/notify/slack.go +++ b/pkg/notify/slack.go @@ -18,6 +18,7 @@ type Slack struct { Token string Channel string ClusterName string + NotifType string } // NewSlack returns new Slack object @@ -34,6 +35,7 @@ func NewSlack(c *config.Config) Notifier { Token: c.Communications.Slack.Token, Channel: c.Communications.Slack.Channel, ClusterName: c.Settings.ClusterName, + NotifType: c.Communications.Slack.NotifType, } } @@ -45,80 +47,97 @@ func (s *Slack) SendEvent(event events.Event) error { params := slack.PostMessageParameters{ AsUser: true, } - attachment := slack.Attachment{ - Fields: []slack.AttachmentField{ - { - Title: "Kind", - Value: event.Kind, - Short: true, - }, - { - Title: "Name", - Value: event.Name, - Short: true, + var attachment slack.Attachment + + switch s.NotifType { + case "brief": + // set missing cluster name to event object + event.Cluster = s.ClusterName + attachment = slack.Attachment{ + Fields: []slack.AttachmentField{ + { + Title: fmt.Sprintf("%s", event.Kind+" "+string(event.Type)), + Value: event.Message(), + }, }, - }, - Footer: "BotKube", - } + Footer: "BotKube", + } + default: + attachment = slack.Attachment{ + Fields: []slack.AttachmentField{ + { + Title: "Kind", + Value: event.Kind, + Short: true, + }, + { + + Title: "Name", + Value: event.Name, + Short: true, + }, + }, + Footer: "BotKube", + } + if event.Namespace != "" { + attachment.Fields = append(attachment.Fields, slack.AttachmentField{ + Title: "Namespace", + Value: event.Namespace, + Short: true, + }) + } - // Add timestamp - ts := json.Number(strconv.FormatInt(event.TimeStamp.Unix(), 10)) - if ts > "0" { - attachment.Ts = ts - } + if event.Reason != "" { + attachment.Fields = append(attachment.Fields, slack.AttachmentField{ + Title: "Reason", + Value: event.Reason, + Short: true, + }) + } - if event.Namespace != "" { - attachment.Fields = append(attachment.Fields, slack.AttachmentField{ - Title: "Namespace", - Value: event.Namespace, - Short: true, - }) - } + if len(event.Messages) > 0 { + message := "" + for _, m := range event.Messages { + message = message + m + } + attachment.Fields = append(attachment.Fields, slack.AttachmentField{ + Title: "Message", + Value: message, + }) + } - if event.Reason != "" { - attachment.Fields = append(attachment.Fields, slack.AttachmentField{ - Title: "Reason", - Value: event.Reason, - Short: true, - }) - } + if event.Action != "" { + attachment.Fields = append(attachment.Fields, slack.AttachmentField{ + Title: "Action", + Value: event.Action, + }) + } - if len(event.Messages) > 0 { - message := "" - for _, m := range event.Messages { - message = message + m + if len(event.Recommendations) > 0 { + rec := "" + for _, r := range event.Recommendations { + rec = rec + r + } + attachment.Fields = append(attachment.Fields, slack.AttachmentField{ + Title: "Recommendations", + Value: rec, + }) } - attachment.Fields = append(attachment.Fields, slack.AttachmentField{ - Title: "Message", - Value: message, - }) - } - if event.Action != "" { + // Add clustername in the message attachment.Fields = append(attachment.Fields, slack.AttachmentField{ - Title: "Action", - Value: event.Action, + Title: "Cluster", + Value: s.ClusterName, }) } - if len(event.Recommendations) > 0 { - rec := "" - for _, r := range event.Recommendations { - rec = rec + r - } - attachment.Fields = append(attachment.Fields, slack.AttachmentField{ - Title: "Recommendations", - Value: rec, - }) + // Add timestamp + ts := json.Number(strconv.FormatInt(event.TimeStamp.Unix(), 10)) + if ts > "0" { + attachment.Ts = ts } - // Add clustername in the message - attachment.Fields = append(attachment.Fields, slack.AttachmentField{ - Title: "Cluster", - Value: s.ClusterName, - }) - attachment.Color = attachmentColor[event.Level] params.Attachments = []slack.Attachment{attachment}