2022-02-27 20:18:27 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
_ "embed"
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
"github.com/99designs/httpsignatures-go"
|
2022-02-27 22:31:40 +01:00
|
|
|
"github.com/joho/godotenv"
|
2022-02-27 20:18:27 +01:00
|
|
|
"github.com/woodpecker-ci/woodpecker/server/model"
|
|
|
|
)
|
|
|
|
|
|
|
|
type config struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Data string `json:"data"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type incoming struct {
|
|
|
|
Repo *model.Repo `json:"repo"`
|
|
|
|
Build *model.Build `json:"build"`
|
|
|
|
Configuration []*config `json:"configs"`
|
|
|
|
}
|
|
|
|
|
|
|
|
//go:embed central-pipeline-config.yml
|
|
|
|
var overrideConfiguration string
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
log.Println("Woodpecker central config server")
|
|
|
|
|
2022-02-27 22:31:40 +01:00
|
|
|
err := godotenv.Load()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Error loading .env file: %v", err)
|
|
|
|
}
|
|
|
|
|
2022-02-27 20:18:27 +01:00
|
|
|
secretToken := os.Getenv("CONFIG_SERVICE_SECRET")
|
|
|
|
host := os.Getenv("CONFIG_SERVICE_HOST")
|
|
|
|
filterRegex := os.Getenv("CONFIG_SERVICE_OVERRIDE_FILTER")
|
|
|
|
|
|
|
|
if secretToken == "" && host == "" {
|
2022-02-27 22:31:40 +01:00
|
|
|
log.Fatal("Please make sure CONFIG_SERVICE_HOST and CONFIG_SERVICE_SECRET are set properly")
|
2022-02-27 20:18:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
filter := regexp.MustCompile(filterRegex)
|
|
|
|
|
|
|
|
http.HandleFunc("/ciconfig", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != http.MethodPost {
|
|
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
signature, err := httpsignatures.FromRequest(r)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("config: invalid or missing signature in http.Request")
|
|
|
|
http.Error(w, "Invalid or Missing Signature", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if !signature.IsValid(secretToken, r) {
|
|
|
|
log.Printf("config: invalid signature in http.Request")
|
|
|
|
http.Error(w, "Invalid Signature", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var req incoming
|
|
|
|
body, err := ioutil.ReadAll(r.Body)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error reading body: %v", err)
|
|
|
|
http.Error(w, "can't read body", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(body, &req)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "Failed to parse JSON"+err.Error(), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if filter.MatchString(req.Repo.Name) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
err = json.NewEncoder(w).Encode(map[string]interface{}{"configs": []config{
|
|
|
|
{
|
|
|
|
Name: "central pipe",
|
|
|
|
Data: overrideConfiguration,
|
|
|
|
},
|
|
|
|
}})
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error on encoding json %v\n", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
w.WriteHeader(http.StatusNoContent) // use default config
|
|
|
|
// No need to write a response body
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
2022-02-27 22:31:40 +01:00
|
|
|
err = http.ListenAndServe(os.Getenv("CONFIG_SERVICE_HOST"), nil)
|
2022-02-27 20:18:27 +01:00
|
|
|
if err != nil {
|
2022-02-27 22:31:40 +01:00
|
|
|
log.Fatalf("Error on listen: %v", err)
|
2022-02-27 20:18:27 +01:00
|
|
|
}
|
|
|
|
}
|