diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c70db93a..af529860d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,35 +1,51 @@ -# Changelog - -## 1.0.4 - 2019-02-01 -#### New -- Add of **go mod** ([PR#1](https://github.com/Issif/falcosidekick/pull/9) thanks to [@perriea](https://github.com/perriea)) -#### Enhancement -- Use of *go mod* is Dockerfile for build ([PR#1](https://github.com/Issif/falcosidekick/pull/9) thanks to [@perriea](https://github.com/perriea)) -- Add email maintener in Dockerfile ([PR#1](https://github.com/Issif/falcosidekick/pull/9) thanks to [@perriea](https://github.com/perriea)) - -## 1.0.3 - 2019-01-30 -#### New -- new output : **Alert Manager** -#### Enhancement -- add status of posts to Outputs in logs (stdout) - -## 1.0.2 - 2018-10-10 -#### Enhancement -- update changelog -- update README with new Slack Options + more info - -## 1.0.1 - 2018-10-10 -#### New -- new Slack Options : `SLACK_FOOTER`, `SLACK_ICON` -#### Enhancements -- new Slack Options : `SLACK_FOOTER`, `SLACK_ICON` -- add output status in log to get those which are enabled -- check of `LISTEN_PORT` in `init()` : port must be an integer between 1 and 65535 -- long string in slack field values are not splitten anymore - -#### Fix -- some log level tags were missing -- fix cert errors in alpine ([PR#1](https://github.com/Issif/falcosidekick/pull/1) thanks to [@palmerabollo](https://github.com/palmerabollo)) - -## 1.0.0 - 2018-10-10 +# Changelog + +## 1.0.6 - 2019-05-09 +#### New +- Add `SLACK_HIDE_FIELDS` env var, to enable concise output in Slack (fields are not displayed) ([issue #15](https://github.com/Issif/falcosidekick/issues/15)) +#### Enhancement +- Remove `/checkPayload` endpoint, not usefull anymore +- Change of how enabled/disabled outputs are printed in log (more concise view) +- Falco's payload is printed in log if `DEBUG=true` + +## 1.0.5 - 2019-04-09 +#### New +- Add a `/test` endpoint which sends a fake event to all enabled outputs +- Add a `DEBUG` env var, if enabled, payload for enabled outputs will be printed in stdout +#### Enhancement +- Reformate some logs outputs to be nicer +- Add a check on payload's body from falco to avoid to send empty's ones to outputs + +## 1.0.4 - 2019-02-01 +#### New +- Add of **go mod** ([PR#1](https://github.com/Issif/falcosidekick/pull/9) thanks to [@perriea](https://github.com/perriea)) +#### Enhancement +- Use of *go mod* is Dockerfile for build ([PR#1](https://github.com/Issif/falcosidekick/pull/9) thanks to [@perriea](https://github.com/perriea)) +- Add email maintener in Dockerfile ([PR#1](https://github.com/Issif/falcosidekick/pull/9) thanks to [@perriea](https://github.com/perriea)) + +## 1.0.3 - 2019-01-30 +#### New +- new output : **Alert Manager** +#### Enhancement +- add status of posts to Outputs in logs (stdout) + +## 1.0.2 - 2018-10-10 +#### Enhancement +- update changelog +- update README with new Slack Options + more info + +## 1.0.1 - 2018-10-10 +#### New +- new Slack Options : `SLACK_FOOTER`, `SLACK_ICON` +#### Enhancements +- new Slack Options : `SLACK_FOOTER`, `SLACK_ICON` +- add output status in log to get those which are enabled +- check of `LISTEN_PORT` in `init()` : port must be an integer between 1 and 65535 +- long string in slack field values are not splitten anymore + +#### Fix +- some log level tags were missing +- fix cert errors in alpine ([PR#1](https://github.com/Issif/falcosidekick/pull/1) thanks to [@palmerabollo](https://github.com/palmerabollo)) + +## 1.0.0 - 2018-10-10 - First tagged release \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e5f7ef3a9..551f24a48 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,29 @@ -# Build image (Golang) -FROM golang:1.11-alpine3.8 AS build-stage -ENV GO111MODULE on -ENV CGO_ENABLED 0 - -RUN apk add --no-cache gcc git make - -WORKDIR /src -ADD . . - -RUN go mod download -RUN go build -o falcosidekick - -# Final Docker image -FROM alpine:3.8 AS final-stage -LABEL MAINTAINER "Thomas Labarussias " - -RUN apk add --no-cache ca-certificates - -# Create user falcosidekick -RUN addgroup -S falcosidekick && adduser -S falcosidekick -G falcosidekick -USER falcosidekick - -WORKDIR ${HOME}/app -COPY --from=build-stage /src/falcosidekick . - -EXPOSE 2801 - -ENTRYPOINT ["./falcosidekick"] +# Build image (Golang) +FROM golang:1.11-alpine3.8 AS build-stage +ENV GO111MODULE on +ENV CGO_ENABLED 0 + +RUN apk add --no-cache gcc git make + +WORKDIR /src +ADD . . + +RUN go mod download +RUN go build -o falcosidekick + +# Final Docker image +FROM alpine:3.8 AS final-stage +LABEL MAINTAINER "Thomas Labarussias " + +RUN apk add --no-cache ca-certificates + +# Create user falcosidekick +RUN addgroup -S falcosidekick && adduser -S falcosidekick -G falcosidekick +USER falcosidekick + +WORKDIR ${HOME}/app +COPY --from=build-stage /src/falcosidekick . + +EXPOSE 2801 + +ENTRYPOINT ["./falcosidekick"] diff --git a/README.md b/README.md index adfd55302..f428dc8cd 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Configuration of the daemon is made by Env vars : * **SLACK_TOKEN** : Slack URL + token (ex: https://hooks.slack.com/services/XXXX/YYYY/ZZZZ), if not `empty`, Slack output is *enabled* * **SLACK_FOOTER** : Slack footer * **SLACK_ICON** : Slack icon (avatar) +* **SLACK_HIDE_FIELDS** : if `true`, detailed fields will not be displayed * **DATADOG_TOKEN** : Datadog token, if not `empty`, Datadog output is *enabled* * **ALERTMANAGER_HOST_PORT** : AlertManager host:port, if not `empty`, AlertManager is *enabled* * **DEBUG** : if *true* all outputs will print in stdout the payload they send @@ -51,7 +52,6 @@ Different URI (handlers) are available : * `/` : main and default handler, your falco config must be configured to use it * `/ping` : you will get a `pong` as answer, useful to test if falcosidekick is running and its port is opened (for healthcheck purpose for example) -* `/checkpayload` : (for debug only) you will get in response the exact payload which has been received by falcosidekick (no notification are sent to ouputs) * `/test` : (for debug only) send a test event to all enabled outputs. # Logs @@ -75,6 +75,7 @@ You should get : **Slack** : ![slack example](https://github.com/Issif/falcosidekick/raw/master/imgs/slack.png) +![slack no fields example](https://github.com/Issif/falcosidekick/raw/master/imgs/slack_no_fields.png) **Datadog** : diff --git a/handlers.go b/handlers.go index e9d3c8c1b..6dea0dfd9 100644 --- a/handlers.go +++ b/handlers.go @@ -3,7 +3,6 @@ package main import ( "bytes" "encoding/json" - "io/ioutil" "log" "net/http" "os" @@ -13,18 +12,6 @@ import ( "github.com/Issif/falcosidekick/types" ) -// checkpayloadHandler prints received falco's payload in stdout (for debug) of daemon -func checkpayloadHandler(w http.ResponseWriter, r *http.Request) { - // Read body - requestDump, err := ioutil.ReadAll(r.Body) - if err != nil { - w.Write([]byte(err.Error() + "\n")) - log.Printf("[ERROR] : %v\n", err.Error()) - } - w.Write([]byte(requestDump)) - log.Printf("[DEBUG] : Falco's Payload = %v\n", string(requestDump)) -} - // mainHandler is Falco Sidekick' main handler (default). func mainHandler(w http.ResponseWriter, r *http.Request) { @@ -41,6 +28,11 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { return } + if os.Getenv("DEBUG") == "true" { + body, _ := json.Marshal(falcopayload) + log.Printf("[DEBUG] : Falco's payload : %v", string(body)) + } + if os.Getenv("SLACK_TOKEN") != "" { go outputs.SlackPost(falcopayload) } @@ -57,8 +49,8 @@ func pingHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong\n")) } -// test sends a test event to all enabled outputs. -func test(w http.ResponseWriter, r *http.Request) { +// testHandler sends a test event to all enabled outputs. +func testHandler(w http.ResponseWriter, r *http.Request) { testEvent := `{"output":"This is a test from Falco Sidekick","priority":"Debug","rule":"Test rule", "output_fields": {"proc.name":"falcosidekick","user.name":"falcosidekick"}}` port = "2801" diff --git a/imgs/slack_no_fields.png b/imgs/slack_no_fields.png new file mode 100644 index 000000000..7727d0374 Binary files /dev/null and b/imgs/slack_no_fields.png differ diff --git a/main.go b/main.go index 12a6f6194..39200dc3d 100644 --- a/main.go +++ b/main.go @@ -19,33 +19,36 @@ func init() { log.Fatalf("[ERROR] : Bad port number\n") } } - configText := "[INFO] : Outputs configuration : " + enableOutputsText := "[INFO] : Enable Outputs : " + disableOutputsText := "[INFO] : Disable Outputs : " if os.Getenv("SLACK_TOKEN") != "" { - configText += "Slack=enabled, " + enableOutputsText += "Slack, " } else { - configText += "Slack=disabled, " + disableOutputsText += "Slack, " } if os.Getenv("DATADOG_TOKEN") != "" { - configText += "Datadog=enabled," + enableOutputsText += "Datadog, " } else { - configText += "Datadog=disabled," + disableOutputsText += "Datadog, " } if os.Getenv("ALERTMANAGER_HOST_PORT") != "" { - configText += "AlertManager=enabled" + enableOutputsText += "AlertManager" } else { - configText += "AlertManager=disabled" + disableOutputsText += "AlertManager" } - log.Printf("%v\n", configText) + + log.Printf("%v\n", enableOutputsText) + log.Printf("%v\n", disableOutputsText) } func main() { http.HandleFunc("/", mainHandler) http.HandleFunc("/ping", pingHandler) - http.HandleFunc("/checkpayload", checkpayloadHandler) - http.HandleFunc("/test", test) + http.HandleFunc("/test", testHandler) log.Printf("[INFO] : Falco Sidekick is up and listening on port %v\n", port) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatalf("[ERROR] : %v\n", err.Error()) + } else { } } diff --git a/outputs/alertmanager.go b/outputs/alertmanager.go index 1387a2376..8d968f7b3 100644 --- a/outputs/alertmanager.go +++ b/outputs/alertmanager.go @@ -1,66 +1,66 @@ -package outputs - -import ( - "bytes" - "encoding/json" - "log" - "net/http" - "os" - "strings" - - "github.com/Issif/falcosidekick/types" -) - -const ( - alertmanagerURL string = "/api/v1/alerts" -) - -type alertmanagerIncident struct { - Labels map[string]string `json:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` -} - -func newAlertmanagerPayload(falcopayload types.FalcoPayload) []alertmanagerIncident { - var alertmanagerincident alertmanagerIncident - alertmanagerincident.Labels = make(map[string]string) - alertmanagerincident.Annotations = make(map[string]string) - - for i, j := range falcopayload.OutputFields { - switch j.(type) { - case string: - //AlertManger doesn't support dots in a label name - alertmanagerincident.Labels[strings.Replace(i, ".", "_", -1)] = j.(string) - } - } - alertmanagerincident.Labels["source"] = "falco" - alertmanagerincident.Labels["rule"] = falcopayload.Rule - - alertmanagerincident.Annotations["info"] = falcopayload.Output - alertmanagerincident.Annotations["summary"] = falcopayload.Rule - - var a []alertmanagerIncident - - a = append(a, alertmanagerincident) - - return a -} - -// AlertmanagerPost posts event to Alert Manager -func AlertmanagerPost(falcopayload types.FalcoPayload) { - alertmanagerPayload := newAlertmanagerPayload(falcopayload) - b := new(bytes.Buffer) - json.NewEncoder(b).Encode(alertmanagerPayload) - - if os.Getenv("DEBUG") == "true" { - log.Printf("[DEBUG] : AlertManager's payload : %v\n", b) - } - - resp, err := http.Post(os.Getenv("ALERTMANAGER_HOST_PORT")+alertmanagerURL, "application/json; charset=utf-8", b) - if err != nil { - log.Printf("[ERROR] : AlertManager - %v\n", err.Error()) - } else if resp.StatusCode != 200 { - log.Printf("[ERROR] : AlertManager - %v\n", resp) - } else { - log.Printf("[INFO] : AlertManager - Post sent successfully\n") - } -} +package outputs + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + "os" + "strings" + + "github.com/Issif/falcosidekick/types" +) + +const ( + alertmanagerURL string = "/api/v1/alerts" +) + +type alertmanagerIncident struct { + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` +} + +func newAlertmanagerPayload(falcopayload types.FalcoPayload) []alertmanagerIncident { + var alertmanagerincident alertmanagerIncident + alertmanagerincident.Labels = make(map[string]string) + alertmanagerincident.Annotations = make(map[string]string) + + for i, j := range falcopayload.OutputFields { + switch j.(type) { + case string: + //AlertManger doesn't support dots in a label name + alertmanagerincident.Labels[strings.Replace(i, ".", "_", -1)] = j.(string) + } + } + alertmanagerincident.Labels["source"] = "falco" + alertmanagerincident.Labels["rule"] = falcopayload.Rule + + alertmanagerincident.Annotations["info"] = falcopayload.Output + alertmanagerincident.Annotations["summary"] = falcopayload.Rule + + var a []alertmanagerIncident + + a = append(a, alertmanagerincident) + + return a +} + +// AlertmanagerPost posts event to Alert Manager +func AlertmanagerPost(falcopayload types.FalcoPayload) { + alertmanagerPayload := newAlertmanagerPayload(falcopayload) + b := new(bytes.Buffer) + json.NewEncoder(b).Encode(alertmanagerPayload) + + if os.Getenv("DEBUG") == "true" { + log.Printf("[DEBUG] : AlertManager's payload : %v\n", b) + } + + resp, err := http.Post(os.Getenv("ALERTMANAGER_HOST_PORT")+alertmanagerURL, "application/json; charset=utf-8", b) + if err != nil { + log.Printf("[ERROR] : AlertManager - %v\n", err.Error()) + } else if resp.StatusCode != 200 { + log.Printf("[ERROR] : AlertManager - %v\n", resp) + } else { + log.Printf("[INFO] : AlertManager - Post sent successfully\n") + } +} diff --git a/outputs/datadog.go b/outputs/datadog.go index 88fa5c32f..add13fbad 100644 --- a/outputs/datadog.go +++ b/outputs/datadog.go @@ -1,72 +1,72 @@ -package outputs - -import ( - "bytes" - "encoding/json" - "log" - "net/http" - "os" - - "github.com/Issif/falcosidekick/types" -) - -const ( - datadogURL string = "https://api.datadoghq.com/api/v1/events" -) - -type datadogPayload struct { - Title string `json:"title,omitempty"` - Text string `json:"text,omitempty"` - AlertType string `json:"alert_type,omitempty"` - SourceType string `json:"source_type_name,omitempty"` - Tags []string `json:"tags,omitempty"` -} - -func newDatadogPayload(falcopayload types.FalcoPayload) datadogPayload { - var ddpayload datadogPayload - var tags []string - - for i, j := range falcopayload.OutputFields { - switch j.(type) { - case string: - tags = append(tags, i+":"+j.(string)) - } - } - ddpayload.Tags = tags - - ddpayload.Title = falcopayload.Rule - ddpayload.Text = falcopayload.Output - ddpayload.SourceType = "falco" - - var status string - switch falcopayload.Priority { - case "Emergency", "Alert", "Critical", "Error": - status = "error" - case "Warning": - status = "warning" - default: - status = "info" - } - ddpayload.AlertType = status - - return ddpayload -} - -func DatadogPost(falcopayload types.FalcoPayload) { - datadogPayload := newDatadogPayload(falcopayload) - b := new(bytes.Buffer) - json.NewEncoder(b).Encode(datadogPayload) - - if os.Getenv("DEBUG") == "true" { - log.Printf("[DEBUG] : Datadog's payload : %v\n", b) - } - - resp, err := http.Post(datadogURL+"?api_key="+os.Getenv("DATADOG_TOKEN"), "application/json; charset=utf-8", b) - if err != nil { - log.Printf("[ERROR] : Datadog - %v\n", err.Error()) - } else if resp.StatusCode != 202 { - log.Printf("[ERROR] : Datadog - %v\n", resp) - } else { - log.Printf("[INFO] : Datadog - Post sent successfully\n") - } -} +package outputs + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + "os" + + "github.com/Issif/falcosidekick/types" +) + +const ( + datadogURL string = "https://api.datadoghq.com/api/v1/events" +) + +type datadogPayload struct { + Title string `json:"title,omitempty"` + Text string `json:"text,omitempty"` + AlertType string `json:"alert_type,omitempty"` + SourceType string `json:"source_type_name,omitempty"` + Tags []string `json:"tags,omitempty"` +} + +func newDatadogPayload(falcopayload types.FalcoPayload) datadogPayload { + var ddpayload datadogPayload + var tags []string + + for i, j := range falcopayload.OutputFields { + switch j.(type) { + case string: + tags = append(tags, i+":"+j.(string)) + } + } + ddpayload.Tags = tags + + ddpayload.Title = falcopayload.Rule + ddpayload.Text = falcopayload.Output + ddpayload.SourceType = "falco" + + var status string + switch falcopayload.Priority { + case "Emergency", "Alert", "Critical", "Error": + status = "error" + case "Warning": + status = "warning" + default: + status = "info" + } + ddpayload.AlertType = status + + return ddpayload +} + +func DatadogPost(falcopayload types.FalcoPayload) { + datadogPayload := newDatadogPayload(falcopayload) + b := new(bytes.Buffer) + json.NewEncoder(b).Encode(datadogPayload) + + if os.Getenv("DEBUG") == "true" { + log.Printf("[DEBUG] : Datadog's payload : %v\n", b) + } + + resp, err := http.Post(datadogURL+"?api_key="+os.Getenv("DATADOG_TOKEN"), "application/json; charset=utf-8", b) + if err != nil { + log.Printf("[ERROR] : Datadog - %v\n", err.Error()) + } else if resp.StatusCode != 202 { + log.Printf("[ERROR] : Datadog - %v\n", resp) + } else { + log.Printf("[INFO] : Datadog - Post sent successfully\n") + } +} diff --git a/outputs/slack.go b/outputs/slack.go index da316f6c1..c8f8b20d0 100644 --- a/outputs/slack.go +++ b/outputs/slack.go @@ -1,135 +1,138 @@ -package outputs - -import ( - "bytes" - "encoding/json" - "log" - "net/http" - "os" - - "github.com/Issif/falcosidekick/types" -) - -// Field -type slackAttachmentField struct { - Title string `json:"title"` - Value string `json:"value"` - Short bool `json:"short"` -} - -//Attachment -type slackAttachment struct { - Fallback string `json:"fallback"` - Color string `json:"color"` - PreText string `json:"pretext,omitempty"` - Fields []slackAttachmentField `json:"fields"` - Footer string `json:"footer,omitempty"` - FooterIcon string `json:"footer_icon,omitempty"` -} - -// Payload -type slackPayload struct { - Username string `json:"username,omitempty"` - IconURL string `json:"icon_url,omitempty"` - Attachments []slackAttachment `json:"attachments,omitempty"` -} - -func newSlackPayload(falcopayload types.FalcoPayload) slackPayload { - var attachments []slackAttachment - var attachment slackAttachment - var fields []slackAttachmentField - var field slackAttachmentField - - for i, j := range falcopayload.OutputFields { - switch j.(type) { - case string: - field.Title = i - field.Value = j.(string) - if len([]rune(j.(string))) < 36 { - field.Short = true - } else { - field.Short = false - } - } - fields = append(fields, field) - } - - field.Title = "rule" - field.Value = falcopayload.Rule - field.Short = true - fields = append(fields, field) - field.Title = "priority" - field.Value = falcopayload.Priority - field.Short = true - fields = append(fields, field) - field.Title = "time" - field.Short = false - field.Value = falcopayload.Time.String() - fields = append(fields, field) - - attachment.Fallback = falcopayload.Output - attachment.Fields = fields - attachment.PreText = falcopayload.Output - if os.Getenv("SLACK_FOOTER") != "" { - attachment.Footer = os.Getenv("SLACK_FOOTER") - } else { - attachment.Footer = "https://github.com/Issif/falcosidekick" - } - - var color string - switch falcopayload.Priority { - case "Emergency": - color = "#e20b0b" - case "Alert": - color = "#ff5400" - case "Critical": - color = "#ff9000" - case "Error": - color = "#ffc700" - case "Warning": - color = "#ffff00" - case "Notice": - color = "#5bffb5" - case "Informationnal": - color = "#68c2ff" - case "Debug": - color = "#ccfff2" - } - attachment.Color = color - - attachments = append(attachments, attachment) - - var iconUrl string - if os.Getenv("SLACK_ICON") != "" { - iconUrl = os.Getenv("SLACK_ICON") - } else { - iconUrl = "https://raw.githubusercontent.com/Issif/falcosidekick/master/imgs/falcosidekick.png" - } - - slackPayload := slackPayload{ - Username: "Falco Sidekick", - IconURL: iconUrl, - Attachments: attachments} - - return slackPayload -} - -// slackPost posts event to slack -func SlackPost(falcopayload types.FalcoPayload) { - slackPayload := newSlackPayload(falcopayload) - b := new(bytes.Buffer) - json.NewEncoder(b).Encode(slackPayload) - - if os.Getenv("DEBUG") == "true" { - log.Printf("[DEBUG] : Slack's payload : %v\n", b) - } - - resp, err := http.Post(os.Getenv("SLACK_TOKEN"), "application/json; charset=utf-8", b) - if err != nil { - log.Printf("[ERROR] : Slack - %v\n", err.Error()) - } else if resp.StatusCode != 200 { - log.Printf("[ERROR] : Slack - %v\n", resp) - } else { - log.Printf("[INFO] : Slack - Post sent successfully\n") - } -} +package outputs + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + "os" + + "github.com/Issif/falcosidekick/types" +) + +// Field +type slackAttachmentField struct { + Title string `json:"title"` + Value string `json:"value"` + Short bool `json:"short"` +} + +//Attachment +type slackAttachment struct { + Fallback string `json:"fallback"` + Color string `json:"color"` + Text string `json:"text,omitempty"` + Fields []slackAttachmentField `json:"fields"` + Footer string `json:"footer,omitempty"` + FooterIcon string `json:"footer_icon,omitempty"` +} + +// Payload +type slackPayload struct { + Username string `json:"username,omitempty"` + IconURL string `json:"icon_url,omitempty"` + Attachments []slackAttachment `json:"attachments,omitempty"` +} + +func newSlackPayload(falcopayload types.FalcoPayload) slackPayload { + var attachments []slackAttachment + var attachment slackAttachment + var fields []slackAttachmentField + var field slackAttachmentField + + if os.Getenv("SLACK_HIDE_FIELDS") != "true" { + for i, j := range falcopayload.OutputFields { + switch j.(type) { + case string: + field.Title = i + field.Value = j.(string) + if len([]rune(j.(string))) < 36 { + field.Short = true + } else { + field.Short = false + } + } + fields = append(fields, field) + } + + field.Title = "rule" + field.Value = falcopayload.Rule + field.Short = true + fields = append(fields, field) + field.Title = "priority" + field.Value = falcopayload.Priority + field.Short = true + fields = append(fields, field) + field.Title = "time" + field.Short = false + field.Value = falcopayload.Time.String() + fields = append(fields, field) + + if os.Getenv("SLACK_FOOTER") != "" { + attachment.Footer = os.Getenv("SLACK_FOOTER") + } else { + attachment.Footer = "https://github.com/Issif/falcosidekick" + } + } + + attachment.Fallback = falcopayload.Output + attachment.Fields = fields + attachment.Text = falcopayload.Output + + var color string + switch falcopayload.Priority { + case "Emergency": + color = "#e20b0b" + case "Alert": + color = "#ff5400" + case "Critical": + color = "#ff9000" + case "Error": + color = "#ffc700" + case "Warning": + color = "#ffff00" + case "Notice": + color = "#5bffb5" + case "Informationnal": + color = "#68c2ff" + case "Debug": + color = "#ccfff2" + } + attachment.Color = color + + attachments = append(attachments, attachment) + + var iconUrl string + if os.Getenv("SLACK_ICON") != "" { + iconUrl = os.Getenv("SLACK_ICON") + } else { + iconUrl = "https://raw.githubusercontent.com/Issif/falcosidekick/master/imgs/falcosidekick.png" + } + + slackPayload := slackPayload{ + Username: "Falco Sidekick", + IconURL: iconUrl, + Attachments: attachments} + + return slackPayload +} + +// slackPost posts event to slack +func SlackPost(falcopayload types.FalcoPayload) { + slackPayload := newSlackPayload(falcopayload) + b := new(bytes.Buffer) + json.NewEncoder(b).Encode(slackPayload) + + if os.Getenv("DEBUG") == "true" { + log.Printf("[DEBUG] : Slack's payload : %v", b) + } + + resp, err := http.Post(os.Getenv("SLACK_TOKEN"), "application/json; charset=utf-8", b) + if err != nil { + log.Printf("[ERROR] : Slack - %v\n", err.Error()) + } else if resp.StatusCode != 200 { + log.Printf("[ERROR] : Slack - %v\n", resp) + } else { + log.Printf("[INFO] : Slack - Post sent successfully\n") + } +}