153 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			3.3 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
 | 
						|
	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(&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())
 | 
						|
}
 |