This repository has been archived by the owner on May 1, 2024. It is now read-only.
forked from skx/overseer
/
main.go
164 lines (139 loc) · 3.43 KB
/
main.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//
// This is the webhook bridge, which should be built like so:
//
// go build .
//
// Once built launch it as follows:
//
// $ ./webhook-bridge -url=https://example.com/bla
//
// When a test fails a webhook will sent
//
// Alberto
// --
//
package main
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"github.com/cmaster11/overseer/test"
"github.com/go-redis/redis"
)
// The url we notify
var webhookURL *string
var sendTestSuccess *bool
var sendTestRecovered *bool
// The redis handle
var r *redis.Client
//
// Given a JSON string decode it and post it via webhook if it describes
// a test-failure.
//
func process(msg []byte) {
testResult, err := test.ResultFromJSON(msg)
if err != nil {
panic(err)
}
// If the test passed then we don't care, unless otherwise defined
shouldSend := true
if testResult.Error == nil {
shouldSend = false
if *sendTestSuccess {
shouldSend = true
}
if *sendTestRecovered && testResult.Recovered {
shouldSend = true
}
}
if !shouldSend {
return
}
fmt.Printf("Processing result: %+v\n", testResult)
res, err := http.Post(*webhookURL, "application/json", bytes.NewBuffer(msg))
if err != nil {
fmt.Printf("Failed to execute webhook request: %s\n", err.Error())
return
}
//
// OK now we've submitted the post.
//
// We should retrieve the status-code + body, if the status-code
// is "odd" then we'll show them.
//
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Printf("Error reading response to post: %s\n", err.Error())
return
}
status := res.StatusCode
if status < 200 || status >= 400 {
fmt.Printf("Error - Status code was not successful: %d\n", status)
fmt.Printf("Response - %s\n", body)
}
}
//
// Entry Point
//
func main() {
//
// Parse our flags
//
redisHost := flag.String("redis-host", "127.0.0.1:6379", "Specify the address of the redis queue.")
redisPass := flag.String("redis-pass", "", "Specify the password of the redis queue.")
redisQueueKey := flag.String("redis-queue-key", "overseer.results", "Specify the redis queue key to use.")
webhookURL = flag.String("url", "", "The url address to notify")
sendTestSuccess = flag.Bool("send-test-success", false, "Send also test results when successful")
sendTestRecovered = flag.Bool("send-test-recovered", false, "Send also test results when a test recovers from failure (valid only when used together with deduplication rules)")
flag.Parse()
//
// Sanity-check.
//
if *webhookURL == "" {
fmt.Printf("Usage: webhook-bridge -url=https://example.com/bla [-redis-host=127.0.0.1:6379] [-redis-pass=foo]\n")
os.Exit(1)
}
_, err := url.Parse(*webhookURL)
if err != nil {
fmt.Printf("Failed to parse provided URL: %s\n", err.Error())
os.Exit(1)
}
//
// Create the redis client
//
r = redis.NewClient(&redis.Options{
Addr: *redisHost,
Password: *redisPass,
DB: 0, // use default DB
})
//
// And run a ping, just to make sure it worked.
//
_, err = r.Ping().Result()
if err != nil {
fmt.Printf("Redis connection failed: %s\n", err.Error())
os.Exit(1)
}
fmt.Printf("webhook bridge started with url %s\n", *webhookURL)
for {
//
// Get test-results
//
msg, _ := r.BLPop(0, *redisQueueKey).Result()
//
// If they were non-empty, process them.
//
// msg[0] will be "overseer.results"
//
// msg[1] will be the value removed from the list.
//
if len(msg) >= 1 {
process([]byte(msg[1]))
}
}
}