From 32e3f946ab2f699b7eaeaf22181aab24a8472446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Mon, 16 Jul 2018 22:08:50 +0200 Subject: [PATCH] refactor(backend): turn index.html back into Go template There are a few config keys that needs to be passed to ui code before react app starts, we'll render them in the index.html as template --- assets.go | 35 ++++++++++++++++++++++++++++++++++- main.go | 5 +++++ views.go | 27 +++++++++++++++++++++------ views_test.go | 6 ++++++ 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/assets.go b/assets.go index 1c7a73b4a..bc48da1a5 100644 --- a/assets.go +++ b/assets.go @@ -3,11 +3,14 @@ package main import ( "bytes" "errors" + "html/template" "net/http" "strings" - assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/gin-gonic/gin" + + assetfs "github.com/elazarl/go-bindata-assetfs" + log "github.com/sirupsen/logrus" ) type binaryFileSystem struct { @@ -43,6 +46,36 @@ func newBinaryFileSystem(root string) *binaryFileSystem { return &binaryFileSystem{fs} } +// load a template from binary asset resource +func loadTemplate(t *template.Template, path string) *template.Template { + templateContent, err := Asset(path) + if err != nil { + log.Fatal(err) + } + + var tmpl *template.Template + if t == nil { + // if template wasn't yet initialized do it here + t = template.New(path) + } + + if path == t.Name() { + tmpl = t + } else { + // if we already have an instance of template.Template then + // add a new file to it + tmpl = t.New(path) + } + + _, err = tmpl.Parse(string(templateContent)) + if err != nil { + log.Fatal(err) + return nil + } + + return t +} + func responseFromStaticFile(c *gin.Context, filepath string, contentType string) { if !staticFileSystem.Exists("/", filepath) { c.String(404, "Not found") diff --git a/main.go b/main.go index d4fbae3b0..1ff82378f 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "html/template" "net/http" "path" "strings" @@ -172,6 +173,10 @@ func main() { router := gin.New() + var t *template.Template + t = loadTemplate(t, "ui/build/index.html") + router.SetHTMLTemplate(t) + prom := ginprometheus.NewPrometheus("gin") prom.MetricsPath = getViewURL("/metrics") prom.Use(router) diff --git a/views.go b/views.go index c743e53b7..e84f2c084 100644 --- a/views.go +++ b/views.go @@ -1,6 +1,7 @@ package main import ( + "encoding/base64" "encoding/json" "net/http" "sort" @@ -17,12 +18,6 @@ import ( log "github.com/sirupsen/logrus" ) -func index(c *gin.Context) { - // http.FileServer doesn't allow serving index.html, it will always redirect - // such request to ./ so we need to manually read that file and return it - responseFromStaticFile(c, "/index.html", "text/html") -} - func notFound(c *gin.Context) { c.String(404, "404 page not found") } @@ -31,6 +26,26 @@ func noCache(c *gin.Context) { c.Header("Cache-Control", "no-cache, no-store, must-revalidate") } +func index(c *gin.Context) { + start := time.Now() + + noCache(c) + + filtersJSON, err := json.Marshal(config.Config.Filters.Default) + if err != nil { + panic(err) + } + filtersB64 := base64.StdEncoding.EncodeToString(filtersJSON) + + c.HTML(http.StatusOK, "ui/build/index.html", gin.H{ + "Version": version, + "SentryDSN": config.Config.Sentry.Public, + "DefaultFilter": filtersB64, + }) + + log.Infof("[%s] %s %s took %s", c.ClientIP(), c.Request.Method, c.Request.RequestURI, time.Since(start)) +} + func logAlertsView(c *gin.Context, cacheStatus string, duration time.Duration) { log.Infof("[%s %s] <%d> %s %s took %s", c.ClientIP(), cacheStatus, http.StatusOK, c.Request.Method, c.Request.RequestURI, duration) } diff --git a/views_test.go b/views_test.go index 2e9fceb5b..f64cb356e 100644 --- a/views_test.go +++ b/views_test.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "html/template" "io/ioutil" "net/http" "net/http/httptest" @@ -39,6 +40,11 @@ func ginTestEngine() *gin.Engine { gin.SetMode(gin.TestMode) r := gin.New() setupRouter(r) + + var t *template.Template + t = loadTemplate(t, "ui/build/index.html") + r.SetHTMLTemplate(t) + return r }