add grafana support
This commit is contained in:
parent
c650f280f5
commit
caf0dfe497
|
@ -6,51 +6,62 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/bdlm/log"
|
"github.com/bdlm/log"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
libHTTP "github.com/genofire/golang-lib/http"
|
libHTTP "github.com/genofire/golang-lib/http"
|
||||||
xmpp "github.com/mattn/go-xmpp"
|
xmpp "github.com/mattn/go-xmpp"
|
||||||
|
|
||||||
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
const hookType = "git"
|
const hookType = "circleci"
|
||||||
|
|
||||||
|
|
||||||
|
type requestBody struct {
|
||||||
|
Payload struct {
|
||||||
|
VCSURL string `mapstructure:"vcs_url"`
|
||||||
|
Status string `mapstructure:"status"`
|
||||||
|
BuildNum float64 `mapstructure:"build_num"`
|
||||||
|
BuildURL string `mapstructure:"build_url"`
|
||||||
|
BuildTime float64 `mapstructure:"build_time_millis"`
|
||||||
|
Subject string `mapstructure:"subject"`
|
||||||
|
} `mapstructure:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r requestBody) String() string {
|
||||||
|
return fmt.Sprintf("#%0.f (%0.fs): %s", r.Payload.BuildNum, r.Payload.BuildTime/1000, r.Payload.Subject)
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
logger := log.WithField("type", hookType)
|
logger := log.WithField("type", hookType)
|
||||||
|
|
||||||
var body map[string]interface{}
|
var body interface{}
|
||||||
libHTTP.Read(r, &body)
|
libHTTP.Read(r, &body)
|
||||||
|
|
||||||
payload := body["payload"].(map[string]interface{})
|
var request requestBody
|
||||||
url, ok := payload["vcs_url"].(string)
|
if err := mapstructure.Decode(body, &request); err != nil {
|
||||||
if !ok {
|
logger.Errorf("no readable payload: %s", err)
|
||||||
logger.Error("no readable payload")
|
|
||||||
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
|
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger = logger.WithField("url", url)
|
logger = logger.WithFields(map[string]interface{}{
|
||||||
|
"url": request.Payload.VCSURL,
|
||||||
|
"msg": request.String(),
|
||||||
|
})
|
||||||
|
|
||||||
status := payload["status"].(string)
|
ok := false
|
||||||
buildNum := payload["build_num"].(float64)
|
|
||||||
buildURL := payload["build_url"].(string)
|
|
||||||
buildTime := payload["build_time_millis"].(float64)
|
|
||||||
subject := payload["subject"].(string)
|
|
||||||
msg := fmt.Sprintf("[%s] %s (%0.fs) - #%0.f: %s \n%s", url, status, buildTime/1000, buildNum, subject, buildURL)
|
|
||||||
logger = logger.WithField("msg", msg)
|
|
||||||
|
|
||||||
ok = false
|
|
||||||
for _, hook := range hooks {
|
for _, hook := range hooks {
|
||||||
if url != hook.URL {
|
if request.Payload.VCSURL != hook.URL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logger.Infof("run hook")
|
logger.Infof("run hook")
|
||||||
runtime.Notify(client, hook, msg)
|
runtime.Notify(client, hook, request.String())
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Warnf("no hook found")
|
logger.Warnf("no hook found")
|
||||||
http.Error(w, fmt.Sprintf("no configuration for circleci for url: %s", url), http.StatusNotFound)
|
http.Error(w, fmt.Sprintf("no configuration for %s for url: %s", hookType, request.Payload.VCSURL), http.StatusNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
package circleci
|
|
24
git/main.go
24
git/main.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/bdlm/log"
|
"github.com/bdlm/log"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
libHTTP "github.com/genofire/golang-lib/http"
|
libHTTP "github.com/genofire/golang-lib/http"
|
||||||
xmpp "github.com/mattn/go-xmpp"
|
xmpp "github.com/mattn/go-xmpp"
|
||||||
|
|
||||||
|
@ -37,30 +38,29 @@ func init() {
|
||||||
var body map[string]interface{}
|
var body map[string]interface{}
|
||||||
libHTTP.Read(r, &body)
|
libHTTP.Read(r, &body)
|
||||||
|
|
||||||
repository := body["repository"].(map[string]interface{})
|
var request requestBody
|
||||||
url, ok := repository["html_url"].(string)
|
if err := mapstructure.Decode(body, &request); err != nil {
|
||||||
if !ok {
|
logger.Errorf("no readable payload: %s", err)
|
||||||
logger.Error("no readable payload")
|
|
||||||
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
|
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger = logger.WithField("url", url)
|
logger = logger.WithFields(map[string]interface{}{
|
||||||
|
"url": request.Repository.HTMLURL,
|
||||||
|
"msg": request.String(event),
|
||||||
|
})
|
||||||
|
|
||||||
msg := PayloadToString(event, body)
|
ok := false
|
||||||
logger = logger.WithField("msg", msg)
|
|
||||||
|
|
||||||
ok = false
|
|
||||||
for _, hook := range hooks {
|
for _, hook := range hooks {
|
||||||
if url != hook.URL {
|
if request.Repository.HTMLURL != hook.URL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logger.Infof("run hook")
|
logger.Infof("run hook")
|
||||||
runtime.Notify(client, hook, msg)
|
runtime.Notify(client, hook, request.String(event))
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Warnf("no hook found")
|
logger.Warnf("no hook found")
|
||||||
http.Error(w, fmt.Sprintf("no configuration for git for url: %s", url), http.StatusNotFound)
|
http.Error(w, fmt.Sprintf("no configuration for %s for url: %s", hookType, request.Repository.HTMLURL), http.StatusNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
55
git/msg.go
55
git/msg.go
|
@ -49,38 +49,57 @@ var eventMsg = map[string]string{
|
||||||
"gollum_edited": "Wiki: edited page",
|
"gollum_edited": "Wiki: edited page",
|
||||||
}
|
}
|
||||||
|
|
||||||
func PayloadToString(event string, payloadOrigin interface{}) string {
|
|
||||||
payload := payloadOrigin.(map[string]interface{})
|
|
||||||
|
|
||||||
repository := payload["repository"].(map[string]interface{})
|
type requestBody struct {
|
||||||
repoName := repository["full_name"].(string)
|
Repository struct {
|
||||||
|
HTMLURL string `mapstructure:"html_url"`
|
||||||
|
FullName string `mapstructure:"full_name"`
|
||||||
|
} `mapstructure:"repository"`
|
||||||
|
//push
|
||||||
|
Pusher struct {
|
||||||
|
Name string `mapstructure:"name"`
|
||||||
|
} `mapstructure:"pusher"`
|
||||||
|
Commits []struct {
|
||||||
|
Added []interface{} `mapstructure:"added"`
|
||||||
|
Removed []interface{} `mapstructure:"removed"`
|
||||||
|
Modified []interface{} `mapstructure:"modified"`
|
||||||
|
} `mapstructure:"commits"`
|
||||||
|
Compare string `mapstructure:"compare"`
|
||||||
|
Ref string `mapstructure:"ref"`
|
||||||
|
// issue + fallback
|
||||||
|
Sender struct {
|
||||||
|
Login string `mapstructure:"login"`
|
||||||
|
} `mapstructure:"sender"`
|
||||||
|
// issue
|
||||||
|
Action string `mapstructure:"action"`
|
||||||
|
Issue struct {
|
||||||
|
HTMLURL string `mapstructure:"html_url"`
|
||||||
|
Number float64 `mapstructure:"number"`
|
||||||
|
Title string `mapstructure:"title"`
|
||||||
|
} `mapstructure:"issue"`
|
||||||
|
}
|
||||||
|
|
||||||
msg := fmt.Sprintf("[%s]", repoName)
|
func (r requestBody) String(event string) string {
|
||||||
|
msg := fmt.Sprintf("[%s]", r.Repository.FullName)
|
||||||
|
|
||||||
if event == "push" {
|
if event == "push" {
|
||||||
pusher := payload["pusher"].(map[string]interface{})
|
|
||||||
commits := payload["commits"].([]interface{})
|
|
||||||
added := 0
|
added := 0
|
||||||
removed := 0
|
removed := 0
|
||||||
modified := 0
|
modified := 0
|
||||||
for _, commitOrigin := range commits {
|
for _, commit := range r.Commits {
|
||||||
commit := commitOrigin.(map[string]interface{})
|
added += len(commit.Added)
|
||||||
added += len(commit["added"].([]interface{}))
|
removed += len(commit.Removed)
|
||||||
removed += len(commit["removed"].([]interface{}))
|
modified += len(commit.Modified)
|
||||||
modified += len(commit["modified"].([]interface{}))
|
|
||||||
}
|
}
|
||||||
msg = fmt.Sprintf("%s %s - pushed %d commit(s) to %s [+%d/-%d/\u00B1%d] \n %s", msg, pusher["name"], len(commits), strings.TrimLeft(payload["ref"].(string), "refs/heads/"), added, removed, modified, payload["compare"])
|
msg = fmt.Sprintf("%s %s - pushed %d commit(s) to %s [+%d/-%d/\u00B1%d]: %s", msg, r.Pusher.Name, len(r.Commits), strings.TrimLeft(r.Ref, "refs/heads/"), added, removed, modified, r.Compare)
|
||||||
} else if event == "issues" || event == "issue_comment" {
|
} else if event == "issues" || event == "issue_comment" {
|
||||||
sender := payload["sender"].(map[string]interface{})
|
msg = fmt.Sprintf("%s %s - %s action #%.0f: %s - %s", msg, r.Sender.Login, r.Action, r.Issue.Number, r.Issue.Title, r.Issue.HTMLURL)
|
||||||
issue := payload["issue"].(map[string]interface{})
|
|
||||||
msg = fmt.Sprintf("%s %s - %s action #%.0f: %s \n %s", msg, sender["login"], payload["action"], issue["number"], issue["title"], issue["html_url"])
|
|
||||||
} else {
|
} else {
|
||||||
sender := payload["sender"].(map[string]interface{})
|
|
||||||
text := eventMsg[event]
|
text := eventMsg[event]
|
||||||
if text == "" {
|
if text == "" {
|
||||||
text = event
|
text = event
|
||||||
}
|
}
|
||||||
msg = fmt.Sprintf("%s %s - %s", msg, sender["login"], text)
|
msg = fmt.Sprintf("%s %s - %s", msg, r.Sender.Login, text)
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package circleci
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/bdlm/log"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
libHTTP "github.com/genofire/golang-lib/http"
|
||||||
|
xmpp "github.com/mattn/go-xmpp"
|
||||||
|
|
||||||
|
"dev.sum7.eu/genofire/hook2xmpp/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
const hookType = "grafana"
|
||||||
|
|
||||||
|
|
||||||
|
type evalMatch struct {
|
||||||
|
Tags map[string]string `mapstructure:"tags,omitempty"`
|
||||||
|
Metric string `mapstructure:"metric"`
|
||||||
|
Value float64 `mapstructure:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type requestBody struct {
|
||||||
|
Title string `mapstructure:"title"`
|
||||||
|
State string `mapstructure:"state"`
|
||||||
|
RuleID int64 `mapstructure:"ruleId"`
|
||||||
|
RuleName string `mapstructure:"ruleName"`
|
||||||
|
RuleURL string `mapstructure:"ruleUrl"`
|
||||||
|
EvalMatches []evalMatch `mapstructure:"evalMatches"`
|
||||||
|
ImageURL string `mapstructure:"imageUrl"`
|
||||||
|
Message string `mapstructure:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r requestBody) String() string {
|
||||||
|
msg := fmt.Sprintf("%s: %s", r.Title, r.Message)
|
||||||
|
for _, e := range r.EvalMatches {
|
||||||
|
msg = fmt.Sprintf("%s %s=%d", msg, e.Metric, e.Value)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
runtime.HookRegister[hookType] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger := log.WithField("type", hookType)
|
||||||
|
|
||||||
|
var body interface{}
|
||||||
|
libHTTP.Read(r, &body)
|
||||||
|
|
||||||
|
var request requestBody
|
||||||
|
if err := mapstructure.Decode(body, &request); err != nil {
|
||||||
|
logger.Errorf("no readable payload: %s", err)
|
||||||
|
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger = logger.WithFields(map[string]interface{}{
|
||||||
|
"url": request.RuleURL,
|
||||||
|
"msg": request.String(),
|
||||||
|
})
|
||||||
|
|
||||||
|
ruleURL, err := url.Parse(request.RuleURL)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("could not parse ruleURL: %s", err)
|
||||||
|
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok := false
|
||||||
|
for _, hook := range hooks {
|
||||||
|
if ruleURL.Hostname() != hook.URL {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
logger.Infof("run hook")
|
||||||
|
runtime.Notify(client, hook, request.String())
|
||||||
|
runtime.NotifyImage(client, hook, request.ImageURL)
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
logger.Warnf("no hook found")
|
||||||
|
http.Error(w, fmt.Sprintf("no configuration for %s for url: %s", hookType, request.RuleURL), http.StatusNotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue