Repository: abahmed/kwatch
Pull request #142 (2022-09-18 14:29:48)

fix build and max characters per line
Changes proposed in this pull request:
- Fixes build and max characters per line



Patch:
diff --git a/client/client.go b/client/client.go
index 8c87863..b4147f3 100644
--- a/client/client.go
+++ b/client/client.go
@@ -28,7 +28,9 @@ func Create() kubernetes.Interface {
 
 		config, err = clientcmd.BuildConfigFromFlags("", kubeconfigPath)
 		if err != nil {
-			logrus.Fatalf("cannot build kubernetes out of cluster config: %v", err)
+			logrus.Fatalf(
+				"cannot build kubernetes out of cluster config: %v",
+				err)
 		}
 	}
 
diff --git a/constant/constant.go b/constant/constant.go
index 7bba91f..c0c54ca 100644
--- a/constant/constant.go
+++ b/constant/constant.go
@@ -6,8 +6,11 @@ const Version = "dev"
 // WelcomeMsg is used to be sent to all providers when kwatch starts
 const WelcomeMsg = ":tada: kwatch@%s just started!"
 
-// KwatchUpdateMsg is used to notify all registered providers when a newer version is available
-const KwatchUpdateMsg = ":tada: A newer version <https://github.com/abahmed/kwatch/releases/tag/%[1]s|%[1]s> of Kwatch is available! Please update to the latest version."
+// KwatchUpdateMsg is used to notify all registered providers when a newer
+// version is available
+const KwatchUpdateMsg = ":tada: A newer version " +
+	"<https://github.com/abahmed/kwatch/releases/tag/%[1]s|%[1]s> of Kwatch " +
+	"is available! Please update to the latest version."
 
 // NumRequeues indicates number of retries when worker fails to handle item
 const NumRequeues = 5
diff --git a/controller/controller.go b/controller/controller.go
index cb4a5d6..2a14569 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -33,7 +33,7 @@ type Controller struct {
 	namespaceForbidList          []string
 	reasonAllowList              []string
 	reasonForbidList             []string
-	ignoreContainerList	     []string
+	ignoreContainerList          []string
 }
 
 // run starts the controller
