1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View file

@ -0,0 +1,456 @@
# github webhooks
You should configure your Organization's Webhooks to point at the `webhooks`
service. To do this go to `github.com/{my_organization}` and click
`Settings > Webhooks > Add webhook`. In the resulting menu set `Payload URL` to
`http://<my_ip>:1619/github`, `Content type` to `application/json` and under
the section `Which events would you like to trigger this webhook?` select
'Send me **everything**'. By default all of the events will write to the
`github_webhooks` measurement, this is configurable by setting the
`measurement_name` in the config file.
You can also add a secret that will be used by telegraf to verify the
authenticity of the requests.
## Metrics
The titles of the following sections are links to the full payloads and details
for each event. The body contains what information from the event is persisted.
The format is as follows:
```toml
# TAGS
* 'tagKey' = `tagValue` type
# FIELDS
* 'fieldKey' = `fieldValue` type
```
The tag values and field values show the place on the incoming JSON object
where the data is sourced from.
### [`commit_comment` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#commit_comment)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'commit' = `event.comment.commit_id` string
* 'comment' = `event.comment.body` string
### [`create` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#create)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'ref' = `event.ref` string
* 'refType' = `event.ref_type` string
### [`delete` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#delete)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'ref' = `event.ref` string
* 'refType' = `event.ref_type` string
### [`deployment` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#deployment)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'commit' = `event.deployment.sha` string
* 'task' = `event.deployment.task` string
* 'environment' = `event.deployment.environment` string
* 'description' = `event.deployment.description` string
### [`deployment_status` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#deployment_status)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'commit' = `event.deployment.sha` string
* 'task' = `event.deployment.task` string
* 'environment' = `event.deployment.environment` string
* 'description' = `event.deployment.description` string
* 'depState' = `event.deployment_status.state` string
* 'depDescription' = `event.deployment_status.description` string
### [`fork` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#fork)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'forkee' = `event.forkee.repository` string
### [`gollum` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#gollum)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
### [`issue_comment` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#issue_comment)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'issue' = `event.issue.number` int
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'title' = `event.issue.title` string
* 'comments' = `event.issue.comments` int
* 'body' = `event.comment.body` string
### [`issues` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#issues)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'issue' = `event.issue.number` int
* 'action' = `event.action` string
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'title' = `event.issue.title` string
* 'comments' = `event.issue.comments` int
### [`member` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#member)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'newMember' = `event.sender.login` string
* 'newMemberStatus' = `event.sender.site_admin` bool
### [`membership` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#membership)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'action' = `event.action` string
**Fields:**
* 'newMember' = `event.sender.login` string
* 'newMemberStatus' = `event.sender.site_admin` bool
### [`page_build` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#page_build)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
### [`public` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#public)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
### [`pull_request_review_comment` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#pull_request_review_comment)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'action' = `event.action` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'prNumber' = `event.pull_request.number` int
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'state' = `event.pull_request.state` string
* 'title' = `event.pull_request.title` string
* 'comments' = `event.pull_request.comments` int
* 'commits' = `event.pull_request.commits` int
* 'additions' = `event.pull_request.additions` int
* 'deletions' = `event.pull_request.deletions` int
* 'changedFiles' = `event.pull_request.changed_files` int
* 'commentFile' = `event.comment.file` string
* 'comment' = `event.comment.body` string
### [`pull_request` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#pull_request)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'action' = `event.action` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'prNumber' = `event.pull_request.number` int
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'state' = `event.pull_request.state` string
* 'title' = `event.pull_request.title` string
* 'comments' = `event.pull_request.comments` int
* 'commits' = `event.pull_request.commits` int
* 'additions' = `event.pull_request.additions` int
* 'deletions' = `event.pull_request.deletions` int
* 'changedFiles' = `event.pull_request.changed_files` int
### [`push` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#push)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'ref' = `event.ref` string
* 'before' = `event.before` string
* 'after' = `event.after` string
### [`repository` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#repository)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
### [`release` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#release)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'tagName' = `event.release.tag_name` string
### [`status` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#status)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'commit' = `event.sha` string
* 'state' = `event.state` string
### [`team_add` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#team_add)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
* 'teamName' = `event.team.name` string
### [`watch` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#watch)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
**Fields:**
* 'stars' = `event.repository.stargazers_count` int
* 'forks' = `event.repository.forks_count` int
* 'issues' = `event.repository.open_issues_count` int
### [`workflow_job` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#workflow_job)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'action' = `event.action` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'name' = `event.workflow_job.name` string
* 'conclusion' = `event.workflow_job.conclusion` string
**Fields:**
* 'run_attempt' = `event.workflow_job.run_attempt` int
* 'queue_time' = `event.workflow_job.started_at - event.workflow_job.created_at at event.action = in_progress in milliseconds` int
* 'run_time' = `event.workflow_job.completed_at - event.workflow_job.started_at at event.action = completed in milliseconds` int
* 'head_branch' = `event.workflow_job.head_branch` string
### [`workflow_run` event](https://docs.github.com/en/webhooks/webhook-events-and-payloads#workflow_run)
**Tags:**
* 'event' = `headers[X-Github-Event]` string
* 'action' = `event.action` string
* 'repository' = `event.repository.full_name` string
* 'private' = `event.repository.private` bool
* 'user' = `event.sender.login` string
* 'admin' = `event.sender.site_admin` bool
* 'name' = `event.workflow_run.name` string
* 'conclusion' = `event.workflow_run.conclusion` string
**Fields:**
* 'run_attempt' = `event.workflow_run.run_attempt` int
* 'run_time' = `event.workflow_run.completed_at - event.workflow_run.run_started_at at event.action = completed in milliseconds` int
* 'head_branch' = `event.workflow_run.head_branch` string

