Skip to content

Commit

Permalink
Merge pull request #13 from infracloudio/support-multiple-clusters
Browse files Browse the repository at this point in the history
Support notifications from multiple clusters
  • Loading branch information
sanketsudake authored Jan 15, 2019
2 parents 0839f2f + 46d6f9b commit fb8e876
Show file tree
Hide file tree
Showing 7 changed files with 730 additions and 19 deletions.
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,10 @@ communications:
slack:
channel: 'SLACK_CHANNEL'
token: 'SLACK_API_TOKEN'

# Setting to support multiple clusters
settings:
# Cluster name to differentiate incoming messages
clustername: not-configured
# Set false to disable kubectl commands execution
allowkubectl: false
9 changes: 8 additions & 1 deletion helm/botkube/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replicaCount: 1

image:
repository: infracloud/botkube
tag: "0.1"
tag: "0.2"
pullPolicy: Always

nameOverride: ""
Expand Down Expand Up @@ -134,6 +134,13 @@ config:
channel: 'SLACK_CHANNEL'
token: 'SLACK_API_TOKEN'

# Setting to support multiple clusters
settings:
# Cluster name to differentiate incoming messages
clustername: not-configured
# Set false to disable kubectl commands execution
allowkubectl: false

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
Expand Down
7 changes: 7 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
Recommendations bool
Communications Communications
Events K8SEvents
Settings Settings
}

// K8SEvents contains event types
Expand All @@ -44,6 +45,12 @@ type Slack struct {
Token string
}

// Settings for multicluster support
type Settings struct {
ClusterName string
AllowKubectl bool
}

// New returns new Config
func New() (*Config, error) {
c := &Config{}
Expand Down
18 changes: 12 additions & 6 deletions pkg/execute/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ var validNotifierCommands = map[string]bool{
var kubectlBinary = "/usr/local/bin/kubectl"

const (
notifierStartMsg = "Brace yourselves, notifications are coming."
notifierStopMsg = "Sure! I won't send you notifications anymore."
unsupportedCmdMsg = "Command not supported. Please run '@botkube help' to see supported commands."
notifierStartMsg = "Brace yourselves, notifications are coming."
notifierStopMsg = "Sure! I won't send you notifications anymore."
unsupportedCmdMsg = "Command not supported. Please run '@botkube help' to see supported commands."
kubectlDisabledMsg = "Sorry, the admin hasn't given me the permission to execute kubectl command."
)

// Executor is an interface for processes to execute commands
Expand All @@ -46,20 +47,25 @@ type Executor interface {

// DefaultExecutor is a default implementations of Executor
type DefaultExecutor struct {
Message string
Message string
AllowKubectl bool
}

// NewDefaultExecutor returns new Executor object
func NewDefaultExecutor(msg string) Executor {
func NewDefaultExecutor(msg string, allowkubectl bool) Executor {
return &DefaultExecutor{
Message: msg,
Message: msg,
AllowKubectl: allowkubectl,
}
}

// Execute executes commands and returns output
func (e *DefaultExecutor) Execute() string {
args := strings.Split(e.Message, " ")
if validKubectlCommands[args[0]] {
if !e.AllowKubectl {
return kubectlDisabledMsg
}
return runKubectlCommand(args)
}
if validNotifierCommands[args[0]] {
Expand Down
18 changes: 13 additions & 5 deletions pkg/notify/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ var attachmentColor map[events.Level]string

// Slack contains Token for authentication with slack and Channel name to send notification to
type Slack struct {
Token string
Channel string
Token string
Channel string
ClusterName string
}

// NewSlack returns new Slack object
Expand All @@ -35,8 +36,9 @@ func NewSlack() Notifier {
}

return &Slack{
Token: c.Communications.Slack.Token,
Channel: c.Communications.Slack.Channel,
Token: c.Communications.Slack.Token,
Channel: c.Communications.Slack.Channel,
ClusterName: c.Settings.ClusterName,
}
}

Expand All @@ -62,7 +64,7 @@ func (s *Slack) SendEvent(event events.Event) error {
Short: true,
},
},
Footer: "botkube",
Footer: "BotKube",
}

// Add timestamp
Expand Down Expand Up @@ -116,6 +118,12 @@ func (s *Slack) SendEvent(event events.Event) error {
})
}

// 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}

Expand Down
16 changes: 9 additions & 7 deletions pkg/slack/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (

// Bot listens for user's message, execute commands and sends back the response
type Bot struct {
Token string
Token string
AllowKubectl bool
}

// slackMessage contains message details to execute command and send back the result
Expand All @@ -32,13 +33,14 @@ func NewSlackBot() *Bot {
logging.Logger.Fatal(fmt.Sprintf("Error in loading configuration. Error:%s", err.Error()))
}
return &Bot{
Token: c.Communications.Slack.Token,
Token: c.Communications.Slack.Token,
AllowKubectl: c.Settings.AllowKubectl,
}
}

// Start starts the slacknot RTM connection and listens for messages
func (s *Bot) Start() {
api := slack.New(s.Token)
func (b *Bot) Start() {
api := slack.New(b.Token)
authResp, err := api.AuthTest()
if err != nil {
logging.Logger.Fatal(err)
Expand Down Expand Up @@ -66,7 +68,7 @@ func (s *Bot) Start() {
InMessage: msg,
RTM: rtm,
}
sm.HandleMessage()
sm.HandleMessage(b.AllowKubectl)

case *slack.RTMError:
logging.Logger.Errorf("Slack RMT error: %+v", ev.Error())
Expand All @@ -79,8 +81,8 @@ func (s *Bot) Start() {
}
}

func (sm *slackMessage) HandleMessage() {
e := execute.NewDefaultExecutor(sm.InMessage)
func (sm *slackMessage) HandleMessage(allowkubectl bool) {
e := execute.NewDefaultExecutor(sm.InMessage, allowkubectl)
sm.OutMessage = e.Execute()
sm.OutMsgLength = len(sm.OutMessage)
sm.Send()
Expand Down

0 comments on commit fb8e876

Please sign in to comment.