Files
KubePi/internal/server/server.go
2021-07-29 16:56:41 +08:00

157 lines
3.4 KiB
Go

package server
import (
"embed"
"fmt"
"github.com/KubeOperator/ekko/internal/config"
v1Config "github.com/KubeOperator/ekko/internal/model/v1/config"
"github.com/KubeOperator/ekko/migrate"
"github.com/asdine/storm/v3"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/sessions"
"github.com/kataras/iris/v12/view"
"github.com/sirupsen/logrus"
"net/http"
"strings"
)
const sessionCookieName = "SESS_COOKIE_EKKO"
var EmbedWebDashboard embed.FS
var EmbedWebTerminal embed.FS
type EkkoSerer struct {
*iris.Application
db *storm.DB
logger *logrus.Logger
config v1Config.Config
}
func NewEkkoSerer() *EkkoSerer {
c := &EkkoSerer{}
return c.bootstrap()
}
func (e *EkkoSerer) setUpConfig() {
c, err := config.ReadConfig()
if err != nil {
panic(err)
}
e.config = c
}
func (e *EkkoSerer) setUpLogger() {
e.logger = logrus.New()
l, err := logrus.ParseLevel(e.config.Spec.Logger.Level)
if err != nil {
e.logger.Errorf("cant not parse logger level %s, %s,use default level: INFO", e.config.Spec.Logger.Level, err)
}
e.logger.SetLevel(l)
}
func (e *EkkoSerer) setUpDB() {
d, err := storm.Open(e.config.Spec.DB.Path)
if err != nil {
panic(err)
}
e.db = d
}
func (e *EkkoSerer) setUpStaticFile() {
dashboardFS := iris.PrefixDir("web/dashboard", http.FS(EmbedWebDashboard))
e.RegisterView(view.HTML(dashboardFS, ".html"))
e.HandleDir("/ui", dashboardFS)
terminalFS := iris.PrefixDir("web/terminal", http.FS(EmbedWebTerminal))
e.RegisterView(view.HTML(terminalFS, ".html"))
e.HandleDir("/terminal", terminalFS)
}
func (e *EkkoSerer) setUpSession() {
sess := sessions.New(sessions.Config{Cookie: sessionCookieName, AllowReclaim: true})
e.Use(sess.Handler())
}
func (e *EkkoSerer) setResultHandler() {
e.Use(func(ctx *context.Context) {
ctx.Next()
isProxyPath := func() bool {
p := ctx.GetCurrentRoute().Path()
ss := strings.Split(p, "/")
if len(ss) >= 3 {
for i := range ss {
if ss[i] == "proxy" || ss[i] == "ws" {
return true
}
}
}
return false
}()
if !isProxyPath {
if ctx.GetStatusCode() >= iris.StatusOK && ctx.GetStatusCode() < iris.StatusBadRequest {
resp := iris.Map{
"success": true,
"data": ctx.Values().Get("data"),
}
_, _ = ctx.JSON(resp)
}
}
})
}
func (e *EkkoSerer) setUpErrHandler() {
e.OnAnyErrorCode(func(ctx iris.Context) {
if ctx.Values().GetString("message") == "" {
switch ctx.GetStatusCode() {
case iris.StatusNotFound:
ctx.Values().Set("message", "the server could not find the requested resource")
}
}
err := iris.Map{
"success": false,
"code": ctx.GetStatusCode(),
"message": ctx.Values().GetString("message"),
}
_, _ = ctx.JSON(err)
})
}
func (e *EkkoSerer) runMigrations() {
migrate.RunMigrate(e.db, e.logger)
}
func (e *EkkoSerer) bootstrap() *EkkoSerer {
e.Application = iris.New()
e.setUpConfig()
e.setUpLogger()
e.setUpDB()
e.setUpSession()
e.setResultHandler()
e.setUpErrHandler()
e.runMigrations()
return e
}
var es *EkkoSerer
func DB() *storm.DB {
return es.db
}
func Config() v1Config.Config {
return es.config
}
func Logger() *logrus.Logger {
return es.logger
}
func Listen(route func(party iris.Party)) error {
es = NewEkkoSerer()
route(es.Application)
return es.Run(iris.Addr(fmt.Sprintf("%s:%d", es.config.Spec.Server.Bind.Host, es.config.Spec.Server.Bind.Port)))
}