mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 12:50:05 +01:00
chore: cleanup and route refactoring
Signed-off-by: allanice001 <allanice001@gmail.com>
This commit is contained in:
@@ -3,11 +3,10 @@ package api
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
httpPprof "net/http/pprof"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/glueops/autoglue/docs"
|
||||
"github.com/glueops/autoglue/internal/api/httpmiddleware"
|
||||
"github.com/glueops/autoglue/internal/bg"
|
||||
"github.com/glueops/autoglue/internal/config"
|
||||
@@ -23,8 +22,6 @@ import (
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
httpSwagger "github.com/swaggo/http-swagger/v2"
|
||||
)
|
||||
|
||||
func NewRouter(db *gorm.DB, jobs *bg.Jobs, studio http.Handler) http.Handler {
|
||||
@@ -38,7 +35,6 @@ func NewRouter(db *gorm.DB, jobs *bg.Jobs, studio http.Handler) http.Handler {
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(zeroLogMiddleware())
|
||||
r.Use(middleware.Recoverer)
|
||||
// r.Use(middleware.RedirectSlashes)
|
||||
r.Use(SecurityHeaders)
|
||||
r.Use(requestBodyLimit(10 << 20))
|
||||
r.Use(httprate.LimitByIP(100, 1*time.Minute))
|
||||
@@ -60,198 +56,44 @@ func NewRouter(db *gorm.DB, jobs *bg.Jobs, studio http.Handler) http.Handler {
|
||||
MaxAge: 600,
|
||||
}))
|
||||
|
||||
r.Use(middleware.AllowContentType("application/json"))
|
||||
r.Use(middleware.Maybe(
|
||||
middleware.AllowContentType("application/json"),
|
||||
func(r *http.Request) bool {
|
||||
// return true => run AllowContentType
|
||||
// return false => skip AllowContentType for this request
|
||||
return !strings.HasPrefix(r.URL.Path, "/db-studio")
|
||||
}))
|
||||
//r.Use(middleware.AllowContentType("application/json"))
|
||||
|
||||
// Unversioned, non-auth endpoints
|
||||
r.Get("/.well-known/jwks.json", handlers.JWKSHandler)
|
||||
r.Route("/api", func(api chi.Router) {
|
||||
api.Route("/v1", func(v1 chi.Router) {
|
||||
authUser := httpmiddleware.AuthMiddleware(db, false)
|
||||
authOrg := httpmiddleware.AuthMiddleware(db, true)
|
||||
|
||||
// Also serving a versioned JWKS for swagger, which uses BasePath
|
||||
v1.Get("/.well-known/jwks.json", handlers.JWKSHandler)
|
||||
|
||||
v1.Get("/healthz", handlers.HealthCheck)
|
||||
v1.Get("/version", handlers.Version)
|
||||
|
||||
v1.Route("/auth", func(a chi.Router) {
|
||||
a.Post("/{provider}/start", handlers.AuthStart(db))
|
||||
a.Get("/{provider}/callback", handlers.AuthCallback(db))
|
||||
a.Post("/refresh", handlers.Refresh(db))
|
||||
a.Post("/logout", handlers.Logout(db))
|
||||
})
|
||||
|
||||
v1.Route("/admin", func(admin chi.Router) {
|
||||
admin.Route("/archer", func(archer chi.Router) {
|
||||
archer.Use(authUser)
|
||||
archer.Use(httpmiddleware.RequirePlatformAdmin())
|
||||
|
||||
archer.Get("/jobs", handlers.AdminListArcherJobs(db))
|
||||
archer.Post("/jobs", handlers.AdminEnqueueArcherJob(db, jobs))
|
||||
archer.Post("/jobs/{id}/retry", handlers.AdminRetryArcherJob(db))
|
||||
archer.Post("/jobs/{id}/cancel", handlers.AdminCancelArcherJob(db))
|
||||
archer.Get("/queues", handlers.AdminListArcherQueues(db))
|
||||
})
|
||||
})
|
||||
|
||||
v1.Route("/me", func(me chi.Router) {
|
||||
me.Use(authUser)
|
||||
|
||||
me.Get("/", handlers.GetMe(db))
|
||||
me.Patch("/", handlers.UpdateMe(db))
|
||||
|
||||
me.Get("/api-keys", handlers.ListUserAPIKeys(db))
|
||||
me.Post("/api-keys", handlers.CreateUserAPIKey(db))
|
||||
me.Delete("/api-keys/{id}", handlers.DeleteUserAPIKey(db))
|
||||
})
|
||||
|
||||
v1.Route("/orgs", func(o chi.Router) {
|
||||
o.Use(authUser)
|
||||
o.Get("/", handlers.ListMyOrgs(db))
|
||||
o.Post("/", handlers.CreateOrg(db))
|
||||
|
||||
o.Group(func(og chi.Router) {
|
||||
og.Use(authOrg)
|
||||
og.Get("/{id}", handlers.GetOrg(db))
|
||||
og.Patch("/{id}", handlers.UpdateOrg(db))
|
||||
og.Delete("/{id}", handlers.DeleteOrg(db))
|
||||
|
||||
// members
|
||||
og.Get("/{id}/members", handlers.ListMembers(db))
|
||||
og.Post("/{id}/members", handlers.AddOrUpdateMember(db))
|
||||
og.Delete("/{id}/members/{user_id}", handlers.RemoveMember(db))
|
||||
|
||||
// org-scoped key/secret pair
|
||||
og.Get("/{id}/api-keys", handlers.ListOrgKeys(db))
|
||||
og.Post("/{id}/api-keys", handlers.CreateOrgKey(db))
|
||||
og.Delete("/{id}/api-keys/{key_id}", handlers.DeleteOrgKey(db))
|
||||
})
|
||||
})
|
||||
|
||||
v1.Route("/credentials", func(c chi.Router) {
|
||||
c.Use(authOrg)
|
||||
c.Get("/", handlers.ListCredentials(db))
|
||||
c.Post("/", handlers.CreateCredential(db))
|
||||
c.Get("/{id}", handlers.GetCredential(db))
|
||||
c.Patch("/{id}", handlers.UpdateCredential(db))
|
||||
c.Delete("/{id}", handlers.DeleteCredential(db))
|
||||
c.Post("/{id}/reveal", handlers.RevealCredential(db))
|
||||
})
|
||||
|
||||
v1.Route("/ssh", func(s chi.Router) {
|
||||
s.Use(authOrg)
|
||||
s.Get("/", handlers.ListPublicSshKeys(db))
|
||||
s.Post("/", handlers.CreateSSHKey(db))
|
||||
s.Get("/{id}", handlers.GetSSHKey(db))
|
||||
s.Delete("/{id}", handlers.DeleteSSHKey(db))
|
||||
s.Get("/{id}/download", handlers.DownloadSSHKey(db))
|
||||
})
|
||||
|
||||
v1.Route("/servers", func(s chi.Router) {
|
||||
s.Use(authOrg)
|
||||
s.Get("/", handlers.ListServers(db))
|
||||
s.Post("/", handlers.CreateServer(db))
|
||||
s.Get("/{id}", handlers.GetServer(db))
|
||||
s.Patch("/{id}", handlers.UpdateServer(db))
|
||||
s.Delete("/{id}", handlers.DeleteServer(db))
|
||||
})
|
||||
|
||||
v1.Route("/taints", func(s chi.Router) {
|
||||
s.Use(authOrg)
|
||||
s.Get("/", handlers.ListTaints(db))
|
||||
s.Post("/", handlers.CreateTaint(db))
|
||||
s.Get("/{id}", handlers.GetTaint(db))
|
||||
s.Patch("/{id}", handlers.UpdateTaint(db))
|
||||
s.Delete("/{id}", handlers.DeleteTaint(db))
|
||||
})
|
||||
|
||||
v1.Route("/labels", func(l chi.Router) {
|
||||
l.Use(authOrg)
|
||||
l.Get("/", handlers.ListLabels(db))
|
||||
l.Post("/", handlers.CreateLabel(db))
|
||||
l.Get("/{id}", handlers.GetLabel(db))
|
||||
l.Patch("/{id}", handlers.UpdateLabel(db))
|
||||
l.Delete("/{id}", handlers.DeleteLabel(db))
|
||||
})
|
||||
|
||||
v1.Route("/annotations", func(a chi.Router) {
|
||||
a.Use(authOrg)
|
||||
a.Get("/", handlers.ListAnnotations(db))
|
||||
a.Post("/", handlers.CreateAnnotation(db))
|
||||
a.Get("/{id}", handlers.GetAnnotation(db))
|
||||
a.Patch("/{id}", handlers.UpdateAnnotation(db))
|
||||
a.Delete("/{id}", handlers.DeleteAnnotation(db))
|
||||
})
|
||||
|
||||
v1.Route("/node-pools", func(n chi.Router) {
|
||||
n.Use(authOrg)
|
||||
n.Get("/", handlers.ListNodePools(db))
|
||||
n.Post("/", handlers.CreateNodePool(db))
|
||||
n.Get("/{id}", handlers.GetNodePool(db))
|
||||
n.Patch("/{id}", handlers.UpdateNodePool(db))
|
||||
n.Delete("/{id}", handlers.DeleteNodePool(db))
|
||||
|
||||
// Servers
|
||||
n.Get("/{id}/servers", handlers.ListNodePoolServers(db))
|
||||
n.Post("/{id}/servers", handlers.AttachNodePoolServers(db))
|
||||
n.Delete("/{id}/servers/{serverId}", handlers.DetachNodePoolServer(db))
|
||||
|
||||
// Taints
|
||||
n.Get("/{id}/taints", handlers.ListNodePoolTaints(db))
|
||||
n.Post("/{id}/taints", handlers.AttachNodePoolTaints(db))
|
||||
n.Delete("/{id}/taints/{taintId}", handlers.DetachNodePoolTaint(db))
|
||||
|
||||
// Labels
|
||||
n.Get("/{id}/labels", handlers.ListNodePoolLabels(db))
|
||||
n.Post("/{id}/labels", handlers.AttachNodePoolLabels(db))
|
||||
n.Delete("/{id}/labels/{labelId}", handlers.DetachNodePoolLabel(db))
|
||||
|
||||
// Annotations
|
||||
n.Get("/{id}/annotations", handlers.ListNodePoolAnnotations(db))
|
||||
n.Post("/{id}/annotations", handlers.AttachNodePoolAnnotations(db))
|
||||
n.Delete("/{id}/annotations/{annotationId}", handlers.DetachNodePoolAnnotation(db))
|
||||
})
|
||||
})
|
||||
})
|
||||
// Versioned API
|
||||
mountAPIRoutes(r, db, jobs)
|
||||
|
||||
// Optional DB studio
|
||||
if studio != nil {
|
||||
r.Group(func(gr chi.Router) {
|
||||
authUser := httpmiddleware.AuthMiddleware(db, false)
|
||||
adminOnly := httpmiddleware.RequirePlatformAdmin()
|
||||
gr.Use(authUser)
|
||||
gr.Use(adminOnly)
|
||||
gr.Use(authUser, adminOnly)
|
||||
gr.Mount("/db-studio", studio)
|
||||
})
|
||||
}
|
||||
|
||||
// pprof
|
||||
if config.IsDebug() {
|
||||
r.Route("/debug/pprof", func(pr chi.Router) {
|
||||
pr.Get("/", httpPprof.Index)
|
||||
pr.Get("/cmdline", httpPprof.Cmdline)
|
||||
pr.Get("/profile", httpPprof.Profile)
|
||||
pr.Get("/symbol", httpPprof.Symbol)
|
||||
pr.Get("/trace", httpPprof.Trace)
|
||||
|
||||
pr.Handle("/allocs", httpPprof.Handler("allocs"))
|
||||
pr.Handle("/block", httpPprof.Handler("block"))
|
||||
pr.Handle("/goroutine", httpPprof.Handler("goroutine"))
|
||||
pr.Handle("/heap", httpPprof.Handler("heap"))
|
||||
pr.Handle("/mutex", httpPprof.Handler("mutex"))
|
||||
pr.Handle("/threadcreate", httpPprof.Handler("threadcreate"))
|
||||
})
|
||||
mountPprofRoutes(r)
|
||||
}
|
||||
|
||||
// Swagger
|
||||
if config.IsSwaggerEnabled() {
|
||||
r.Get("/swagger/*", httpSwagger.Handler(
|
||||
httpSwagger.URL("swagger.json"),
|
||||
))
|
||||
r.Get("/swagger/swagger.json", serveSwaggerFromEmbed(docs.SwaggerJSON, "application/json"))
|
||||
r.Get("/swagger/swagger.yaml", serveSwaggerFromEmbed(docs.SwaggerYAML, "application/x-yaml"))
|
||||
mountSwaggerRoutes(r)
|
||||
}
|
||||
|
||||
// UI dev/prod
|
||||
if config.IsUIDev() {
|
||||
fmt.Println("Running in development mode")
|
||||
// Dev: isolate proxy from chi middlewares so WS upgrade can hijack.
|
||||
proxy, err := web.DevProxy("http://localhost:5173")
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("dev proxy init failed")
|
||||
@@ -259,23 +101,20 @@ func NewRouter(db *gorm.DB, jobs *bg.Jobs, studio http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
// Send API/Swagger/pprof to chi
|
||||
mux.Handle("/api/", r)
|
||||
mux.Handle("/api", r)
|
||||
mux.Handle("/swagger/", r)
|
||||
mux.Handle("/db-studio/", r)
|
||||
mux.Handle("/debug/pprof/", r)
|
||||
// Everything else (/, /brand-preview, assets) → proxy (no middlewares)
|
||||
mux.Handle("/", proxy)
|
||||
|
||||
return mux
|
||||
}
|
||||
|
||||
fmt.Println("Running in production mode")
|
||||
if h, err := web.SPAHandler(); err == nil {
|
||||
r.NotFound(h.ServeHTTP)
|
||||
} else {
|
||||
fmt.Println("Running in production mode")
|
||||
if h, err := web.SPAHandler(); err == nil {
|
||||
r.NotFound(h.ServeHTTP)
|
||||
} else {
|
||||
log.Error().Err(err).Msg("spa handler init failed")
|
||||
}
|
||||
log.Error().Err(err).Msg("spa handler init failed")
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
Reference in New Issue
Block a user