podterminal/web/router.go

132 lines
2.9 KiB
Go
Raw Normal View History

2024-01-27 11:20:40 +01:00
package web
import (
"fmt"
"log"
"net"
"net/http/httputil"
"net/url"
"time"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/spf13/viper"
2024-01-27 11:20:40 +01:00
"git.jmbit.de/jmb/podterminal/pods"
)
var proxies = make(map[string]*httputil.ReverseProxy)
func Run(listener net.Listener) error {
router := setupRouter()
err := router.RunListener(listener)
if err != nil {
return err
}
return nil
}
func setupRouter() *gin.Engine {
log.Println("Setting up router")
2024-01-27 11:20:40 +01:00
gin.ForceConsoleColor()
gin.SetMode("release")
router := gin.New()
store := cookie.NewStore([]byte(uuid.NewString()))
store.Options(sessions.Options{
MaxAge: viper.GetInt("maxAge"),
})
2024-01-27 11:20:40 +01:00
router.Use(gin.Recovery())
router.Use(sessions.Sessions("session", store))
//router.Use(urlLog())
2024-01-28 11:24:18 +01:00
router.Use(containerProxy)
// router.Any("/", containerProxy)
log.Println("Router is ready")
2024-01-27 11:20:40 +01:00
return router
}
func urlLog() gin.HandlerFunc {
return func(c *gin.Context) {
log.Printf(
"[INFO] %s: %s: %s",
c.Request.RemoteAddr,
c.Request.Method,
c.Request.URL,
)
}
}
func createReverseProxy(backendService string) (*httputil.ReverseProxy, error) {
var err error
log.Println("Creating reverse Proxy for ", backendService)
2024-01-27 11:20:40 +01:00
backendURL, err := url.Parse(backendService)
if err != nil {
log.Printf("Could not parse backend URL: %v", err)
2024-01-27 11:20:40 +01:00
}
proxy := &httputil.ReverseProxy{
Rewrite: func(request *httputil.ProxyRequest) {
request.SetURL(backendURL)
request.Out.Host = request.In.Host
},
}
return proxy, err
}
func containerProxy(c *gin.Context) {
session := sessions.Default(c)
sessionID := session.ID()
2024-01-27 11:20:40 +01:00
if session.Get("ct") == nil {
log.Println("Creating Container for Session ", sessionID)
2024-01-27 11:20:40 +01:00
ct, err := pods.CreateContainer()
if err != nil {
c.HTML(500, "Error", fmt.Sprintf("[%s] Could not create Container: %v", sessionID, err))
2024-01-27 11:20:40 +01:00
c.Abort()
}
err = pods.StartContainer(ct)
if err != nil {
c.HTML(500, "Error", fmt.Sprintf("[%s] Could not start Container: %v", sessionID, err))
2024-01-27 11:20:40 +01:00
c.Abort()
}
// Hack to wait for Container to start up and get assigned an IP
2024-01-28 11:24:18 +01:00
time.Sleep(3 * time.Second)
2024-01-27 11:20:40 +01:00
ctip, err := pods.GetContainerIP(ct)
if err != nil {
c.HTML(500, "Error", fmt.Sprintf("[%s] Could not get Container ip: %v", sessionID, err))
2024-01-27 11:20:40 +01:00
c.Abort()
}
proxies[ct], err = createReverseProxy(fmt.Sprintf("http://%s:3000", ctip))
if err != nil {
c.HTML(
500,
"Error",
fmt.Sprintf("[%s] Could not create Container Proxy: %v", sessionID, err),
)
2024-01-27 11:20:40 +01:00
c.Abort()
}
session.Set("ct", ct)
session.Save()
c.Redirect(301, "/")
} else {
sessionCT := session.Get("ct")
switch sessionCT.(type) {
2024-01-27 11:20:40 +01:00
case string:
default:
c.HTML(500, "Error", "Session Container ID is not a string")
2024-01-27 11:20:40 +01:00
c.Abort()
}
id := session.Get("ct").(string)
proxy := proxies[id]
proxy.ServeHTTP(c.Writer, c.Request)
}
}