From 3349ae9015df28d67b50ba41080e7f444514c681 Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Sat, 23 Sep 2023 18:04:51 +0200 Subject: [PATCH 1/6] Add subpath in the backend Signed-off-by: Thomas Labarussias --- README.md | 6 ++-- configuration/configuration.go | 1 + main.go | 52 +++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 14241bc..720158d 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,13 @@ Usage of Falcosidekick-UI: -d boolean Disable authentication (environment "FALCOSIDEKICK_UI_DISABLEAUTH") -l string - Log level: "debug", "info", "warning", "error" (default "info", environment "FALCOSIDEKICK_UI_LOGLEVEL") + Log level: "debug", "info", "warning", "error" (default "info", environment "FALCOSIDEKICK_UI_LOGLEVEL") -p int Listen Port (default "2802", environment "FALCOSIDEKICK_UI_PORT") -r string Redis server address (default "localhost:6379", environment "FALCOSIDEKICK_UI_REDIS_URL") +-s string + Serve the UI and the API under this subpath (default "", environment "FALCOSIDEKICK_UI_SUBPATH") -t string TTL for keys, the format is X, with unit (s, m, h, d, W, M, y)" (default "0", environment "FALCOSIDEKICK_UI_TTL") @@ -38,7 +40,7 @@ Usage of Falcosidekick-UI: -v boolean Display version -w string - Redis password (default "", environment "FALCOSIDEKICK_REDIS_PASSWORD") + Redis password (default "", environment "FALCOSIDEKICK_UI_REDIS_PASSWORD") -x boolean Allow CORS for development (environment "FALCOSIDEKICK_UI_DEV") ``` diff --git a/configuration/configuration.go b/configuration/configuration.go index 95e1735..eb34147 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -11,6 +11,7 @@ type Configuration struct { LogLevel string `json:"log-level"` TTL int `json:"ttl"` Credentials string `json:"credentials"` + Subpath string `json:"subpath"` } var config *Configuration diff --git a/main.go b/main.go index cae095f..39f921c 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,7 @@ func init() { loglevel := utils.GetStringFlagOrEnvParam("l", "FALCOSIDEKICK_UI_LOGLEVEL", "info", "Log Level") user := utils.GetStringFlagOrEnvParam("u", "FALCOSIDEKICK_UI_USER", "admin:admin", "User in format :") disableauth := utils.GetBoolFlagOrEnvParam("d", "FALCOSIDEKICK_UI_DISABLEAUTH", false, "Disable authentication") + subpath := utils.GetStringFlagOrEnvParam("s", "FALCOSIDEKICK_UI_SUBPATH", "", "Serve the UI and the API under this subpath") flag.Usage = func() { help := `Usage of Falcosidekick-UI: @@ -45,11 +46,13 @@ func init() { -d boolean Disable authentication (environment "FALCOSIDEKICK_UI_DISABLEAUTH") -l string - Log level: "debug", "info", "warning", "error" (default "info", environment "FALCOSIDEKICK_UI_LOGLEVEL") + Log level: "debug", "info", "warning", "error" (default "info", environment "FALCOSIDEKICK_UI_LOGLEVEL") -p int Listen Port (default "2802", environment "FALCOSIDEKICK_UI_PORT") -r string Redis server address (default "localhost:6379", environment "FALCOSIDEKICK_UI_REDIS_URL") +-s string + Serve the UI and the API under this subpath (default "", environment "FALCOSIDEKICK_UI_SUBPATH") -t string TTL for keys, the format is X, with unit (s, m, h, d, W, M, y)" (default "0", environment "FALCOSIDEKICK_UI_TTL") @@ -58,7 +61,7 @@ func init() { -v boolean Display version -w string - Redis password (default "", environment "FALCOSIDEKICK_REDIS_PASSWORD") + Redis password (default "", environment "FALCOSIDEKICK_UI_REDIS_PASSWORD") -x boolean Allow CORS for development (environment "FALCOSIDEKICK_UI_DEV") ` @@ -91,6 +94,11 @@ func init() { config.LogLevel = *loglevel config.Credentials = *user config.DisableAuth = *disableauth + if !strings.HasPrefix(*subpath, "/") { + utils.WriteLog("warning", "Wrong subpath, it must start with /") + } else { + config.Subpath = strings.TrimSuffix(*subpath, "/") + } if utils.GetPriortiyInt(config.LogLevel) < 0 { config.LogLevel = "info" @@ -117,41 +125,51 @@ func init() { func main() { e := echo.New() v := &CustomValidator{validator: validator.New()} - c := configuration.GetConfiguration() + config := configuration.GetConfiguration() e.Validator = v e.HideBanner = true e.HidePort = true - if c.DevMode { + if config.DevMode { utils.WriteLog("warning", "DEV mode enabled") e.Use(middleware.CORS()) } - if c.DisableAuth { + if config.DisableAuth { utils.WriteLog("warning", "Auhentication disabled") e.Use(middleware.CORS()) } - utils.WriteLog("info", fmt.Sprintf("Falcosidekick UI is listening on %v:%v", c.ListenAddress, c.ListenPort)) - utils.WriteLog("info", fmt.Sprintf("log level is %v", c.LogLevel)) + e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + c.Response().Header().Set("Subpath", config.Subpath) + if err := next(c); err != nil { + c.Error(err) + } + return nil + } + }) + + utils.WriteLog("info", fmt.Sprintf("Falcosidekick UI is listening on %v:%v", config.ListenAddress, config.ListenPort)) + utils.WriteLog("info", fmt.Sprintf("Log level is %v", config.LogLevel)) - e.GET("/docs/*", echoSwagger.WrapHandler) - e.GET("/docs", func(c echo.Context) error { + e.GET(config.Subpath+"/docs/*", echoSwagger.WrapHandler) + e.GET(config.Subpath+"/docs", func(c echo.Context) error { if err := c.Redirect(http.StatusPermanentRedirect, "docs/"); err != nil { return err } return nil }) - e.Static("/*", "frontend/dist").Name = "webui-home" - e.Static("/dashboard", "frontend/dist").Name = "webui-dashboard" - e.Static("/events", "frontend/dist").Name = "webui-events" - e.Static("/info", "frontend/dist").Name = "webui-info" - e.Static("/login", "frontend/dist").Name = "webui-login" - e.POST("/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks + e.Static(config.Subpath+"/*", "frontend/dist").Name = "webui-home" + e.Static(config.Subpath+"/dashboard", "frontend/dist").Name = "webui-dashboard" + e.Static(config.Subpath+"/events", "frontend/dist").Name = "webui-events" + e.Static(config.Subpath+"/info", "frontend/dist").Name = "webui-info" + e.Static(config.Subpath+"/login", "frontend/dist").Name = "webui-login" + e.POST(config.Subpath+"/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks // e.Use(middleware.BodyDump(func(c echo.Context, reqBody, resBody []byte) { // })) - apiRoute := e.Group("/api/v1") + apiRoute := e.Group(config.Subpath + "/api/v1") apiRoute.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ Skipper: func(c echo.Context) bool { if configuration.GetConfiguration().DisableAuth { @@ -192,7 +210,7 @@ func main() { eventsRoute.GET("/count/:groupby", api.CountByEvent).Name = "count-events-by" eventsRoute.GET("/search", api.Search).Name = "search-keys" - e.Logger.Fatal(e.Start(fmt.Sprintf("%v:%v", c.ListenAddress, c.ListenPort))) + e.Logger.Fatal(e.Start(fmt.Sprintf("%v:%v", config.ListenAddress, config.ListenPort))) } func (cv *CustomValidator) Validate(i interface{}) error { From 410e0c17999c1e1ea0f06c12ec34cba3cabbf871 Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Sun, 24 Sep 2023 12:48:50 +0200 Subject: [PATCH 2/6] feat: init subpath support Signed-off-by: Frank Jogeleit --- frontend/src/router/index.js | 2 +- frontend/vue.config.js | 3 +++ main.go | 8 ++++---- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 frontend/vue.config.js diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index 65b6f7d..0f679c8 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -44,7 +44,7 @@ const routes = [ ]; const router = new VueRouter({ - mode: 'history', + mode: 'hash', base: process.env.BASE_URL, routes, }); diff --git a/frontend/vue.config.js b/frontend/vue.config.js new file mode 100644 index 0000000..fdb4f9e --- /dev/null +++ b/frontend/vue.config.js @@ -0,0 +1,3 @@ +module.exports = { + publicPath: './', +}; diff --git a/main.go b/main.go index 39f921c..7dab08d 100644 --- a/main.go +++ b/main.go @@ -40,12 +40,12 @@ func init() { subpath := utils.GetStringFlagOrEnvParam("s", "FALCOSIDEKICK_UI_SUBPATH", "", "Serve the UI and the API under this subpath") flag.Usage = func() { - help := `Usage of Falcosidekick-UI: + help := `Usage of Falcosidekick-UI: -a string Listen Address (default "0.0.0.0", environment "FALCOSIDEKICK_UI_ADDR") -d boolean Disable authentication (environment "FALCOSIDEKICK_UI_DISABLEAUTH") --l string +-l string Log level: "debug", "info", "warning", "error" (default "info", environment "FALCOSIDEKICK_UI_LOGLEVEL") -p int Listen Port (default "2802", environment "FALCOSIDEKICK_UI_PORT") @@ -56,11 +56,11 @@ func init() { -t string TTL for keys, the format is X, with unit (s, m, h, d, W, M, y)" (default "0", environment "FALCOSIDEKICK_UI_TTL") --u string +-u string User in format : (default "admin:admin", environment "FALCOSIDEKICK_UI_USER") -v boolean Display version --w string +-w string Redis password (default "", environment "FALCOSIDEKICK_UI_REDIS_PASSWORD") -x boolean Allow CORS for development (environment "FALCOSIDEKICK_UI_DEV") From fc598e041ae4f68c71c9f50bfee79a1a515a2796 Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Sun, 24 Sep 2023 14:45:48 +0200 Subject: [PATCH 3/6] handle api subpath Signed-off-by: Frank Jogeleit --- frontend/src/http.js | 2 +- main.go | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/frontend/src/http.js b/frontend/src/http.js index 76e4147..e53d3c3 100644 --- a/frontend/src/http.js +++ b/frontend/src/http.js @@ -4,7 +4,7 @@ import store from './store'; const production = process.env.NODE_ENV === 'production'; const api = axios.create({ - baseURL: `${production ? `//${window.location.host}` : process.env.VUE_APP_API}/api/v1`, + baseURL: `${production ? `//${window.location.host}${window.location.pathname}` : process.env.VUE_APP_API}api/v1`, headers: { 'Content-type': 'application/json', 'Access-Control-Allow-Origin': '*', diff --git a/main.go b/main.go index 7dab08d..9d7bd91 100644 --- a/main.go +++ b/main.go @@ -154,21 +154,11 @@ func main() { e.GET(config.Subpath+"/docs/*", echoSwagger.WrapHandler) e.GET(config.Subpath+"/docs", func(c echo.Context) error { - if err := c.Redirect(http.StatusPermanentRedirect, "docs/"); err != nil { - return err - } - return nil + return c.Redirect(http.StatusPermanentRedirect, "docs/") }) e.Static(config.Subpath+"/*", "frontend/dist").Name = "webui-home" - e.Static(config.Subpath+"/dashboard", "frontend/dist").Name = "webui-dashboard" - e.Static(config.Subpath+"/events", "frontend/dist").Name = "webui-events" - e.Static(config.Subpath+"/info", "frontend/dist").Name = "webui-info" - e.Static(config.Subpath+"/login", "frontend/dist").Name = "webui-login" e.POST(config.Subpath+"/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks - // e.Use(middleware.BodyDump(func(c echo.Context, reqBody, resBody []byte) { - // })) - apiRoute := e.Group(config.Subpath + "/api/v1") apiRoute.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ Skipper: func(c echo.Context) bool { From 29e34af9b531dd7bd95c83c277f50f0f3abc5cf3 Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Sun, 24 Sep 2023 16:22:35 +0200 Subject: [PATCH 4/6] Add redirects to subpath + keep an endpoint without subpath for falcosidekick puts Signed-off-by: Thomas Labarussias --- main.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/main.go b/main.go index 9d7bd91..93c2fe5 100644 --- a/main.go +++ b/main.go @@ -152,11 +152,21 @@ func main() { utils.WriteLog("info", fmt.Sprintf("Falcosidekick UI is listening on %v:%v", config.ListenAddress, config.ListenPort)) utils.WriteLog("info", fmt.Sprintf("Log level is %v", config.LogLevel)) + if config.Subpath != "" { + e.GET("/", func(c echo.Context) error { + return c.Redirect(http.StatusPermanentRedirect, config.Subpath+"/") + }) + } + e.GET(strings.TrimSuffix(config.Subpath, "/"), func(c echo.Context) error { + return c.Redirect(http.StatusPermanentRedirect, config.Subpath+"/") + }) + e.GET(config.Subpath+"/docs/*", echoSwagger.WrapHandler) e.GET(config.Subpath+"/docs", func(c echo.Context) error { return c.Redirect(http.StatusPermanentRedirect, "docs/") }) e.Static(config.Subpath+"/*", "frontend/dist").Name = "webui-home" + e.POST("/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks e.POST(config.Subpath+"/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks apiRoute := e.Group(config.Subpath + "/api/v1") From b1bcbe6e6318f3d033f7c68d2c93ead685662f7c Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Sun, 24 Sep 2023 16:25:55 +0200 Subject: [PATCH 5/6] remove the header with subpath Signed-off-by: Thomas Labarussias --- main.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/main.go b/main.go index 93c2fe5..9ce2a3b 100644 --- a/main.go +++ b/main.go @@ -139,15 +139,6 @@ func main() { utils.WriteLog("warning", "Auhentication disabled") e.Use(middleware.CORS()) } - e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - c.Response().Header().Set("Subpath", config.Subpath) - if err := next(c); err != nil { - c.Error(err) - } - return nil - } - }) utils.WriteLog("info", fmt.Sprintf("Falcosidekick UI is listening on %v:%v", config.ListenAddress, config.ListenPort)) utils.WriteLog("info", fmt.Sprintf("Log level is %v", config.LogLevel)) From c13dbeb36c170f1a65dba088fb7c1f4f8eebe36e Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Sun, 24 Sep 2023 16:40:13 +0200 Subject: [PATCH 6/6] remove subpath config from the backend Signed-off-by: Thomas Labarussias --- README.md | 2 -- configuration/configuration.go | 1 - main.go | 29 ++++++----------------------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 720158d..6554c6c 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,6 @@ Usage of Falcosidekick-UI: Listen Port (default "2802", environment "FALCOSIDEKICK_UI_PORT") -r string Redis server address (default "localhost:6379", environment "FALCOSIDEKICK_UI_REDIS_URL") --s string - Serve the UI and the API under this subpath (default "", environment "FALCOSIDEKICK_UI_SUBPATH") -t string TTL for keys, the format is X, with unit (s, m, h, d, W, M, y)" (default "0", environment "FALCOSIDEKICK_UI_TTL") diff --git a/configuration/configuration.go b/configuration/configuration.go index eb34147..95e1735 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -11,7 +11,6 @@ type Configuration struct { LogLevel string `json:"log-level"` TTL int `json:"ttl"` Credentials string `json:"credentials"` - Subpath string `json:"subpath"` } var config *Configuration diff --git a/main.go b/main.go index 9ce2a3b..a2d966d 100644 --- a/main.go +++ b/main.go @@ -37,7 +37,6 @@ func init() { loglevel := utils.GetStringFlagOrEnvParam("l", "FALCOSIDEKICK_UI_LOGLEVEL", "info", "Log Level") user := utils.GetStringFlagOrEnvParam("u", "FALCOSIDEKICK_UI_USER", "admin:admin", "User in format :") disableauth := utils.GetBoolFlagOrEnvParam("d", "FALCOSIDEKICK_UI_DISABLEAUTH", false, "Disable authentication") - subpath := utils.GetStringFlagOrEnvParam("s", "FALCOSIDEKICK_UI_SUBPATH", "", "Serve the UI and the API under this subpath") flag.Usage = func() { help := `Usage of Falcosidekick-UI: @@ -51,8 +50,6 @@ func init() { Listen Port (default "2802", environment "FALCOSIDEKICK_UI_PORT") -r string Redis server address (default "localhost:6379", environment "FALCOSIDEKICK_UI_REDIS_URL") --s string - Serve the UI and the API under this subpath (default "", environment "FALCOSIDEKICK_UI_SUBPATH") -t string TTL for keys, the format is X, with unit (s, m, h, d, W, M, y)" (default "0", environment "FALCOSIDEKICK_UI_TTL") @@ -94,11 +91,6 @@ func init() { config.LogLevel = *loglevel config.Credentials = *user config.DisableAuth = *disableauth - if !strings.HasPrefix(*subpath, "/") { - utils.WriteLog("warning", "Wrong subpath, it must start with /") - } else { - config.Subpath = strings.TrimSuffix(*subpath, "/") - } if utils.GetPriortiyInt(config.LogLevel) < 0 { config.LogLevel = "info" @@ -143,24 +135,15 @@ func main() { utils.WriteLog("info", fmt.Sprintf("Falcosidekick UI is listening on %v:%v", config.ListenAddress, config.ListenPort)) utils.WriteLog("info", fmt.Sprintf("Log level is %v", config.LogLevel)) - if config.Subpath != "" { - e.GET("/", func(c echo.Context) error { - return c.Redirect(http.StatusPermanentRedirect, config.Subpath+"/") - }) - } - e.GET(strings.TrimSuffix(config.Subpath, "/"), func(c echo.Context) error { - return c.Redirect(http.StatusPermanentRedirect, config.Subpath+"/") - }) - - e.GET(config.Subpath+"/docs/*", echoSwagger.WrapHandler) - e.GET(config.Subpath+"/docs", func(c echo.Context) error { + e.GET("/docs/*", echoSwagger.WrapHandler) + e.GET("/docs", func(c echo.Context) error { return c.Redirect(http.StatusPermanentRedirect, "docs/") }) - e.Static(config.Subpath+"/*", "frontend/dist").Name = "webui-home" - e.POST("/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks - e.POST(config.Subpath+"/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks + e.Static("/*", "frontend/dist").Name = "webui-home" + e.POST("/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks + e.POST("/", api.AddEvent).Name = "add-event" // for compatibility with old Falcosidekicks - apiRoute := e.Group(config.Subpath + "/api/v1") + apiRoute := e.Group("/api/v1") apiRoute.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ Skipper: func(c echo.Context) bool { if configuration.GetConfiguration().DisableAuth {