@@ -54,7 +54,10 @@ func (c *Controller) run(workers int, stopCh chan struct{}) {
 	logrus.Infof("%s controller synced and ready", c.name)
 
 	// send notification to providers
-	util.SendProvidersMsg(c.providers, fmt.Sprintf(constant.WelcomeMsg, constant.Version))
+	util.SendProvidersMsg(
+		c.providers,
+		fmt.Sprintf(constant.WelcomeMsg, constant.Version),
+	)
 
 	// start workers
 	for i := 0; i < workers; i++ {
@@ -107,8 +110,8 @@ func (c *Controller) processItem(key string) error {
 	}
 
 	if !exists {
-		// Below we will warm up our cache with a Pod, so that we will see
-		// a delete for one pod
+		// Below we will warm up our cache with a Pod, so that we will see a
+		// delete for one pod
 		logrus.Infof("pod %s does not exist anymore\n", key)
 
 		c.store.DelPod(key)
@@ -126,12 +129,18 @@ func (c *Controller) processItem(key string) error {
 	}
 
 	// filter by namespaces in config if specified
-	if len(c.namespaceAllowList) > 0 && !util.IsStrInSlice(pod.Namespace, c.namespaceAllowList) {
-		logrus.Infof("skip namespace %s as not in namespace allow list", pod.Namespace)
+	if len(c.namespaceAllowList) > 0 &&
+		!util.IsStrInSlice(pod.Namespace, c.namespaceAllowList) {
+		logrus.Infof(
+			"skip namespace %s as not in namespace allow list",
+			pod.Namespace)
 		return nil
 	}
-	if len(c.namespaceForbidList) > 0 && util.IsStrInSlice(pod.Namespace, c.namespaceForbidList) {
-		logrus.Infof("skip namespace %s as in namespace forbid list", pod.Namespace)
+	if len(c.namespaceForbidList) > 0 &&
+		util.IsStrInSlice(pod.Namespace, c.namespaceForbidList) {
+		logrus.Infof(
+			"skip namespace %s as in namespace forbid list",
+			pod.Namespace)
 		return nil
 	}
 
@@ -176,8 +185,13 @@ func (c *Controller) processPod(key string, pod *v1.Pod) {
 			continue
 		}
 
-		if c.ignoreFailedGracefulShutdown && util.ContainsKillingStoppingContainerEvents(c.kclient, pod.Name, pod.Namespace) {
-			// Graceful shutdown did not work and container was killed during shutdown.
+		if c.ignoreFailedGracefulShutdown &&
+			util.ContainsKillingStoppingContainerEvents(
+				c.kclient,
+				pod.Name,
+				pod.Namespace) {
+			// Graceful shutdown did not work and container was killed during
+			// shutdown.
 			//  Not really an error
 			continue
 		}
@@ -196,17 +210,22 @@ func (c *Controller) processPod(key string, pod *v1.Pod) {
 			reason = container.State.Terminated.Reason
 		}
 
-		if len(c.reasonAllowList) > 0 && !util.IsStrInSlice(reason, c.reasonAllowList) {
+		if len(c.reasonAllowList) > 0 &&
+			!util.IsStrInSlice(reason, c.reasonAllowList) {
 			logrus.Infof("skip reason %s as not in reason allow list", reason)
 			return
 		}
-		if len(c.reasonForbidList) > 0 && util.IsStrInSlice(reason, c.reasonForbidList) {
+		if len(c.reasonForbidList) > 0 &&
+			util.IsStrInSlice(reason, c.reasonForbidList) {
 			logrus.Infof("skip reason %s as in reason forbid list", reason)
 			return
 		}
 
-		if len(c.ignoreContainerList) > 0 && util.IsStrInSlice(container.Name, c.ignoreContainerList) {
-			logrus.Infof("skip pod %s as in container ignore list", container.Name)
+		if len(c.ignoreContainerList) > 0 &&
+			util.IsStrInSlice(container.Name, c.ignoreContainerList) {
+			logrus.Infof(
+				"skip pod %s as in container ignore list",
+				container.Name)
 			return
 		}
 
diff --git a/main.go b/main.go
index 0094aec..a0babb6 100644
--- a/main.go
+++ b/main.go
@@ -51,7 +51,9 @@ func main() {
 		namespaceAllowList = append(namespaceAllowList, namespace)
 	}
 	if len(namespaceAllowList) > 0 && len(namespaceForbidList) > 0 {
-		logrus.Fatal("Either allowed or forbidden namespaces must be set. Can't set both")
+		logrus.Fatal(
+			"Either allowed or forbidden namespaces must be set. " +
+				"Can't set both")
 	}
 
 	// Parse reason allow/forbid lists
@@ -65,14 +67,22 @@ func main() {
 		reasonAllowList = append(reasonAllowList, namespace)
 	}
 	if len(reasonAllowList) > 0 && len(reasonForbidList) > 0 {
-		logrus.Fatal("Either allowed or forbidden reasons must be set. Can't set both")
+		logrus.Fatal("Either allowed or forbidden reasons must be set. " +
+			"Can't set both")
 	}
 
 	ignoreContainerList := make([]string, 0)
-	for _, container := range viper.GetStringSlice("ignoreContainerNames") {
-		ignoreContainerList = append(ignoreContainerList, container)
-	}
+	ignoreContainerList = append(
+		ignoreContainerList,
+		viper.GetStringSlice("ignoreContainerNames")...)
 
 	// start controller
-	controller.Start(providers, viper.GetBool("ignoreFailedGracefulShutdown"), namespaceAllowList, namespaceForbidList, reasonAllowList, reasonForbidList, ignoreContainerList)
+	controller.Start(
+		providers,
+		viper.GetBool("ignoreFailedGracefulShutdown"),
+		namespaceAllowList,
+		namespaceForbidList,
+		reasonAllowList,
+		reasonForbidList,
+		ignoreContainerList)
 }
diff --git a/provider/discord.go b/provider/discord.go
index 11fde2e..9442e10 100644
--- a/provider/discord.go
+++ b/provider/discord.go
@@ -117,19 +117,23 @@ func (s *discord) SendEvent(ev *event.Event) error {
 	}
 
 	// send message
-	_, err := discordClient.WebhookExecute(s.id, s.token, false, &discordgo.WebhookParams{
-		Embeds: []*discordgo.MessageEmbed{
-			{
-				Color:       13041664,
-				Title:       title,
-				Description: text,
-				Fields:      fields,
-				Footer: &discordgo.MessageEmbedFooter{
-					Text: footer,
+	_, err := discordClient.WebhookExecute(
+		s.id,
+		s.token,
+		false,
+		&discordgo.WebhookParams{
+			Embeds: []*discordgo.MessageEmbed{
+				{
+					Color:       13041664,
+					Title:       title,
+					Description: text,
+					Fields:      fields,
+					Footer: &discordgo.MessageEmbedFooter{
+						Text: footer,
+					},
 				},
 			},
-		},
-	})
+		})
 	return err
 }
 
@@ -143,8 +147,12 @@ func (s *discord) SendMessage(msg string) error {
 	discordClient, _ := discordgo.New("")
 
 	// send message
-	_, err := discordClient.WebhookExecute(s.id, s.token, false, &discordgo.WebhookParams{
-		Content: msg,
-	})
+	_, err := discordClient.WebhookExecute(
+		s.id,
+		s.token,
+		false,
+		&discordgo.WebhookParams{
+			Content: msg,
+		})
 	return err
 }
diff --git a/provider/email.go b/provider/email.go
index a859c8b..3c6e717 100644
--- a/provider/email.go
+++ b/provider/email.go
@@ -2,11 +2,12 @@ package provider
 
 import (
 	"fmt"
+	"math"
+	"strings"
+
 	"github.com/abahmed/kwatch/event"
 	"github.com/sirupsen/logrus"
 	gomail "gopkg.in/mail.v2"
-	"math"
-	"strings"
 )
 
 type email struct {
@@ -18,7 +19,12 @@ type email struct {
 }
 
 // NewEmail returns new email instance
-func NewEmail(from string, password string, host string, port int, to string) Provider {
+func NewEmail(
+	from string,
+	password string,
+	host string,
+	port int,
+	to string) Provider {
 	if len(from) == 0 {
 		logrus.Warnf("initializing email with an empty from")
 	}
diff --git a/provider/mattermost.go b/provider/mattermost.go
index c936f33..8c489bf 100644
--- a/provider/mattermost.go
+++ b/provider/mattermost.go
@@ -5,7 +5,8 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
+
 	"net/http"
 
 	"github.com/abahmed/kwatch/event"
@@ -111,7 +112,7 @@ func (m *mattermost) sendAPI(content []byte) error {
 	}
 
 	if response.StatusCode != 200 {
-		body, _ := ioutil.ReadAll(response.Body)
+		body, _ := io.ReadAll(response.Body)
 		return fmt.Errorf(
 			"call to mattermost alert returned status code %d: %s",
 			response.StatusCode,
diff --git a/provider/opsgenie.go b/provider/opsgenie.go
index 37d9013..7d6ebc3 100644
--- a/provider/opsgenie.go
+++ b/provider/opsgenie.go
@@ -5,7 +5,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 
 	"github.com/abahmed/kwatch/event"
@@ -57,11 +57,6 @@ func (m *opsgenie) SendMessage(msg string) error {
 func (m *opsgenie) SendEvent(e *event.Event) error {
 	logrus.Debugf("sending to opsgenie event: %v", e)
 
-	// validate webhook url
-	if len(m.apikey) == 0 {
-		errors.New("apikey url is empty")
-	}
-
 	reqBody, err := m.buildMessage(e)
 	if err != nil {
 		return err
@@ -89,7 +84,7 @@ func (m *opsgenie) sendAPI(content []byte) error {
 	}
 
 	if response.StatusCode != 202 {
-		body, _ := ioutil.ReadAll(response.Body)
+		body, _ := io.ReadAll(response.Body)
 		return fmt.Errorf(
 			"call to opsgenie alert returned status code %d: %s",
 			response.StatusCode,
diff --git a/provider/rocketchat.go b/provider/rocketchat.go
index 8b543ca..6a75d2d 100644
--- a/provider/rocketchat.go
+++ b/provider/rocketchat.go
@@ -5,7 +5,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"strings"
 
@@ -76,7 +76,7 @@ func sendByRocketChatApi(reqBody string, r *rocketChat) error {
 	}
 
 	if response.StatusCode != 200 {
-		body, _ := ioutil.ReadAll(response.Body)
+		body, _ := io.ReadAll(response.Body)
 		return fmt.Errorf(
 			"call to rocket chat alert returned status code %d: %s",
 			response.StatusCode,
@@ -106,8 +106,8 @@ func buildRequestBodyRocketChat(e *event.Event, customMsg string) (string, error
 		logsText = e.Logs
 	}
 
-	// build text will be sent in the message
-	// use custom text if it's provided, otherwise use default
+	// build text will be sent in the message use custom text if it's provided,
+	// otherwise use default
 	text := viper.GetString("alert.rocketchat.text")
 	if len(customMsg) <= 0 {
 		text = fmt.Sprintf(
diff --git a/provider/slack.go b/provider/slack.go
index 1885bb5..2f315f9 100644
--- a/provider/slack.go
+++ b/provider/slack.go
@@ -93,7 +93,9 @@ func (s *slack) SendEvent(ev *event.Event) error {
 	}
 
 	msg := slackClient.WebhookMessage{
-		Blocks: &slackClient.Blocks{BlockSet: append(blocks, markdownSection(footer))},
+		Blocks: &slackClient.Blocks{
+			BlockSet: append(blocks, markdownSection(footer)),
+		},
 	}
 
 	// send message
@@ -136,7 +138,11 @@ func chunks(s string, chunkSize int) []string {
 }
 
 func plain(txt string) *slackClient.TextBlockObject {
-	return slackClient.NewTextBlockObject(slackClient.PlainTextType, txt, true, false)
+	return slackClient.NewTextBlockObject(
+		slackClient.PlainTextType,
+		txt,
+		true,
+		false)
 }
 func plainSection(txt string) slackClient.SectionBlock {
 	return slackClient.SectionBlock{
@@ -145,7 +151,10 @@ func plainSection(txt string) slackClient.SectionBlock {
 	}
 }
 func markdown(txt string) *slackClient.TextBlockObject {
-	return slackClient.NewTextBlockObject(slackClient.MarkdownType, txt, false, true)
+	return slackClient.NewTextBlockObject(slackClient.MarkdownType,
+		txt,
+		false,
+		true)
 }
 func markdownSection(txt string) slackClient.SectionBlock {
 	return slackClient.SectionBlock{
@@ -154,9 +163,14 @@ func markdownSection(txt string) slackClient.SectionBlock {
 	}
 }
 func markdownF(format string, a ...interface{}) *slackClient.TextBlockObject {
-	return slackClient.NewTextBlockObject(slackClient.MarkdownType, fmt.Sprintf(format, a...), false, true)
+	return slackClient.NewTextBlockObject(
+		slackClient.MarkdownType,
+		fmt.Sprintf(format, a...),
+		false,
+		true)
 }
-func markdownSectionF(format string, a ...interface{}) slackClient.SectionBlock {
+func markdownSectionF(
+	format string, a ...interface{}) slackClient.SectionBlock {
 	return slackClient.SectionBlock{
 		Type: "section",
 		Text: markdownF(format, a...),
diff --git a/provider/teams.go b/provider/teams.go
index 6746f90..f89ced2 100644
--- a/provider/teams.go
+++ b/provider/teams.go
@@ -4,7 +4,8 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
+
 	"net/http"
 	"strings"
 
@@ -72,7 +73,7 @@ func (t *teams) SendMessage(msg string) error {
 	}
 
 	if response.StatusCode != 200 {
-		body, _ := ioutil.ReadAll(response.Body)
+		body, _ := io.ReadAll(response.Body)
 		return fmt.Errorf(
 			"call to teams alert returned status code %d: %s",
 			response.StatusCode,
@@ -130,7 +131,8 @@ func (t *teams) buildRequestBodyTeams(e *event.Event) (string, error) {
 
 	jsonBytes, err := json.Marshal(msgPayload)
 	if err != nil {
-		return "", fmt.Errorf("failed to marshal string %v: %s", msgPayload, err)
+		return "",
+			fmt.Errorf("failed to marshal string %v: %s", msgPayload, err)
 	}
 
 	return string(jsonBytes), nil
diff --git a/provider/telegram.go b/provider/telegram.go
index 8e9dff9..72224c0 100644
--- a/provider/telegram.go
+++ b/provider/telegram.go
@@ -28,7 +28,10 @@ func NewTelegram(token string, chatId string) Provider {
 	} else if len(chatId) == 0 {
 		logrus.Warnf("initializing telegram with empty chat_id")
 	} else {
-		logrus.Infof("initializing telegram with token  %s and chat_id %s", token, chatId)
+		logrus.Infof(
+			"initializing telegram with token  %s and chat_id %s",
+			token,
+			chatId)
 	}
 
 	// returns a new telegram object
@@ -70,7 +73,10 @@ func (t *telegram) SendMessage(msg string) error {
 	return sendByTelegramApi(reqBody, t)
 }
 
-func buildRequestBodyTelegram(e *event.Event, chatId string, customMsg string) string {
+func buildRequestBodyTelegram(
+	e *event.Event,
+	chatId string,
+	customMsg string) string {
 	eventsText := "No events captured"
 	logsText := "No logs captured"
 
diff --git a/util/util.go b/util/util.go
index ef8dc3b..fb8930c 100644
--- a/util/util.go
+++ b/util/util.go
@@ -23,7 +23,11 @@ func GetPodEventsStr(c kubernetes.Interface, name, namespace string) string {
 
 	eventsString := ""
 	if err != nil {
-		logrus.Warnf("failed to get events for %s@%s: %s", name, namespace, err.Error())
+		logrus.Warnf(
+			"failed to get events for %s@%s: %s",
+			name,
+			namespace,
+			err.Error())
 		return eventsString
 	}
 
@@ -39,9 +43,13 @@ func GetPodEventsStr(c kubernetes.Interface, name, namespace string) string {
 	return strings.TrimSpace(eventsString)
 }
 
-// ContainsKillingStoppingContainerEvents checks if the events contain an event with "Killing Stopping container" which
-// indicates that a container could not be gracefully shutdown
-func ContainsKillingStoppingContainerEvents(c kubernetes.Interface, name, namespace string) bool {
+// ContainsKillingStoppingContainerEvents checks if the events contain an event
+// with "Killing Stopping container" which indicates that a container could not
+// be gracefully shutdown
+func ContainsKillingStoppingContainerEvents(
+	c kubernetes.Interface,
+	name,
+	namespace string) bool {
 	events, err := getPodEvents(c, name, namespace)
 	if err != nil {
 		return false
@@ -49,7 +57,9 @@ func ContainsKillingStoppingContainerEvents(c kubernetes.Interface, name, namesp
 
 	for _, ev := range events.Items {
 		if strings.ToLower(ev.Reason) == "killing" &&
-			strings.Contains(strings.ToLower(ev.Message), "stopping container") {
+			strings.Contains(
+				strings.ToLower(ev.Message),
+				"stopping container") {
 			return true
 		}
 	}
@@ -104,7 +114,10 @@ func GetPodContainerLogs(
 	return string(logs)
 }
 
-func getPodEvents(c kubernetes.Interface, name, namespace string) (*v1.EventList, error) {
+func getPodEvents(
+	c kubernetes.Interface,
+	name,
+	namespace string) (*v1.EventList, error) {
 	return c.CoreV1().
 		Events(namespace).
 		List(context.TODO(), metav1.ListOptions{
@@ -121,57 +134,112 @@ func GetProviders() []provider.Provider {
 
 	for key, value := range viper.Get("alert").(map[string]interface{}) {
 		for c, v := range value.(map[string]interface{}) {
-			if key == "slack" && c == "webhook" && len(strings.TrimSpace(v.(string))) > 0 {
-				providers = append(providers, provider.NewSlack(viper.GetString("alert.slack.webhook")))
+			if key == "slack" &&
+				c == "webhook" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewSlack(viper.GetString("alert.slack.webhook")))
 			}
-			if key == "pagerduty" && c == "integrationkey" && len(strings.TrimSpace(v.(string))) > 0 {
-				providers = append(providers, provider.NewPagerDuty(viper.GetString("alert.pagerduty.integrationKey")))
+			if key == "pagerduty" &&
+				c == "integrationkey" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewPagerDuty(
+						viper.GetString("alert.pagerduty.integrationKey")))
 			}
-			if key == "discord" && c == "webhook" && len(strings.TrimSpace(v.(string))) > 0 {
-				providers = append(providers, provider.NewDiscord(viper.GetString("alert.discord.webhook")))
+			if key == "discord" &&
+				c == "webhook" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewDiscord(
+						viper.GetString("alert.discord.webhook")))
 			}
-			if key == "telegram" && c == "token" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "telegram" &&
+				c == "token" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				telegram[0] = true
 			}
-			if key == "telegram" && c == "chatid" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "telegram" &&
+				c == "chatid" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				telegram[1] = true
 			}
-			if key == "teams" && c == "webhook" && len(strings.TrimSpace(v.(string))) > 0 {
-				providers = append(providers, provider.NewTeams(viper.GetString("alert.teams.webhook")))
+			if key == "teams" &&
+				c == "webhook" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewTeams(viper.GetString("alert.teams.webhook")))
 			}
-			if key == "email" && c == "from" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "email" &&
+				c == "from" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				email[0] = true
 			}
-			if key == "email" && c == "to" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "email" &&
+				c == "to" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				email[1] = true
 			}
-			if key == "email" && c == "port" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "email" &&
+				c == "port" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				email[2] = true
 			}
-			if key == "email" && c == "host" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "email" &&
+				c == "host" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				email[3] = true
 			}
-			if key == "email" && c == "password" && len(strings.TrimSpace(v.(string))) > 0 {
+			if key == "email" &&
+				c == "password" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
 				email[4] = true
-				if key == "rocketchat" && c == "webhook" && len(strings.TrimSpace(v.(string))) > 0 {
-					providers = append(providers, provider.NewRocketChat(viper.GetString("alert.rocketchat.webhook")))
-				}
-				if key == "mattermost" && c == "webhook" && len(strings.TrimSpace(v.(string))) > 0 {
-					providers = append(providers, provider.NewMattermost(viper.GetString("alert.mattermost.webhook")))
-				}
-				if key == "opsgenie" && c == "apikey" && len(strings.TrimSpace(v.(string))) > 0 {
-					providers = append(providers, provider.NewOpsgenie(viper.GetString("alert.opsgenie.apikey")))
-				}
-			}
-			if key == "telegram" && IsListAllBool(true, telegram) {
-				providers = append(providers, provider.NewTelegram(viper.GetString("alert.telegram.token"), viper.GetString("alert.telegram.chatId")))
-			}
-			if key == "email" && IsListAllBool(true, email) {
-				providers = append(providers, provider.NewEmail(viper.GetString("alert.email.from"),
-					viper.GetString("alert.email.password"),
-					viper.GetString("alert.email.host"),
-					viper.GetInt("alert.email.port"),
-					viper.GetString("alert.email.to")))
+			}
+			if key == "rocketchat" &&
+				c == "webhook" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewRocketChat(
+						viper.GetString("alert.rocketchat.webhook")))
+			}
+			if key == "mattermost" &&
+				c == "webhook" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewMattermost(
+						viper.GetString("alert.mattermost.webhook")))
+			}
+			if key == "opsgenie" &&
+				c == "apikey" &&
+				len(strings.TrimSpace(v.(string))) > 0 {
+				providers = append(
+					providers,
+					provider.NewOpsgenie(
+						viper.GetString("alert.opsgenie.apikey")))
+			}
+			if key == "telegram" &&
+				IsListAllBool(true, telegram) {
+				providers = append(
+					providers,
+					provider.NewTelegram(
+						viper.GetString("alert.telegram.token"),
+						viper.GetString("alert.telegram.chatId")))
+			}
+			if key == "email" &&
+				IsListAllBool(true, email) {
+				providers = append(
+					providers,
+					provider.NewEmail(viper.GetString("alert.email.from"),
+						viper.GetString("alert.email.password"),
+						viper.GetString("alert.email.host"),
+						viper.GetInt("alert.email.port"),
+						viper.GetString("alert.email.to")))
 			}
 		}
 	}


Test patch:
diff --git a/util/util_test.go b/util/util_test.go
index 872ad88..2462a34 100644
--- a/util/util_test.go
+++ b/util/util_test.go
@@ -1,6 +1,7 @@
 package util
 
 import (
+	"fmt"
 	"testing"
 
 	"github.com/abahmed/kwatch/event"
@@ -63,7 +64,12 @@ func TestGetPodContainerLogs(t *testing.T) {
 	viper.SetDefault("maxRecentLogLines", 20)
 	podName := "test"
 	containerName := "test"
-	logs := GetPodContainerLogs(client, podName, containerName, "default", false)
+	logs := GetPodContainerLogs(
+		client,
+		podName,
+		containerName,
+		"default",
+		false)
 	if logs != "fake logs" {
 		t.Fatalf(
 			"get logs for %s in %s: returned %s expected %s",
@@ -128,7 +134,7 @@ func TestGetProviders(t *testing.T) {
 		},
 		"telegram": map[string]interface{}{
 			"token":  "test",
-			"chatid": "test",
+			"chatId": "test",
 		},
 		"teams": map[string]interface{}{
 			"webhook": "test",
@@ -143,6 +149,7 @@ func TestGetProviders(t *testing.T) {
 	viper.SetDefault("alert", alertMap)
 
 	providers := GetProviders()
+	fmt.Printf("t: %v\n", providers)
 	if len(providers) != len(alertMap) {
 		t.Fatalf(
 			"get providers returned %d expected %d",