209 lines
4.2 KiB
Go
209 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"embed"
|
|
"encoding/json"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"html/template"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"kumoly.io/tools/configui/configui"
|
|
)
|
|
|
|
//go:embed templates
|
|
var tmplFS embed.FS
|
|
var tmpl *template.Template
|
|
|
|
var (
|
|
cmdPath string
|
|
cmdAction string
|
|
cmdAlias string
|
|
cmdConfigPath string
|
|
|
|
cmdBind string
|
|
)
|
|
|
|
var files = map[string]*configui.File{}
|
|
|
|
func init() {
|
|
log.SetFlags(0)
|
|
|
|
flag.StringVar(&cmdConfigPath, "f", "", "path to config file")
|
|
flag.StringVar(&cmdPath, "p", "", "path to file, precedence over config")
|
|
flag.StringVar(&cmdAlias, "n", "", "alias of file")
|
|
flag.StringVar(&cmdAction, "c", "", "cmd to apply")
|
|
flag.StringVar(&cmdBind, "b", "localhost:8000", "address to bind")
|
|
flag.Usage = func() {
|
|
fmt.Fprintf(os.Stderr, "Usage: configui [options]\n")
|
|
flag.PrintDefaults()
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
// setup values
|
|
if cmdPath != "" {
|
|
if cmdAlias == "" {
|
|
cmdAlias = cmdPath
|
|
}
|
|
files[cmdAlias] = &configui.File{
|
|
Path: cmdPath,
|
|
Alias: cmdAlias,
|
|
Action: cmdAction,
|
|
}
|
|
} else if cmdConfigPath == "" {
|
|
log.Fatalln(errors.New("no config found"))
|
|
} else {
|
|
conf, err := os.ReadFile(cmdConfigPath)
|
|
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/files", func(rw http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "GET" {
|
|
ListFiles(rw, r)
|
|
} else {
|
|
rw.WriteHeader(404)
|
|
}
|
|
})
|
|
mux.HandleFunc("/api/file", func(rw http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "GET" {
|
|
GetFile(rw, r)
|
|
} else if r.Method == "POST" {
|
|
PostFile(rw, r)
|
|
} else {
|
|
rw.WriteHeader(404)
|
|
}
|
|
})
|
|
mux.HandleFunc("/api/apply", func(rw http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "POST" {
|
|
Apply(rw, r)
|
|
} else {
|
|
rw.WriteHeader(404)
|
|
}
|
|
})
|
|
mux.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
|
|
buf := &bytes.Buffer{}
|
|
err := tmpl.ExecuteTemplate(buf, "home", nil)
|
|
if err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
} else {
|
|
rw.Write(buf.Bytes())
|
|
}
|
|
})
|
|
|
|
tmpl = template.Must(template.New("").ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
|
|
|
|
server := &http.Server{
|
|
Addr: cmdBind,
|
|
WriteTimeout: time.Second * 3,
|
|
ReadTimeout: time.Second * 30,
|
|
Handler: mux,
|
|
}
|
|
|
|
// start server
|
|
log.Println("Listening on ", cmdBind)
|
|
log.Fatal(server.ListenAndServe())
|
|
}
|
|
|
|
func ListFiles(rw http.ResponseWriter, r *http.Request) {
|
|
data, err := json.Marshal(files)
|
|
if err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
rw.Write(data)
|
|
}
|
|
|
|
func GetFile(rw http.ResponseWriter, r *http.Request) {
|
|
name := r.URL.Query().Get("name")
|
|
file, ok := files[name]
|
|
if name == "" || !ok {
|
|
rw.WriteHeader(404)
|
|
rw.Write([]byte("file not found"))
|
|
return
|
|
}
|
|
data, err := file.Read()
|
|
if err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
response, err := json.Marshal(map[string]string{
|
|
"path": file.Path,
|
|
"name": file.Alias,
|
|
"action": file.Action,
|
|
"data": string(data),
|
|
})
|
|
if err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
rw.Write(response)
|
|
}
|
|
|
|
func PostFile(rw http.ResponseWriter, r *http.Request) {
|
|
data, err := ioutil.ReadAll(r.Body)
|
|
r.Body.Close()
|
|
if err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
f := configui.File{}
|
|
if err := json.Unmarshal(data, &f); err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
file, ok := files[f.Alias]
|
|
if !ok {
|
|
rw.WriteHeader(404)
|
|
rw.Write([]byte("file not found"))
|
|
return
|
|
}
|
|
if err := file.Write([]byte(f.Data)); err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
rw.Write([]byte("ok"))
|
|
}
|
|
|
|
func Apply(rw http.ResponseWriter, r *http.Request) {
|
|
name := r.URL.Query().Get("name")
|
|
file, ok := files[name]
|
|
if name == "" || !ok {
|
|
rw.WriteHeader(404)
|
|
rw.Write([]byte("file not found"))
|
|
return
|
|
}
|
|
result, err := file.Do()
|
|
if err != nil {
|
|
rw.WriteHeader(500)
|
|
rw.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
rw.Write([]byte(result))
|
|
}
|