configui/main.go

155 lines
3.4 KiB
Go

package main
import (
"embed"
"flag"
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"time"
"kumoly.io/tools/configui/configui"
"kumoly.io/tools/configui/public"
)
//go:embed templates
var tmplFS embed.FS
var tmpl *template.Template
var (
flagPath string
flagAction string
flagAlias string
flagConfigPath string
flagBind string
flagNoReconfig bool
flagLogFile string
flagAllow string
flagVer bool
)
var Version = "0.0.0"
var Build = "alpha"
var files = map[string]*configui.File{}
func init() {
// log.SetFlags(0)
flag.StringVar(&flagConfigPath, "f", "", "path to config file")
flag.StringVar(&flagPath, "p", "", "path to file, precedence over config")
flag.StringVar(&flagAlias, "n", "", "alias of file")
flag.StringVar(&flagAction, "c", "", "cmd to apply")
flag.StringVar(&flagLogFile, "log", "", "log to file")
flag.StringVar(&flagAllow, "allow", "", "IPs to allow, blank to allow all")
flag.StringVar(&flagBind, "bind", "0.0.0.0:8000", "address to bind")
flag.BoolVar(&flagNoReconfig, "static", false, "disable config api")
flag.BoolVar(&flagVer, "v", false, "show version")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: configui [options]\n")
flag.PrintDefaults()
}
}
func main() {
flag.Parse()
if flagVer {
fmt.Printf("%v - %v\n", Version, Build)
}
// setup logging
if flagLogFile != "" {
f, err := os.OpenFile(flagLogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Error opening file: %v", err)
}
defer f.Close()
mwriter := io.MultiWriter(f, os.Stderr)
log.SetOutput(mwriter)
}
// setup values
if flagPath != "" {
if flagAlias == "" {
flagAlias = flagPath
}
files[flagAlias] = &configui.File{
Path: flagPath,
Alias: flagAlias,
Action: flagAction,
}
} else if flagConfigPath == "" {
log.Println("no config found")
} else {
conf, err := os.ReadFile(flagConfigPath)
if err != nil {
log.Fatalln(err)
}
ftmp, err := configui.ReadConfig(string(conf))
if err != nil {
log.Fatalln(err)
}
files = configui.GetFileMap(ftmp)
}
// setup routes
mux := http.NewServeMux()
mux.HandleFunc("/api/conf", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
getConfigHandler(w, r)
} else if r.Method == "POST" {
LoadConfig(w, r)
} else {
w.WriteHeader(404)
}
})
mux.HandleFunc("/api/files", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
ListFiles(w, r)
} else {
w.WriteHeader(404)
}
})
mux.HandleFunc("/api/file", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
GetFile(w, r)
} else if r.Method == "POST" {
PostFile(w, r)
} else {
w.WriteHeader(404)
}
})
mux.HandleFunc("/api/apply", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
Apply(w, r)
} else {
w.WriteHeader(404)
}
})
mux.HandleFunc("/api/export", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
Download(w, r)
} else {
w.WriteHeader(404)
}
})
mux.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.FS(public.FS))))
tmpl = template.Must(template.New("").ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
setRoutes(mux)
server := &http.Server{
Addr: flagBind,
WriteTimeout: time.Second * 3,
ReadTimeout: time.Second * 30,
Handler: Middleware(mux),
}
// start server
log.Println("Listening on", flagBind)
log.Fatal(server.ListenAndServe())
}