Skip to content

Commit

Permalink
Merge pull request #18 from Issif/v1.0.6
Browse files Browse the repository at this point in the history
## 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`
  • Loading branch information
Issif authored May 9, 2019
2 parents 5a8d559 + fbefacf commit aff03bd
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 362 deletions.
84 changes: 50 additions & 34 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
58 changes: 29 additions & 29 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>"

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 <[email protected]>"

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"]
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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** :

Expand Down
22 changes: 7 additions & 15 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"os"
Expand All @@ -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) {

Expand All @@ -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)
}
Expand All @@ -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"
Expand Down
Binary file added imgs/slack_no_fields.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 13 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
}
}
132 changes: 66 additions & 66 deletions outputs/alertmanager.go
Original file line number Diff line number Diff line change
@@ -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")
}
}
Loading

0 comments on commit aff03bd

Please sign in to comment.