Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output WebUI #180

Merged
merged 4 commits into from
Feb 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Currently available outputs are :
- [**Apache Kafka**](https://kafka.apache.org/)
- [**PagerDuty**](https://pagerduty.com/)
- [**Kubeless**](https://kubeless.io/)
- [**WebUI**](https://github.com/falcosecurity/falcosidekick-ui) (a Web UI for displaying latest events in real time)

## Usage

Expand Down Expand Up @@ -296,6 +297,9 @@ kubeless:
port: 8080 # Port of service of Kubeless function
kubeconfig: "~/.kube/config" # Kubeconfig file to use (only if falcoside is running outside the cluster)
# minimumpriority: "debug" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

webui:
url: "" # WebUI URL, if not empty, WebUI output is enabled
```

Usage :
Expand Down Expand Up @@ -544,6 +548,8 @@ care of lower/uppercases**) : `yaml: a.b --> envvar: A_B` :
- **KUBELESS_MINIMUMPRIORITY**: "debug" # minimum priority of event for using
this output, order is
`emergency|alert|critical|error|warning|notice|informational|debug or "" (default)`
- **WEBUI_URL** : WebUI URL, if not empty, WebUI output is
_enabled_

#### Slack/Rocketchat/Mattermost/Googlechat Message Formatting

Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func getConfig() *types.Configuration {
v.SetDefault("Kubeless.Port", 8080)
v.SetDefault("Kubeless.Kubeconfig", "")
v.SetDefault("Kubeless.MinimumPriority", "")
v.SetDefault("Webui.URL", "http://localhost:2802")

v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.AutomaticEnv()
Expand Down
5 changes: 4 additions & 1 deletion config_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ azure:
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

discord:
webhookurl: "" # discord WebhookURL (ex: https://discord.com/api/webhooks/xxxxxxxxxx...), if not empty, Discord output is enabled
webhookurl: "" # Discord WebhookURL (ex: https://discord.com/api/webhooks/xxxxxxxxxx...), if not empty, Discord output is enabled
Issif marked this conversation as resolved.
Show resolved Hide resolved
# icon: "" # Discord icon (avatar)
# minimumpriority: "debug" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

Expand Down Expand Up @@ -160,3 +160,6 @@ kubeless:
port: 8080 # Port of service of Kubeless function
kubeconfig: "~/.kube/config" # Kubeconfig file to use (only if falcoside is running outside the cluster)
# minimumpriority: "debug" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

webui:
url: "" # WebUI URL, if not empty, WebUI output is enabled
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ require (
github.com/DataDog/datadog-go v4.2.0+incompatible
github.com/PagerDuty/go-pagerduty v1.3.0
github.com/aws/aws-sdk-go v1.36.23
github.com/cloudevents/sdk-go/v2 v2.3.1
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
github.com/emersion/go-smtp v0.14.0
github.com/gkarthiks/k8s-discovery v0.19.0
github.com/cloudevents/sdk-go/v2 v2.3.1
github.com/google/uuid v1.1.2
github.com/imdario/mergo v0.3.7 // indirect
github.com/nats-io/nats-streaming-server v0.19.0 // indirect
Expand All @@ -24,6 +23,5 @@ require (
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5
google.golang.org/api v0.36.0
gopkg.in/alecthomas/kingpin.v2 v2.2.6
k8s.io/apimachinery v0.20.1
k8s.io/client-go v0.20.1
)
79 changes: 28 additions & 51 deletions go.sum

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"log"
"net/http"
"strings"
"time"

"github.com/falcosecurity/falcosidekick/types"
Expand Down Expand Up @@ -104,7 +105,7 @@ func newFalcoPayload(payload io.Reader) (types.FalcoPayload, error) {
}

nullClient.CountMetric("falco.accepted", 1, []string{"priority:" + falcopayload.Priority.String()})
stats.Falco.Add(falcopayload.Priority.String(), 1)
stats.Falco.Add(strings.ToLower(falcopayload.Priority.String()), 1)
promStats.Falco.With(map[string]string{"rule": falcopayload.Rule, "priority": falcopayload.Priority.String(), "k8s_ns_name": kn, "k8s_pod_name": kp}).Inc()

if config.Debug == true {
Expand Down Expand Up @@ -219,4 +220,8 @@ func forwardEvent(falcopayload types.FalcoPayload) {
if config.Kubeless.Namespace != "" && config.Kubeless.Function != "" && (falcopayload.Priority >= types.Priority(config.Kubeless.MinimumPriority) || falcopayload.Rule == testRule) {
go kubelessClient.KubelessCall(falcopayload)
}

if config.WebUI.URL != "" {
go webUIClient.WebUIPost(falcopayload)
}
}
72 changes: 42 additions & 30 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/DataDog/datadog-go/statsd"
"github.com/falcosecurity/falcosidekick/outputs"
"github.com/falcosecurity/falcosidekick/types"
"github.com/google/uuid"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

Expand Down Expand Up @@ -38,6 +39,7 @@ var (
kafkaClient *outputs.Client
pagerdutyClient *outputs.Client
kubelessClient *outputs.Client
webUIClient *outputs.Client

statsdClient, dogstatsdClient *statsd.Client
config *types.Configuration
Expand All @@ -50,15 +52,15 @@ func init() {
stats = getInitStats()
promStats = getInitPromStats()

enabledOutputsText := "[INFO] : Enabled Outputs : "
config.UUID = uuid.New().String()

if config.Statsd.Forwarder != "" {
var err error
statsdClient, err = outputs.NewStatsdClient("StatsD", config, stats)
if err != nil {
config.Statsd.Forwarder = ""
} else {
enabledOutputsText += "StatsD "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "StatsD")
}
}

Expand All @@ -68,7 +70,7 @@ func init() {
if err != nil {
config.Statsd.Forwarder = ""
} else {
enabledOutputsText += "StatsD "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "StatsD")
nullClient.DogstatsdClient = dogstatsdClient
}
}
Expand All @@ -88,7 +90,7 @@ func init() {
if err != nil {
config.Slack.WebhookURL = ""
} else {
enabledOutputsText += "Slack "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Slack")
}
}

Expand All @@ -98,7 +100,7 @@ func init() {
if err != nil {
config.Rocketchat.WebhookURL = ""
} else {
enabledOutputsText += "Rocketchat "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Rocketchat")
}
}

Expand All @@ -108,7 +110,7 @@ func init() {
if err != nil {
config.Mattermost.WebhookURL = ""
} else {
enabledOutputsText += "Mattermost "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Mattermost")
}
}

Expand All @@ -118,7 +120,7 @@ func init() {
if err != nil {
config.Teams.WebhookURL = ""
} else {
enabledOutputsText += "Teams "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Teams")
}
}

Expand All @@ -128,7 +130,7 @@ func init() {
if err != nil {
config.Datadog.APIKey = ""
} else {
enabledOutputsText += "Datadog "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Datadog")
}
}

Expand All @@ -138,7 +140,7 @@ func init() {
if err != nil {
config.Discord.WebhookURL = ""
} else {
enabledOutputsText += "Discord "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Discord")
}
}

Expand All @@ -148,7 +150,7 @@ func init() {
if err != nil {
config.Alertmanager.HostPort = ""
} else {
enabledOutputsText += "AlertManager "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "AlertManager")
}
}

Expand All @@ -158,7 +160,7 @@ func init() {
if err != nil {
config.Elasticsearch.HostPort = ""
} else {
enabledOutputsText += "Elasticsearch "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Elasticsearch")
}
}

Expand All @@ -168,7 +170,7 @@ func init() {
if err != nil {
config.Loki.HostPort = ""
} else {
enabledOutputsText += "Loki "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Loki")
}
}

Expand All @@ -178,7 +180,7 @@ func init() {
if err != nil {
config.Nats.HostPort = ""
} else {
enabledOutputsText += "NATS "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "NATS")
}
}

Expand All @@ -190,7 +192,7 @@ func init() {
config.Stan.ClusterID = ""
config.Stan.ClientID = ""
} else {
enabledOutputsText += "STAN "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "STAN")
}
}

Expand All @@ -205,7 +207,7 @@ func init() {
if err != nil {
config.Influxdb.HostPort = ""
} else {
enabledOutputsText += "Influxdb "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Influxdb")
}
}

Expand All @@ -224,16 +226,16 @@ func init() {
config.AWS.CloudWatchLogs.LogStream = ""
} else {
if config.AWS.Lambda.FunctionName != "" {
enabledOutputsText += "AWSLambda "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "AWSLambda")
}
if config.AWS.SQS.URL != "" {
enabledOutputsText += "AWSSQS "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "AWSSQS")
}
if config.AWS.SNS.TopicArn != "" {
enabledOutputsText += "AWSSNS "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "AWSSNS")
}
if config.AWS.CloudWatchLogs.LogGroup != "" {
enabledOutputsText += "AWSCloudWatchLogs "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "AWSCloudWatchLogs")
}
}
}
Expand All @@ -244,7 +246,7 @@ func init() {
if err != nil {
config.SMTP.HostPort = ""
} else {
enabledOutputsText += "SMTP "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "SMTP")
}
}

Expand All @@ -258,7 +260,7 @@ func init() {
if err != nil {
config.Opsgenie.APIKey = ""
} else {
enabledOutputsText += "Opsgenie "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Opsgenie")
}
}

Expand All @@ -268,7 +270,7 @@ func init() {
if err != nil {
config.Webhook.Address = ""
} else {
enabledOutputsText += "Webhook "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Webhook")
}
}

Expand All @@ -278,7 +280,7 @@ func init() {
if err != nil {
config.CloudEvents.Address = ""
} else {
enabledOutputsText += "CloudEvents "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "CloudEvents")
}
}

Expand All @@ -290,7 +292,7 @@ func init() {
config.Azure.EventHub.Namespace = ""
} else {
if config.Azure.EventHub.Name != "" {
enabledOutputsText += "EventHub "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "EventHub")
}
}
}
Expand All @@ -302,7 +304,7 @@ func init() {
config.GCP.PubSub.ProjectID = ""
config.GCP.PubSub.Topic = ""
} else {
enabledOutputsText += "GCPPubSub "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "GCPPubSub")
}
}

Expand All @@ -312,7 +314,7 @@ func init() {
if err != nil {
config.Googlechat.WebhookURL = ""
} else {
enabledOutputsText += "Google Chat "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Google Chat")
}
}

Expand All @@ -322,7 +324,7 @@ func init() {
if err != nil {
config.Kafka.HostPort = ""
} else {
enabledOutputsText += "Kafka "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Kafka")
}
}

Expand All @@ -333,7 +335,7 @@ func init() {
config.Pagerduty.APIKey = ""
config.Pagerduty.Service = ""
} else {
enabledOutputsText += "Pagerduty "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Pagerduty")
}
}

Expand All @@ -345,11 +347,21 @@ func init() {
config.Kubeless.Namespace = ""
config.Kubeless.Function = ""
} else {
enabledOutputsText += "Kubeless "
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Kubeless")
}
}

log.Printf("%v\n", enabledOutputsText)
if config.WebUI.URL != "" {
var err error
webUIClient, err = outputs.NewClient("WebUI", config.WebUI.URL, config, stats, promStats, statsdClient, dogstatsdClient)
if err != nil {
config.WebUI.URL = ""
} else {
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "WebUI")
}
}

log.Printf("[INFO] : Enabled Outputs : %s\n", outputs.EnabledOutputs)
}

func main() {
Expand Down
3 changes: 3 additions & 0 deletions outputs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ var ErrTooManyRequest = errors.New("Exceeding post rate limit")
// ErrClientCreation is returned if client can't be created
var ErrClientCreation = errors.New("Client creation Error")

// EnabledOutputs list all enabled outputs
var EnabledOutputs []string

// Client communicates with the different API.
type Client struct {
OutputType string
Expand Down
Loading