Skip to content

Commit

Permalink
优化结构.
Browse files Browse the repository at this point in the history
  • Loading branch information
moonagic committed May 25, 2018
1 parent 99eb445 commit 62f2690
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 157 deletions.
165 changes: 8 additions & 157 deletions gowebhook.go
Original file line number Diff line number Diff line change
@@ -1,173 +1,24 @@
package main

import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"GoWebhooks/src/utils"
"GoWebhooks/src/config"
"GoWebhooks/src/server"
"log"
"net/http"
"os"
"os/exec"
"time"
)

var (
targetSecret = ""
targetURL = ""
targetPort = ""
targetHost = ""
targetShell = ""
targetLogDir = "/etc/gowebhook/"
targetLogFile = "log"
queue []string
running = false
)

func generateHashSignature(message string) string {
h := hmac.New(sha1.New, []byte(targetSecret))
h.Write([]byte(message))
return "sha1=" + hex.EncodeToString(h.Sum(nil))
}

func index(w http.ResponseWriter, r *http.Request) {
log2file(string(r.URL.Host))
fmt.Fprintln(w, "{\"code\":200, \"description\":\"service running...\"}")
}

func autoBuild(w http.ResponseWriter, r *http.Request) {
if (r.Method == "post" || r.Method == "POST") && r.URL.RequestURI() == targetURL {
if r.Header.Get("x-github-event") == "push" {
bodyContent, _ := ioutil.ReadAll(r.Body)
r.Body.Close()
signature := r.Header.Get("X-Hub-Signature")
if verifySignature(signature, string(bodyContent)) {
fmt.Fprintln(w, "{\"code\":200, \"description\":\"OK\"}")
log2file("验证通过,启动部署任务")
queue = append(queue, "1")
checkoutTaskStatus()
} else {
log2file("验证失败")
fmt.Fprintln(w, "{\"code\":200, \"error\":\"Signature error\"}")
}
} else {
fmt.Fprintln(w, "{\"code\":200, \"error\":\"Unmatch x-github-event\"}")
}
} else {
fmt.Fprintln(w, "{\"code\":200, \"error\":\"Error Method or unknow request url\"}")
}
}
func main() {

func loadConfig() {
result, err := ioutil.ReadFile("/etc/gowebhook/config")
if err == nil {
var f interface{}
json.Unmarshal(result, &f)
m := f.(map[string]interface{})
localUrl, ok0 := m["requestUrl"].(string)
localSecret, ok1 := m["secret"].(string)
localHost, ok2 := m["host"].(string)
localPort, ok3 := m["port"].(string)
localShell, ok4 := m["script"].(string)
if ok0 && ok1 && ok2 && ok3 && ok4 {
targetURL = localUrl
targetSecret = localSecret
targetHost = localHost
targetPort = localPort
targetShell = localShell
} else {
log2file("Broken config.")
os.Exit(0)
}
} else {
log2file("Can not find config file...in \"/etc/gowebhook/config\"")
if errorString := config.LoadConfig(); errorString != "" {
utils.Log2file(errorString)
os.Exit(0)
}
}

func checkoutTaskStatus() {
if running {
return
}
if len(queue) > 0 {
data := []string{""}
queue = data[:0:0]
go startTask()
}
}

func startService() {
http.HandleFunc("/", index)
http.HandleFunc("/auto_build", autoBuild)


log2file(fmt.Sprintf("service starting... %s:%s", targetHost, targetPort))
listenErr := http.ListenAndServe(fmt.Sprintf("%s:%s", targetHost, targetPort), nil)
listenErr := server.StartService(config.GetHost(), config.GetPort())
if listenErr != nil {
log.Fatal("ListenAndServe: ", listenErr)
}
}

func startTask() {
running = true
cmd := exec.Command("/bin/sh", targetShell)
_, err := cmd.Output()
if err == nil {
running = false
log2file("部署成功")
checkoutTaskStatus()
} else {
running = false
log2file(fmt.Sprintf("部署失败:\n %s", err))
checkoutTaskStatus()
log.Fatal("ListenAndServer error: ", listenErr)
}
}

func verifySignature(signature string, data string) bool {
return signature == generateHashSignature(string(data))
}

func log2file(content string) {
var err error

if _, err := os.Stat(targetLogDir); err == nil {
fmt.Println("Dir exists", targetLogDir)
} else {
fmt.Println("Dir not exists, try to create...", targetLogDir)
err := os.MkdirAll(targetLogDir, 0711)
if err != nil {
fmt.Println("Error creating directory", targetLogDir)
fmt.Println("err:", err)
return
}
}

if _, err := os.Stat(targetLogDir + targetLogFile); err == nil {
fmt.Println("Path exists", targetLogDir + targetLogFile)
} else {
fmt.Println("Path not exists, try to create...", targetLogDir + targetLogFile)
_, err := os.Create(targetLogDir + targetLogFile)
if err != nil {
fmt.Println("Error creating file", targetLogDir + targetLogFile)
fmt.Println("err:", err)
return
}
}

f, err := os.OpenFile(targetLogDir + targetLogFile, os.O_APPEND|os.O_WRONLY, 0600)
if err == nil {
timeString := time.Now().Format("2006-01-02 15:04:05")
f.WriteString("[" + timeString + "]" + "" + content)
f.WriteString("\n")
} else {
fmt.Println("Open file faild...", targetLogDir + targetLogFile)
fmt.Println("err:", err)
}
}

func main() {
loadConfig()
startService()
}
57 changes: 57 additions & 0 deletions src/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package config

import (
"io/ioutil"
"encoding/json"
)

var (
config map[string]string
)

func LoadConfig() string {
result, err := ioutil.ReadFile("/etc/gowebhook/config")
if err == nil {
var f interface{}
json.Unmarshal(result, &f)
m := f.(map[string]interface{})
localUrl, ok0 := m["requestUrl"].(string)
localSecret, ok1 := m["secret"].(string)
localHost, ok2 := m["host"].(string)
localPort, ok3 := m["port"].(string)
localShell, ok4 := m["script"].(string)
if ok0 && ok1 && ok2 && ok3 && ok4 {
config = make(map[string]string)
config["url"] = localUrl
config["secret"] = localSecret
config["host"] = localHost
config["port"] = localPort
config["shell"] = localShell
return ""
} else {
return "Broken config."
}
} else {
return "Can not find config file...in \"/etc/gowebhook/config\""
}
}

func GetURL() string {
return config["url"]
}

func GetSecret() string {
return config["secret"]
}

func GetHost() string {
return config["host"]
}

func GetPort() string {
return config["port"]
}

func GetShell() string {
return config["shell"]
}
46 changes: 46 additions & 0 deletions src/server/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package server

import (
"net/http"
"fmt"
"GoWebhooks/src/utils"
"io/ioutil"
"GoWebhooks/src/task"
"GoWebhooks/src/config"
)

func StartService(address string, port string) error {
http.HandleFunc("/", index)
http.HandleFunc("/auto_build", autoBuild)

utils.Log2file(fmt.Sprintf("service starting... %s:%s", address, port))
return http.ListenAndServe(fmt.Sprintf("%s:%s", address, port), nil)
}

func index(w http.ResponseWriter, r *http.Request) {
utils.Log2file(string(r.URL.Host))
fmt.Fprintln(w, "{\"code\":200, \"description\":\"service running...\"}")
}

func autoBuild(w http.ResponseWriter, r *http.Request) {
if (r.Method == "post" || r.Method == "POST") && r.URL.RequestURI() == config.GetURL() {
if r.Header.Get("x-github-event") == "push" {
bodyContent, _ := ioutil.ReadAll(r.Body)
r.Body.Close()
signature := r.Header.Get("X-Hub-Signature")
if utils.VerifySignature(signature, string(bodyContent), config.GetSecret()) {
fmt.Fprintln(w, "{\"code\":200, \"description\":\"OK\"}")
utils.Log2file("验证通过,启动部署任务")
task.AddNewTask(string(bodyContent))
task.CheckoutTaskStatus()
} else {
utils.Log2file("验证失败")
fmt.Fprintln(w, "{\"code\":200, \"error\":\"Signature error\"}")
}
} else {
fmt.Fprintln(w, "{\"code\":200, \"error\":\"Unmatch x-github-event\"}")
}
} else {
fmt.Fprintln(w, "{\"code\":200, \"error\":\"Error Method or unknow request url\"}")
}
}
48 changes: 48 additions & 0 deletions src/task/task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package task

import (
"os/exec"
"GoWebhooks/src/utils"
"fmt"
"GoWebhooks/src/config"
)

var running = false
var queue []*structTaskQueue

type structTaskQueue struct {
requestBodyString string
}

func AddNewTask(bodyContent string) {
queue = append(queue, NewStructTaskQueue(bodyContent))
}

func NewStructTaskQueue(body string) *structTaskQueue {
return &structTaskQueue{body}
}

func CheckoutTaskStatus() {
if running {
return
}
if len(queue) > 0 {
queue = queue[:0:0]
go startTask()
}
}

func startTask() {
running = true
cmd := exec.Command("/bin/sh", config.GetShell())
_, err := cmd.Output()
if err == nil {
running = false
utils.Log2file("部署成功")
CheckoutTaskStatus()
} else {
running = false
utils.Log2file(fmt.Sprintf("部署失败:\n %s", err))
CheckoutTaskStatus()
}
}
48 changes: 48 additions & 0 deletions src/utils/log2file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package utils

import (
"os"
"fmt"
"time"
)

var targetLogDir = "/etc/gowebhook/"
var targetLogFile = "log"

func Log2file(content string) {
var err error

if _, err := os.Stat(targetLogDir); err == nil {

} else {
fmt.Println("Dir not exists, try to create...", targetLogDir)
err := os.MkdirAll(targetLogDir, 0711)
if err != nil {
fmt.Println("Error creating directory", targetLogDir)
fmt.Println("err:", err)
return
}
}

if _, err := os.Stat(targetLogDir + targetLogFile); err == nil {

} else {
fmt.Println("Path not exists, try to create...", targetLogDir + targetLogFile)
_, err := os.Create(targetLogDir + targetLogFile)
if err != nil {
fmt.Println("Error creating file", targetLogDir + targetLogFile)
fmt.Println("err:", err)
return
}
}

f, err := os.OpenFile(targetLogDir + targetLogFile, os.O_APPEND|os.O_WRONLY, 0600)
if err == nil {
timeString := time.Now().Format("2006-01-02 15:04:05")
f.WriteString("[" + timeString + "]" + "" + content)
f.WriteString("\n")
} else {
fmt.Println("Open file faild...", targetLogDir + targetLogFile)
fmt.Println("err:", err)
}
}
Loading

0 comments on commit 62f2690

Please sign in to comment.