diff --git a/CHANGELOG.md b/CHANGELOG.md index a4e358be3..45782b176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 2.9.0 - 2019-10-04 +#### New +- New output : **Opsgenie** +#### Enhancement +- New avatar : with colors and squared +#### Fix +- Duplicated entries when events have non-string fields ([PR#38](https://github.com/falcosecurity/falcosidekick/pull/38) thanks to [@actgardner](https://github.com/actgardner)) + ## 2.8.0 - 2019-09-11 #### New - New output : **NATS** diff --git a/README.md b/README.md index d69940dc4..b55dbfdb5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Falcosidekick -![falcosidekick](https://github.com/falcosecurity/falcosidekick/raw/master/imgs/falcosidekick.png) +![falcosidekick](https://github.com/falcosecurity/falcosidekick/raw/master/imgs/falcosidekick_color.png) ![release](https://flat.badgen.net/github/release/falcosecurity/falcosidekick/latest?color=green) ![last commit](https://flat.badgen.net/github/last-commit/falcosecurity/falcosidekick) ![licence](https://flat.badgen.net/badge/license/MIT/blue) ![docker pulls](https://flat.badgen.net/docker/pulls/falcosecurity/falcosidekick?icon=docker) @@ -23,6 +23,7 @@ Currently available outputs are : * **AWS Lambda** * **AWS SQS** * **SMTP** (email) +* **Opsgenie** ## Usage @@ -133,7 +134,12 @@ smtp: # from: "" # Sender address (mandatory if SMTP output is enabled) # to: "" # comma-separated list of Recipident addresses, can't be empty (mandatory if SMTP output is enabled) # outputformat: "" # html (default), text - # minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default) + # minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default) + +opsgenie: + # apikey: "" # Opsgenie API Key, if not empty, Opsgenie output is enabled + # region: "eu" # (us|eu) region of your domain (default is 'us') + # minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default) ``` Usage : @@ -196,6 +202,9 @@ The *env vars* "match" field names in *yaml file with this structure (**take car * **SMTP_TO** : comma-separated list of Recipident addresses, can't be empty (mandatory if SMTP output is enabled) * **SMTP_OUTPUTFORMAT** : "" # html (default), text * **SMTP_MINIMUMPRIORITY** : minimum priority of event for using this output, order is `emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default)` +* **OPSGENIE_APIKEY** : Opsgenie API Key, if not empty, Opsgenie output is enabled +* **OPSGENIE_REGION** : "" # (us|eu) region of your domain (default is 'us') +* **OPSGENIE_MINIMUMPRIORITY** : minimum priority of event for using this output, order is `emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default)` ## Handlers @@ -291,6 +300,10 @@ time akey bkey ckey priority rule value (SMTP_OUTPUTFORMAT="**text**") ![smtp plaintext example](https://github.com/falcosecurity/falcosidekick/raw/master/imgs/smtp_plaintext.png) +### Opsgenie + +![opsgenie example](https://github.com/falcosecurity/falcosidekick/raw/master/imgs/opsgenie.png) + ## Development ### Build diff --git a/config.go b/config.go index 3d9c1f5e7..4ad45550f 100644 --- a/config.go +++ b/config.go @@ -25,11 +25,11 @@ func getConfig() *types.Configuration { v.SetDefault("Debug", false) v.SetDefault("Slack.WebhookURL", "") v.SetDefault("Slack.Footer", "https://github.com/falcosecurity/falcosidekick") - v.SetDefault("Slack.Icon", "https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick.png") + v.SetDefault("Slack.Icon", "https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick_color.png") v.SetDefault("Slack.OutputFormat", "all") v.SetDefault("Slack.MinimumPriority", "") v.SetDefault("Teams.WebhookURL", "") - v.SetDefault("Teams.ActivityImage", "https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick.png") + v.SetDefault("Teams.ActivityImage", "https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick_color.png") v.SetDefault("Teams.OutputFormat", "all") v.SetDefault("Teams.MinimumPriority", "") v.SetDefault("Datadog.APIKey", "") @@ -64,7 +64,9 @@ func getConfig() *types.Configuration { v.SetDefault("SMTP.To", "") v.SetDefault("SMTP.OutputFormat", "html") v.SetDefault("SMTP.MinimumPriority", "") - v.SetDefault("AWS.SQS.MinimumPriority", "") + v.SetDefault("Opsgenie.Region", "us") + v.SetDefault("Opsgenie.APIKey", "") + v.SetDefault("Opsgenie.MinimumPriority", "") v.SetDefault("Customfields", map[string]string{}) v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) @@ -99,6 +101,7 @@ func getConfig() *types.Configuration { } if match, _ := regexp.MatchString("(?i)(emergency|alert|critical|error|warning|notice|informationnal|debug)", c.Slack.MinimumPriority); !match { c.Slack.MinimumPriority = "" + c.Teams.MinimumPriority = "" } return c diff --git a/config_example.yaml b/config_example.yaml index 621cf847b..34580f2c3 100644 --- a/config_example.yaml +++ b/config_example.yaml @@ -66,4 +66,9 @@ smtp: # from: "" # Sender address (mandatory if SMTP output is enabled) # to: "" # comma-separated list of Recipident addresses, can't be empty (mandatory if SMTP output is enabled) # outputformat: "" # html (default), text + # minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default) + +opsgenie: + # apikey: "" # Opsgenie API Key, if not empty, Opsgenie output is enabled + # region: "eu" # (us|eu) region of your domain # minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informationnal|debug or "" (default) \ No newline at end of file diff --git a/deploy/helm/falcosidekick/Chart.yaml b/deploy/helm/falcosidekick/Chart.yaml index 12e66229d..170dd2dcf 100644 --- a/deploy/helm/falcosidekick/Chart.yaml +++ b/deploy/helm/falcosidekick/Chart.yaml @@ -1,9 +1,9 @@ apiVersion: v1 -appVersion: "2.8.0" +appVersion: "2.9.0" description: A simple daemon to help you with falco's outputs icon: https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick.png name: falcosidekick -version: 0.1.6 +version: 0.1.7 maintainers: - name: SweetOps - name: Issif diff --git a/deploy/helm/falcosidekick/templates/deployment.yaml b/deploy/helm/falcosidekick/templates/deployment.yaml index a50a4d33d..61128743d 100644 --- a/deploy/helm/falcosidekick/templates/deployment.yaml +++ b/deploy/helm/falcosidekick/templates/deployment.yaml @@ -180,6 +180,17 @@ spec: key: smtp-password {{- end }} {{- end }} + {{- if .Values.opsgenie.datadog.apikey }} + - name: OPSGENIE_APIKEY + valueFrom: + secretKeyRef: + name: {{ include "falcosidekick.fullname" . }} + key: opsgenie-apikey + - name: OPSGENIE_REGION + value: {{ .Values.config.opsgenie.region | quote }} + - name: OPSGENIE_MINIMUMPRIORITY + value: {{ .Values.config.opsgenie.minimumpriority | quote }} + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} diff --git a/deploy/helm/falcosidekick/templates/secrets.yaml b/deploy/helm/falcosidekick/templates/secrets.yaml index d80329b15..0e80bba02 100644 --- a/deploy/helm/falcosidekick/templates/secrets.yaml +++ b/deploy/helm/falcosidekick/templates/secrets.yaml @@ -30,3 +30,6 @@ data: smtp-user: "{{ .Values.config.smtp.user | b64enc }}" smtp-password: "{{ .Values.config.smtp.password | b64enc }}" {{- end }} + {{- if .Values.config.opsgenie.apikey }} + opsgenie-apikey: "{{ .Values.config.opsgenie.apikey | b64enc }}" + {{- end }} diff --git a/deploy/helm/falcosidekick/values.yaml b/deploy/helm/falcosidekick/values.yaml index 3530a6721..58b52417f 100644 --- a/deploy/helm/falcosidekick/values.yaml +++ b/deploy/helm/falcosidekick/values.yaml @@ -6,7 +6,7 @@ replicaCount: 1 image: repository: falcosecurity/falcosidekick - tag: 2.7.2 + tag: 2.9.0 pullPolicy: IfNotPresent nameOverride: "" @@ -80,6 +80,11 @@ config: outputformat: "html" minimumpriority: "" + opsgenie: + aipkey: "" + region: "" + minimumpriority: "" + service: type: ClusterIP port: 2801 diff --git a/handlers.go b/handlers.go index cbb0fd4e2..6212daf63 100644 --- a/handlers.go +++ b/handlers.go @@ -98,6 +98,9 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { if config.SMTP.HostPort != "" && (priorityMap[strings.ToLower(falcopayload.Priority)] >= priorityMap[strings.ToLower(config.SMTP.MinimumPriority)] || falcopayload.Rule == "Test rule") { go smtpClient.SendMail(falcopayload) } + if config.Opsgenie.APIKey != "" && (priorityMap[strings.ToLower(falcopayload.Priority)] >= priorityMap[strings.ToLower(config.Opsgenie.MinimumPriority)] || falcopayload.Rule == "Test rule") { + go opsgenieClient.OpsgeniePost(falcopayload) + } } // pingHandler is a simple handler to test if daemon is UP. diff --git a/imgs/falcosidekick_color.png b/imgs/falcosidekick_color.png new file mode 100644 index 000000000..d64ab4ef6 Binary files /dev/null and b/imgs/falcosidekick_color.png differ diff --git a/imgs/falcosidekick_color.svg b/imgs/falcosidekick_color.svg new file mode 100644 index 000000000..0c77ad4b8 --- /dev/null +++ b/imgs/falcosidekick_color.svg @@ -0,0 +1,457 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imgs/opsgenie.png b/imgs/opsgenie.png new file mode 100644 index 000000000..b78d6ca12 Binary files /dev/null and b/imgs/opsgenie.png differ diff --git a/main.go b/main.go index 422c6fb8c..f75aeb8b9 100644 --- a/main.go +++ b/main.go @@ -4,13 +4,14 @@ import ( "log" "net/http" "strconv" + "strings" "github.com/falcosecurity/falcosidekick/outputs" "github.com/falcosecurity/falcosidekick/types" ) // Globale variables -var slackClient, teamsClient, datadogClient, alertmanagerClient, elasticsearchClient, influxdbClient, lokiClient, natsClient, awsClient, smtpClient *outputs.Client +var slackClient, teamsClient, datadogClient, alertmanagerClient, elasticsearchClient, influxdbClient, lokiClient, natsClient, awsClient, smtpClient, opsgenieClient *outputs.Client var config *types.Configuration var stats *types.Statistics @@ -122,6 +123,19 @@ func init() { enabledOutputsText += "SMTP " } } + if config.Opsgenie.APIKey != "" { + var err error + url := "https://api.opsgenie.com/v2/alerts" + if strings.ToLower(config.Opsgenie.Region) == "eu" { + url = "https://api.eu.opsgenie.com/v2/alerts" + } + opsgenieClient, err = outputs.NewClient("Opsgenie", url, config, stats) + if err != nil { + config.Opsgenie.APIKey = "" + } else { + enabledOutputsText += "Opsgenie " + } + } log.Printf("%v\n", enabledOutputsText) } diff --git a/outputs/alertmanager_test.go b/outputs/alertmanager_test.go index 6fc991ccd..db7ae4c6f 100644 --- a/outputs/alertmanager_test.go +++ b/outputs/alertmanager_test.go @@ -9,7 +9,7 @@ import ( ) func TestNewAlertmanagerPayload(t *testing.T) { - expectedOutput := `[{"labels":{"proc_name":"falcosidekick","rule":"Test rule","source":"falco","user_name":"falcosidekick"},"annotations":{"info":"This is a test from falcosidekick","summary":"Test rule"}}]` + expectedOutput := `[{"labels":{"proc_name":"falcosidekick","rule":"Test rule","source":"falco"},"annotations":{"info":"This is a test from falcosidekick","summary":"Test rule"}}]` var f types.FalcoPayload json.Unmarshal([]byte(falcoTestInput), &f) diff --git a/outputs/client.go b/outputs/client.go index d3470fd76..52138a262 100644 --- a/outputs/client.go +++ b/outputs/client.go @@ -83,11 +83,25 @@ func (c *Client) Post(payload interface{}) error { log.Printf("[DEBUG] : %v payload : %v\n", c.OutputType, body) } + client := &http.Client{} + + req, err := http.NewRequest("POST", c.EndpointURL.String(), body) + if err != nil { + log.Printf("[ERROR] : %v - %v\n", c.OutputType, err.Error()) + } contentType := "application/json; charset=utf-8" if c.OutputType == "Loki" { contentType = "application/json" } - resp, err := http.Post(c.EndpointURL.String(), contentType, body) + req.Header.Add("Content-Type", contentType) + + if c.OutputType == "Opsgenie" { + req.Header.Add("Authorization", "GenieKey "+c.Config.Opsgenie.APIKey) + } + + req.Header.Add("User-Agent", "Falcosidekick") + + resp, err := client.Do(req) if err != nil { log.Printf("[ERROR] : %v - %v\n", c.OutputType, err.Error()) } diff --git a/outputs/client_test.go b/outputs/client_test.go index eeaa9672e..5aa774ed4 100644 --- a/outputs/client_test.go +++ b/outputs/client_test.go @@ -11,7 +11,7 @@ import ( "github.com/falcosecurity/falcosidekick/types" ) -var falcoTestInput = `{"output":"This is a test from falcosidekick","priority":"Debug","rule":"Test rule", "time":"2001-01-01T01:10:00Z","output_fields": {"proc.name":"falcosidekick","user.name":"falcosidekick", "proc.tty": 1234}}` +var falcoTestInput = `{"output":"This is a test from falcosidekick","priority":"Debug","rule":"Test rule", "time":"2001-01-01T01:10:00Z","output_fields": {"proc.name":"falcosidekick", "proc.tty": 1234}}` func TestNewClient(t *testing.T) { u, _ := url.Parse("http://localhost") diff --git a/outputs/datadog.go b/outputs/datadog.go index 61518bb33..de19488d5 100644 --- a/outputs/datadog.go +++ b/outputs/datadog.go @@ -27,6 +27,8 @@ func newDatadogPayload(falcopayload types.FalcoPayload) datadogPayload { switch j.(type) { case string: tags = append(tags, i+":"+j.(string)) + default: + continue } } d.Tags = tags diff --git a/outputs/datadog_test.go b/outputs/datadog_test.go index 3beb3bdf5..7af24310f 100644 --- a/outputs/datadog_test.go +++ b/outputs/datadog_test.go @@ -9,7 +9,7 @@ import ( ) func TestNewDatadogPayload(t *testing.T) { - expectedOutput := `{"title":"Test rule","text":"This is a test from falcosidekick","alert_type":"info","source_type_name":"falco","tags":["proc.name:falcosidekick","user.name:falcosidekick"]}` + expectedOutput := `{"title":"Test rule","text":"This is a test from falcosidekick","alert_type":"info","source_type_name":"falco","tags":["proc.name:falcosidekick"]}` var f types.FalcoPayload json.Unmarshal([]byte(falcoTestInput), &f) diff --git a/outputs/influxdb.go b/outputs/influxdb.go index 3a27e846d..819d15db2 100644 --- a/outputs/influxdb.go +++ b/outputs/influxdb.go @@ -17,6 +17,8 @@ func newInfluxdbPayload(falcopayload types.FalcoPayload, config *types.Configura switch j.(type) { case string: s += "," + i + "=" + strings.Replace(j.(string), " ", "_", -1) + default: + continue } } diff --git a/outputs/influxdb_test.go b/outputs/influxdb_test.go index e84b2b32a..2f515acad 100644 --- a/outputs/influxdb_test.go +++ b/outputs/influxdb_test.go @@ -8,7 +8,7 @@ import ( ) func TestNewInfluxdbPayload(t *testing.T) { - expectedOutput := `"events,rule=Test_rule,priority=Debug,proc.name=falcosidekick,user.name=falcosidekick value=\"This is a test from falcosidekick\""` + expectedOutput := `"events,rule=Test_rule,priority=Debug,proc.name=falcosidekick value=\"This is a test from falcosidekick\""` var f types.FalcoPayload json.Unmarshal([]byte(falcoTestInput), &f) diff --git a/outputs/loki.go b/outputs/loki.go index 1ea04f478..4db99b357 100644 --- a/outputs/loki.go +++ b/outputs/loki.go @@ -30,6 +30,8 @@ func newLokiPayload(falcopayload types.FalcoPayload, config *types.Configuration switch j.(type) { case string: s += strings.Replace(strings.Replace(strings.Replace(i, ".", "", -1), "]", "", -1), "[", "", -1) + "=\"" + j.(string) + "\"," + default: + continue } } s += "rule=\"" + falcopayload.Rule + "\"," diff --git a/outputs/loki_test.go b/outputs/loki_test.go new file mode 100644 index 000000000..79c9676bf --- /dev/null +++ b/outputs/loki_test.go @@ -0,0 +1,32 @@ +package outputs + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/falcosecurity/falcosidekick/types" +) + +func TestNewLokiPayload(t *testing.T) { + expectedOutput := lokiPayload{ + Streams: []lokiStream{ + lokiStream{ + Labels: "{procname=\"falcosidekick\",rule=\"Test rule\",priority=\"Debug\"}", + Entries: []lokiEntry{ + lokiEntry{ + Ts: "2001-01-01T01:10:00Z", + Line: "This is a test from falcosidekick", + }, + }, + }, + }, + } + + var f types.FalcoPayload + json.Unmarshal([]byte(falcoTestInput), &f) + output := newLokiPayload(f, &types.Configuration{}) + if !reflect.DeepEqual(output, expectedOutput) { + t.Fatalf("\nexpected payload: \n%#v\ngot: \n%#v\n", expectedOutput, output) + } +} diff --git a/outputs/opsgenie.go b/outputs/opsgenie.go new file mode 100644 index 000000000..a73af28cb --- /dev/null +++ b/outputs/opsgenie.go @@ -0,0 +1,59 @@ +package outputs + +import ( + "github.com/falcosecurity/falcosidekick/types" + "strings" +) + +type opsgeniePayload struct { + Message string `json:"message"` + Entity string `json:"entity,omitempty"` + Description string `json:"description,omitempty"` + Details map[string]string `json:"details,omitempty"` + Priority string `json:"priority,omitempty"` +} + +func newOpsgeniePayload(falcopayload types.FalcoPayload, config *types.Configuration) opsgeniePayload { + details := make(map[string]string, len(falcopayload.OutputFields)) + for i, j := range falcopayload.OutputFields { + switch j.(type) { + case string: + details[i] = j.(string) + default: + continue + } + } + + var prio string + switch strings.ToLower(falcopayload.Priority) { + case "emergency", "alert": + prio = "P1" + case "critical": + prio = "P2" + case "error": + prio = "P3" + case "warning": + prio = "P4" + default: + prio = "P5" + } + + return opsgeniePayload{ + Message: falcopayload.Output, + Entity: "Falcosidekick", + Description: falcopayload.Rule, + Details: details, + Priority: prio, + } +} + +// OpsgeniePost posts event to OpsGenie +func (c *Client) OpsgeniePost(falcopayload types.FalcoPayload) { + err := c.Post(newOpsgeniePayload(falcopayload, c.Config)) + if err != nil { + c.Stats.Opsgenie.Add("error", 1) + } else { + c.Stats.Opsgenie.Add("sent", 1) + } + c.Stats.Opsgenie.Add("total", 1) +} diff --git a/outputs/opsgenie_test.go b/outputs/opsgenie_test.go new file mode 100644 index 000000000..f9b48f0bb --- /dev/null +++ b/outputs/opsgenie_test.go @@ -0,0 +1,28 @@ +package outputs + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/falcosecurity/falcosidekick/types" +) + +func TestNewOpsgeniePayload(t *testing.T) { + expectedOutput := opsgeniePayload{ + Message: "This is a test from falcosidekick", + Entity: "Falcosidekick", + Description: "Test rule", + Details: map[string]string{ + "proc.name": "falcosidekick", + }, + Priority: "P5", + } + + var f types.FalcoPayload + json.Unmarshal([]byte(falcoTestInput), &f) + output := newOpsgeniePayload(f, &types.Configuration{}) + if !reflect.DeepEqual(output, expectedOutput) { + t.Fatalf("\nexpected payload: \n%#v\ngot: \n%#v\n", expectedOutput, output) + } +} diff --git a/outputs/slack.go b/outputs/slack.go index ccedf017b..884d9722f 100644 --- a/outputs/slack.go +++ b/outputs/slack.go @@ -110,7 +110,7 @@ func newSlackPayload(falcopayload types.FalcoPayload, config *types.Configuratio } s := slackPayload{ - Username: "Falco Sidekick", + Username: "Falcosidekick", IconURL: iconURL, Attachments: attachments} diff --git a/outputs/slack_test.go b/outputs/slack_test.go index 15ae1e407..230277360 100644 --- a/outputs/slack_test.go +++ b/outputs/slack_test.go @@ -10,7 +10,7 @@ import ( func TestNewSlackPayload(t *testing.T) { expectedOutput := slackPayload{ - Username: "Falco Sidekick", + Username: "Falcosidekick", IconURL: "https://raw.githubusercontent.com/falcosecurity/falcosidekick/master/imgs/falcosidekick.png", Attachments: []slackAttachment{ slackAttachment{ @@ -24,11 +24,6 @@ func TestNewSlackPayload(t *testing.T) { Value: "falcosidekick", Short: true, }, - slackAttachmentField{ - Title: "user.name", - Value: "falcosidekick", - Short: true, - }, slackAttachmentField{ Title: "rule", Value: "Test rule", diff --git a/outputs/teams_test.go b/outputs/teams_test.go index 304243cdf..840b44761 100644 --- a/outputs/teams_test.go +++ b/outputs/teams_test.go @@ -24,10 +24,6 @@ func TestNewTeamsPayload(t *testing.T) { Name: "proc.name", Value: "falcosidekick", }, - teamsFact{ - Name: "user.name", - Value: "falcosidekick", - }, teamsFact{ Name: "rule", Value: "Test rule", diff --git a/stats.go b/stats.go index c6f273e45..a65a54ffc 100644 --- a/stats.go +++ b/stats.go @@ -20,6 +20,7 @@ func getInitStats() *types.Statistics { AWSLambda: expvar.NewMap("outputs.awslambda"), AWSSQS: expvar.NewMap("outputs.awssqs"), SMTP: expvar.NewMap("outputs.smtp"), + Opsgenie: expvar.NewMap("outputs.opsgenie"), } stats.Requests.Add("total", 0) stats.Requests.Add("rejected", 0) @@ -57,6 +58,9 @@ func getInitStats() *types.Statistics { stats.SMTP.Add("total", 0) stats.SMTP.Add("error", 0) stats.SMTP.Add("sent", 0) + stats.Opsgenie.Add("total", 0) + stats.Opsgenie.Add("error", 0) + stats.Opsgenie.Add("sent", 0) return stats } diff --git a/types/types.go b/types/types.go index 2cb35f80b..994718120 100644 --- a/types/types.go +++ b/types/types.go @@ -28,6 +28,7 @@ type Configuration struct { Nats natsOutputConfig AWS awsOutputConfig SMTP smtpOutputConfig + Opsgenie opsgenieOutputConfig Customfields map[string]string } @@ -112,6 +113,12 @@ type smtpOutputConfig struct { MinimumPriority string } +type opsgenieOutputConfig struct { + Region string + APIKey string + MinimumPriority string +} + // Statistics is a struct to store stastics type Statistics struct { Requests *expvar.Map @@ -126,4 +133,5 @@ type Statistics struct { AWSLambda *expvar.Map AWSSQS *expvar.Map SMTP *expvar.Map + Opsgenie *expvar.Map }