View file

@ -0,0 +1,150 @@
package github
import (
"crypto/hmac"
"crypto/sha1" //nolint:gosec // G505: Blocklisted import crypto/sha1: weak cryptographic primitive - sha1 hash is what is desired in this case
"encoding/hex"
"encoding/json"
"io"
"net/http"
"github.com/gorilla/mux"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/common/auth"
)
type Webhook struct {
Path string
secret string
acc telegraf.Accumulator
log telegraf.Logger
auth.BasicAuth
}
// Register registers the webhook with the provided router
func (gh *Webhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
router.HandleFunc(gh.Path, gh.eventHandler).Methods("POST")
gh.log = log
gh.log.Infof("Started the webhooks_github on %s", gh.Path)
gh.acc = acc
}
func (gh *Webhook) eventHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if !gh.Verify(r) {
w.WriteHeader(http.StatusUnauthorized)
return
}
eventType := r.Header.Get("X-Github-Event")
data, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if gh.secret != "" && !checkSignature(gh.secret, data, r.Header.Get("X-Hub-Signature")) {
gh.log.Error("Fail to check the github webhook signature")
w.WriteHeader(http.StatusBadRequest)
return
}
e, err := gh.newEvent(data, eventType)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if e != nil {
p := e.newMetric()
gh.acc.AddFields("github_webhooks", p.Fields(), p.Tags(), p.Time())
}
w.WriteHeader(http.StatusOK)
}
func generateEvent(data []byte, event event) (event, error) {
err := json.Unmarshal(data, event)
if err != nil {
return nil, err
}
return event, nil
}
type newEventError struct {
s string
}
func (e *newEventError) Error() string {
return e.s
}
func (gh *Webhook) newEvent(data []byte, name string) (event, error) {
gh.log.Debugf("New %v event received", name)
switch name {
case "commit_comment":
return generateEvent(data, &commitCommentEvent{})
case "create":
return generateEvent(data, &createEvent{})
case "delete":
return generateEvent(data, &deleteEvent{})
case "deployment":
return generateEvent(data, &deploymentEvent{})
case "deployment_status":
return generateEvent(data, &deploymentStatusEvent{})
case "fork":
return generateEvent(data, &forkEvent{})
case "gollum":
return generateEvent(data, &gollumEvent{})
case "issue_comment":
return generateEvent(data, &issueCommentEvent{})
case "issues":
return generateEvent(data, &issuesEvent{})
case "member":
return generateEvent(data, &memberEvent{})
case "membership":
return generateEvent(data, &membershipEvent{})
case "page_build":
return generateEvent(data, &pageBuildEvent{})
case "ping":
return nil, nil
case "public":
return generateEvent(data, &publicEvent{})
case "pull_request":
return generateEvent(data, &pullRequestEvent{})
case "pull_request_review_comment":
return generateEvent(data, &pullRequestReviewCommentEvent{})
case "push":
return generateEvent(data, &pushEvent{})
case "release":
return generateEvent(data, &releaseEvent{})
case "repository":
return generateEvent(data, &repositoryEvent{})
case "status":
return generateEvent(data, &statusEvent{})
case "team_add":
return generateEvent(data, &teamAddEvent{})
case "watch":
return generateEvent(data, &watchEvent{})
case "workflow_job":
return generateEvent(data, &workflowJobEvent{})
case "workflow_run":
return generateEvent(data, &workflowRunEvent{})
}
return nil, &newEventError{"Not a recognized event type"}
}
func checkSignature(secret string, data []byte, signature string) bool {
return hmac.Equal([]byte(signature), []byte(generateSignature(secret, data)))
}
func generateSignature(secret string, data []byte) string {
mac := hmac.New(sha1.New, []byte(secret))
if _, err := mac.Write(data); err != nil {
return err.Error()
}
result := mac.Sum(nil)
return "sha1=" + hex.EncodeToString(result)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,739 @@
package github
import (
"strconv"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
)
const meas = "github_webhooks"
type event interface {
newMetric() telegraf.Metric
}
type repository struct {
Repository string `json:"full_name"`
Private bool `json:"private"`
Stars int `json:"stargazers_count"`
Forks int `json:"forks_count"`
Issues int `json:"open_issues_count"`
}
type sender struct {
User string `json:"login"`
Admin bool `json:"site_admin"`
}
type commitComment struct {
Commit string `json:"commit_id"`
Body string `json:"body"`
}
type deployment struct {
Commit string `json:"sha"`
Task string `json:"task"`
Environment string `json:"environment"`
Description string `json:"description"`
}
type page struct {
Name string `json:"page_name"`
Title string `json:"title"`
Action string `json:"action"`
}
type issue struct {
Number int `json:"number"`
Title string `json:"title"`
Comments int `json:"comments"`
}
type issueComment struct {
Body string `json:"body"`
}
type team struct {
Name string `json:"name"`
}
type pullRequest struct {
Number int `json:"number"`
State string `json:"state"`
Title string `json:"title"`
Comments int `json:"comments"`
Commits int `json:"commits"`
Additions int `json:"additions"`
Deletions int `json:"deletions"`
ChangedFiles int `json:"changed_files"`
}
type pullRequestReviewComment struct {
File string `json:"path"`
Comment string `json:"body"`
}
type workflowJob struct {
RunAttempt int `json:"run_attempt"`
HeadBranch string `json:"head_branch"`
CreatedAt time.Time `json:"created_at"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
Name string `json:"name"`
Conclusion string `json:"conclusion"`
}
type workflowRun struct {
HeadBranch string `json:"head_branch"`
CreatedAt time.Time `json:"created_at"`
RunStartedAt time.Time `json:"run_started_at"`
UpdatedAt time.Time `json:"updated_at"`
RunAttempt int `json:"run_attempt"`
Name string `json:"name"`
Conclusion string `json:"conclusion"`
}
type release struct {
TagName string `json:"tag_name"`
}
type deploymentStatus struct {
State string `json:"state"`
Description string `json:"description"`
}
type commitCommentEvent struct {
Comment commitComment `json:"comment"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s commitCommentEvent) newMetric() telegraf.Metric {
event := "commit_comment"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"commit": s.Comment.Commit,
"comment": s.Comment.Body,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type createEvent struct {
Ref string `json:"ref"`
RefType string `json:"ref_type"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s createEvent) newMetric() telegraf.Metric {
event := "create"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"ref": s.Ref,
"refType": s.RefType,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type deleteEvent struct {
Ref string `json:"ref"`
RefType string `json:"ref_type"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s deleteEvent) newMetric() telegraf.Metric {
event := "delete"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"ref": s.Ref,
"refType": s.RefType,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type deploymentEvent struct {
Deployment deployment `json:"deployment"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s deploymentEvent) newMetric() telegraf.Metric {
event := "deployment"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"commit": s.Deployment.Commit,
"task": s.Deployment.Task,
"environment": s.Deployment.Environment,
"description": s.Deployment.Description,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type deploymentStatusEvent struct {
Deployment deployment `json:"deployment"`
DeploymentStatus deploymentStatus `json:"deployment_status"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s deploymentStatusEvent) newMetric() telegraf.Metric {
event := "delete"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"commit": s.Deployment.Commit,
"task": s.Deployment.Task,
"environment": s.Deployment.Environment,
"description": s.Deployment.Description,
"depState": s.DeploymentStatus.State,
"depDescription": s.DeploymentStatus.Description,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type forkEvent struct {
Forkee repository `json:"forkee"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s forkEvent) newMetric() telegraf.Metric {
event := "fork"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"fork": s.Forkee.Repository,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type gollumEvent struct {
Pages []page `json:"pages"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
// REVIEW: Going to be lazy and not deal with the pages.
func (s gollumEvent) newMetric() telegraf.Metric {
event := "gollum"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type issueCommentEvent struct {
Issue issue `json:"issue"`
Comment issueComment `json:"comment"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s issueCommentEvent) newMetric() telegraf.Metric {
event := "issue_comment"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"issue": strconv.Itoa(s.Issue.Number),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"title": s.Issue.Title,
"comments": s.Issue.Comments,
"body": s.Comment.Body,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type issuesEvent struct {
Action string `json:"action"`
Issue issue `json:"issue"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s issuesEvent) newMetric() telegraf.Metric {
event := "issue"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"issue": strconv.Itoa(s.Issue.Number),
"action": s.Action,
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"title": s.Issue.Title,
"comments": s.Issue.Comments,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type memberEvent struct {
Member sender `json:"member"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s memberEvent) newMetric() telegraf.Metric {
event := "member"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"newMember": s.Member.User,
"newMemberStatus": s.Member.Admin,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type membershipEvent struct {
Action string `json:"action"`
Member sender `json:"member"`
Sender sender `json:"sender"`
Team team `json:"team"`
}
func (s membershipEvent) newMetric() telegraf.Metric {
event := "membership"
t := map[string]string{
"event": event,
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"action": s.Action,
}
f := map[string]interface{}{
"newMember": s.Member.User,
"newMemberStatus": s.Member.Admin,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type pageBuildEvent struct {
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s pageBuildEvent) newMetric() telegraf.Metric {
event := "page_build"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type publicEvent struct {
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s publicEvent) newMetric() telegraf.Metric {
event := "public"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type pullRequestEvent struct {
Action string `json:"action"`
PullRequest pullRequest `json:"pull_request"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s pullRequestEvent) newMetric() telegraf.Metric {
event := "pull_request"
t := map[string]string{
"event": event,
"action": s.Action,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"prNumber": strconv.Itoa(s.PullRequest.Number),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"state": s.PullRequest.State,
"title": s.PullRequest.Title,
"comments": s.PullRequest.Comments,
"commits": s.PullRequest.Commits,
"additions": s.PullRequest.Additions,
"deletions": s.PullRequest.Deletions,
"changedFiles": s.PullRequest.ChangedFiles,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type pullRequestReviewCommentEvent struct {
Comment pullRequestReviewComment `json:"comment"`
PullRequest pullRequest `json:"pull_request"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s pullRequestReviewCommentEvent) newMetric() telegraf.Metric {
event := "pull_request_review_comment"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"prNumber": strconv.Itoa(s.PullRequest.Number),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"state": s.PullRequest.State,
"title": s.PullRequest.Title,
"comments": s.PullRequest.Comments,
"commits": s.PullRequest.Commits,
"additions": s.PullRequest.Additions,
"deletions": s.PullRequest.Deletions,
"changedFiles": s.PullRequest.ChangedFiles,
"commentFile": s.Comment.File,
"comment": s.Comment.Comment,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type pushEvent struct {
Ref string `json:"ref"`
Before string `json:"before"`
After string `json:"after"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s pushEvent) newMetric() telegraf.Metric {
event := "push"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"ref": s.Ref,
"before": s.Before,
"after": s.After,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type releaseEvent struct {
Release release `json:"release"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s releaseEvent) newMetric() telegraf.Metric {
event := "release"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"tagName": s.Release.TagName,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type repositoryEvent struct {
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s repositoryEvent) newMetric() telegraf.Metric {
event := "repository"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type statusEvent struct {
Commit string `json:"sha"`
State string `json:"state"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s statusEvent) newMetric() telegraf.Metric {
event := "status"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"commit": s.Commit,
"state": s.State,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type teamAddEvent struct {
Team team `json:"team"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s teamAddEvent) newMetric() telegraf.Metric {
event := "team_add"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
"teamName": s.Team.Name,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type watchEvent struct {
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s watchEvent) newMetric() telegraf.Metric {
event := "delete"
t := map[string]string{
"event": event,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
}
f := map[string]interface{}{
"stars": s.Repository.Stars,
"forks": s.Repository.Forks,
"issues": s.Repository.Issues,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type workflowJobEvent struct {
Action string `json:"action"`
WorkflowJob workflowJob `json:"workflow_job"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s workflowJobEvent) newMetric() telegraf.Metric {
event := "workflow_job"
t := map[string]string{
"event": event,
"action": s.Action,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"name": s.WorkflowJob.Name,
"conclusion": s.WorkflowJob.Conclusion,
}
var runTimeMs int64
var queueTimeMs int64
if s.Action == "in_progress" {
queueTimeMs = s.WorkflowJob.StartedAt.Sub(s.WorkflowJob.CreatedAt).Milliseconds()
}
if s.Action == "completed" {
runTimeMs = s.WorkflowJob.CompletedAt.Sub(s.WorkflowJob.StartedAt).Milliseconds()
}
f := map[string]interface{}{
"run_attempt": s.WorkflowJob.RunAttempt,
"queue_time": queueTimeMs,
"run_time": runTimeMs,
"head_branch": s.WorkflowJob.HeadBranch,
}
m := metric.New(meas, t, f, time.Now())
return m
}
type workflowRunEvent struct {
Action string `json:"action"`
WorkflowRun workflowRun `json:"workflow_run"`
Repository repository `json:"repository"`
Sender sender `json:"sender"`
}
func (s workflowRunEvent) newMetric() telegraf.Metric {
event := "workflow_run"
t := map[string]string{
"event": event,
"action": s.Action,
"repository": s.Repository.Repository,
"private": strconv.FormatBool(s.Repository.Private),
"user": s.Sender.User,
"admin": strconv.FormatBool(s.Sender.Admin),
"name": s.WorkflowRun.Name,
"conclusion": s.WorkflowRun.Conclusion,
}
var runTimeMs int64
if s.Action == "completed" {
runTimeMs = s.WorkflowRun.UpdatedAt.Sub(s.WorkflowRun.RunStartedAt).Milliseconds()
}
f := map[string]interface{}{
"run_attempt": s.WorkflowRun.RunAttempt,
"run_time": runTimeMs,
"head_branch": s.WorkflowRun.HeadBranch,
}
m := metric.New(meas, t, f, time.Now())
return m
}

View file

@ -0,0 +1,147 @@
package github
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf/testutil"
)
func githubWebhookRequest(t *testing.T, event, jsonString string) {
var acc testutil.Accumulator
gh := &Webhook{Path: "/github", acc: &acc, log: testutil.Logger{}}
req, err := http.NewRequest("POST", "/github", strings.NewReader(jsonString))
require.NoError(t, err)
req.Header.Add("X-Github-Event", event)
w := httptest.NewRecorder()
gh.eventHandler(w, req)
if w.Code != http.StatusOK {
t.Errorf("POST "+event+" returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK)
}
}
func githubWebhookRequestWithSignature(t *testing.T, event, jsonString, signature string, expectedStatus int) {
var acc testutil.Accumulator
gh := &Webhook{Path: "/github", secret: "signature", acc: &acc, log: testutil.Logger{}}
req, err := http.NewRequest("POST", "/github", strings.NewReader(jsonString))
require.NoError(t, err)
req.Header.Add("X-Github-Event", event)
req.Header.Add("X-Hub-Signature", signature)
w := httptest.NewRecorder()
gh.eventHandler(w, req)
if w.Code != expectedStatus {
t.Errorf("POST "+event+" returned HTTP status code %v.\nExpected %v", w.Code, expectedStatus)
}
}
func TestCommitCommentEvent(t *testing.T) {
githubWebhookRequest(t, "commit_comment", commitCommentEventJSON())
}
func TestPingEvent(t *testing.T) {
githubWebhookRequest(t, "ping", "")
}
func TestDeleteEvent(t *testing.T) {
githubWebhookRequest(t, "delete", deleteEventJSON())
}
func TestDeploymentEvent(t *testing.T) {
githubWebhookRequest(t, "deployment", deploymentEventJSON())
}
func TestDeploymentStatusEvent(t *testing.T) {
githubWebhookRequest(t, "deployment_status", deploymentStatusEventJSON())
}
func TestForkEvent(t *testing.T) {
githubWebhookRequest(t, "fork", forkEventJSON())
}
func TestGollumEvent(t *testing.T) {
githubWebhookRequest(t, "gollum", gollumEventJSON())
}
func TestIssueCommentEvent(t *testing.T) {
githubWebhookRequest(t, "issue_comment", issueCommentEventJSON())
}
func TestIssuesEvent(t *testing.T) {
githubWebhookRequest(t, "issues", issuesEventJSON())
}
func TestMemberEvent(t *testing.T) {
githubWebhookRequest(t, "member", memberEventJSON())
}
func TestMembershipEvent(t *testing.T) {
githubWebhookRequest(t, "membership", membershipEventJSON())
}
func TestPageBuildEvent(t *testing.T) {
githubWebhookRequest(t, "page_build", pageBuildEventJSON())
}
func TestPublicEvent(t *testing.T) {
githubWebhookRequest(t, "public", publicEventJSON())
}
func TestPullRequestReviewCommentEvent(t *testing.T) {
githubWebhookRequest(t, "pull_request_review_comment", pullRequestReviewCommentEventJSON())
}
func TestPushEvent(t *testing.T) {
githubWebhookRequest(t, "push", pushEventJSON())
}
func TestReleaseEvent(t *testing.T) {
githubWebhookRequest(t, "release", releaseEventJSON())
}
func TestRepositoryEvent(t *testing.T) {
githubWebhookRequest(t, "repository", repositoryEventJSON())
}
func TestStatusEvent(t *testing.T) {
githubWebhookRequest(t, "status", statusEventJSON())
}
func TestTeamAddEvent(t *testing.T) {
githubWebhookRequest(t, "team_add", teamAddEventJSON())
}
func TestWatchEvent(t *testing.T) {
githubWebhookRequest(t, "watch", watchEventJSON())
}
func TestEventWithSignatureFail(t *testing.T) {
githubWebhookRequestWithSignature(t, "watch", watchEventJSON(), "signature", http.StatusBadRequest)
}
func TestEventWithSignatureSuccess(t *testing.T) {
githubWebhookRequestWithSignature(t, "watch", watchEventJSON(), generateSignature("signature", []byte(watchEventJSON())), http.StatusOK)
}
func TestWorkflowJob(t *testing.T) {
githubWebhookRequest(t, "workflow_job", WorkflowJobJSON())
}
func TestWorkflowRun(t *testing.T) {
githubWebhookRequest(t, "workflow_run", WorkflowRunJSON())
}
func TestCheckSignatureSuccess(t *testing.T) {
if !checkSignature("my_little_secret", []byte("random-signature-body"), "sha1=3dca279e731c97c38e3019a075dee9ebbd0a99f0") {
t.Errorf("check signature failed")
}
}
func TestCheckSignatureFailed(t *testing.T) {
if checkSignature("m_little_secret", []byte("random-signature-body"), "sha1=3dca279e731c97c38e3019a075dee9ebbd0a99f0") {
t.Errorf("check signature failed")
}
}