-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gh webhooks #573
Gh webhooks #573
Changes from 7 commits
8bdcd6d
8653bae
ddcd99a
46b367e
dbf1383
5b15cd9
89f5b77
4e5dfa5
7878b22
a704522
4c74a2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,338 @@ | ||
package ghwebhooks | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"net/http" | ||
"sync" | ||
|
||
"github.com/gorilla/mux" | ||
mod "github.com/influxdb/support-tools/ghWebhooks/models" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't use this repo for Telegraf because it's private |
||
"github.com/influxdb/telegraf/plugins/inputs" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change influxdb -> influxdata |
||
) | ||
|
||
func init() { | ||
inputs.Add("ghwebhooks", func() inputs.Input { return &GHWebhooks{} }) | ||
} | ||
|
||
type GHWebhooks struct { | ||
ServiceAddress string | ||
MeasurementName string | ||
// Lock for the struct | ||
sync.Mutex | ||
// Events buffer to store events between Gather calls | ||
events []mod.Event | ||
} | ||
|
||
func NewGHWebhooks() *GHWebhooks { | ||
return &GHWebhooks{} | ||
} | ||
|
||
func (gh *GHWebhooks) SampleConfig() string { | ||
return ` | ||
# Address and port to host Webhook listener on | ||
service_address = ":1618" | ||
# Measurement name | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these should be 2-space indentation |
||
measurement_name = "ghwebhooks" | ||
` | ||
} | ||
|
||
func (gh *GHWebhooks) Description() string { | ||
return "A Github Webhook Event collector" | ||
} | ||
|
||
// Writes the points from <-gh.in to the Accumulator | ||
func (gh *GHWebhooks) Gather(acc inputs.Accumulator) error { | ||
gh.Lock() | ||
defer gh.Unlock() | ||
for _, event := range gh.events { | ||
p := event.NewPoint() | ||
acc.AddFields(gh.MeasurementName, p.Fields(), p.Tags(), p.Time()) | ||
} | ||
gh.events = make([]mod.Event, 0) | ||
return nil | ||
} | ||
|
||
func (gh *GHWebhooks) Listen() { | ||
r := mux.NewRouter() | ||
r.HandleFunc("/", gh.eventHandler).Methods("POST") | ||
err := http.ListenAndServe(fmt.Sprintf("%s", gh.ServiceAddress), r) | ||
if err != nil { | ||
log.Printf("Error starting server: %v", err) | ||
} | ||
} | ||
|
||
func (gh *GHWebhooks) Start() error { | ||
go gh.Listen() | ||
log.Printf("Started the ghwebhooks service on %s\n", gh.ServiceAddress) | ||
return nil | ||
} | ||
|
||
func (gh *GHWebhooks) Stop() { | ||
log.Println("Stopping the ghWebhooks service") | ||
} | ||
|
||
// Handles the / route | ||
func (gh *GHWebhooks) eventHandler(w http.ResponseWriter, r *http.Request) { | ||
eventType := r.Header["X-Github-Event"][0] | ||
data, err := ioutil.ReadAll(r.Body) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
} | ||
e, err := NewEvent(data, eventType) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
} | ||
gh.Lock() | ||
gh.events = append(gh.events, e) | ||
gh.Unlock() | ||
w.WriteHeader(http.StatusOK) | ||
} | ||
|
||
func newCommitComment(data []byte) (mod.Event, error) { | ||
commitCommentStruct := mod.CommitCommentEvent{} | ||
err := json.Unmarshal(data, &commitCommentStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return commitCommentStruct, nil | ||
} | ||
|
||
func newCreate(data []byte) (mod.Event, error) { | ||
createStruct := mod.CreateEvent{} | ||
err := json.Unmarshal(data, &createStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return createStruct, nil | ||
} | ||
|
||
func newDelete(data []byte) (mod.Event, error) { | ||
deleteStruct := mod.DeleteEvent{} | ||
err := json.Unmarshal(data, &deleteStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return deleteStruct, nil | ||
} | ||
|
||
func newDeployment(data []byte) (mod.Event, error) { | ||
deploymentStruct := mod.DeploymentEvent{} | ||
err := json.Unmarshal(data, &deploymentStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return deploymentStruct, nil | ||
} | ||
|
||
func newDeploymentStatus(data []byte) (mod.Event, error) { | ||
deploymentStatusStruct := mod.DeploymentStatusEvent{} | ||
err := json.Unmarshal(data, &deploymentStatusStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return deploymentStatusStruct, nil | ||
} | ||
|
||
func newFork(data []byte) (mod.Event, error) { | ||
forkStruct := mod.ForkEvent{} | ||
err := json.Unmarshal(data, &forkStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return forkStruct, nil | ||
} | ||
|
||
func newGollum(data []byte) (mod.Event, error) { | ||
gollumStruct := mod.GollumEvent{} | ||
err := json.Unmarshal(data, &gollumStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return gollumStruct, nil | ||
} | ||
|
||
func newIssueComment(data []byte) (mod.Event, error) { | ||
issueCommentStruct := mod.IssueCommentEvent{} | ||
err := json.Unmarshal(data, &issueCommentStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return issueCommentStruct, nil | ||
} | ||
|
||
func newIssues(data []byte) (mod.Event, error) { | ||
issuesStruct := mod.IssuesEvent{} | ||
err := json.Unmarshal(data, &issuesStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return issuesStruct, nil | ||
} | ||
|
||
func newMember(data []byte) (mod.Event, error) { | ||
memberStruct := mod.MemberEvent{} | ||
err := json.Unmarshal(data, &memberStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return memberStruct, nil | ||
} | ||
|
||
func newMembership(data []byte) (mod.Event, error) { | ||
membershipStruct := mod.MembershipEvent{} | ||
err := json.Unmarshal(data, &membershipStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return membershipStruct, nil | ||
} | ||
|
||
func newPageBuild(data []byte) (mod.Event, error) { | ||
pageBuildEvent := mod.PageBuildEvent{} | ||
err := json.Unmarshal(data, &pageBuildEvent) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return pageBuildEvent, nil | ||
} | ||
|
||
func newPublic(data []byte) (mod.Event, error) { | ||
publicEvent := mod.PublicEvent{} | ||
err := json.Unmarshal(data, &publicEvent) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return publicEvent, nil | ||
} | ||
|
||
func newPullRequest(data []byte) (mod.Event, error) { | ||
pullRequestStruct := mod.PullRequestEvent{} | ||
err := json.Unmarshal(data, &pullRequestStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return pullRequestStruct, nil | ||
} | ||
|
||
func newPullRequestReviewComment(data []byte) (mod.Event, error) { | ||
pullRequestReviewCommentStruct := mod.PullRequestReviewCommentEvent{} | ||
err := json.Unmarshal(data, &pullRequestReviewCommentStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return pullRequestReviewCommentStruct, nil | ||
} | ||
|
||
func newPush(data []byte) (mod.Event, error) { | ||
pushStruct := mod.PushEvent{} | ||
err := json.Unmarshal(data, &pushStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return pushStruct, nil | ||
} | ||
|
||
func newRelease(data []byte) (mod.Event, error) { | ||
releaseStruct := mod.ReleaseEvent{} | ||
err := json.Unmarshal(data, &releaseStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return releaseStruct, nil | ||
} | ||
|
||
func newRepository(data []byte) (mod.Event, error) { | ||
repositoryStruct := mod.RepositoryEvent{} | ||
err := json.Unmarshal(data, &repositoryStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return repositoryStruct, nil | ||
} | ||
|
||
func newStatus(data []byte) (mod.Event, error) { | ||
statusStruct := mod.StatusEvent{} | ||
err := json.Unmarshal(data, &statusStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return statusStruct, nil | ||
} | ||
|
||
func newTeamAdd(data []byte) (mod.Event, error) { | ||
teamAddStruct := mod.TeamAddEvent{} | ||
err := json.Unmarshal(data, &teamAddStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return teamAddStruct, nil | ||
} | ||
|
||
func newWatch(data []byte) (mod.Event, error) { | ||
watchStruct := mod.WatchEvent{} | ||
err := json.Unmarshal(data, &watchStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return watchStruct, nil | ||
} | ||
|
||
type newEventError struct { | ||
s string | ||
} | ||
|
||
func (e *newEventError) Error() string { | ||
return e.s | ||
} | ||
|
||
func NewEvent(r []byte, t string) (mod.Event, error) { | ||
log.Printf("New %v event recieved", t) | ||
switch t { | ||
case "commit_comment": | ||
return newCommitComment(r) | ||
case "create": | ||
return newCreate(r) | ||
case "delete": | ||
return newDelete(r) | ||
case "deployment": | ||
return newDeployment(r) | ||
case "deployment_status": | ||
return newDeploymentStatus(r) | ||
case "fork": | ||
return newFork(r) | ||
case "gollum": | ||
return newGollum(r) | ||
case "issue_comment": | ||
return newIssueComment(r) | ||
case "issues": | ||
return newIssues(r) | ||
case "member": | ||
return newMember(r) | ||
case "membership": | ||
return newMembership(r) | ||
case "page_build": | ||
return newPageBuild(r) | ||
case "public": | ||
return newPublic(r) | ||
case "pull_request": | ||
return newPullRequest(r) | ||
case "pull_request_review_comment": | ||
return newPullRequestReviewComment(r) | ||
case "push": | ||
return newPush(r) | ||
case "release": | ||
return newRelease(r) | ||
case "repository": | ||
return newRepository(r) | ||
case "status": | ||
return newStatus(r) | ||
case "team_add": | ||
return newTeamAdd(r) | ||
case "watch": | ||
return newWatch(r) | ||
} | ||
return nil, &newEventError{"Not a recgonized event type"} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a new dependency for Telegraf, you'll need to add it like this: https://github.com/influxdata/telegraf/blob/master/CONTRIBUTING.md#adding-a-dependency