Skip to content

Commit

Permalink
Merge e9f82dd into 14cf119
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-nguyen committed Jul 10, 2018
2 parents 14cf119 + e9f82dd commit 76aa01a
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 79 deletions.
14 changes: 1 addition & 13 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ func (c *Client) SetSSLVerification(verify bool) {
// public-private key-pair. It outputs configuration information
// for the user.
func (c *Client) BootstrapRemote(repoName string) error {
fmt.Fprintf(c.out, "Setting up remote %s at %s", c.Name, c.IP)
fmt.Fprintf(c.out, "Setting up remote %s at %s\n", c.Name, c.IP)

fmt.Fprint(c.out, ">> Step 1/4: Installing docker...")
fmt.Fprintln(c.out, ">> Step 1/4: Installing docker...")
err := c.installDocker(c.sshRunner)
if err != nil {
return err
}

fmt.Fprint(c.out, "\n>> Step 2/4: Building deploy key...")
fmt.Fprintln(c.out, "\n>> Step 2/4: Building deploy key...")
if err != nil {
return err
}
Expand All @@ -88,7 +88,7 @@ func (c *Client) BootstrapRemote(repoName string) error {

// This step needs to run before any other commands that rely on
// the daemon image, since the daemon is loaded here.
fmt.Fprint(c.out, "\n>> Step 3/4: Starting daemon...")
fmt.Fprintln(c.out, "\n>> Step 3/4: Starting daemon...")
if err != nil {
return err
}
Expand All @@ -97,32 +97,32 @@ func (c *Client) BootstrapRemote(repoName string) error {
return err
}

fmt.Fprint(c.out, "\n>> Step 4/4: Fetching daemon API token...")
fmt.Fprintln(c.out, "\n>> Step 4/4: Fetching daemon API token...")
token, err := c.getDaemonAPIToken(c.sshRunner, c.version)
if err != nil {
return err
}
c.Daemon.Token = token

fmt.Fprint(c.out, "\nInertia has been set up and daemon is running on remote!")
fmt.Fprint(c.out, "You may have to wait briefly for Inertia to set up some dependencies.")
fmt.Fprintln(c.out, "\nInertia has been set up and daemon is running on remote!")
fmt.Fprintln(c.out, "You may have to wait briefly for Inertia to set up some dependencies.")
fmt.Fprintf(c.out, "Use 'inertia %s logs --stream' to check on the daemon's setup progress.\n\n", c.Name)

fmt.Fprint(c.out, "=============================\n")

// Output deploy key to user.
fmt.Fprintf(c.out, ">> GitHub Deploy Key (add to https://www.github.com/%s/settings/keys/new): ", repoName)
fmt.Fprintf(c.out, ">> GitHub Deploy Key (add to https://www.github.com/%s/settings/keys/new):\n", repoName)
fmt.Fprint(c.out, pub.String())

// Output Webhook url to user.
fmt.Fprintf(c.out, ">> GitHub WebHook URL (add to https://www.github.com/%s/settings/hooks/new): ", repoName)
fmt.Fprintf(c.out, "WebHook Address: https://%s:%s/webhook", c.IP, c.Daemon.Port)
fmt.Fprint(c.out, "WebHook Secret: "+c.Daemon.WebHookSecret)
fmt.Fprintf(c.out, ">> GitHub WebHook URL (add to https://www.github.com/%s/settings/hooks/new):\n", repoName)
fmt.Fprintf(c.out, "WebHook Address: https://%s:%s/webhook\n", c.IP, c.Daemon.Port)
fmt.Fprintln(c.out, "WebHook Secret: "+c.Daemon.WebHookSecret)
fmt.Fprint(c.out, `Note that you will have to disable SSH verification in your webhook
settings - Inertia uses self-signed certificates that GitHub won't
be able to verify.`+"\n")

fmt.Fprint(c.out, `Inertia daemon successfully deployed! Add your webhook url and deploy
fmt.Fprintln(c.out, `Inertia daemon successfully deployed! Add your webhook url and deploy
key to enable continuous deployment.`)
fmt.Fprintf(c.out, "Then run 'inertia %s up' to deploy your application.\n", c.Name)

Expand Down
2 changes: 1 addition & 1 deletion daemon/inertiad/auth/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func (h *PermissionsHandler) listUsersHandler(w http.ResponseWriter, r *http.Req
if len(users) != 0 {
fmt.Fprintf(w, "[SUCCESS %d] Users: \n%s\n", http.StatusOK, userList)
} else {
fmt.Fprintf(w, "[SUCCESS %d] No users registered.", http.StatusOK)
fmt.Fprintf(w, "[SUCCESS %d] No users registered.\n", http.StatusOK)
}
}

Expand Down
2 changes: 1 addition & 1 deletion daemon/inertiad/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func run(host, port, version string) {
)

// GitHub webhook endpoint
handler.AttachPublicHandlerFunc("/webhook", gitHubWebHookHandler)
handler.AttachPublicHandlerFunc("/webhook", webhookHandler)

// CLI API endpoints
handler.AttachUserRestrictedHandlerFunc("/status", statusHandler)
Expand Down
79 changes: 28 additions & 51 deletions daemon/inertiad/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,67 @@ package main

import (
"fmt"
"io"
"net/http"
"os"

docker "github.com/docker/docker/client"
"github.com/google/go-github/github"
"github.com/ubclaunchpad/inertia/common"
"github.com/ubclaunchpad/inertia/daemon/inertiad/project"
"github.com/ubclaunchpad/inertia/daemon/inertiad/webhook"
)

var webhookSecret = "inertia"

// gitHubWebHookHandler writes a response to a request into the given ResponseWriter.
func gitHubWebHookHandler(w http.ResponseWriter, r *http.Request) {
// webhookHandler writes a response to a request into the given ResponseWriter.
func webhookHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, common.MsgDaemonOK)

payload, err := github.ValidatePayload(r, []byte(webhookSecret))
payload, err := webhook.Parse(r, os.Stdout)
if err != nil {
println(err.Error())
fmt.Fprintln(os.Stdout, err.Error())
return
}

event, err := github.ParseWebHook(github.WebHookType(r), payload)
if err != nil {
println(err.Error())
return
}

switch event := event.(type) {
case *github.PushEvent:
processPushEvent(event)
case *github.PullRequestEvent:
processPullRequestEvent(event)
switch event := payload.GetEventType(); event {
case webhook.PushEvent:
processPushEvent(payload, os.Stdout)
// case webhook.PullEvent:
// processPullRequestEvent(payload)
default:
println("Unrecognized event type")
fmt.Fprintln(os.Stdout, "Unrecognized event type")
}
}

// processPushEvent prints information about the given PushEvent.
func processPushEvent(event *github.PushEvent) {
repo := event.GetRepo()
branch := common.GetBranchFromRef(event.GetRef())
println("Received PushEvent")
println(fmt.Sprintf("Repository Name: %s", *repo.Name))
println(fmt.Sprintf("Repository Git URL: %s", *repo.GitURL))
println(fmt.Sprintf("Branch: %s", branch))
func processPushEvent(payload webhook.Payload, out io.Writer) {
branch := common.GetBranchFromRef(payload.GetRef())

fmt.Fprintln(out, "Received PushEvent")
fmt.Fprintln(out, fmt.Sprintf("Repository Name: %s", payload.GetRepoName()))
fmt.Fprintln(out, fmt.Sprintf("Repository Git URL: %s", payload.GetGitURL()))
fmt.Fprintln(out, fmt.Sprintf("Branch: %s", branch))

// Ignore event if repository not set up yet, otherwise
// let deploy() handle the update.
if deployment == nil {
println("No deployment detected - try running 'inertia $REMOTE up'")
fmt.Fprintln(out, "No deployment detected - try running 'inertia $REMOTE up'")
return
}

// Check for matching remotes
err := deployment.CompareRemotes(common.GetSSHRemoteURL(repo.GetGitURL()))
err := deployment.CompareRemotes(payload.GetSSHURL())
if err != nil {
println(err.Error())
fmt.Fprintln(out, err.Error())
return
}

// If branches match, deploy, otherwise ignore the event.
if deployment.GetBranch() == branch {
println("Event branch matches deployed branch " + branch)
fmt.Fprintln(out, "Event branch matches deployed branch "+branch)
cli, err := docker.NewEnvClient()
if err != nil {
println(err.Error())
fmt.Fprintln(out, err.Error())
return
}
defer cli.Close()
Expand All @@ -77,30 +72,12 @@ func processPushEvent(event *github.PushEvent) {
SkipUpdate: false,
})
if err != nil {
println(err.Error())
fmt.Fprintln(out, err.Error())
}
} else {
println(
"Event branch " + branch + " does not match deployed branch " +
deployment.GetBranch() + " - ignoring event.",
fmt.Fprintln(out,
"Event branch "+branch+" does not match deployed branch "+
deployment.GetBranch()+" - ignoring event.",
)
}
}

// processPullRequestEvent prints information about the given PullRequestEvent.
// Handling PRs is unnecessary because merging one will trigger a PushEvent.
// For now, simply logs events - may in the future do something configured
// by the user.
func processPullRequestEvent(event *github.PullRequestEvent) {
repo := event.GetRepo()
pr := event.GetPullRequest()
merged := "false"
if *pr.Merged {
merged = "true"
}
println("Received PullRequestEvent")
println(fmt.Sprintf("Repository Name: %s", *repo.Name))
println(fmt.Sprintf("Repository Git URL: %s", *repo.GitURL))
println(fmt.Sprintf("Ref: %s", pr.GetBase().GetRef()))
println(fmt.Sprintf("Merge status: %v", merged))
}
2 changes: 2 additions & 0 deletions daemon/inertiad/webhook/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package webhook contains Inertia's webhook parsing code
package webhook
71 changes: 71 additions & 0 deletions daemon/inertiad/webhook/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package webhook

import (
"encoding/json"
"errors"
"net/http"
)

// x-github-event header values
var (
GithubPushHeader = "push"
// GithubPullHeader = "pull"
)

// GithubPushEvent represents a push to a Github repository
// see https://developer.github.com/v3/activity/events/types/#pushevent
type GithubPushEvent struct {
eventType string
Ref string `json:"ref"`
Repo GithubPushEventRepository `json:"repository"`
}

// GithubPushEventRepository represents the repository object in a Github PushEvent
// see https://developer.github.com/v3/activity/events/types/#pushevent
type GithubPushEventRepository struct {
FullName string `json:"full_name"`
GitURL string `json:"clone_url"`
SSHURL string `json:"ssh_url"`
}

func parseGithubEvent(r *http.Request, event string) (Payload, error) {
dec := json.NewDecoder(r.Body)

switch event {
case GithubPushHeader:
payload := GithubPushEvent{eventType: PushEvent}

if err := dec.Decode(&payload); err != nil {
return nil, errors.New("Error parsing PushEvent")
}

return payload, nil
default:
return nil, errors.New("Unsupported Github event")
}
}

// GetEventType returns the event type of the webhook
func (g GithubPushEvent) GetEventType() string {
return g.eventType
}

// GetRepoName returns the full repo name
func (g GithubPushEvent) GetRepoName() string {
return g.Repo.FullName
}

// GetRef returns the full ref
func (g GithubPushEvent) GetRef() string {
return g.Ref
}

// GetGitURL returns the git clone URL
func (g GithubPushEvent) GetGitURL() string {
return g.Repo.GitURL
}

// GetSSHURL returns the ssh URL
func (g GithubPushEvent) GetSSHURL() string {
return g.Repo.SSHURL
}
70 changes: 70 additions & 0 deletions daemon/inertiad/webhook/gitlab.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package webhook

import (
"encoding/json"
"errors"
"net/http"
)

// x-gitlab-event header values
var (
GitlabPushHeader = "Push Hook"
)

// GitlabPushEvent represents a push to a Gitlab repository
// see https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#push-events
type GitlabPushEvent struct {
eventType string
Ref string `json:"ref"`
Repo GitlabPushEventRepository `json:"repository"`
}

// GitlabPushEventRepository represents the repository object in a Gitlab PushEvent
// see https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#push-events
type GitlabPushEventRepository struct {
Name string `json:"name"`
GitURL string `json:"git_http_url"`
SSHURL string `json:"git_ssh_url"`
}

func parseGitlabEvent(r *http.Request, event string) (Payload, error) {
dec := json.NewDecoder(r.Body)

switch event {
case GitlabPushHeader:
payload := GitlabPushEvent{eventType: PushEvent}

if err := dec.Decode(&payload); err != nil {
return nil, errors.New("Error parsing PushEvent")
}

return payload, nil
default:
return nil, errors.New("Unsupported Gitlab event")
}
}

// GetEventType returns the event type of the webhook
func (g GitlabPushEvent) GetEventType() string {
return g.eventType
}

// GetRepoName returns the repo name
func (g GitlabPushEvent) GetRepoName() string {
return g.Repo.Name
}

// GetRef returns the full ref
func (g GitlabPushEvent) GetRef() string {
return g.Ref
}

// GetGitURL returns the git clone URL
func (g GitlabPushEvent) GetGitURL() string {
return g.Repo.GitURL
}

// GetSSHURL returns the ssh URL
func (g GitlabPushEvent) GetSSHURL() string {
return g.Repo.SSHURL
}
Loading

0 comments on commit 76aa01a

Please sign in to comment.