package main import ( "encoding/json" "gopkg.in/macaron.v1" // "github.com/go-macaron/pongo2" mypongo2 "github.com/flosch/pongo2" "log" "net/http" "os" "os/exec" "strings" ) const CFGFILE = "/config/config.json" const WEBSITETPLFILE = "/app/website.tpl" const WEBSITENGINXFILE = "/etc/nginx/conf.d/websites.conf" const ADMINTPLFILE = "/app/admin.tpl" const ADMINNGINXFILE = "/etc/nginx/conf.d/admin.conf" var Config struct { Admin Website `json:"admin"` Websites []Website `json:"websites"` } type Website struct { Name string `json:"name"` Enabled bool `json:"enabled"` Url string `json:"url"` Aliases []string `json:"aliases"` Http Http `json:"http"` Https Https `json:"https"` } type Http struct { Redirect_to_https bool `json:"redirect_to_https"` Locations []Location `json:"locations"` } type Https struct { Http2 bool `json:"http2"` Letsencrypt bool `json:"letsencrypt"` Locations []Location `json:"locations"` } type Location struct { Location string `json:"location"` Destination string `json:"destination"` } func loadConfig() { jsonFile, err := os.Open(CFGFILE) if err != nil { log.Println(err) } defer jsonFile.Close() jsonParser := json.NewDecoder(jsonFile) if err = jsonParser.Decode(&Config); err != nil { log.Println("Error parsing config file: ", err.Error()) } log.Println("Successfully parsed: " + CFGFILE) } func startServer() { m := macaron.Classic() // m.Use(macaron.Static("public")) // static files served by nginx m.Get("/", myHandler) log.Println("Server is running...") log.Println(http.ListenAndServe("0.0.0.0:4000", m)) } func main() { loadConfig() writeAdminTemplate() writeTemplate() nginxReloadConfig() startServer() } func nginxReloadConfig() { // TODO: check why this is always in error but it's working... _, err := exec.Command("/usr/sbin/nginx", "-s", "reload").Output() if err != nil { log.Printf("Successfully reloaded nginx config") } else { log.Printf("could not reload nginx: %s", err) } } func writeTemplate() { t, err := mypongo2.FromFile(WEBSITETPLFILE) if err != nil { log.Printf("could not render: %s", err) return } f, err := os.Create(WEBSITENGINXFILE) if err != nil { log.Printf("cannot open: %s", WEBSITENGINXFILE) } defer f.Close() for _, v := range Config.Websites { var http_locations []map[string]string var https_locations []map[string]string for _, s := range v.Http.Locations { loc := map[string]string{ "location": s.Location, "destination": s.Destination, } http_locations = append(http_locations, loc) } for _, s := range v.Https.Locations { loc := map[string]string{ "location": s.Location, "destination": s.Destination, } https_locations = append(https_locations, loc) } data := mypongo2.Context{ "url": v.Url, "name": v.Name, "http2": v.Https.Http2, "aliases": v.Aliases, "http_redirect_to_https": v.Http.Redirect_to_https, "https_locations": https_locations, "http_locations": http_locations, } if err := t.ExecuteWriter(data, f); err != nil { log.Printf("could not execute: %s", err) } } log.Printf("Successfully created: %s", WEBSITENGINXFILE) } func writeAdminTemplate() { t, err := mypongo2.FromFile(ADMINTPLFILE) if err != nil { log.Printf("could not render: %s", err) return } f, err := os.Create(ADMINNGINXFILE) if err != nil { log.Printf("cannot open: %s", ADMINNGINXFILE) } defer f.Close() data := mypongo2.Context{ "url": Config.Admin.Url, "http2": Config.Admin.Https.Http2, "http_redirect_to_https": Config.Admin.Http.Redirect_to_https, } if err := t.ExecuteWriter(data, f); err != nil { log.Printf("could not execute: %s", err) } log.Printf("Successfully created: %s", ADMINNGINXFILE) } func myHandler(ctx *macaron.Context) string { return "The request path is: " + ctx.Req.RequestURI } func init() { mypongo2.RegisterFilter("filterdomaindots", PongoFilterDomainDots) } func PongoFilterDomainDots(in *mypongo2.Value, param *mypongo2.Value) (out *mypongo2.Value, err *mypongo2.Error) { if !in.IsString() { return nil, &mypongo2.Error{ Sender: "you should use only strings", } } s := in.String() s = strings.Replace(s, ".", "\\.", -1) return mypongo2.AsValue(s), nil }