From 8a8d83f6841848920005639ce7c6710e70158415 Mon Sep 17 00:00:00 2001 From: Matt Berther Date: Sun, 13 Oct 2019 16:32:55 -0600 Subject: [PATCH 1/2] implement mailgun notifier --- README.md | 14 ++++++++ go.mod | 1 + go.sum | 10 ++++++ notifier.go | 3 ++ notifier/mailgun/mailgun.go | 67 +++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+) create mode 100644 notifier/mailgun/mailgun.go diff --git a/README.md b/README.md index b119c4c..590d791 100644 --- a/README.md +++ b/README.md @@ -293,6 +293,20 @@ Enable E-mail notifications with this Notifier configuration: The settings for `subject`, `smtp.port` (default to 25), `smtp.username` and `smtp.password` are optional. +#### Mailgun notifier + +Enable notifications using Mailgun with this Notifier configuration: +```js +{ + "type": "mailgun", + "apikey": "mailgun-api-key", + "domain": "mailgun-domain", + "from": "sender@example.com", + "to": "recipient@example.com" + "subject": "Custom subject line" +} +``` + ## Setting up storage on S3 The easiest way to do this is to give an IAM user these two privileges (keep the credentials secret): diff --git a/go.mod b/go.mod index 0e01477..83d9072 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/google/go-querystring v1.0.0 // indirect github.com/jmoiron/sqlx v1.2.0 github.com/lib/pq v1.3.0 + github.com/mailgun/mailgun-go/v4 v4.1.0 github.com/mattn/go-sqlite3 v2.0.3+incompatible github.com/miekg/dns v1.1.29 github.com/parnurzeal/gorequest v0.2.16 // indirect diff --git a/go.sum b/go.sum index 80b2de4..9aae369 100644 --- a/go.sum +++ b/go.sum @@ -28,10 +28,15 @@ github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad h1:zPs0fNF2Io1Qytf github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi v4.0.0+incompatible h1:SiLLEDyAkqNnw+T/uDTf3aFB9T4FTrwMpuYrgaRcnW4= +github.com/go-chi/chi v4.0.0+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -83,6 +88,10 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailgun/mailgun-go/v4 v4.1.0 h1:uLpVaYVGUn140doqoYoWscVnFis6x+0c8befRvXG6Z4= +github.com/mailgun/mailgun-go/v4 v4.1.0/go.mod h1:R9kHUQBptF4iSEjhriCQizplCDwrnDShy8w/iPiOfaM= +github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -102,6 +111,7 @@ github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmU github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/notifier.go b/notifier.go index 5f72ba5..aa17098 100644 --- a/notifier.go +++ b/notifier.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/sourcegraph/checkup/notifier/mail" + "github.com/sourcegraph/checkup/notifier/mailgun" "github.com/sourcegraph/checkup/notifier/slack" ) @@ -14,6 +15,8 @@ func notifierDecode(typeName string, config json.RawMessage) (Notifier, error) { return mail.New(config) case slack.Type: return slack.New(config) + case mailgun.Type: + return mailgun.New(config) default: return nil, fmt.Errorf(errUnknownNotifierType, typeName) } diff --git a/notifier/mailgun/mailgun.go b/notifier/mailgun/mailgun.go new file mode 100644 index 0000000..7a7fe0f --- /dev/null +++ b/notifier/mailgun/mailgun.go @@ -0,0 +1,67 @@ +package mailgun + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "time" + + mailgun "github.com/mailgun/mailgun-go/v4" + "github.com/sourcegraph/checkup/types" +) + +const Type = "mailgun" + +type Notifier struct { + APIKey string `json:"apikey"` + Domain string `json:"domain"` + From string `json:"from"` + To string `json:"to"` + Subject string `json:"subject,omitempty"` +} + +func New(config json.RawMessage) (Notifier, error) { + var notifier Notifier + err := json.Unmarshal(config, ¬ifier) + if strings.TrimSpace(notifier.Subject) == "" { + notifier.Subject = "Checkup: Service Unavailable" + } + return notifier, err +} + +func (Notifier) Type() string { + return Type +} + +func (m Notifier) Notify(results []types.Result) error { + issues := []types.Result{} + for _, result := range results { + if !result.Healthy { + issues = append(issues, result) + } + } + + if len(issues) == 0 { + return nil + } + + mg := mailgun.NewMailgun(m.Domain, m.APIKey) + msg := mg.NewMessage(m.From, m.Subject, renderMessage(issues), m.To) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + _, _, err := mg.Send(ctx, msg) + return err +} + +func renderMessage(issues []types.Result) string { + body := []string{"Checkup has detected the following issues:", "

