From f8d88e3893aba894748dd07eca82592c1de13714 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 17 Feb 2020 22:39:43 +0100 Subject: [PATCH] Add Gotify notification client (#36) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Paul Götzinger --- .res/notif-gotify.png | Bin 0 -> 23148 bytes doc/configuration.md | 13 ++++ doc/notifications.md | 7 +++ internal/config/config.go | 4 ++ internal/config/config.test.yml | 6 ++ internal/config/config_test.go | 7 +++ internal/model/notif.go | 10 +++ internal/notif/client.go | 4 ++ internal/notif/gotify/client.go | 101 +++++++++++++++++++++++++++++++ internal/notif/webhook/client.go | 2 +- 10 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 .res/notif-gotify.png create mode 100644 internal/notif/gotify/client.go diff --git a/.res/notif-gotify.png b/.res/notif-gotify.png new file mode 100644 index 0000000000000000000000000000000000000000..136e10446b42920cfe30633323c0a6f6953f6030 GIT binary patch literal 23148 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 literal 0 HcmV?d00001 diff --git a/doc/configuration.md b/doc/configuration.md index a093252d..a64cdca7 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -49,6 +49,12 @@ notif: Content-Type: application/json Authorization: Token123456 timeout: 10 + gotify: + enable: false + endpoint: http://gotify.foo.com + token: Token123456 + priority: 1 + timeout: 10 regopts: someregistryoptions: @@ -146,6 +152,13 @@ providers: * `headers`: Map of additional headers to be sent. * `timeout`: Timeout specifies a time limit for the request to be made. (default: `10`). +* `gotify` + * `enable`: Enable gotify notification (default: `false`). + * `endpoint`: Gotify base URL (e.g. `http://gotify.foo.com`). **required** + * `token`: Application token. **required** + * `priority`: The priority of the message. + * `timeout`: Timeout specifies a time limit for the request to be made. (default: `10`). + ### regopts * `username`: Registry username. diff --git a/doc/notifications.md b/doc/notifications.md index 934cf08b..fbf7be08 100644 --- a/doc/notifications.md +++ b/doc/notifications.md @@ -1,10 +1,17 @@ # Notifications +* [Gotify](#gotify) * [Mail](#mail) * [Slack](#slack) * [Telegram](#telegram) * [Webhook](#webhook) +## Gotify + +Notifications can be sent using a [Gotify](https://gotify.net/) instance. [Follow the instructions](https://gotify.net/docs/install) to set up a Gotify server. + +![](../.res/notif-gotify.png) + ## Mail Here is an email sample if you add `mail` notification: diff --git a/internal/config/config.go b/internal/config/config.go index 0db7d95f..1270ceea 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -67,6 +67,10 @@ func Load(flags model.Flags, version string) (*Config, error) { Method: "GET", Timeout: 10, }, + Gotify: model.NotifGotify{ + Enable: false, + Timeout: 10, + }, }, } diff --git a/internal/config/config.test.yml b/internal/config/config.test.yml index c03cd6c0..3cf2594e 100644 --- a/internal/config/config.test.yml +++ b/internal/config/config.test.yml @@ -36,6 +36,12 @@ notif: Content-Type: application/json Authorization: Token123456 timeout: 10 + gotify: + enable: false + endpoint: http://gotify.foo.com + token: Token123456 + priority: 1 + timeout: 10 regopts: someregopts: diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 8744e45b..d4f59d81 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -78,6 +78,13 @@ func TestLoad(t *testing.T) { }, Timeout: 10, }, + Gotify: model.NotifGotify{ + Enable: false, + Endpoint: "http://gotify.foo.com", + Token: "Token123456", + Priority: 1, + Timeout: 10, + }, }, RegOpts: map[string]model.RegOpts{ "someregopts": { diff --git a/internal/model/notif.go b/internal/model/notif.go index 78fe826a..2539fdda 100644 --- a/internal/model/notif.go +++ b/internal/model/notif.go @@ -18,6 +18,7 @@ type Notif struct { Slack NotifSlack `yaml:"slack,omitempty"` Telegram NotifTelegram `yaml:"telegram,omitempty"` Webhook NotifWebhook `yaml:"webhook,omitempty"` + Gotify NotifGotify `yaml:"gotify,omitempty"` } // NotifMail holds mail notification configuration details @@ -56,3 +57,12 @@ type NotifWebhook struct { Headers map[string]string `yaml:"headers,omitempty"` Timeout int `yaml:"timeout,omitempty"` } + +// NotifGotify holds gotify notification configuration details +type NotifGotify struct { + Enable bool `yaml:"enable,omitempty"` + Endpoint string `yaml:"endpoint,omitempty"` + Token string `yaml:"token,omitempty"` + Priority int `yaml:"priority,omitempty"` + Timeout int `yaml:"timeout,omitempty"` +} diff --git a/internal/notif/client.go b/internal/notif/client.go index 8f17d73c..d803ec39 100644 --- a/internal/notif/client.go +++ b/internal/notif/client.go @@ -2,6 +2,7 @@ package notif import ( "github.com/crazy-max/diun/internal/model" + "github.com/crazy-max/diun/internal/notif/gotify" "github.com/crazy-max/diun/internal/notif/mail" "github.com/crazy-max/diun/internal/notif/notifier" "github.com/crazy-max/diun/internal/notif/slack" @@ -38,6 +39,9 @@ func New(config model.Notif, app model.App) (*Client, error) { if config.Webhook.Enable { c.notifiers = append(c.notifiers, webhook.New(config.Webhook, app)) } + if config.Gotify.Enable { + c.notifiers = append(c.notifiers, gotify.New(config.Gotify, app)) + } log.Debug().Msgf("%d notifier(s) created", len(c.notifiers)) return c, nil diff --git a/internal/notif/gotify/client.go b/internal/notif/gotify/client.go new file mode 100644 index 00000000..698993a9 --- /dev/null +++ b/internal/notif/gotify/client.go @@ -0,0 +1,101 @@ +package gotify + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "strconv" + "strings" + "text/template" + "time" + + "github.com/crazy-max/diun/internal/model" + "github.com/crazy-max/diun/internal/notif/notifier" +) + +// Client represents an active gotify notification object +type Client struct { + *notifier.Notifier + cfg model.NotifGotify + app model.App +} + +// New creates a new gotify notification instance +func New(config model.NotifGotify, app model.App) notifier.Notifier { + return notifier.Notifier{ + Handler: &Client{ + cfg: config, + app: app, + }, + } +} + +// Name returns notifier's name +func (c *Client) Name() string { + return "gotify" +} + +// Send creates and sends a gotify notification with an entry +func (c *Client) Send(entry model.NotifEntry) error { + hc := http.Client{ + Timeout: time.Duration(c.cfg.Timeout) * time.Second, + } + + title := fmt.Sprintf("Image update for %s", entry.Image.String()) + if entry.Status == model.ImageStatusNew { + title = fmt.Sprintf("New image %s has been added", entry.Image.String()) + } + + var msgBuf bytes.Buffer + msgTpl := template.Must(template.New("gotify").Parse(`Docker 🐳 tag {{ .Image.Domain }}/{{ .Image.Path }}:{{ .Image.Tag }} which you subscribed to through {{ .Provider }} provider has been {{ if (eq .Status "new") }}newly added{{ else }}updated{{ end }}.`)) + if err := msgTpl.Execute(&msgBuf, entry); err != nil { + return err + } + + data := url.Values{} + data.Set("message", msgBuf.String()) + data.Set("title", title) + data.Set("priority", strconv.Itoa(c.cfg.Priority)) + + u, err := url.Parse(c.cfg.Endpoint) + if err != nil { + return err + } + u.Path = path.Join(u.Path, "message") + + q := u.Query() + q.Set("token", c.cfg.Token) + u.RawQuery = q.Encode() + + req, err := http.NewRequest("POST", u.String(), strings.NewReader(data.Encode())) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode()))) + req.Header.Set("User-Agent", fmt.Sprintf("%s %s", c.app.Name, c.app.Version)) + + resp, err := hc.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + var errBody struct { + Error string `json:"error"` + ErrorCode int `json:"errorCode"` + ErrorDescription string `json:"errorDescription"` + } + err := json.NewDecoder(resp.Body).Decode(&errBody) + if err != nil { + return err + } + return fmt.Errorf("%d %s: %s", errBody.ErrorCode, errBody.Error, errBody.ErrorDescription) + } + + return nil +} diff --git a/internal/notif/webhook/client.go b/internal/notif/webhook/client.go index 8267f64f..1f0581b4 100644 --- a/internal/notif/webhook/client.go +++ b/internal/notif/webhook/client.go @@ -65,7 +65,7 @@ func (c *Client) Send(entry model.NotifEntry) error { return err } - req, err := http.NewRequest(c.cfg.Method, c.cfg.Endpoint, bytes.NewBuffer([]byte(body))) + req, err := http.NewRequest(c.cfg.Method, c.cfg.Endpoint, bytes.NewBuffer(body)) if err != nil { return err }