155 lines
3.4 KiB
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", "localhost: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())
|
|
}
|