From 67cfe7713038bf8dd4d2b7ce191993591565795e Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Thu, 4 Apr 2019 09:28:26 +0200 Subject: [PATCH 1/3] add a new test handler + more controls on input for main handler, to avoid empty posts to outputs --- go.mod | 2 ++ handlers.go | 37 ++++++++++++++++++++++++++++++++----- main.go | 1 + 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 5c2b309e5..7c3cd63f2 100644 --- a/go.mod +++ b/go.mod @@ -1 +1,3 @@ module github.com/Issif/falcosidekick + +go 1.12 diff --git a/handlers.go b/handlers.go index c231cf6f1..cf00ed242 100644 --- a/handlers.go +++ b/handlers.go @@ -1,17 +1,19 @@ package main import ( + "bytes" "encoding/json" "io/ioutil" "log" "net/http" "os" + "strconv" "github.com/Issif/falcosidekick/outputs" "github.com/Issif/falcosidekick/types" ) -// Print falco's payload in stdout (for debug) of daemon +// 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) @@ -20,10 +22,10 @@ func checkpayloadHandler(w http.ResponseWriter, r *http.Request) { log.Printf("[ERROR] : %v\n", err.Error()) } w.Write([]byte(requestDump)) - log.Printf("[DEBUG] : Paylod = %v\n", string(requestDump)) + log.Printf("[DEBUG] : Falco's Payload = %v\n", string(requestDump)) } -// mainHandler +// mainHandler is Falco Sidekick' main handler (default). func mainHandler(w http.ResponseWriter, r *http.Request) { var falcopayload types.FalcoPayload @@ -34,7 +36,7 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { } err := json.NewDecoder(r.Body).Decode(&falcopayload) - if err != nil && err.Error() != "EOF" { + if err != nil && err.Error() != "EOF" || len(falcopayload.Output) == 0 { http.Error(w, "Please send a valid request body : "+err.Error(), 400) return } @@ -50,7 +52,32 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { } } -// pingHandler in a simple handler to test if daemon responds +// pingHandler is a simple handler to test if daemon is UP. 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) { + testEvent := `{"output":"This is a test from Falco Sidekick","priority":"Debug","rule":"Test rule", "output_fields": {"proc.name":"falcosidekick","user.name":"falcosidekick"}}` + + port = "2801" + if lport, err := strconv.Atoi(os.Getenv("LISTEN_PORT")); err == nil { + if lport > 0 && lport < 65536 { + port = os.Getenv("LISTEN_PORT") + } + } + + resp, err := http.Post("http://localhost:"+port, "application/json", bytes.NewBuffer([]byte(testEvent))) + if err != nil { + log.Printf("[DEBUG] : Test Failed. Falcosidekick can't call itself.\n") + } + defer resp.Body.Close() + + log.Printf("[DEBUG] : Test sent.\n") + if resp.StatusCode == http.StatusOK { + log.Printf("[DEBUG] : Test OK (%v).\n", resp.Status) + } else { + log.Printf("[DEBUG] : Test KO (%v).\n", resp.Status) + } +} diff --git a/main.go b/main.go index fc05919ba..12a6f6194 100644 --- a/main.go +++ b/main.go @@ -42,6 +42,7 @@ func main() { http.HandleFunc("/", mainHandler) http.HandleFunc("/ping", pingHandler) http.HandleFunc("/checkpayload", checkpayloadHandler) + http.HandleFunc("/test", test) log.Printf("[INFO] : Falco Sidekick is up and listening on port %v\n", port) if err := http.ListenAndServe(":"+port, nil); err != nil { From 2d58a51b9da53506eab0ec168f9b464e36e7105c Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Thu, 4 Apr 2019 09:35:44 +0200 Subject: [PATCH 2/3] reformate a little logs in stdout --- handlers.go | 8 ++++---- outputs/alertmanager.go | 6 +++--- outputs/datadog.go | 6 +++--- outputs/slack.go | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/handlers.go b/handlers.go index cf00ed242..e9d3c8c1b 100644 --- a/handlers.go +++ b/handlers.go @@ -70,14 +70,14 @@ func test(w http.ResponseWriter, r *http.Request) { resp, err := http.Post("http://localhost:"+port, "application/json", bytes.NewBuffer([]byte(testEvent))) if err != nil { - log.Printf("[DEBUG] : Test Failed. Falcosidekick can't call itself.\n") + log.Printf("[DEBUG] : Test Failed. Falcosidekick can't call itself\n") } defer resp.Body.Close() - log.Printf("[DEBUG] : Test sent.\n") + log.Printf("[DEBUG] : Test sent\n") if resp.StatusCode == http.StatusOK { - log.Printf("[DEBUG] : Test OK (%v).\n", resp.Status) + log.Printf("[DEBUG] : Test OK (%v)\n", resp.Status) } else { - log.Printf("[DEBUG] : Test KO (%v).\n", resp.Status) + log.Printf("[DEBUG] : Test KO (%v)\n", resp.Status) } } diff --git a/outputs/alertmanager.go b/outputs/alertmanager.go index 045fbecc4..53f18054d 100644 --- a/outputs/alertmanager.go +++ b/outputs/alertmanager.go @@ -52,10 +52,10 @@ func AlertmanagerPost(falcopayload types.FalcoPayload) { json.NewEncoder(b).Encode(alertmanagerPayload) 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()) + log.Printf("[ERROR] : AlertManager - %v\n", err.Error()) } else if resp.StatusCode != 200 { - log.Printf("[ERROR] : (AlertManager) %v\n", resp) + log.Printf("[ERROR] : AlertManager - %v\n", resp) } else { - log.Printf("[INFO] : (AlertManager) Post sent successfully\n") + log.Printf("[INFO] : AlertManager - Post sent successfully\n") } } diff --git a/outputs/datadog.go b/outputs/datadog.go index e873b11a0..3743b5e28 100644 --- a/outputs/datadog.go +++ b/outputs/datadog.go @@ -58,10 +58,10 @@ func DatadogPost(falcopayload types.FalcoPayload) { json.NewEncoder(b).Encode(datadogPayload) 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()) + log.Printf("[ERROR] : Datadog - %v\n", err.Error()) } else if resp.StatusCode != 202 { - log.Printf("[ERROR] : (Datadog) %v\n", resp) + log.Printf("[ERROR] : Datadog - %v\n", resp) } else { - log.Printf("[INFO] : (Datadog) Post sent successfully\n") + log.Printf("[INFO] : Datadog - Post sent successfully\n") } } diff --git a/outputs/slack.go b/outputs/slack.go index 16b8f2871..ef35c8b4c 100644 --- a/outputs/slack.go +++ b/outputs/slack.go @@ -121,10 +121,10 @@ func SlackPost(falcopayload types.FalcoPayload) { json.NewEncoder(b).Encode(slackPayload) 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()) + log.Printf("[ERROR] : Slack - %v\n", err.Error()) } else if resp.StatusCode != 200 { - log.Printf("[ERROR] : (Slack) %v\n", resp) + log.Printf("[ERROR] : Slack - %v\n", resp) } else { - log.Printf("[INFO] : (Slack) Post sent successfully\n") + log.Printf("[INFO] : Slack - Post sent successfully\n") } } From 33848079400cba81dcef19bfbf746a1838b28c29 Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Thu, 4 Apr 2019 09:42:56 +0200 Subject: [PATCH 3/3] add handler /test in README + add DEBUG envvar for all outputs --- README.md | 5 +++++ outputs/alertmanager.go | 5 +++++ outputs/datadog.go | 5 +++++ outputs/slack.go | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/README.md b/README.md index 99ff40bf2..adfd55302 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Configuration of the daemon is made by Env vars : * **SLACK_ICON** : Slack icon (avatar) * **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 # Handlers @@ -51,6 +52,7 @@ 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 @@ -71,11 +73,14 @@ curl "http://localhost:2801/" -d'{"output":"16:31:56.746609046: Error File below You should get : **Slack** : + ![slack example](https://github.com/Issif/falcosidekick/raw/master/imgs/slack.png) **Datadog** : + *(Tip: filter on `sources: falco`)* ![datadog example](https://github.com/Issif/falcosidekick/raw/master/imgs/datadog.png) **AlertManager** : + ![alertmanager example](https://github.com/Issif/falcosidekick/raw/master/imgs/alertmanager.png) \ No newline at end of file diff --git a/outputs/alertmanager.go b/outputs/alertmanager.go index 53f18054d..1387a2376 100644 --- a/outputs/alertmanager.go +++ b/outputs/alertmanager.go @@ -50,6 +50,11 @@ 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()) diff --git a/outputs/datadog.go b/outputs/datadog.go index 3743b5e28..88fa5c32f 100644 --- a/outputs/datadog.go +++ b/outputs/datadog.go @@ -56,6 +56,11 @@ 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()) diff --git a/outputs/slack.go b/outputs/slack.go index ef35c8b4c..da316f6c1 100644 --- a/outputs/slack.go +++ b/outputs/slack.go @@ -119,6 +119,11 @@ 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())