From 71c9f67ac00aa5e09afeab58c9ee14c09267e8b4 Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Tue, 30 Jan 2024 18:58:23 +0100 Subject: [PATCH] add new notifier elasticsearch Signed-off-by: Thomas Labarussias --- README.md | 32 +++-- actionners/actionners.go | 28 ++-- actionners/kubernetes/exec/exec.go | 2 +- actionners/kubernetes/labelize/labelize.go | 2 +- actionners/kubernetes/log/log.go | 2 +- .../kubernetes/networkpolicy/networkpolicy.go | 2 +- actionners/kubernetes/script/script.go | 2 +- actionners/kubernetes/terminate/terminate.go | 2 +- notifiers/elasticsearch/elasticsearch.go | 69 ++++++++++ notifiers/elasticsearch/mapping.go | 122 ++++++++++++++++++ notifiers/loki/loki.go | 37 ++++-- notifiers/notifiers.go | 30 +++-- notifiers/slack/slack.go | 39 +++--- notifiers/smtp/smtp.go | 43 +++--- notifiers/webhook/webhook.go | 29 +++-- utils/utils.go | 2 +- 16 files changed, 343 insertions(+), 100 deletions(-) create mode 100644 notifiers/elasticsearch/elasticsearch.go create mode 100644 notifiers/elasticsearch/mapping.go diff --git a/README.md b/README.md index 53d2fbc3..67850e66 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ - [K8s Events](#k8s-events) - [Slack](#slack) - [Loki](#loki) + - [Elasticsearch](#elasticsearch) - [SMTP](#smtp) - [Webhook](#webhook) - [Configuration](#configuration) @@ -154,23 +155,34 @@ Results: | Setting | Default | Description | | ---------------- | ------- | ---------------------------- | -| `host_port` | n/a | http://{domain or ip}:{port} | +| `url` | n/a | http://{domain or ip}:{port} | | `user` | n/a | User for Grafana Logs | | `api_key` | n/a | API Key for Grafana Logs | | `tenant` | n/a | Add the Tenant header | | `custom_headers` | n/a | Custom HTTP Headers | +### Elasticsearch + +| Setting | Default | Description | +| ---------------- | ------------- | --------------------------------------------------------------------------------- | +| `host_port` | n/a | http://{domain or ip}:{port} | +| `user` | n/a | User for Grafana Logs | +| `password` | n/a | Password for Grafana Logs | +| `index` | `falco-talon` | Elasticsearch index | +| `suffix` | `daily` | Date suffix for index rotation : `daily` (default), `monthly`, `annually`, `none` | +| `custom_headers` | n/a | Custom HTTP Headers | + ### SMTP -| Setting | Default | Description | | -| ----------- | ------- | ------------------------------------- | ------ | -| `host_port` | n/a | Host:Port of SMTP server | | -| `user` | n/a | User for SMTP | | -| `password` | n/a | Password for SMTP | | -| `from` | n/a | From | | -| `to` | n/a | To (comma separated list of adresses) | | -| `format` | `html` | Format of the email (`text | html`) | -| `tls` | `false` | Use TLS connection | | +| Setting | Default | Description | +| ----------- | ------- | ------------------------------------- | +| `host_port` | n/a | Host:Port of SMTP server | +| `user` | n/a | User for SMTP | +| `password` | n/a | Password for SMTP | +| `from` | n/a | From | +| `to` | n/a | To (comma separated list of adresses) | +| `format` | `html` | Format of the email (`text`, `html`) | +| `tls` | `false` | Use TLS connection | Results: diff --git a/actionners/actionners.go b/actionners/actionners.go index 6670802e..115db02d 100644 --- a/actionners/actionners.go +++ b/actionners/actionners.go @@ -31,7 +31,7 @@ type checkActionner func(event *events.Event) error type Actionners []*Actionner -var defaultActionners *Actionners +var availableActionners *Actionners var enabledActionners *Actionners const ( @@ -40,14 +40,14 @@ const ( ) func init() { - defaultActionners = new(Actionners) - defaultActionners = GetDefaultActionners() + availableActionners = new(Actionners) + availableActionners = GetDefaultActionners() enabledActionners = new(Actionners) } func GetDefaultActionners() *Actionners { - if len(*defaultActionners) == 0 { - defaultActionners.Add( + if len(*availableActionners) == 0 { + availableActionners.Add( &Actionner{ Category: "kubernetes", Name: "terminate", @@ -55,7 +55,7 @@ func GetDefaultActionners() *Actionners { Init: kubernetes.Init, Checks: []checkActionner{kubernetes.CheckPodExist}, CheckParameters: terminate.CheckParameters, - Action: terminate.Terminate, + Action: terminate.Action, }, &Actionner{ Category: "kubernetes", @@ -64,7 +64,7 @@ func GetDefaultActionners() *Actionners { Init: kubernetes.Init, Checks: []checkActionner{kubernetes.CheckPodExist}, CheckParameters: labelize.CheckParameters, - Action: labelize.Labelize, + Action: labelize.Action, }, &Actionner{ Category: "kubernetes", @@ -75,7 +75,7 @@ func GetDefaultActionners() *Actionners { kubernetes.CheckPodExist, }, CheckParameters: networkpolicy.CheckParameters, - Action: networkpolicy.NetworkPolicy, + Action: networkpolicy.Action, }, &Actionner{ Category: "kubernetes", @@ -86,7 +86,7 @@ func GetDefaultActionners() *Actionners { kubernetes.CheckPodExist, }, CheckParameters: exec.CheckParameters, - Action: exec.Exec, + Action: exec.Action, }, &Actionner{ Category: "kubernetes", @@ -97,7 +97,7 @@ func GetDefaultActionners() *Actionners { kubernetes.CheckPodExist, }, CheckParameters: script.CheckParameters, - Action: script.Script, + Action: script.Action, }, &Actionner{ Category: "kubernetes", @@ -108,12 +108,12 @@ func GetDefaultActionners() *Actionners { kubernetes.CheckPodExist, }, CheckParameters: logActionner.CheckParameters, - Action: logActionner.Log, + Action: logActionner.Action, }, ) } - return defaultActionners + return availableActionners } func Init() error { @@ -131,7 +131,7 @@ func Init() error { } for category := range categories { - for _, actionner := range *defaultActionners { + for _, actionner := range *availableActionners { if category == actionner.Category { if actionner.Init != nil { utils.PrintLog("info", config.LogFormat, utils.LogLine{Message: "init", ActionnerCategory: actionner.Category}) @@ -147,7 +147,7 @@ func Init() error { } for i := range enabledCategories { - for _, j := range *defaultActionners { + for _, j := range *availableActionners { if i == j.Category { enabledActionners.Add(j) } diff --git a/actionners/kubernetes/exec/exec.go b/actionners/kubernetes/exec/exec.go index 4798cce9..ae40eaaf 100644 --- a/actionners/kubernetes/exec/exec.go +++ b/actionners/kubernetes/exec/exec.go @@ -16,7 +16,7 @@ import ( "github.com/Issif/falco-talon/utils" ) -var Exec = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { +var Action = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { pod := event.GetPodName() namespace := event.GetNamespaceName() diff --git a/actionners/kubernetes/labelize/labelize.go b/actionners/kubernetes/labelize/labelize.go index 0c395332..1c0bb401 100644 --- a/actionners/kubernetes/labelize/labelize.go +++ b/actionners/kubernetes/labelize/labelize.go @@ -25,7 +25,7 @@ const ( metadataLabels = "/metadata/labels/" ) -var Labelize = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { +var Action = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { pod := event.GetPodName() namespace := event.GetNamespaceName() diff --git a/actionners/kubernetes/log/log.go b/actionners/kubernetes/log/log.go index 8d8d7418..11fffe9c 100644 --- a/actionners/kubernetes/log/log.go +++ b/actionners/kubernetes/log/log.go @@ -14,7 +14,7 @@ import ( "github.com/Issif/falco-talon/utils" ) -var Log = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { +var Action = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { pod := event.GetPodName() namespace := event.GetNamespaceName() diff --git a/actionners/kubernetes/networkpolicy/networkpolicy.go b/actionners/kubernetes/networkpolicy/networkpolicy.go index 40c3bb27..5d7f43b2 100644 --- a/actionners/kubernetes/networkpolicy/networkpolicy.go +++ b/actionners/kubernetes/networkpolicy/networkpolicy.go @@ -16,7 +16,7 @@ import ( "github.com/Issif/falco-talon/utils" ) -var NetworkPolicy = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { +var Action = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { podName := event.GetPodName() namespace := event.GetNamespaceName() diff --git a/actionners/kubernetes/script/script.go b/actionners/kubernetes/script/script.go index edb10a4e..ba1838b8 100644 --- a/actionners/kubernetes/script/script.go +++ b/actionners/kubernetes/script/script.go @@ -18,7 +18,7 @@ import ( "github.com/Issif/falco-talon/utils" ) -var Script = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { +var Action = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { pod := event.GetPodName() namespace := event.GetNamespaceName() diff --git a/actionners/kubernetes/terminate/terminate.go b/actionners/kubernetes/terminate/terminate.go index f44cf671..b56ee119 100644 --- a/actionners/kubernetes/terminate/terminate.go +++ b/actionners/kubernetes/terminate/terminate.go @@ -15,7 +15,7 @@ import ( "github.com/Issif/falco-talon/utils" ) -var Terminate = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { +var Action = func(rule *rules.Rule, action *rules.Action, event *events.Event) (utils.LogLine, error) { podName := event.GetPodName() namespace := event.GetNamespaceName() diff --git a/notifiers/elasticsearch/elasticsearch.go b/notifiers/elasticsearch/elasticsearch.go new file mode 100644 index 00000000..fe81c393 --- /dev/null +++ b/notifiers/elasticsearch/elasticsearch.go @@ -0,0 +1,69 @@ +package elasticsearch + +import ( + "errors" + "time" + + "github.com/Issif/falco-talon/notifiers/http" + "github.com/Issif/falco-talon/utils" +) + +type Settings struct { + CustomHeaders map[string]string `field:"custom_headers"` + URL string `field:"url"` + User string `field:"user"` + Password string `field:"password"` + Suffix string `field:"suffix" default:"daily"` + Index string `field:"index" default:"falco-talon"` +} + +const docType string = "/_doc" + +var settings *Settings + +var Init = func(fields map[string]interface{}) error { + settings = new(Settings) + settings = utils.SetFields(settings, fields).(*Settings) + if err := checkSettings(settings); err != nil { + return err + } + return nil +} + +var Notify = func(log utils.LogLine) error { + + client := http.DefaultClient() + + current := time.Now() + var u string + switch settings.Suffix { + case "none": + u = settings.URL + "/" + settings.Index + docType + case "monthly": + u = settings.URL + "/" + settings.Index + "-" + current.Format("2006.01") + docType + case "annually": + u = settings.URL + "/" + settings.Index + "-" + current.Format("2006") + docType + default: + u = settings.URL + "/" + settings.Index + "-" + current.Format("2006.01.02") + docType + } + + log.Time = time.Now().Format(time.RFC3339) + + if err := client.Post(u, log); err != nil { + return err + } + + return nil +} + +func checkSettings(settings *Settings) error { + if settings.URL == "" { + return errors.New("wrong `url` setting") + } + + if err := http.CheckURL(settings.URL); err != nil { + return err + } + + return nil +} diff --git a/notifiers/elasticsearch/mapping.go b/notifiers/elasticsearch/mapping.go new file mode 100644 index 00000000..bd65d678 --- /dev/null +++ b/notifiers/elasticsearch/mapping.go @@ -0,0 +1,122 @@ +package elasticsearch + +var mapping = ` +{ + "mappings": { + "properties": { + "action": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + }, + "actionner": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + }, + "error": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "event": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 1024 + } + } + }, + "message": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + }, + "output": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 + } + } + }, + "result": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 + } + } + }, + "objects": { + "properties": { + "Namespace": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + }, + "Pod": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + } + } + }, + "rule": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + }, + "status": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 128 + } + } + }, + "trace_id": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + } + } + } +} +` diff --git a/notifiers/loki/loki.go b/notifiers/loki/loki.go index 300b7db5..7a160d9a 100644 --- a/notifiers/loki/loki.go +++ b/notifiers/loki/loki.go @@ -10,7 +10,7 @@ import ( "github.com/Issif/falco-talon/utils" ) -type Configuration struct { +type Settings struct { CustomHeaders map[string]string `field:"custom_headers"` HostPort string `field:"host_port"` User string `field:"user"` @@ -31,40 +31,51 @@ type Value []string const contentType = "application/json" -var lokiconfig *Configuration +var settings *Settings var Init = func(fields map[string]interface{}) error { - lokiconfig = new(Configuration) - lokiconfig = utils.SetFields(lokiconfig, fields).(*Configuration) + settings = new(Settings) + settings = utils.SetFields(settings, fields).(*Settings) + if err := checkSettings(settings); err != nil { + return err + } return nil } var Notify = func(log utils.LogLine) error { - if lokiconfig.HostPort == "" { - return errors.New("wrong config") + if settings.HostPort == "" { + return errors.New("wrong `host_port` setting") } - if err := http.CheckURL(lokiconfig.HostPort); err != nil { + if err := http.CheckURL(settings.HostPort); err != nil { return err } - client := http.NewClient("", contentType, "", lokiconfig.CustomHeaders) + client := http.NewClient("", contentType, "", settings.CustomHeaders) - if lokiconfig.User != "" && lokiconfig.APIKey != "" { - client.SetBasicAuth(lokiconfig.User, lokiconfig.APIKey) + if settings.User != "" && settings.APIKey != "" { + client.SetBasicAuth(settings.User, settings.APIKey) } - if lokiconfig.Tenant != "" { - client.SetHeader("X-Scope-OrgID", lokiconfig.Tenant) + if settings.Tenant != "" { + client.SetHeader("X-Scope-OrgID", settings.Tenant) } - err := client.Post(lokiconfig.HostPort+"/loki/api/v1/push", NewPayload(log)) + err := client.Post(settings.HostPort+"/loki/api/v1/push", NewPayload(log)) if err != nil { return err } return nil } +func checkSettings(settings *Settings) error { + if settings.HostPort == "" { + return errors.New("wrong `host_port` setting") + } + + return nil +} + func NewPayload(log utils.LogLine) Payload { s := make(map[string]string) diff --git a/notifiers/notifiers.go b/notifiers/notifiers.go index db1eadc8..a87c7918 100644 --- a/notifiers/notifiers.go +++ b/notifiers/notifiers.go @@ -6,6 +6,7 @@ import ( "github.com/Issif/falco-talon/configuration" "github.com/Issif/falco-talon/internal/events" "github.com/Issif/falco-talon/internal/rules" + "github.com/Issif/falco-talon/notifiers/elasticsearch" "github.com/Issif/falco-talon/notifiers/k8sevents" "github.com/Issif/falco-talon/notifiers/loki" "github.com/Issif/falco-talon/notifiers/slack" @@ -22,18 +23,18 @@ type Notifier struct { type Notifiers []*Notifier -var notifiers *Notifiers -var defaultNotifiers *Notifiers +var enabledNotifiers *Notifiers +var availableNotifiers *Notifiers func init() { - defaultNotifiers = new(Notifiers) - defaultNotifiers = GetDefaultNotifiers() - notifiers = new(Notifiers) + availableNotifiers = new(Notifiers) + availableNotifiers = GetAvailableNotifiers() + enabledNotifiers = new(Notifiers) } -func GetDefaultNotifiers() *Notifiers { - if len(*defaultNotifiers) == 0 { - defaultNotifiers.Add( +func GetAvailableNotifiers() *Notifiers { + if len(*availableNotifiers) == 0 { + availableNotifiers.Add( &Notifier{ Name: "k8sevents", Init: nil, @@ -59,9 +60,14 @@ func GetDefaultNotifiers() *Notifiers { Init: loki.Init, Notification: loki.Notify, }, + &Notifier{ + Name: "elasticsearch", + Init: elasticsearch.Init, + Notification: elasticsearch.Notify, + }, ) } - return defaultNotifiers + return availableNotifiers } func Init() { @@ -80,7 +86,7 @@ func Init() { } for i := range specifiedNotifiers { - for _, j := range *defaultNotifiers { + for _, j := range *availableNotifiers { if strings.ToLower(i) == j.Name { if j.Init != nil { if err := j.Init(config.Notifiers[i]); err != nil { @@ -89,14 +95,14 @@ func Init() { } utils.PrintLog("info", config.LogFormat, utils.LogLine{Notifier: i, Message: "init", Status: "success"}) } - notifiers.Add(j) + enabledNotifiers.Add(j) } } } } func GetNotifiers() *Notifiers { - return notifiers + return enabledNotifiers } func Notify(rule *rules.Rule, action *rules.Action, event *events.Event, log utils.LogLine) { diff --git a/notifiers/slack/slack.go b/notifiers/slack/slack.go index 7bcb4b3d..74a70b72 100644 --- a/notifiers/slack/slack.go +++ b/notifiers/slack/slack.go @@ -20,7 +20,7 @@ const ( resultStr string = "result" ) -type Configuration struct { +type Settings struct { WebhookURL string `field:"webhook_url"` Icon string `field:"icon" default:"https://upload.wikimedia.org/wikipedia/commons/2/26/Circaetus_gallicus_claw.jpg"` Username string `field:"username" default:"Falco Talon"` @@ -51,29 +51,36 @@ type Payload struct { Attachments []Attachment `json:"attachments,omitempty"` } -var slackconfig *Configuration +var settings *Settings var Init = func(fields map[string]interface{}) error { - slackconfig = new(Configuration) - slackconfig = utils.SetFields(slackconfig, fields).(*Configuration) + settings = new(Settings) + settings = utils.SetFields(settings, fields).(*Settings) + if err := checkSettings(settings); err != nil { + return err + } return nil } var Notify = func(log utils.LogLine) error { - if slackconfig.WebhookURL == "" { - return errors.New("wrong config") - } + client := http.DefaultClient() - if err := http.CheckURL(slackconfig.WebhookURL); err != nil { + err := client.Post(settings.WebhookURL, NewPayload(log)) + if err != nil { return err } + return nil +} - client := http.DefaultClient() +func checkSettings(settings *Settings) error { + if settings.WebhookURL == "" { + return errors.New("wrong `webhook_url` setting") + } - err := client.Post(slackconfig.WebhookURL, NewPayload(log)) - if err != nil { + if err := http.CheckURL(settings.WebhookURL); err != nil { return err } + return nil } @@ -100,7 +107,7 @@ func NewPayload(log utils.LogLine) Payload { text := fmt.Sprintf("Action `%v` from rule `%v` has been %v", log.Action, log.Rule, status) - if slackconfig.Format == "short" { + if settings.Format == "short" { attachment.Text = text + fmt.Sprintf(", with %v: `%v`", resultOrError, log.Message) text = "" } else { @@ -164,8 +171,8 @@ func NewPayload(log utils.LogLine) Payload { fields = append(fields, field) } - if slackconfig.Footer != "" { - attachment.Footer = slackconfig.Footer + if settings.Footer != "" { + attachment.Footer = settings.Footer } attachment.Fallback = "" @@ -176,8 +183,8 @@ func NewPayload(log utils.LogLine) Payload { s := Payload{ Text: text, - Username: slackconfig.Username, - IconURL: slackconfig.Icon, + Username: settings.Username, + IconURL: settings.Icon, Attachments: attachments, } diff --git a/notifiers/smtp/smtp.go b/notifiers/smtp/smtp.go index 71f8880f..863d201d 100644 --- a/notifiers/smtp/smtp.go +++ b/notifiers/smtp/smtp.go @@ -29,7 +29,7 @@ const ( ignoredStr string = "ignored" ) -type Configuration struct { +type Settings struct { HostPort string `field:"host_port"` User string `field:"user"` Password string `field:"password"` @@ -49,17 +49,20 @@ type Payload struct { Date string } -var smtpconfig *Configuration +var settings *Settings var Init = func(fields map[string]interface{}) error { - smtpconfig = new(Configuration) - smtpconfig = utils.SetFields(smtpconfig, fields).(*Configuration) + settings = new(Settings) + settings = utils.SetFields(settings, fields).(*Settings) + if err := checkSettings(settings); err != nil { + return err + } return nil } var Notify = func(log utils.LogLine) error { - if smtpconfig.HostPort == "" { - return errors.New("wrong host_port") + if settings.HostPort == "" { + return errors.New("wrong `host_port` setting") } payload, err := NewPayload(log) @@ -73,6 +76,14 @@ var Notify = func(log utils.LogLine) error { return nil } +func checkSettings(settings *Settings) error { + if settings.HostPort == "" { + return errors.New("wrong `host_port` setting") + } + + return nil +} + func NewPayload(log utils.LogLine) (Payload, error) { var status string switch log.Status { @@ -85,14 +96,14 @@ func NewPayload(log utils.LogLine) (Payload, error) { } payload := Payload{ - From: fmt.Sprintf("From: %v", smtpconfig.From), - To: fmt.Sprintf("To: %v", smtpconfig.To), + From: fmt.Sprintf("From: %v", settings.From), + To: fmt.Sprintf("To: %v", settings.To), Subject: fmt.Sprintf("Subject: [falco] Action `%v` from rule `%v` has been %v", log.Action, log.Rule, status), Mime: "MIME-version: 1.0;", Date: "Date: " + time.Now().Format(rfc2822), } - if smtpconfig.Format != Text { + if settings.Format != Text { payload.Mime += "\nContent-Type: multipart/alternative; boundary=4t74weu9byeSdJTM\n\n\n--4t74weu9byeSdJTM" } @@ -111,7 +122,7 @@ func NewPayload(log utils.LogLine) (Payload, error) { return Payload{}, err } - if smtpconfig.Format == Text { + if settings.Format == Text { return payload, nil } @@ -141,16 +152,16 @@ func NewPayload(log utils.LogLine) (Payload, error) { } func Send(payload Payload) error { - to := strings.Split(strings.ReplaceAll(smtpconfig.To, " ", ""), ",") - auth := sasl.NewPlainClient("", smtpconfig.User, smtpconfig.Password) + to := strings.Split(strings.ReplaceAll(settings.To, " ", ""), ",") + auth := sasl.NewPlainClient("", settings.User, settings.Password) - smtpClient, err := gosmtp.Dial(smtpconfig.HostPort) + smtpClient, err := gosmtp.Dial(settings.HostPort) if err != nil { return err } - if smtpconfig.TLS { + if settings.TLS { tlsCfg := &tls.Config{ - ServerName: strings.Split(smtpconfig.HostPort, ":")[0], + ServerName: strings.Split(settings.HostPort, ":")[0], MinVersion: tls.VersionTLS12, } if err = smtpClient.StartTLS(tlsCfg); err != nil { @@ -162,7 +173,7 @@ func Send(payload Payload) error { if err != nil { return err } - err = smtpClient.SendMail(smtpconfig.From, to, strings.NewReader(payload.Body)) + err = smtpClient.SendMail(settings.From, to, strings.NewReader(payload.Body)) if err != nil { return err } diff --git a/notifiers/webhook/webhook.go b/notifiers/webhook/webhook.go index a35f22da..98671fe2 100644 --- a/notifiers/webhook/webhook.go +++ b/notifiers/webhook/webhook.go @@ -15,30 +15,35 @@ type Configuration struct { UserAgent string `field:"user_agent" default:"Falco-Talon"` } -var webhookConfig *Configuration +var config *Configuration var Init = func(fields map[string]interface{}) error { - webhookConfig = new(Configuration) - webhookConfig = utils.SetFields(webhookConfig, fields).(*Configuration) + config = new(Configuration) + config = utils.SetFields(config, fields).(*Configuration) return nil } -var Notify = func(log utils.LogLine) error { - if webhookConfig.URL == "" { - return errors.New("wrong config") +var CheckParameters = func(settings map[string]interface{}) error { + if settings["url"].(string) == "" { + return errors.New("wrong `url` setting") } - if err := http.CheckURL(webhookConfig.URL); err != nil { + + if err := http.CheckURL(settings["url"].(string)); err != nil { return err } + return nil +} + +var Notify = func(log utils.LogLine) error { client := http.NewClient( - webhookConfig.HTTPMethod, - webhookConfig.ContentType, - webhookConfig.UserAgent, - webhookConfig.CustomHeaders, + config.HTTPMethod, + config.ContentType, + config.UserAgent, + config.CustomHeaders, ) - err := client.Post(webhookConfig.URL, log) + err := client.Post(config.URL, log) if err != nil { return err } diff --git a/utils/utils.go b/utils/utils.go index 374811c8..cba59fa6 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -36,6 +36,7 @@ const ( ) type LogLine struct { + Time string `json:"time,omitempty"` Objects map[string]string `json:"objects,omitempty"` TraceID string `json:"trace_id,omitempty"` Rule string `json:"rule,omitempty"` @@ -54,7 +55,6 @@ type LogLine struct { } func PrintLog(level, format string, line LogLine) { - // zerolog.TimeFieldFormat = time.RFC3339 var output zerolog.ConsoleWriter var log zerolog.Logger