Skip to content

Commit

Permalink
🚀 support teams as a provider (#31)
Browse files Browse the repository at this point in the history
* feature: support teams as a provider

* feature: support teams as a provider

* update README.md

* add

* cleanup code

* fix custom msg

* provider to capitals

* refactor sendEvent

* refactor SendMessage

* const title
  • Loading branch information
Andrew44Ashraf authored Dec 30, 2021
1 parent a5fa6fe commit a96d74a
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<p>
<img src="./assets/teams.png" width="50%"/>
</p>

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
Expand Down
2 changes: 2 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ alert:
telegram:
token: ""
chatId: ""
teams:
webhook: ""
namespaces:
- default
2 changes: 2 additions & 0 deletions deploy/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ data:
telegram:
token: <token_key>
chatId: <chat_id>
teams:
webhook: <webhook_url>
namespaces:
- <optional_namespace>
119 changes: 119 additions & 0 deletions provider/teams.go
Original file line number Diff line number Diff line change
@@ -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 = "&#9937; 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
}
1 change: 1 addition & 0 deletions storage/storage.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package storage

// Storage interface
type Storage interface {
AddPodContainer(podKey, containerKey string)
DelPodContainer(podKey, containerKey string)
Expand Down
3 changes: 3 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")))
Expand Down

0 comments on commit a96d74a

Please sign in to comment.