rewrite using net/http
tronnet/workflows: Static Analysis -- Golang / static-go (push) Failing after 5s
tronnet/workflows: Static Analysis -- Golang / static-go (push) Failing after 5s
This commit is contained in:
1 parent
db8ed2e830
commit
98790dbe3b
9 files changed
+271
-190
No files matched your search
+25
-28
@@ -4,12 +4,11 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"proxmoxaas-dashboard/app/common"
|
||||
"proxmoxaas-dashboard/app/routes"
|
||||
"strings"
|
||||
"web" // go will complain here until the first build
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/tdewolff/minify/v2"
|
||||
)
|
||||
|
||||
@@ -19,44 +18,42 @@ func Run() {
|
||||
|
||||
common.Global = common.GetConfig(*configPath)
|
||||
|
||||
// setup gin
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
router := gin.Default()
|
||||
// setup http router
|
||||
router := http.NewServeMux()
|
||||
|
||||
// setup static resources
|
||||
m := common.InitMinify()
|
||||
ServeStatic(router, m)
|
||||
html := common.MinifyStatic(m, web.Templates)
|
||||
common.TMPL = common.LoadHTMLToGin(router, html)
|
||||
common.TMPL = common.LoadHTML(html)
|
||||
|
||||
// dynamic routes for pages and page fragments
|
||||
router.GET("/", routes.HandleGETIndex)
|
||||
router.GET("/index", routes.HandleGETIndex)
|
||||
router.GET("/index/instances", routes.HandleGETInstancesFragment)
|
||||
router.GET("/account", routes.HandleGETAccount)
|
||||
router.GET("/config", routes.HandleGETConfig)
|
||||
router.GET("/config/volumes", routes.HandleGETConfigVolumesFragment)
|
||||
router.GET("/config/nets", routes.HandleGETConfigNetsFragment)
|
||||
router.GET("/config/devices", routes.HandleGETConfigDevicesFragment)
|
||||
router.GET("/config/boot", routes.HandleGETConfigBootFragment)
|
||||
router.GET("/backups", routes.HandleGETBackups)
|
||||
router.GET("/backups/backups", routes.HandleGETBackupsFragment)
|
||||
router.GET("/login", routes.HandleGETLogin)
|
||||
router.GET("/settings", routes.HandleGETSettings)
|
||||
router.HandleFunc("GET /", routes.HandleGETIndex)
|
||||
router.HandleFunc("GET /index", routes.HandleGETIndex)
|
||||
router.HandleFunc("GET /index/instances", routes.HandleGETInstancesFragment)
|
||||
router.HandleFunc("GET /account", routes.HandleGETAccount)
|
||||
router.HandleFunc("GET /config", routes.HandleGETConfig)
|
||||
router.HandleFunc("GET /config/volumes", routes.HandleGETConfigVolumesFragment)
|
||||
router.HandleFunc("GET /config/nets", routes.HandleGETConfigNetsFragment)
|
||||
router.HandleFunc("GET /config/devices", routes.HandleGETConfigDevicesFragment)
|
||||
router.HandleFunc("GET /config/boot", routes.HandleGETConfigBootFragment)
|
||||
router.HandleFunc("GET /backups", routes.HandleGETBackups)
|
||||
router.HandleFunc("GET /backups/backups", routes.HandleGETBackupsFragment)
|
||||
router.HandleFunc("GET /login", routes.HandleGETLogin)
|
||||
router.HandleFunc("GET /settings", routes.HandleGETSettings)
|
||||
|
||||
// run on all interfaces with port
|
||||
log.Fatal("[ERR ] starting gin router: ", router.Run(fmt.Sprintf("0.0.0.0:%d", common.Global.Port)))
|
||||
log.Fatal("[ERR ] starting gin router: ", http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", common.Global.Port), router))
|
||||
}
|
||||
|
||||
// setup static resources under web (css, images, modules, scripts)
|
||||
func ServeStatic(router *gin.Engine, m *minify.M) {
|
||||
func ServeStatic(router *http.ServeMux, m *minify.M) {
|
||||
static := common.MinifyStatic(m, web.Static)
|
||||
router.GET("/websrc/*path", func(c *gin.Context) {
|
||||
path, _ := c.Params.Get("path")
|
||||
trimed_path := strings.Replace(path, "/", "", 1) // replace leading "/" captured by *path
|
||||
data := static[trimed_path]
|
||||
fmt.Println(path)
|
||||
c.Header("Content-Encoding", data.MimeType.Encoding)
|
||||
c.Data(200, data.MimeType.Type, []byte(data.Data))
|
||||
router.HandleFunc("GET /websrc/{path...}", func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.PathValue("path")
|
||||
data := static[path]
|
||||
w.Header().Set("Content-Encoding", data.MimeType.Encoding)
|
||||
w.Header().Set("Content-Type", data.MimeType.Type)
|
||||
w.Write([]byte(data.Data))
|
||||
})
|
||||
}
|
||||
+42
-25
@@ -16,7 +16,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/tdewolff/minify/v2"
|
||||
|
||||
paas "proxmoxaas-common-lib"
|
||||
@@ -103,9 +102,8 @@ func MinifyStatic(m *minify.M, files embed.FS) map[string]StaticFile {
|
||||
}
|
||||
}
|
||||
|
||||
func LoadHTMLToGin(engine *gin.Engine, html map[string]StaticFile) *template.Template {
|
||||
root := template.New("")
|
||||
engine.FuncMap = template.FuncMap{
|
||||
func LoadHTML(html map[string]StaticFile) *template.Template {
|
||||
funcMap := template.FuncMap{
|
||||
"MapKeys": func(x any, sep string) string {
|
||||
v := reflect.ValueOf(x)
|
||||
keys := v.MapKeys()
|
||||
@@ -133,9 +131,11 @@ func LoadHTMLToGin(engine *gin.Engine, html map[string]StaticFile) *template.Tem
|
||||
return dict, nil
|
||||
},
|
||||
}
|
||||
tmpl := template.Must(root, LoadAndAddToRoot(engine.FuncMap, root, html))
|
||||
engine.SetHTMLTemplate(root)
|
||||
return tmpl
|
||||
root := template.New("").Funcs(funcMap)
|
||||
if err := LoadAndAddToRoot(funcMap, root, html); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
func LoadAndAddToRoot(FuncMap template.FuncMap, root *template.Template, html map[string]StaticFile) error {
|
||||
@@ -170,9 +170,9 @@ func TemplateMinifier(m *minify.M, w io.Writer, r io.Reader, _ map[string]string
|
||||
return nil
|
||||
}
|
||||
|
||||
func HandleNonFatalError(c *gin.Context, err error) {
|
||||
func HandleNonFatalError(w http.ResponseWriter, err error) {
|
||||
log.Printf("[WARN] encountered a non-fatal error: %s", err.Error())
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
func RequestGetAPI(path string, auth *paas.Auth, body any) (*http.Response, int, error) {
|
||||
@@ -221,25 +221,41 @@ func RequestGetAPI(path string, auth *paas.Auth, body any) (*http.Response, int,
|
||||
return response, response.StatusCode, nil
|
||||
}
|
||||
|
||||
func GetAuthFromRequest(c *gin.Context) (paas.Auth, error) {
|
||||
_, errAuth := c.Cookie("auth")
|
||||
username, errUsername := c.Cookie("username")
|
||||
token, errToken := c.Cookie("PVEAuthCookie")
|
||||
csrf, errCSRF := c.Cookie("CSRFPreventionToken")
|
||||
access, errAccess := c.Cookie("PAASAccessManagerTicket")
|
||||
if errUsername != nil || errAuth != nil || errToken != nil || errCSRF != nil || errAccess != nil {
|
||||
return paas.Auth{}, fmt.Errorf("error occured getting user cookies: (auth: %s, token: %s, csrf: %s)", errAuth, errToken, errCSRF)
|
||||
} else {
|
||||
return paas.Auth{Username: username, Token: token, CSRF: csrf, AccessManagerTicket: access}, nil
|
||||
}
|
||||
func GetAuthFromRequest(r *http.Request) (paas.Auth, error) {
|
||||
_, errAuth := r.Cookie("auth")
|
||||
username, errUsername := r.Cookie("username")
|
||||
token, errToken := r.Cookie("PVEAuthCookie")
|
||||
csrf, errCSRF := r.Cookie("CSRFPreventionToken")
|
||||
access, errAccess := r.Cookie("PAASAccessManagerTicket")
|
||||
|
||||
if errUsername != nil || errAuth != nil || errToken != nil ||
|
||||
errCSRF != nil || errAccess != nil {
|
||||
return paas.Auth{}, fmt.Errorf(
|
||||
"error occurred getting user cookies: (auth: %v, token: %v, csrf: %v)",
|
||||
errAuth, errToken, errCSRF,
|
||||
)
|
||||
}
|
||||
|
||||
func GetInstancePathFromRequest(c *gin.Context) (paas.InstancePath, error) {
|
||||
req_node := c.Query("node")
|
||||
req_type := c.Query("type")
|
||||
req_vmid := c.Query("vmid")
|
||||
return paas.Auth{
|
||||
Username: username.Value,
|
||||
Token: token.Value,
|
||||
CSRF: csrf.Value,
|
||||
AccessManagerTicket: access.Value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetInstancePathFromRequest(r *http.Request) (paas.InstancePath, error) {
|
||||
query := r.URL.Query()
|
||||
|
||||
req_node := query.Get("node")
|
||||
req_type := query.Get("type")
|
||||
req_vmid := query.Get("vmid")
|
||||
|
||||
if req_node == "" || req_type == "" || req_vmid == "" {
|
||||
return paas.InstancePath{}, fmt.Errorf("request missing required values: (node: %s, type: %s, vmid: %s)", req_node, req_type, req_vmid)
|
||||
return paas.InstancePath{}, fmt.Errorf(
|
||||
"request missing required values: (node: %s, type: %s, vmid: %s)",
|
||||
req_node, req_type, req_vmid,
|
||||
)
|
||||
}
|
||||
|
||||
vmid_int, err := strconv.ParseUint(req_vmid, 10, 64)
|
||||
@@ -252,6 +268,7 @@ func GetInstancePathFromRequest(c *gin.Context) (paas.InstancePath, error) {
|
||||
InstanceType: paas.InstanceType(req_type),
|
||||
InstanceID: paas.InstanceID(vmid_int),
|
||||
}
|
||||
|
||||
return vm_path, nil
|
||||
}
|
||||
|
||||
|
||||
+17
-7
@@ -1,13 +1,13 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
paas "proxmoxaas-common-lib"
|
||||
"proxmoxaas-dashboard/app/common"
|
||||
|
||||
"github.com/gerow/go-color"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
@@ -40,29 +40,39 @@ var Green = color.RGB{
|
||||
B: 0,
|
||||
}
|
||||
|
||||
func HandleGETAccount(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETAccount(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
user, err := GetUserBasic(auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
pools, err := GetUserPools(auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "html/account.html", gin.H{
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/account.html", map[string]any{
|
||||
"global": common.Global,
|
||||
"page": "account",
|
||||
"user": user,
|
||||
"pools": pools,
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Redirect(http.StatusFound, "/login") // if user is not authed, redirect user to login page
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Redirect(w, r, "/login", http.StatusFound) // if user is not authed, redirect user to login page
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-19
@@ -1,13 +1,13 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
paas "proxmoxaas-common-lib"
|
||||
"proxmoxaas-dashboard/app/common"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
@@ -20,61 +20,78 @@ type InstanceBackup struct {
|
||||
TimeFormatted string
|
||||
}
|
||||
|
||||
func HandleGETBackups(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETBackups(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
backups, err := GetInstanceBackups(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance backups: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance backups: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
config, err := GetInstanceConfig(vm_path, auth) // only used for the VM's name
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "html/backups.html", gin.H{
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/index.html", map[string]any{
|
||||
"global": common.Global,
|
||||
"page": "backups",
|
||||
"backups": backups,
|
||||
"config": config,
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Redirect(http.StatusFound, "/login")
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETBackupsFragment(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETBackupsFragment(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil { // user should be authed, try to return index with population
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
backups, err := GetInstanceBackups(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance backups: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance backups: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/plain")
|
||||
err = common.TMPL.ExecuteTemplate(c.Writer, "html/backups-backups.go.tmpl", gin.H{
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/backups-backups.go.tmpl", map[string]any{
|
||||
"backups": backups,
|
||||
})
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Status(http.StatusOK)
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else { // return 401
|
||||
c.Status(http.StatusUnauthorized)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+84
-52
@@ -1,6 +1,7 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
paas "proxmoxaas-common-lib"
|
||||
@@ -8,7 +9,6 @@ import (
|
||||
"slices"
|
||||
"sort"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
@@ -31,24 +31,26 @@ type PoolConfig struct {
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETConfig(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETConfig(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := GetInstanceConfig(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if config.Type == "VM" { // if VM, fetch CPU types from node
|
||||
config.ProctypeSelect, err = GetCPUTypes(vm_path, config.Pool, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting proctypes: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting proctypes: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
for i, cpu := range config.ProctypeSelect.Options {
|
||||
@@ -57,125 +59,155 @@ func HandleGETConfig(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "html/config.html", gin.H{
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/config.html", map[string]any{
|
||||
"global": common.Global,
|
||||
"page": "config",
|
||||
"config": config,
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Redirect(http.StatusFound, "/login")
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETConfigVolumesFragment(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETConfigVolumesFragment(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := GetInstanceConfig(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/plain")
|
||||
err = common.TMPL.ExecuteTemplate(c.Writer, "html/config-volumes.go.tmpl", gin.H{
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/config-volumes.go.tmpl", map[string]any{
|
||||
"config": config,
|
||||
})
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Status(http.StatusOK)
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.Status(http.StatusUnauthorized)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETConfigNetsFragment(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETConfigNetsFragment(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := GetInstanceConfig(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/plain")
|
||||
err = common.TMPL.ExecuteTemplate(c.Writer, "html/config-nets.go.tmpl", gin.H{
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/config-nets.go.tmpl", map[string]any{
|
||||
"config": config,
|
||||
})
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Status(http.StatusOK)
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.Status(http.StatusUnauthorized)
|
||||
} else { // return 401
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETConfigDevicesFragment(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETConfigDevicesFragment(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := GetInstanceConfig(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/plain")
|
||||
err = common.TMPL.ExecuteTemplate(c.Writer, "html/config-devices.go.tmpl", gin.H{
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/config-devices.go.tmpl", map[string]any{
|
||||
"config": config,
|
||||
})
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Status(http.StatusOK)
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.Status(http.StatusUnauthorized)
|
||||
} else { // return 401
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETConfigBootFragment(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETConfigBootFragment(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
vm_path, err := common.GetInstancePathFromRequest(c)
|
||||
vm_path, err := common.GetInstancePathFromRequest(r)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := GetInstanceConfig(vm_path, auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
common.HandleNonFatalError(w, fmt.Errorf("error encountered getting instance config: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", "text/plain")
|
||||
err = common.TMPL.ExecuteTemplate(c.Writer, "html/config-boot.go.tmpl", gin.H{
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/config-boot.go.tmpl", map[string]any{
|
||||
"config": config,
|
||||
})
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Status(http.StatusOK)
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.Status(http.StatusUnauthorized)
|
||||
} else { // return 401
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-16
@@ -1,13 +1,13 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
paas "proxmoxaas-common-lib"
|
||||
"proxmoxaas-dashboard/app/common"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
@@ -45,46 +45,61 @@ type InstanceStatus struct {
|
||||
Status string
|
||||
}
|
||||
|
||||
func HandleGETIndex(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETIndex(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil { // user should be authed, try to return index with population
|
||||
instances, _, err := GetClusterResources(auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
page := gin.H{
|
||||
page := map[string]any{
|
||||
"global": common.Global,
|
||||
"page": "index",
|
||||
"instances": instances,
|
||||
}
|
||||
c.HTML(http.StatusOK, "html/index.html", page)
|
||||
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/index.html", page)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else { // return index without populating
|
||||
c.Redirect(http.StatusFound, "/login") // if user is not authed, redirect user to login page
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func HandleGETInstancesFragment(c *gin.Context) {
|
||||
auth, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETInstancesFragment(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil { // user should be authed, try to return index with population
|
||||
instances, _, err := GetClusterResources(auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
c.Header("Content-Type", "text/plain")
|
||||
err = common.TMPL.ExecuteTemplate(c.Writer, "html/index-instances.go.tmpl", gin.H{
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/index-instances.go.tmpl", map[string]any{
|
||||
"instances": instances,
|
||||
})
|
||||
if err != nil {
|
||||
c.Status(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Status(http.StatusOK)
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else { // return 401
|
||||
c.Status(http.StatusUnauthorized)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GetClusterResources(auth paas.Auth) (map[uint]InstanceCard, map[string]Node, error) {
|
||||
|
||||
+14
-4
@@ -1,11 +1,11 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"proxmoxaas-dashboard/app/common"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
@@ -41,10 +41,11 @@ func GetLoginRealms() ([]Realm, error) {
|
||||
return realms, nil
|
||||
}
|
||||
|
||||
func HandleGETLogin(c *gin.Context) {
|
||||
func HandleGETLogin(w http.ResponseWriter, r *http.Request) {
|
||||
realms, err := GetLoginRealms()
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(c, err)
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
sel := common.Select{
|
||||
@@ -60,9 +61,18 @@ func HandleGETLogin(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "html/login.html", gin.H{
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/login.html", map[string]any{
|
||||
"global": common.Global,
|
||||
"page": "login",
|
||||
"realms": sel,
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
}
|
||||
+21
-6
@@ -1,20 +1,35 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"proxmoxaas-dashboard/app/common"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func HandleGETSettings(c *gin.Context) {
|
||||
_, err := common.GetAuthFromRequest(c)
|
||||
func HandleGETSettings(w http.ResponseWriter, r *http.Request) {
|
||||
auth, err := common.GetAuthFromRequest(r)
|
||||
if err == nil {
|
||||
c.HTML(http.StatusOK, "html/settings.html", gin.H{
|
||||
_, err := GetUserBasic(auth)
|
||||
if err != nil {
|
||||
common.HandleNonFatalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
body := bytes.Buffer{}
|
||||
err = common.TMPL.ExecuteTemplate(&body, "html/settings.html", map[string]any{
|
||||
"global": common.Global,
|
||||
"page": "settings",
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
c.Redirect(http.StatusFound, "/login")
|
||||
w.Write(body.Bytes())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ go 1.27.0
|
||||
|
||||
require (
|
||||
github.com/gerow/go-color v0.0.0-20140219113758-125d37f527f1
|
||||
github.com/gin-gonic/gin v1.12.0
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0
|
||||
github.com/tdewolff/minify/v2 v2.24.17
|
||||
proxmoxaas-common-lib v0.0.0
|
||||
@@ -15,35 +14,4 @@ replace proxmoxaas-common-lib => ./proxmoxaas-common-lib
|
||||
|
||||
replace web => ./dist/web
|
||||
|
||||
require (
|
||||
github.com/bytedance/gopkg v0.1.4 // indirect
|
||||
github.com/bytedance/sonic v1.15.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.2 // indirect
|
||||
github.com/cloudwego/base64x v0.1.7 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.15 // indirect
|
||||
github.com/gin-contrib/sse v1.1.1 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.30.3 // indirect
|
||||
github.com/goccy/go-json v0.10.6 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.5.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.24 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.61.0 // indirect
|
||||
github.com/tdewolff/parse/v2 v2.8.16 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.2 // indirect
|
||||
go.mongodb.org/mongo-driver/v2 v2.8.1 // indirect
|
||||
golang.org/x/arch v0.30.0 // indirect
|
||||
golang.org/x/crypto v0.55.0 // indirect
|
||||
golang.org/x/net v0.58.0 // indirect
|
||||
golang.org/x/sys v0.47.0 // indirect
|
||||
golang.org/x/text v0.41.0 // indirect
|
||||
google.golang.org/protobuf v1.36.12 // indirect
|
||||
)
|
||||
require github.com/tdewolff/parse/v2 v2.8.16 // indirect
|
||||
Reference in new issue
Block a user