diff --git a/cdb/db_heartbeat.go b/cdb/db_heartbeat.go index 0964f00..179abc9 100644 --- a/cdb/db_heartbeat.go +++ b/cdb/db_heartbeat.go @@ -76,7 +76,7 @@ func (oDb *DB) HBUpdate(ctx context.Context, hb DBHeartbeat) error { defer logDuration("HBUpdate cluster id:"+hb.ClusterID+" "+hb.Driver, time.Now()) const ( qUpdate = "" + - "INSERT INTO `hbmon` (`cluster_id`, `node_id`, `peer_node_id`, `driver`, `name`, `desc`, `stat e`, `beating`, `last_beating`, `updated`)" + + "INSERT INTO `hbmon` (`cluster_id`, `node_id`, `peer_node_id`, `driver`, `name`, `desc`, `state`, `beating`, `last_beating`, `updated`)" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())" + "ON DUPLICATE KEY UPDATE" + " `cluster_id` = VALUES(`cluster_id`), `driver` = VALUES(`driver`), `desc` = VALUES(`desc`), `state` = VALUES(`state`), `beating`= VALUES(`beating`), `last_beating`= VALUES(`last_beating`), `updated`= VALUES(`updated`)" diff --git a/cmd/feeder.go b/cmd/feeder.go index e723bc8..9ce4248 100644 --- a/cmd/feeder.go +++ b/cmd/feeder.go @@ -14,32 +14,30 @@ import ( "github.com/spf13/viper" "github.com/opensvc/oc3/feeder" - feederhandlers "github.com/opensvc/oc3/feeder/handlers" + "github.com/opensvc/oc3/feeder/handlers" "github.com/opensvc/oc3/xauth" ) -const ( - pathApi = "/api" - pathSpec = "openapi.json" - pathPprof = "pprof" - pathMetric = "metrics" - pathVersion = "version" - pathDoc = "docs" -) - func startFeeder() error { addr := viper.GetString("feeder.addr") return listenAndServeFeeder(addr) } func listenAndServeFeeder(addr string) error { + const ( + pathApi = "/api" + pathSpec = "openapi.json" + pathPprof = "/pprof" + pathMetric = "/metrics" + ) + db, err := newDatabase() if err != nil { return err } - fromPath := func(p string) string { return fmt.Sprintf("%s/%s", pathApi, p) } endingSlash := func(s string) string { return strings.TrimSuffix(s, "/") + "/" } + relPath := func(s string) string { return "./" + strings.TrimPrefix(s, "/") } // get enabled features enableUI := viper.GetBool("feeder.ui.enable") @@ -47,21 +45,26 @@ func listenAndServeFeeder(addr string) error { enablePprof := viper.GetBool("feeder.pprof.enable") // define public paths - publics := []string{fromPath(pathVersion)} + publicPath := []string{pathApi + "/version"} + publicPrefix := []string{} if enableUI { - publics = append(publics, fromPath(pathDoc), fromPath(pathSpec)) + publicPath = append(publicPath, pathApi) + for _, p := range []string{"", pathSpec, "swagger-ui.css", "swagger-ui-bundle.js", "swagger-ui-standalone-preset.js"} { + publicPath = append(publicPath, pathApi+"/"+p) + } } if enableMetrics { - publics = append(publics, fromPath(pathMetric)) + publicPath = append(publicPath, pathMetric) } if enablePprof { - publics = append(publics, fromPath(pathPprof)) + publicPrefix = append(publicPrefix, pathPprof) } - slog.Info(fmt.Sprintf("public paths: %s", strings.Join(publics, ", "))) + slog.Info(fmt.Sprintf("public paths: %s", strings.Join(publicPath, ", "))) + slog.Info(fmt.Sprintf("public path prefixes: %s", strings.Join(publicPrefix, ", "))) // define auth middleware authMiddleware := feederhandlers.AuthMiddleware(union.New( - xauth.NewPublicStrategy(publics...), + xauth.NewPublicStrategy(publicPath, publicPrefix), xauth.NewBasicNode(db), )) @@ -81,11 +84,10 @@ func listenAndServeFeeder(addr string) error { if enablePprof { // TODO: move to authenticated path - s := fromPath(pathPprof) - slog.Info(fmt.Sprintf("add handler for profiling: %s", s)) - pprof.Register(e, s) - e.GET(s, func(c echo.Context) error { - return c.Redirect(http.StatusMovedPermanently, endingSlash(pathPprof)) + slog.Info(fmt.Sprintf("add handler for profiling: %s", pathPprof)) + pprof.Register(e, pathPprof) + e.GET(pathPprof, func(c echo.Context) error { + return c.Redirect(http.StatusMovedPermanently, endingSlash(relPath(pathPprof))) }) } @@ -93,16 +95,15 @@ func listenAndServeFeeder(addr string) error { // TODO: move to authenticated path slog.Info(fmt.Sprintf("add handler for metrics: %s", pathMetric)) e.Use(echoprometheus.NewMiddleware("oc3_feeder")) - e.GET(fromPath(pathMetric), echoprometheus.NewHandler()) + e.GET(pathMetric, echoprometheus.NewHandler()) } if enableUI { - s := fromPath(pathDoc) - slog.Info(fmt.Sprintf("add handler for documentation ui: %s", s)) - g := e.Group(s) - g.Use(feederhandlers.UIMiddleware(context.Background(), s, "../"+pathSpec)) - e.GET(s, func(c echo.Context) error { - return c.Redirect(http.StatusMovedPermanently, endingSlash(pathDoc)) + slog.Info(fmt.Sprintf("add handler for documentation ui: %s", pathApi)) + g := e.Group(pathApi) + g.Use(feederhandlers.UIMiddleware(context.Background(), pathApi, pathSpec)) + e.GET(pathApi, func(c echo.Context) error { + return c.Redirect(http.StatusMovedPermanently, endingSlash(relPath(pathApi))) }) } diff --git a/cmd/server.go b/cmd/server.go index b229edc..8a332bf 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -2,7 +2,10 @@ package cmd import ( "context" + "fmt" "log/slog" + "net/http" + "strings" "github.com/labstack/echo-contrib/echoprometheus" "github.com/labstack/echo-contrib/pprof" @@ -11,7 +14,7 @@ import ( "github.com/spf13/viper" "github.com/opensvc/oc3/server" - serverhandlers "github.com/opensvc/oc3/server/handlers" + "github.com/opensvc/oc3/server/handlers" "github.com/opensvc/oc3/xauth" ) @@ -21,50 +24,88 @@ func startServer() error { } func listenAndServeServer(addr string) error { - enableUI := viper.GetBool("server.ui.enable") + const ( + pathApi = "/api" + pathSpec = "openapi.json" + pathPprof = "/pprof" + pathMetric = "/metrics" + ) db, err := newDatabase() if err != nil { return err } - redisClient := newRedis() + endingSlash := func(s string) string { return strings.TrimSuffix(s, "/") + "/" } + relPath := func(s string) string { return "./" + strings.TrimPrefix(s, "/") } + + // get enabled features + enableUI := viper.GetBool("server.ui.enable") + enableMetrics := viper.GetBool("server.metrics.enable") + enablePprof := viper.GetBool("server.pprof.enable") + // define public paths + publicPath := []string{pathApi + "/version"} + publicPrefix := []string{} + if enableUI { + publicPath = append(publicPath, pathApi) + for _, p := range []string{"", pathSpec, "swagger-ui.css", "swagger-ui-bundle.js", "swagger-ui-standalone-preset.js"} { + publicPath = append(publicPath, pathApi+"/"+p) + } + } + if enableMetrics { + publicPath = append(publicPath, pathMetric) + } + if enablePprof { + publicPrefix = append(publicPrefix, pathPprof) + } + slog.Info(fmt.Sprintf("public paths: %s", strings.Join(publicPath, ", "))) + slog.Info(fmt.Sprintf("public path prefixes: %s", strings.Join(publicPrefix, ", "))) + + // define auth middleware + authMiddleware := serverhandlers.AuthMiddleware(union.New( + xauth.NewPublicStrategy(publicPath, publicPrefix), + xauth.NewBasicNode(db), + )) e := echo.New() e.HideBanner = true e.HidePort = true - if viper.GetBool("server.pprof.enable") { - slog.Info("add handler /oc3/api/public/pprof") - pprof.Register(e, "/oc3/api/public/pprof") - } + e.Use(authMiddleware) - strategy := union.New( - xauth.NewPublicStrategy("/oc3/api/public/", "/oc3/api/docs", "/oc3/api/version", "/oc3/api/openapi"), - xauth.NewBasicNode(db), - ) - if viper.GetBool("server.metrics.enable") { - slog.Info("add handler /oc3/api/public/metrics") - e.Use(echoprometheus.NewMiddleware("oc3_api")) - e.GET("/oc3/api/public/metrics", echoprometheus.NewHandler()) - } - e.Use(serverhandlers.AuthMiddleware(strategy)) - slog.Info("register openapi handlers with base url: /oc3/api") + slog.Info(fmt.Sprintf("add handler for openapi: %s", pathApi)) server.RegisterHandlersWithBaseURL(e, &serverhandlers.Api{ DB: db, - Redis: redisClient, + Redis: newRedis(), UI: enableUI, SyncTimeout: viper.GetDuration("server.sync.timeout"), - }, "/oc3/api") + }, pathApi) + + if enablePprof { + // TODO: move to authenticated path + slog.Info(fmt.Sprintf("add handler for profiling: %s", pathPprof)) + pprof.Register(e, pathPprof) + e.GET(pathPprof, func(c echo.Context) error { + return c.Redirect(http.StatusMovedPermanently, endingSlash(relPath(pathPprof))) + }) + } + + if enableMetrics { + // TODO: move to authenticated path + slog.Info(fmt.Sprintf("add handler for metrics: %s", pathMetric)) + e.Use(echoprometheus.NewMiddleware("oc3_feeder")) + e.GET(pathMetric, echoprometheus.NewHandler()) + } + if enableUI { - registerServerUI(e) + slog.Info(fmt.Sprintf("add handler for documentation ui: %s", pathApi)) + g := e.Group(pathApi) + g.Use(serverhandlers.UIMiddleware(context.Background(), pathApi, pathSpec)) + e.GET(pathApi, func(c echo.Context) error { + return c.Redirect(http.StatusMovedPermanently, endingSlash(relPath(pathApi))) + }) } + slog.Info("listen on " + addr) return e.Start(addr) } - -func registerServerUI(e *echo.Echo) { - slog.Info("add handler /oc3/api/docs/") - g := e.Group("/oc3/api/docs") - g.Use(serverhandlers.UIMiddleware(context.Background())) -} diff --git a/feeder/api.yaml b/feeder/api.yaml index 85d9c8e..babdee1 100644 --- a/feeder/api.yaml +++ b/feeder/api.yaml @@ -1,7 +1,7 @@ openapi: 3.0.0 servers: - - url: /api + - url: ./ info: title: opensvc feeder api diff --git a/feeder/codegen_server_gen.go b/feeder/codegen_server_gen.go index 8e36a55..b197640 100644 --- a/feeder/codegen_server_gen.go +++ b/feeder/codegen_server_gen.go @@ -249,40 +249,40 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/feeder/handlers/middleware-ui.go b/feeder/handlers/middleware-ui.go index 2a0d086..ed6ecf5 100644 --- a/feeder/handlers/middleware-ui.go +++ b/feeder/handlers/middleware-ui.go @@ -6,15 +6,12 @@ import ( "github.com/allenai/go-swaggerui" "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" ) func UIMiddleware(_ context.Context, prefix, specUrl string) echo.MiddlewareFunc { uiHandler := http.StripPrefix(prefix, swaggerui.Handler(specUrl)) echoUI := echo.WrapHandler(uiHandler) - middleware.WWWRedirect() - return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { return echoUI(c) diff --git a/feeder/handlers/middleware.go b/feeder/handlers/middleware.go index 163d093..85fafb4 100644 --- a/feeder/handlers/middleware.go +++ b/feeder/handlers/middleware.go @@ -16,7 +16,7 @@ const ( XNodename = "XNodename" ) -// AuthMiddleware returns auth middleware that authenticate requests from strategies. +// AuthMiddleware returns auth middleware that authenticates requests from strategies. func AuthMiddleware(strategies union.Union) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { @@ -24,6 +24,8 @@ func AuthMiddleware(strategies union.Union) echo.MiddlewareFunc { if err != nil { code := http.StatusUnauthorized return JSONProblem(c, code, http.StatusText(code), err.Error()) + } else if user == nil { + return next(c) } ext := user.GetExtensions() if nodeID := ext.Get(xauth.XNodeID); nodeID != "" { diff --git a/server/api.yaml b/server/api.yaml index 8da6c14..dce6e88 100644 --- a/server/api.yaml +++ b/server/api.yaml @@ -1,14 +1,14 @@ openapi: 3.0.0 servers: - - url: /oc3/api + - url: ./ info: title: opensvc collector api version: 1.0.0 paths: - /docs/openapi: + /openapi.json: get: operationId: GetSwagger tags: diff --git a/server/codegen_server_gen.go b/server/codegen_server_gen.go index 564f890..6e3c492 100644 --- a/server/codegen_server_gen.go +++ b/server/codegen_server_gen.go @@ -19,7 +19,7 @@ import ( // ServerInterface represents all server handlers. type ServerInterface interface { - // (GET /docs/openapi) + // (GET /openapi.json) GetSwagger(ctx echo.Context) error // (GET /version) @@ -77,7 +77,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL Handler: si, } - router.GET(baseURL+"/docs/openapi", wrapper.GetSwagger) + router.GET(baseURL+"/openapi.json", wrapper.GetSwagger) router.GET(baseURL+"/version", wrapper.GetVersion) } @@ -85,19 +85,19 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/7xU34/bRBD+V0YDD61k7KQpIJmnCjh6gLiKpPDQ5GG9nthb2bvL7Pi4a5T/HY19yeV+", - "tQKkPmWz8818n7+ZnR3a0MfgyUvCcodMKQafaPzzcjbXHxu8kBc9mhg7Z4244Iv3KXi9S7al3ujpS6Yt", - "lvhFcVuzmKKpeMOh6qjH/X6fYU3JsotaBkt8680gbWD3gWrcZ/hytvgctGeBK1fX5JXz69nsc3CeeyH2", - "poMl8SUx/MgcGBV3k6y1D/nlDiOHSCxu6kdNYlw3nU6rvoJ26I3/isnUpuoI6Cp2xo/aIUWybussSABp", - "XYJg7cBM3hKELUhLax8nxnztMUO5joQlJmHnG/UmiZEhPaRdtQSvV6s3MAHAhprg2bvfz77/9sVivslg", - "SXaU8M1zaMgTG6EaquuJM7BrnIc0GbEN/IQ6eEyc80INsaoTJx095klqA0t235o09L3h63vFQevmAOcC", - "y9cXb3/9Ye1/u1iBbY1vCLYc+lNhEp6WmQFdWYqy9vpJceAYEiUFdcGazn2YuvKM8ibPYEjON5pqrLhL", - "gpv5W3tPTRA3Yr+DRASP2LrIXz5/tGX7DJn+GhxTjeW7w9gcG3nwbHNMDNV7sqJuXhInNw373dk7CdCV", - "6aN6jrN8ls8/yX9Ifcinw0V2YCfXS53/iaoyydlXg7THJ6c54+0tVysSVXBFhokP6OnfWeDeCJb4858r", - "zE5KjNH7NVSF89ug+TfDhCGST5cWbOg6shIYTHR4Yg/O81k+UwEK1WCJi/Eqw2ikHT+kqINNxRGww4bG", - "1aK+jq09r7HEn0iWf5umGZXd2b8v/uVSuu/ug/Vz8cu0X+dPrbAjfaGg2138KeziZId+HKsgFSamSToc", - "cag6Z3Gjd8XJkN1YdVc/kwzstRdwgGYP3fzjGPpfbn5sxR/Yn/T4P3lhTTSV69z45jb76XnoetToDgfu", - "sMQi2EWh87Tf7P8JAAD//00dve6+BwAA", + "H4sIAAAAAAAC/7xUTY/jRBD9K6WCw65knGQzgGROK2DYAcSsSBYOmxza7YrdK7u7qS4PMzvKf0dlJ5nM", + "R3YFSHNKp+vjPb+qfrdoQxeDJy8Ji1tkSjH4RMOfs+lMf2zwQl70aGJsnTXigp98SMHrXbINdUZPXzJt", + "sMAvJnc9J2M0Td5yKFvqcLvdZlhRsuyitsEC33nTSxPYfaQKtxmeTefPAXseuHRVRV4xv55OnwPzwgux", + "Ny0siK+I4UfmwKh5u2Ltva8vbjFyiMTixnlUJMa14+m462to+s74r5hMZcqWgK5ja/zAHVIk6zbOggSQ", + "xiUI1vbM5C1B2IA0tPJxRMxXHjOUm0hYYBJ2vlZtkhjp02PYZUPwZrl8C2MC2FARvHj/+/n3376az9YZ", + "LMgOFL55CTV5YiNUQXkzYgZ2tfOQRiE2gU+wg6fIOS9UEys7cdLSU5qkJrBkD6VJfdcZvnnQHLRvDnAh", + "sHhz+e7XH1b+t8sl2Mb4mmDDoTsmJuE0zQzo2lKUlddPij3HkChpUhusad3HcSovKK/zDPrkfK2lxoq7", + "Itjt38p7qoO4Ifc7SETwhKzz/OzlkyPbZsj0V++YKize79fmMMi9ZutDYSg/kBVV84o4uXHZ7+/eUYCu", + "TRdVc5zm03z2Wfx96WM8XS6yPTu5Wej+j1ClSc6+7qU5PDmtGW7vsBqRqIRLMky8zx7/nQfujGCBP/+5", + "xOyoxRB92ENZOL8JWr9bJgyRfLqyYEPbkpXAYKLDI3lwlk/zqRLQVA0WOB+uMoxGmuFDJrtYvvePmgZr", + "UV2H0V5UWOBPJIu/TV0PzO7576t/aUoP1X1kP5e/jP46O2VhB/iJJt158edy50ce+ulcTVJiYuqkyxH7", + "snUW13o3OVqynVT3+TNJz15nAfvU7LGafxxC/0vNT1n8Hv2kxv9JC2uiKV3rhje33o7PQ+1Ro7fYc4sF", + "5hPcrrf/BAAA//8BbEqyuAcAAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/server/handlers/middleware-ui.go b/server/handlers/middleware-ui.go index d3d923b..a6f5e95 100644 --- a/server/handlers/middleware-ui.go +++ b/server/handlers/middleware-ui.go @@ -9,8 +9,8 @@ import ( ) // UIMiddleware creates a middleware for UI-related handlers that passes context -func UIMiddleware(_ context.Context) echo.MiddlewareFunc { - uiHandler := http.StripPrefix("/oc3/api/docs", swaggerui.Handler("/oc3/api/docs/openapi")) +func UIMiddleware(_ context.Context, prefix, specUrl string) echo.MiddlewareFunc { + uiHandler := http.StripPrefix(prefix, swaggerui.Handler(specUrl)) echoUI := echo.WrapHandler(uiHandler) return func(next echo.HandlerFunc) echo.HandlerFunc { diff --git a/xauth/public.go b/xauth/public.go index 0cf3f1d..34cd838 100644 --- a/xauth/public.go +++ b/xauth/public.go @@ -11,6 +11,7 @@ import ( type ( public struct { + path []string prefix []string } ) @@ -19,11 +20,17 @@ var ( ErrPrivatePath = errors.New("not public url") ) -func NewPublicStrategy(s ...string) auth.Strategy { - return &public{prefix: s} +func NewPublicStrategy(path, prefix []string) auth.Strategy { + return &public{path: path, prefix: prefix} } func (p *public) Authenticate(_ context.Context, r *http.Request) (auth.Info, error) { + uri := r.RequestURI + for _, s := range p.path { + if uri == s { + return auth.NewUserInfo("public", "", nil, nil), nil + } + } for _, s := range p.prefix { if strings.HasPrefix(r.RequestURI, s) { return auth.NewUserInfo("public", "", nil, nil), nil