mirror of
https://github.com/crazy-max/diun.git
synced 2025-04-14 15:18:32 +00:00
Add Rocket.Chat notifier (#44)
This commit is contained in:
parent
8a49f41fdd
commit
08cd3d90b8
17 changed files with 321 additions and 82 deletions
.res
cmd
doc
internal
config
logging
model
notif
pkg/registry
BIN
.res/notif-rocketchat.png
Normal file
BIN
.res/notif-rocketchat.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 11 KiB |
|
@ -28,7 +28,7 @@ func main() {
|
|||
kingpin.Flag("config", "Diun configuration file.").Envar("CONFIG").Required().StringVar(&flags.Cfgfile)
|
||||
kingpin.Flag("timezone", "Timezone assigned to Diun.").Envar("TZ").Default("UTC").StringVar(&flags.Timezone)
|
||||
kingpin.Flag("log-level", "Set log level.").Envar("LOG_LEVEL").Default("info").StringVar(&flags.LogLevel)
|
||||
kingpin.Flag("log-json", "Enable JSON logging output.").Envar("LOG_JSON").Default("false").BoolVar(&flags.LogJson)
|
||||
kingpin.Flag("log-json", "Enable JSON logging output.").Envar("LOG_JSON").Default("false").BoolVar(&flags.LogJSON)
|
||||
kingpin.Flag("log-caller", "Enable to add file:line of the caller.").Envar("LOG_CALLER").Default("false").BoolVar(&flags.LogCaller)
|
||||
kingpin.UsageTemplate(kingpin.CompactUsageTemplate).Version(version).Author("CrazyMax")
|
||||
kingpin.CommandLine.Name = "diun"
|
||||
|
|
|
@ -22,6 +22,12 @@ watch:
|
|||
first_check_notif: false
|
||||
|
||||
notif:
|
||||
gotify:
|
||||
enable: false
|
||||
endpoint: http://gotify.foo.com
|
||||
token: Token123456
|
||||
priority: 1
|
||||
timeout: 10
|
||||
mail:
|
||||
enable: false
|
||||
host: localhost
|
||||
|
@ -32,6 +38,13 @@ notif:
|
|||
password:
|
||||
from:
|
||||
to:
|
||||
rocketchat:
|
||||
enable: false
|
||||
endpoint: http://rocket.foo.com:3000
|
||||
channel: "#general"
|
||||
user_id: abcdEFGH012345678
|
||||
token: Token123456
|
||||
timeout: 10
|
||||
slack:
|
||||
enable: false
|
||||
webhook_url: https://hooks.slack.com/services/ABCD12EFG/HIJK34LMN/01234567890abcdefghij
|
||||
|
@ -49,12 +62,6 @@ 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:
|
||||
|
@ -123,6 +130,13 @@ providers:
|
|||
|
||||
### notif
|
||||
|
||||
* `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`).
|
||||
|
||||
* `mail`
|
||||
* `enable`: Enable email reports (default: `false`).
|
||||
* `host`: SMTP server host (default: `localhost`). **required**
|
||||
|
@ -136,6 +150,14 @@ providers:
|
|||
* `from`: Sender email address. **required**
|
||||
* `to`: Recipient email address. **required**
|
||||
|
||||
* `rocketchat`
|
||||
* `enable`: Enable Rocket.Chat notification (default: `false`).
|
||||
* `endpoint`: Rocket.Chat base URL (e.g. `http://rocket.foo.com:3000`). **required**
|
||||
* `channel`: Channel name with the prefix in front of it. **required**
|
||||
* `user_id`: User ID. **required**
|
||||
* `token`: Authentication token. **required**
|
||||
* `timeout`: Timeout specifies a time limit for the request to be made. (default: `10`).
|
||||
|
||||
* `slack`
|
||||
* `enable`: Enable slack notification (default: `false`).
|
||||
* `webhook_url`: Slack [incoming webhook URL](https://api.slack.com/messaging/webhooks). **required**
|
||||
|
@ -152,13 +174,6 @@ 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.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
* [Gotify](#gotify)
|
||||
* [Mail](#mail)
|
||||
* [Rocket.Chat](#rocketchat)
|
||||
* [Slack](#slack)
|
||||
* [Telegram](#telegram)
|
||||
* [Webhook](#webhook)
|
||||
|
@ -18,9 +19,15 @@ Here is an email sample if you add `mail` notification:
|
|||
|
||||

|
||||
|
||||
## Rocket.Chat
|
||||
|
||||
To be able to send notifications to your Rocket.Chat channel, you must first create a Personal Access Token through your account settings:
|
||||
|
||||

|
||||
|
||||
## Slack
|
||||
|
||||
You can send notifications to your slack channel using an [incoming webhook URL](https://api.slack.com/messaging/webhooks):
|
||||
You can send notifications to your Slack channel using an [incoming webhook URL](https://api.slack.com/messaging/webhooks):
|
||||
|
||||

|
||||
|
||||
|
|
|
@ -49,6 +49,10 @@ func Load(flags model.Flags, version string) (*Config, error) {
|
|||
FirstCheckNotif: false,
|
||||
},
|
||||
Notif: model.Notif{
|
||||
Gotify: model.NotifGotify{
|
||||
Enable: false,
|
||||
Timeout: 10,
|
||||
},
|
||||
Mail: model.NotifMail{
|
||||
Enable: false,
|
||||
Host: "localhost",
|
||||
|
@ -56,6 +60,10 @@ func Load(flags model.Flags, version string) (*Config, error) {
|
|||
SSL: false,
|
||||
InsecureSkipVerify: false,
|
||||
},
|
||||
RocketChat: model.NotifRocketChat{
|
||||
Enable: false,
|
||||
Timeout: 10,
|
||||
},
|
||||
Slack: model.NotifSlack{
|
||||
Enable: false,
|
||||
},
|
||||
|
@ -67,10 +75,6 @@ func Load(flags model.Flags, version string) (*Config, error) {
|
|||
Method: "GET",
|
||||
Timeout: 10,
|
||||
},
|
||||
Gotify: model.NotifGotify{
|
||||
Enable: false,
|
||||
Timeout: 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,12 @@ watch:
|
|||
first_check_notif: false
|
||||
|
||||
notif:
|
||||
gotify:
|
||||
enable: false
|
||||
endpoint: http://gotify.foo.com
|
||||
token: Token123456
|
||||
priority: 1
|
||||
timeout: 10
|
||||
mail:
|
||||
enable: false
|
||||
host: localhost
|
||||
|
@ -19,6 +25,13 @@ notif:
|
|||
password_file:
|
||||
from:
|
||||
to:
|
||||
rocketchat:
|
||||
enable: false
|
||||
endpoint: http://rocket.foo.com:3000
|
||||
channel: "#general"
|
||||
user_id: abcdEFGH012345678
|
||||
token: Token123456
|
||||
timeout: 10
|
||||
slack:
|
||||
enable: false
|
||||
webhook_url: https://hooks.slack.com/services/ABCD12EFG/HIJK34LMN/01234567890abcdefghij
|
||||
|
@ -36,12 +49,6 @@ 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:
|
||||
|
|
|
@ -52,6 +52,13 @@ func TestLoad(t *testing.T) {
|
|||
Schedule: "*/30 * * * *",
|
||||
},
|
||||
Notif: model.Notif{
|
||||
Gotify: model.NotifGotify{
|
||||
Enable: false,
|
||||
Endpoint: "http://gotify.foo.com",
|
||||
Token: "Token123456",
|
||||
Priority: 1,
|
||||
Timeout: 10,
|
||||
},
|
||||
Mail: model.NotifMail{
|
||||
Enable: false,
|
||||
Host: "localhost",
|
||||
|
@ -59,6 +66,14 @@ func TestLoad(t *testing.T) {
|
|||
SSL: false,
|
||||
InsecureSkipVerify: false,
|
||||
},
|
||||
RocketChat: model.NotifRocketChat{
|
||||
Enable: false,
|
||||
Endpoint: "http://rocket.foo.com:3000",
|
||||
Channel: "#general",
|
||||
UserID: "abcdEFGH012345678",
|
||||
Token: "Token123456",
|
||||
Timeout: 10,
|
||||
},
|
||||
Slack: model.NotifSlack{
|
||||
Enable: false,
|
||||
WebhookURL: "https://hooks.slack.com/services/ABCD12EFG/HIJK34LMN/01234567890abcdefghij",
|
||||
|
@ -78,13 +93,6 @@ 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": {
|
||||
|
|
|
@ -21,7 +21,7 @@ func Configure(fl *model.Flags, location *time.Location) {
|
|||
return time.Now().In(location)
|
||||
}
|
||||
|
||||
if !fl.LogJson {
|
||||
if !fl.LogJSON {
|
||||
w = zerolog.ConsoleWriter{
|
||||
Out: os.Stdout,
|
||||
TimeFormat: time.RFC1123,
|
||||
|
|
|
@ -5,6 +5,6 @@ type Flags struct {
|
|||
Cfgfile string
|
||||
Timezone string
|
||||
LogLevel string
|
||||
LogJson bool
|
||||
LogJSON bool
|
||||
LogCaller bool
|
||||
}
|
||||
|
|
|
@ -14,11 +14,21 @@ type NotifEntry struct {
|
|||
|
||||
// Notif holds data necessary for notification configuration
|
||||
type Notif struct {
|
||||
Mail NotifMail `yaml:"mail,omitempty"`
|
||||
Slack NotifSlack `yaml:"slack,omitempty"`
|
||||
Telegram NotifTelegram `yaml:"telegram,omitempty"`
|
||||
Webhook NotifWebhook `yaml:"webhook,omitempty"`
|
||||
Gotify NotifGotify `yaml:"gotify,omitempty"`
|
||||
Gotify NotifGotify `yaml:"gotify,omitempty"`
|
||||
Mail NotifMail `yaml:"mail,omitempty"`
|
||||
RocketChat NotifRocketChat `yaml:"rocketchat,omitempty"`
|
||||
Slack NotifSlack `yaml:"slack,omitempty"`
|
||||
Telegram NotifTelegram `yaml:"telegram,omitempty"`
|
||||
Webhook NotifWebhook `yaml:"webhook,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"`
|
||||
}
|
||||
|
||||
// NotifMail holds mail notification configuration details
|
||||
|
@ -36,6 +46,16 @@ type NotifMail struct {
|
|||
To string `yaml:"to,omitempty"`
|
||||
}
|
||||
|
||||
// NotifRocketChat holds Rocket.Chat notification configuration details
|
||||
type NotifRocketChat struct {
|
||||
Enable bool `yaml:"enable,omitempty"`
|
||||
Endpoint string `yaml:"endpoint,omitempty"`
|
||||
Channel string `yaml:"channel,omitempty"`
|
||||
UserID string `yaml:"user_id,omitempty"`
|
||||
Token string `yaml:"token,omitempty"`
|
||||
Timeout int `yaml:"timeout,omitempty"`
|
||||
}
|
||||
|
||||
// NotifSlack holds slack notification configuration details
|
||||
type NotifSlack struct {
|
||||
Enable bool `yaml:"enable,omitempty"`
|
||||
|
@ -57,12 +77,3 @@ 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"`
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"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/rocketchat"
|
||||
"github.com/crazy-max/diun/internal/notif/slack"
|
||||
"github.com/crazy-max/diun/internal/notif/telegram"
|
||||
"github.com/crazy-max/diun/internal/notif/webhook"
|
||||
|
@ -27,9 +28,15 @@ func New(config model.Notif, app model.App, userAgent string) (*Client, error) {
|
|||
}
|
||||
|
||||
// Add notifiers
|
||||
if config.Gotify.Enable {
|
||||
c.notifiers = append(c.notifiers, gotify.New(config.Gotify, app, userAgent))
|
||||
}
|
||||
if config.Mail.Enable {
|
||||
c.notifiers = append(c.notifiers, mail.New(config.Mail, app))
|
||||
}
|
||||
if config.RocketChat.Enable {
|
||||
c.notifiers = append(c.notifiers, rocketchat.New(config.RocketChat, app, userAgent))
|
||||
}
|
||||
if config.Slack.Enable {
|
||||
c.notifiers = append(c.notifiers, slack.New(config.Slack, app))
|
||||
}
|
||||
|
@ -39,9 +46,6 @@ func New(config model.Notif, app model.App, userAgent string) (*Client, error) {
|
|||
if config.Webhook.Enable {
|
||||
c.notifiers = append(c.notifiers, webhook.New(config.Webhook, app, userAgent))
|
||||
}
|
||||
if config.Gotify.Enable {
|
||||
c.notifiers = append(c.notifiers, gotify.New(config.Gotify, app, userAgent))
|
||||
}
|
||||
|
||||
log.Debug().Msgf("%d notifier(s) created", len(c.notifiers))
|
||||
return c, nil
|
||||
|
|
136
internal/notif/rocketchat/client.go
Normal file
136
internal/notif/rocketchat/client.go
Normal file
|
@ -0,0 +1,136 @@
|
|||
package rocketchat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/crazy-max/diun/internal/model"
|
||||
"github.com/crazy-max/diun/internal/notif/notifier"
|
||||
)
|
||||
|
||||
// Client represents an active rocketchat notification object
|
||||
type Client struct {
|
||||
*notifier.Notifier
|
||||
cfg model.NotifRocketChat
|
||||
app model.App
|
||||
userAgent string
|
||||
}
|
||||
|
||||
// New creates a new rocketchat notification instance
|
||||
func New(config model.NotifRocketChat, app model.App, userAgent string) notifier.Notifier {
|
||||
return notifier.Notifier{
|
||||
Handler: &Client{
|
||||
cfg: config,
|
||||
app: app,
|
||||
userAgent: userAgent,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns notifier's name
|
||||
func (c *Client) Name() string {
|
||||
return "rocketchat"
|
||||
}
|
||||
|
||||
// Send creates and sends a rocketchat notification with an entry
|
||||
// https://rocket.chat/docs/developer-guides/rest-api/chat/postmessage/
|
||||
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 textBuf bytes.Buffer
|
||||
textTpl := template.Must(template.New("rocketchat").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 := textTpl.Execute(&textBuf, entry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := Message{
|
||||
Alias: c.app.Name,
|
||||
Avatar: "https://raw.githubusercontent.com/crazy-max/diun/master/.res/diun.png",
|
||||
Channel: c.cfg.Channel,
|
||||
Text: title,
|
||||
Attachments: []Attachment{
|
||||
{
|
||||
Text: textBuf.String(),
|
||||
Ts: json.Number(strconv.FormatInt(time.Now().Unix(), 10)),
|
||||
Fields: []AttachmentField{
|
||||
{
|
||||
Title: "Provider",
|
||||
Value: entry.Provider,
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Created",
|
||||
Value: entry.Manifest.Created.Format("Jan 02, 2006 15:04:05 UTC"),
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Digest",
|
||||
Value: entry.Manifest.Digest.String(),
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Platform",
|
||||
Value: fmt.Sprintf("%s/%s", entry.Manifest.Os, entry.Manifest.Architecture),
|
||||
Short: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
dataBuf := new(bytes.Buffer)
|
||||
if err := json.NewEncoder(dataBuf).Encode(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u, err := url.Parse(c.cfg.Endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Path = path.Join(u.Path, "api/v1/chat.postMessage")
|
||||
|
||||
req, err := http.NewRequest("POST", u.String(), dataBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("User-Agent", c.userAgent)
|
||||
req.Header.Add("X-User-Id", c.cfg.UserID)
|
||||
req.Header.Add("X-Auth-Token", c.cfg.Token)
|
||||
|
||||
resp, err := hc.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var respBody struct {
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error,omitempty"`
|
||||
ErrorType string `json:"errorType,omitempty"`
|
||||
}
|
||||
err = json.NewDecoder(resp.Body).Decode(&respBody)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("HTTP error %d: %s", resp.StatusCode, respBody.ErrorType)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
41
internal/notif/rocketchat/model.go
Normal file
41
internal/notif/rocketchat/model.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package rocketchat
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Message contains all the information for a message
|
||||
type Message struct {
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Avatar string `json:"avatar,omitempty"`
|
||||
Channel string `json:"channel,omitempty"`
|
||||
Emoji string `json:"emoji,omitempty"`
|
||||
RoomID string `json:"roomId,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Attachments []Attachment `json:"attachments,omitempty"`
|
||||
}
|
||||
|
||||
// Attachment contains all the information for an attachment
|
||||
type Attachment struct {
|
||||
AudioURL string `json:"audio_url,omitempty"`
|
||||
AuthorIcon string `json:"author_icon,omitempty"`
|
||||
AuthorLink string `json:"author_link,omitempty"`
|
||||
AuthorName string `json:"author_name,omitempty"`
|
||||
Collapsed bool `json:"collapsed,omitempty"`
|
||||
Color bool `json:"color,omitempty"`
|
||||
Fields []AttachmentField `json:"fields,omitempty"`
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
MessageLink string `json:"message_link,omitempty"`
|
||||
Text string `json:"text"`
|
||||
ThumbURL string `json:"thumb_url,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
TitleLink string `json:"title_link,omitempty"`
|
||||
Ts json.Number `json:"ts,omitempty"`
|
||||
VideoURL string `json:"video_url,omitempty"`
|
||||
}
|
||||
|
||||
// AttachmentField contains information for an attachment field
|
||||
// An Attachment can contain multiple of these
|
||||
type AttachmentField struct {
|
||||
Title string `json:"title"`
|
||||
Value string `json:"value"`
|
||||
Short bool `json:"short"`
|
||||
}
|
|
@ -49,37 +49,39 @@ func (c *Client) Send(entry model.NotifEntry) error {
|
|||
}
|
||||
|
||||
return slack.PostWebhook(c.cfg.WebhookURL, &slack.WebhookMessage{
|
||||
Attachments: []slack.Attachment{slack.Attachment{
|
||||
Color: color,
|
||||
AuthorName: "Diun",
|
||||
AuthorSubname: "github.com/crazy-max/diun",
|
||||
AuthorLink: "https://github.com/crazy-max/diun",
|
||||
AuthorIcon: "https://raw.githubusercontent.com/crazy-max/diun/master/.res/diun.png",
|
||||
Text: textBuf.String(),
|
||||
Footer: fmt.Sprintf("%s © %d %s %s", c.app.Author, time.Now().Year(), c.app.Name, c.app.Version),
|
||||
Fields: []slack.AttachmentField{
|
||||
{
|
||||
Title: "Provider",
|
||||
Value: entry.Provider,
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Created",
|
||||
Value: entry.Manifest.Created.Format("Jan 02, 2006 15:04:05 UTC"),
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Digest",
|
||||
Value: entry.Manifest.Digest.String(),
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Platform",
|
||||
Value: fmt.Sprintf("%s/%s", entry.Manifest.Os, entry.Manifest.Architecture),
|
||||
Short: false,
|
||||
Attachments: []slack.Attachment{
|
||||
{
|
||||
Color: color,
|
||||
AuthorName: "Diun",
|
||||
AuthorSubname: "github.com/crazy-max/diun",
|
||||
AuthorLink: "https://github.com/crazy-max/diun",
|
||||
AuthorIcon: "https://raw.githubusercontent.com/crazy-max/diun/master/.res/diun.png",
|
||||
Text: textBuf.String(),
|
||||
Footer: fmt.Sprintf("%s © %d %s %s", c.app.Author, time.Now().Year(), c.app.Name, c.app.Version),
|
||||
Fields: []slack.AttachmentField{
|
||||
{
|
||||
Title: "Provider",
|
||||
Value: entry.Provider,
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Created",
|
||||
Value: entry.Manifest.Created.Format("Jan 02, 2006 15:04:05 UTC"),
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Digest",
|
||||
Value: entry.Manifest.Digest.String(),
|
||||
Short: false,
|
||||
},
|
||||
{
|
||||
Title: "Platform",
|
||||
Value: fmt.Sprintf("%s/%s", entry.Manifest.Os, entry.Manifest.Architecture),
|
||||
Short: false,
|
||||
},
|
||||
},
|
||||
Ts: json.Number(strconv.FormatInt(time.Now().Unix(), 10)),
|
||||
},
|
||||
Ts: json.Number(strconv.FormatInt(time.Now().Unix(), 10)),
|
||||
}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// Source: https://github.com/genuinetools/reg/blob/f3a9b00ec86f334702381edf842f03b3a9243a0a/registry/image.go
|
||||
package registry
|
||||
|
||||
import (
|
||||
|
@ -8,6 +7,8 @@ import (
|
|||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// Source: https://github.com/genuinetools/reg/blob/f3a9b00ec86f334702381edf842f03b3a9243a0a/registry/image.go
|
||||
|
||||
// Image holds information about an image.
|
||||
type Image struct {
|
||||
Domain string
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// Manifest is the Docker image manifest information
|
||||
type Manifest struct {
|
||||
Name string
|
||||
Tag string
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/crazy-max/diun/pkg/utl"
|
||||
)
|
||||
|
||||
// Tags holds information about image tags.
|
||||
type Tags struct {
|
||||
List []string
|
||||
NotIncluded int
|
||||
|
@ -12,6 +13,7 @@ type Tags struct {
|
|||
Total int
|
||||
}
|
||||
|
||||
// TagsOptions holds docker tags image options
|
||||
type TagsOptions struct {
|
||||
Image Image
|
||||
Max int
|
||||
|
|
Loading…
Add table
Reference in a new issue