Skip to content

Commit

Permalink
Refactor notifier to use Bot interface to send notifications (#309)
Browse files Browse the repository at this point in the history
##### ISSUE TYPE

 - Feature Pull Request

##### SUMMARY

In the notifier, we send events by creating a new connection to the communication medium on every new event. We can reduce the number of connections by sending messages via the Bot interface.

Fixes #270
  • Loading branch information
PrasadG193 authored Jul 13, 2020
1 parent 7b28f66 commit b887214
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 165 deletions.
50 changes: 16 additions & 34 deletions cmd/botkube/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,22 @@ const (
)

func main() {
// Prometheus metrics
metricsPort, exists := os.LookupEnv("METRICS_PORT")
if !exists {
metricsPort = defaultMetricsPort
}
go metrics.ServeMetrics(metricsPort)
if err := startController(); err != nil {
log.Fatal(err)
}
}

func startController() error {
log.Info("Starting controller")
conf, err := config.New()
if err != nil {
log.Fatal(fmt.Sprintf("Error in loading configuration. Error:%s", err.Error()))
return fmt.Errorf("Error in loading configuration. Error:%s", err.Error())
}

if conf.Communications.Slack.Enabled {
Expand All @@ -55,14 +67,8 @@ func main() {
go mb.Start()
}

// Prometheus metrics
metricsPort, exists := os.LookupEnv("METRICS_PORT")
if !exists {
metricsPort = defaultMetricsPort
}
go metrics.ServeMetrics(metricsPort)

notifiers := listNotifiers(conf)
notifiers := notify.ListNotifiers(conf.Communications)
log.Infof("Notifier List: config=%#v list=%#v\n", conf.Communications, notifiers)
// Start upgrade notifier
if conf.Settings.UpgradeNotifier {
log.Info("Starting upgrade notifier")
Expand All @@ -74,29 +80,5 @@ func main() {
utils.InitInformerMap(conf)
utils.InitResourceMap(conf)
controller.RegisterInformers(conf, notifiers)
}

func listNotifiers(conf *config.Config) []notify.Notifier {
var notifiers []notify.Notifier
if conf.Communications.Slack.Enabled {
notifiers = append(notifiers, notify.NewSlack(conf))
}
if conf.Communications.Mattermost.Enabled {
if notifier, err := notify.NewMattermost(conf); err == nil {
notifiers = append(notifiers, notifier)
} else {
log.Error(fmt.Sprintf("Failed to create Mattermost client. Error: %v", err))
}
}
if conf.Communications.ElasticSearch.Enabled {
if els, err := notify.NewElasticSearch(conf); err == nil {
notifiers = append(notifiers, els)
} else {
log.Error(fmt.Sprintf("Failed to create els client. Error: %v", err))
}
}
if conf.Communications.Webhook.Enabled {
notifiers = append(notifiers, notify.NewWebhook(conf))
}
return notifiers
return nil
}
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tF
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
Expand Down Expand Up @@ -308,6 +307,7 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 h1:j2hhcujLRHAg872RWAV5yaUrEjHEObwDv3aImCaNLek=
Expand Down Expand Up @@ -352,8 +352,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb h1:TR699M2v0qoKTOHxeLgp6zPqaQNs74f01a/ob9W0qko=
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down
60 changes: 46 additions & 14 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,25 @@ const (
ShortNotify NotifType = "short"
// LongNotify for short events notification
LongNotify NotifType = "long"

// Info level
Info Level = "info"
// Warn level
Warn Level = "warn"
// Debug level
Debug Level = "debug"
// Error level
Error Level = "error"
// Critical level
Critical Level = "critical"
)

// EventType to watch
type EventType string

// Level type to store event levels
type Level string

// ResourceConfigFileName is a name of botkube resource configuration file
var ResourceConfigFileName = "resource_config.yaml"

Expand All @@ -69,10 +83,15 @@ type NotifType string
type Config struct {
Resources []Resource
Recommendations bool
Communications Communications
Communications CommunicationsConfig
Settings Settings
}

// Communications contains communication config
type Communications struct {
Communications CommunicationsConfig
}

// Resource contains resources to watch
type Resource struct {
Name string
Expand All @@ -98,8 +117,8 @@ type Namespaces struct {
Ignore []string `yaml:",omitempty"`
}

// Communications channels to send events to
type Communications struct {
// CommunicationsConfig channels to send events to
type CommunicationsConfig struct {
Slack Slack
ElasticSearch ElasticSearch
Mattermost Mattermost
Expand Down Expand Up @@ -181,40 +200,53 @@ func (eventType EventType) String() string {
return string(eventType)
}

// New returns new Config
func New() (*Config, error) {
c := &Config{}
// NewCommunicationsConfig return new communication config object
func NewCommunicationsConfig() (*Communications, error) {
c := &Communications{}
configPath := os.Getenv("CONFIG_PATH")
resourceConfigFilePath := filepath.Join(configPath, ResourceConfigFileName)
resourceConfigFile, err := os.Open(resourceConfigFilePath)
defer resourceConfigFile.Close()
communicationConfigFilePath := filepath.Join(configPath, CommunicationConfigFileName)
communicationConfigFile, err := os.Open(communicationConfigFilePath)
defer communicationConfigFile.Close()
if err != nil {
return c, err
}

b, err := ioutil.ReadAll(resourceConfigFile)
b, err := ioutil.ReadAll(communicationConfigFile)
if err != nil {
return c, err
}

if len(b) != 0 {
yaml.Unmarshal(b, c)
}
return c, nil
}

communicationConfigFilePath := filepath.Join(configPath, CommunicationConfigFileName)
communicationConfigFile, err := os.Open(communicationConfigFilePath)
defer communicationConfigFile.Close()
// New returns new Config
func New() (*Config, error) {
c := &Config{}
configPath := os.Getenv("CONFIG_PATH")
resourceConfigFilePath := filepath.Join(configPath, ResourceConfigFileName)
resourceConfigFile, err := os.Open(resourceConfigFilePath)
defer resourceConfigFile.Close()
if err != nil {
return c, err
}

b, err = ioutil.ReadAll(communicationConfigFile)
b, err := ioutil.ReadAll(resourceConfigFile)
if err != nil {
return c, err
}

if len(b) != 0 {
yaml.Unmarshal(b, c)
}

comm, err := NewCommunicationsConfig()
if err != nil {
return nil, err
}
c.Communications = comm.Communications

return c, nil
}
32 changes: 8 additions & 24 deletions pkg/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,6 @@ import (
rbacV1 "k8s.io/api/rbac/v1"
)

// Level type to store event levels
type Level string

const (
// Info level
Info Level = "info"
// Warn level
Warn Level = "warn"
// Debug level
Debug Level = "debug"
// Error level
Error Level = "error"
// Critical level
Critical Level = "critical"
)

// Event to store required information from k8s objects
type Event struct {
Code string
Expand All @@ -60,7 +44,7 @@ type Event struct {
Type config.EventType
Reason string
Error string
Level Level
Level config.Level
Cluster string
Channel string
TimeStamp time.Time
Expand All @@ -73,15 +57,15 @@ type Event struct {
}

// LevelMap is a map of event type to Level
var LevelMap map[config.EventType]Level
var LevelMap map[config.EventType]config.Level

func init() {
LevelMap = make(map[config.EventType]Level)
LevelMap[config.CreateEvent] = Info
LevelMap[config.UpdateEvent] = Warn
LevelMap[config.DeleteEvent] = Critical
LevelMap[config.ErrorEvent] = Error
LevelMap[config.WarningEvent] = Error
LevelMap = make(map[config.EventType]config.Level)
LevelMap[config.CreateEvent] = config.Info
LevelMap[config.UpdateEvent] = config.Warn
LevelMap[config.DeleteEvent] = config.Critical
LevelMap[config.ErrorEvent] = config.Error
LevelMap[config.WarningEvent] = config.Error
}

// New extract required details from k8s object and returns new Event object
Expand Down
4 changes: 2 additions & 2 deletions pkg/filterengine/filters/node_event_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ func (f NodeEventsChecker) Run(object interface{}, event *events.Event) {
switch event.Reason {
case NodeNotReady:
event.Type = config.ErrorEvent
event.Level = events.Critical
event.Level = config.Critical
case NodeReady:
event.Type = config.InfoEvent
event.Level = events.Info
event.Level = config.Info
default:
// skip events with least significant reasons
event.Skip = true
Expand Down
Loading

0 comments on commit b887214

Please sign in to comment.