Add mechanism for bundling UI assets. (#153)
* Add mechanism for bundling UI assets. The scripts/uigen.sh script will check out the UI repo, build assets, create a static assets file, and clean up. The dev Makefile target has been modified to run this script if no assets file is found. There is also a build-ui target that will unilaterally update (the dev target only builds if the file isn't found, but doesn't update). The handler has been updated to add the default org ID as a header if the request path is "/". Co-authored-by: Randall Morey <randall@randallmorey.com>
This commit is contained in:
1 parent
8d8bb42418
commit
8da4effd5e
10 files changed
+147
-65
No files matched your search
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -25,6 +24,7 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/projects"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/roles"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/users"
|
||||
"github.com/hashicorp/watchtower/internal/ui"
|
||||
)
|
||||
|
||||
type HandlerProperties struct {
|
||||
@@ -43,10 +43,7 @@ func (c *Controller) handler(props HandlerProperties) (http.Handler, error) {
|
||||
}
|
||||
mux.Handle("/v1/", h)
|
||||
|
||||
// TODO: enable when not in this mode, when we bundle the assets
|
||||
if c.conf.RawConfig.PassthroughDirectory != "" {
|
||||
mux.Handle("/", handleUi(c))
|
||||
}
|
||||
mux.Handle("/", handleUi(c))
|
||||
|
||||
corsWrappedHandler := wrapHandlerWithCors(mux, props)
|
||||
commonWrappedHandler := wrapHandlerWithCommonFuncs(corsWrappedHandler, c, props)
|
||||
@@ -55,13 +52,25 @@ func (c *Controller) handler(props HandlerProperties) (http.Handler, error) {
|
||||
}
|
||||
|
||||
func handleUi(c *Controller) http.Handler {
|
||||
// TODO: Do stuff with real UI data when it's bundled. We may also have to
|
||||
// do a similar thing with fetching index.html in advance.
|
||||
var nextHandler http.Handler
|
||||
if c.conf.RawConfig.PassthroughDirectory != "" {
|
||||
nextHandler = devPassthroughHandler(c)
|
||||
nextHandler = ui.DevPassthroughHandler(c.logger, c.conf.RawConfig.PassthroughDirectory)
|
||||
} else {
|
||||
nextHandler = http.FileServer(ui.AssetFile())
|
||||
}
|
||||
|
||||
rootHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/":
|
||||
irw := newIndexResponseWriter(c.conf.DefaultOrgId)
|
||||
nextHandler.ServeHTTP(irw, r)
|
||||
irw.writeToWriter(w)
|
||||
|
||||
default:
|
||||
nextHandler.ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
@@ -95,25 +104,10 @@ func handleUi(c *Controller) http.Handler {
|
||||
}
|
||||
|
||||
// Fall through to the next handler
|
||||
nextHandler.ServeHTTP(w, r)
|
||||
rootHandler.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func devPassthroughHandler(c *Controller) http.Handler {
|
||||
// Panic may not be ideal but this is never a production call and it'll
|
||||
// panic on startup. We could also just change the function to return
|
||||
// an error.
|
||||
abs, err := filepath.Abs(c.conf.RawConfig.PassthroughDirectory)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.logger.Warn("serving passthrough files at /", "path", abs)
|
||||
fs := http.FileServer(http.Dir(abs))
|
||||
prefixHandler := http.StripPrefix("/", fs)
|
||||
|
||||
return prefixHandler
|
||||
}
|
||||
|
||||
func handleGrpcGateway(c *Controller) (http.Handler, error) {
|
||||
// Register*ServiceHandlerServer methods ignore the passed in ctx. Using the baseContext now just in case this changes
|
||||
// in the future, at which point we'll want to be using the baseContext.
|
||||
|
||||
Reference in new issue
Block a user