", "") + return strings.Join(body, "\n") +} From a36a7d61e6f320f19cf1542af0ca18b64c2d6960 Mon Sep 17 00:00:00 2001 From: Matt Berther Date: Thu, 28 May 2020 13:05:46 -0600 Subject: [PATCH 2/2] implement pushover notifier --- README.md | 12 +++++++ go.mod | 1 + go.sum | 2 ++ notifier.go | 3 ++ notifier/pushover/pushover.go | 60 +++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+) create mode 100644 notifier/pushover/pushover.go diff --git a/README.md b/README.md index 590d791..e4ba53e 100644 --- a/README.md +++ b/README.md @@ -307,6 +307,18 @@ Enable notifications using Mailgun with this Notifier configuration: } ``` +#### Pushover notifier + +Enable notifications using Pushover with this Notifier configuration: +```js +{ + "type": "pushover", + "token": "API_TOKEN", + "recipient": "USER_KEY" + "subject": "Custom subject line" +} +``` + ## Setting up storage on S3 The easiest way to do this is to give an IAM user these two privileges (keep the credentials secret): diff --git a/go.mod b/go.mod index 83d9072..dead54a 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/fatih/color v1.9.0 github.com/google/go-github v17.0.0+incompatible github.com/google/go-querystring v1.0.0 // indirect + github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4 github.com/jmoiron/sqlx v1.2.0 github.com/lib/pq v1.3.0 github.com/mailgun/mailgun-go/v4 v4.1.0 diff --git a/go.sum b/go.sum index 9aae369..555f9db 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,8 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4 h1:QZVozMeLCqyMOOhA+OuqQdNXkyu4uUQEu4+mPBB5pPQ= +github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= diff --git a/notifier.go b/notifier.go index aa17098..17736bb 100644 --- a/notifier.go +++ b/notifier.go @@ -6,6 +6,7 @@ import ( "github.com/sourcegraph/checkup/notifier/mail" "github.com/sourcegraph/checkup/notifier/mailgun" + "github.com/sourcegraph/checkup/notifier/pushover" "github.com/sourcegraph/checkup/notifier/slack" ) @@ -17,6 +18,8 @@ func notifierDecode(typeName string, config json.RawMessage) (Notifier, error) { return slack.New(config) case mailgun.Type: return mailgun.New(config) + case pushover.Type: + return pushover.New(config) default: return nil, fmt.Errorf(errUnknownNotifierType, typeName) } diff --git a/notifier/pushover/pushover.go b/notifier/pushover/pushover.go new file mode 100644 index 0000000..144a1ef --- /dev/null +++ b/notifier/pushover/pushover.go @@ -0,0 +1,60 @@ +package pushover + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/gregdel/pushover" + "github.com/sourcegraph/checkup/types" +) + +const Type = "pushover" + +type Notifier struct { + Token string `json:"token"` + Recipient string `json:"recipient"` + Subject string `json:"subject,omitempty"` +} + +func New(config json.RawMessage) (Notifier, error) { + var notifier Notifier + err := json.Unmarshal(config, ¬ifier) + if strings.TrimSpace(notifier.Subject) == "" { + notifier.Subject = "Checkup: Service Unavailable" + } + return notifier, err +} + +func (Notifier) Type() string { + return Type +} + +func (p Notifier) Notify(results []types.Result) error { + issues := []types.Result{} + for _, result := range results { + if !result.Healthy { + issues = append(issues, result) + } + } + + if len(issues) == 0 { + return nil + } + + app := pushover.New(p.Token) + recipient := pushover.NewRecipient(p.Recipient) + msg := pushover.NewMessageWithTitle(renderMessage(issues), p.Subject) + + _, err := app.SendMessage(msg, recipient) + return err +} + +func renderMessage(issues []types.Result) string { + body := []string{"Checkup has detected the following issues:", "\n\n"} + for _, issue := range issues { + format := "%s - Status: %s" + body = append(body, fmt.Sprintf(format, issue.Title, issue.Status())) + } + return strings.Join(body, "\n") +}