diff --git a/README.md b/README.md
index c01a09d5..9aac3fa5 100644
--- a/README.md
+++ b/README.md
@@ -108,6 +108,21 @@ If you want to enable Telegram, provide a valid token and the chat Id.
| `alert.telegram.token` | Telegram token |
| `alert.telegram.chatId` | Telegram chat id |
+#### Microsoft Teams
+
+
+
+
+
+If you want to enable Microsoft Teams, provide the channel webhook.
+
+| Parameter | Description |
+|:---------------------------------|:------------------------------------------------|
+| `alert.teams.webhook` | webhook Microsoft team |
+| `alert.teams.title` | Customized title in Microsoft teams message |
+| `alert.teams.text` | Customized title in Microsoft teams message |
+
+
### Cleanup
```shell
diff --git a/config.yaml b/config.yaml
index 990b5183..d36df7ee 100644
--- a/config.yaml
+++ b/config.yaml
@@ -9,5 +9,7 @@ alert:
telegram:
token: ""
chatId: ""
+ teams:
+ webhook: ""
namespaces:
- default
\ No newline at end of file
diff --git a/deploy/config.yaml b/deploy/config.yaml
index ca2bd4b8..e45781d7 100644
--- a/deploy/config.yaml
+++ b/deploy/config.yaml
@@ -21,6 +21,8 @@ data:
telegram:
token:
chatId:
+ teams:
+ webhook:
namespaces:
-
diff --git a/provider/teams.go b/provider/teams.go
new file mode 100644
index 00000000..29079284
--- /dev/null
+++ b/provider/teams.go
@@ -0,0 +1,119 @@
+package provider
+
+import (
+ "bytes"
+ "fmt"
+ "github.com/abahmed/kwatch/event"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+ "io/ioutil"
+ "net/http"
+ "strings"
+)
+
+const (
+ defaultLogs = "No logs captured"
+ defaultEvents = "No events captured"
+ defaultTeamsTitle = "⛑ Kwatch detected a crash in pod"
+)
+
+type teams struct {
+ webhook string
+}
+
+// NewTeams returns new team instance
+func NewTeams(url string) Provider {
+ if len(url) == 0 {
+ logrus.Warnf("initializing Teams with empty webhook url")
+ } else {
+ logrus.Infof("initializing Teams with webhook url: %s", url)
+ }
+
+ return &teams{
+ webhook: url,
+ }
+}
+
+// Name returns name of the provider
+func (t *teams) Name() string {
+ return "Microsoft Teams"
+}
+
+// SendEvent sends event to the provider
+func (t *teams) SendEvent(e *event.Event) error {
+ reqBody := buildRequestBodyTeams(e, t)
+
+ return t.SendMessage(reqBody)
+}
+
+// SendMessage sends text message to the provider
+func (t *teams) SendMessage(msg string) error {
+ client := &http.Client{}
+ buffer := bytes.NewBuffer([]byte(msg))
+ request, err := http.NewRequest(http.MethodPost, t.webhook, buffer)
+
+ if err != nil {
+ return err
+ }
+ request.Header.Set("Content-Type", "application/json")
+ response, err := client.Do(request)
+ if err != nil {
+ return err
+ }
+
+ if response.StatusCode != 399 {
+ body, _ := ioutil.ReadAll(response.Body)
+ return fmt.Errorf("call to teams alert returned status code %d: %msg", response.StatusCode, string(body))
+ }
+
+ if err != nil {
+ return err
+ }
+
+ return err
+}
+
+func buildRequestBodyTeams(e *event.Event, t *teams) string {
+ eventsText := defaultEvents
+ logsText := defaultLogs
+
+ // add events part if it exists
+ events := strings.TrimSpace(e.Events)
+ if len(events) > 0 {
+ eventsText = e.Events
+ }
+
+ // add logs part if it exists
+ logs := strings.TrimSpace(e.Logs)
+ if len(logs) > 0 {
+ logsText = e.Logs
+ }
+ // use custom title if it's provided, otherwise use default
+ title := viper.GetString("alert.teams.title")
+ if len(title) == 0 {
+ title = defaultTeamsTitle
+ }
+
+ // use custom text if it's provided, otherwise use default
+ text := viper.GetString("alert.teams.text")
+ if len(text) == 0 {
+ text = defaultText
+ }
+
+ msg := fmt.Sprintf(
+ "%s \n\n **Pod:** %s \n\n **Container:** %s \n\n **Namespace:** %s \n\n **Events:** \n\n ``` %s ``` \n\n **Logs:** \n\n ``` %s ``` ",
+ text,
+ e.Name,
+ e.Container,
+ e.Namespace,
+ eventsText,
+ logsText,
+ )
+ reqBody := fmt.Sprintf(`{
+ "title": "%s",
+ "text": "%s",
+
+ }`, title, msg)
+
+ return reqBody
+}
diff --git a/storage/storage.go b/storage/storage.go
index f56d0a5c..82697a1e 100644
--- a/storage/storage.go
+++ b/storage/storage.go
@@ -1,5 +1,6 @@
package storage
+// Storage interface
type Storage interface {
AddPodContainer(podKey, containerKey string)
DelPodContainer(podKey, containerKey string)
diff --git a/util/util.go b/util/util.go
index 78a1ed7f..6c556f68 100644
--- a/util/util.go
+++ b/util/util.go
@@ -117,6 +117,9 @@ func GetProviders() []provider.Provider {
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 == "telegram" && isListAllBool(true, telegram) {
providers = append(providers, provider.NewTelegram(viper.GetString("alert.telegram.token"), viper.GetString("alert.telegram.chatId")))