-
Notifications
You must be signed in to change notification settings - Fork 7
/
webhook.go
124 lines (97 loc) · 2.31 KB
/
webhook.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
"github.com/hashicorp/go-retryablehttp"
)
func sendWebhook(c *retryablehttp.Client, sendTime sobaTime, results BackupResults, url, format string) error {
ok, failed := getBackupsStats(results)
if sendTime.IsZero() {
sendTime = sobaTime{
Time: time.Now(),
f: time.RFC3339,
}
}
webhookData := WebhookData{
App: appName,
Type: "backups.complete",
Timestamp: sendTime,
Stats: BackupStats{
Succeeded: ok,
Failed: failed,
},
Data: results,
}
// exclude result data if format is short
if format == "short" {
webhookData.Data.Results = nil
}
// o, err := json.MarshalIndent(webhookData, "", " ")
o, err := json.Marshal(webhookData)
if err != nil {
return fmt.Errorf("error marshalling webhook data: %w", err)
}
// send to webhook
c.RetryMax = 3
c.RetryWaitMin = 1 * time.Second
c.RetryWaitMax = 3 * time.Second
var req *retryablehttp.Request
req, err = retryablehttp.NewRequest(http.MethodPost, url, strings.NewReader(string(o)))
if err != nil {
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
_, err = c.Do(req)
if err != nil {
fmt.Printf("error: %s\n", err)
}
return nil
}
type BackupStats struct {
Succeeded int `json:"succeeded"`
Failed int `json:"failed"`
}
type sobaTime struct {
time.Time
f string
}
func (j sobaTime) format() string {
return j.Time.Format(j.f)
}
func (j sobaTime) MarshalText() ([]byte, error) { // nolint: unparam
return []byte(j.format()), nil
}
func (j sobaTime) MarshalJSON() ([]byte, error) { // nolint: unparam
return []byte(`"` + j.format() + `"`), nil
}
type WebhookData struct {
App string `json:"app"`
Type string `json:"type"`
Stats BackupStats `json:"stats"`
Timestamp sobaTime `json:"timestamp"`
Data BackupResults `json:"data,omitempty"`
}
func getBackupsStats(br BackupResults) (ok, failed int) {
if br.Results == nil {
return 0, 0
}
for _, pr := range *br.Results {
// catch error from provider
if pr.Results.Error != nil {
failed++
continue
}
for _, r := range pr.Results.BackupResults {
// catch error from repository backup
if r.Error != nil {
failed++
continue
}
ok++
}
}
return ok, failed
}