From bbdecb204e226aa61de051d55d0dd6bafbf7562f Mon Sep 17 00:00:00 2001 From: elads Date: Wed, 27 May 2020 05:15:33 -0400 Subject: [PATCH] new microsoft teams support --- pkg/sinks/reciever.go | 5 ++++ pkg/sinks/teams.go | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 pkg/sinks/teams.go diff --git a/pkg/sinks/reciever.go b/pkg/sinks/reciever.go index 72a9417..efcfbc6 100644 --- a/pkg/sinks/reciever.go +++ b/pkg/sinks/reciever.go @@ -17,6 +17,7 @@ type ReceiverConfig struct { Kafka *KafkaConfig `yaml:"kafka"` Pubsub *PubsubConfig `yaml:"pubsub"` Opscenter *OpsCenterConfig `yaml:"opscenter"` + Teams *TeamsConfig `yaml:"teams"` } func (r *ReceiverConfig) Validate() error { @@ -77,5 +78,9 @@ func (r *ReceiverConfig) GetSink() (Sink, error) { return NewOpsCenterSink(r.Opscenter) } + if r.Teams != nil { + return NewTeamsSink(r.Teams) + } + return nil, errors.New("unknown sink") } diff --git a/pkg/sinks/teams.go b/pkg/sinks/teams.go new file mode 100644 index 0000000..9d7e04a --- /dev/null +++ b/pkg/sinks/teams.go @@ -0,0 +1,70 @@ +package sinks + +import ( + "bytes" + "fmt" + "encoding/json" + "context" + "errors" + "github.com/opsgenie/kubernetes-event-exporter/pkg/kube" + "io/ioutil" + "net/http" +) + +type TeamsConfig struct { + Endpoint string `yaml:"endpoint"` + Layout map[string]interface{} `yaml:"layout"` + Headers map[string]string `yaml:"headers"` +} + +func NewTeamsSink(cfg *TeamsConfig) (Sink, error) { + return &Teams{cfg: cfg}, nil +} + +type Teams struct { + cfg *TeamsConfig +} + +func (w *Teams) Close() { + // No-op +} + +func (w *Teams) Send(ctx context.Context, ev *kube.EnhancedEvent) error { + event, err := serializeEventWithLayout(w.cfg.Layout, ev) + if err != nil { + return err + } + + var eventData map[string]interface{} + json.Unmarshal([]byte(event), &eventData) + output := fmt.Sprintf("Event: %s \nStatus: %s \nMetadata: %s", eventData["message"], eventData["reason"], eventData["metadata"]) + + reqBody, err := json.Marshal(map[string]string{ + "summary": "event", + "text": string([]byte(output)), + }) + + req, err := http.NewRequest(http.MethodPost, w.cfg.Endpoint, bytes.NewReader(reqBody)) + if err != nil { + return err + } + req.Header.Add("Content-Type", "application/json") + for k, v := range w.cfg.Headers { + req.Header.Add(k, v) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil + } + + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + + // TODO: make this prettier please + if resp.StatusCode != http.StatusOK { + return errors.New("not 200: " + string(body)) + } + + return nil +}