Files
autoglue/internal/api/routes.go
2025-09-04 03:09:17 +01:00

179 lines
6.1 KiB
Go

package api
import (
httpPprof "net/http/pprof"
"github.com/glueops/autoglue/internal/config"
"github.com/glueops/autoglue/internal/handlers/annotations"
"github.com/glueops/autoglue/internal/handlers/authn"
"github.com/glueops/autoglue/internal/handlers/health"
"github.com/glueops/autoglue/internal/handlers/labels"
"github.com/glueops/autoglue/internal/handlers/nodepools"
"github.com/glueops/autoglue/internal/handlers/orgs"
"github.com/glueops/autoglue/internal/handlers/servers"
"github.com/glueops/autoglue/internal/handlers/ssh"
"github.com/glueops/autoglue/internal/handlers/taints"
"github.com/glueops/autoglue/internal/middleware"
"github.com/glueops/autoglue/internal/ui"
"github.com/go-chi/chi/v5"
"github.com/spf13/viper"
)
func RegisterRoutes(r chi.Router) {
r.Route("/api", func(api chi.Router) {
api.Get("/healthz", health.Check)
api.Route("/v1", func(v1 chi.Router) {
secret := viper.GetString("authentication.jwt_secret")
authMW := middleware.AuthMiddleware(secret)
v1.Route("/admin", func(ad chi.Router) {
ad.Use(authMW)
ad.Get("/users", authn.AdminListUsers)
ad.Post("/users", authn.AdminCreateUser)
ad.Patch("/users/{userId}", authn.AdminUpdateUser)
ad.Delete("/users/{userId}", authn.AdminDeleteUser)
})
v1.Route("/auth", func(a chi.Router) {
a.Post("/login", authn.Login)
a.Post("/register", authn.Register)
a.Post("/introspect", authn.Introspect)
a.Post("/password/forgot", authn.RequestPasswordReset)
a.Post("/password/reset", authn.ConfirmPasswordReset)
a.Get("/verify", authn.VerifyEmail)
a.Post("/verify/resend", authn.ResendVerification)
a.Group(func(pr chi.Router) {
pr.Use(authMW)
pr.Post("/refresh", authn.Refresh)
pr.Post("/logout", authn.Logout)
pr.Post("/logout_all", authn.LogoutAll)
pr.Get("/me", authn.Me)
pr.Post("/password/change", authn.ChangePassword)
pr.Post("/refresh/rotate", authn.RotateRefreshToken)
})
})
v1.Route("/annotations", func(a chi.Router) {
a.Use(authMW)
a.Get("/", annotations.ListAnnotations)
a.Post("/", annotations.CreateAnnotation)
a.Get("/{id}", annotations.GetAnnotation)
a.Patch("/{id}", annotations.UpdateAnnotation)
a.Delete("/{id}", annotations.DeleteAnnotation)
a.Get("/{id}/node_pools", annotations.ListNodePoolsWithAnnotation)
a.Post("/{id}/node_pools", annotations.AddAnnotationToNodePools)
a.Delete("/{id}/node_pools/{poolId}", annotations.RemoveAnnotationFromNodePool)
})
v1.Route("/orgs", func(o chi.Router) {
o.Use(authMW)
o.Post("/", orgs.CreateOrganization)
o.Get("/", orgs.ListOrganizations)
o.Post("/invite", orgs.InviteMember)
o.Get("/members", orgs.ListMembers)
o.Delete("/members/{userId}", orgs.DeleteMember)
o.Patch("/{orgId}", orgs.UpdateOrganization)
o.Delete("/{orgId}", orgs.DeleteOrganization)
})
v1.Route("/ssh", func(s chi.Router) {
s.Use(authMW)
s.Get("/", ssh.ListPublicKeys)
s.Post("/", ssh.CreateSSHKey)
s.Get("/{id}", ssh.GetSSHKey)
s.Delete("/{id}", ssh.DeleteSSHKey)
s.Get("/{id}/download", ssh.DownloadSSHKey)
})
v1.Route("/servers", func(s chi.Router) {
s.Use(authMW)
s.Get("/", servers.ListServers)
s.Post("/", servers.CreateServer)
s.Get("/{id}", servers.GetServer)
s.Patch("/{id}", servers.UpdateServer)
s.Delete("/{id}", servers.DeleteServer)
})
v1.Route("/node-pools", func(np chi.Router) {
np.Use(authMW)
np.Get("/", nodepools.ListNodePools)
np.Post("/", nodepools.CreateNodePool)
np.Get("/{id}", nodepools.GetNodePool)
np.Patch("/{id}", nodepools.UpdateNodePool)
np.Delete("/{id}", nodepools.DeleteNodePool)
// servers
np.Get("/{id}/servers", nodepools.ListNodePoolServers)
np.Post("/{id}/servers", nodepools.AttachNodePoolServers)
np.Delete("/{id}/servers/{serverId}", nodepools.DetachNodePoolServer)
// taints
np.Get("/{id}/taints", nodepools.ListNodePoolTaints)
np.Post("/{id}/taints", nodepools.AttachNodePoolTaints)
np.Delete("/{id}/taints/{taintId}", nodepools.DetachNodePoolTaint)
// labels
np.Get("/{id}/labels", nodepools.ListNodePoolLabels)
np.Post("/{id}/labels", nodepools.AttachNodePoolLabels)
np.Delete("/{id}/labels/{labelId}", nodepools.DetachNodePoolLabel)
// annotations
np.Get("/{id}/annotations", nodepools.ListNodePoolAnnotations)
np.Post("/{id}/annotations", nodepools.AttachNodePoolAnnotations)
np.Delete("/{id}/annotations/{annotationId}", nodepools.DetachNodePoolAnnotation)
})
v1.Route("/taints", func(t chi.Router) {
t.Use(authMW)
t.Get("/", taints.ListTaints)
t.Post("/", taints.CreateTaint)
t.Get("/{id}", taints.GetTaint)
t.Patch("/{id}", taints.UpdateTaint)
t.Delete("/{id}", taints.DeleteTaint)
t.Post("/{id}/node_pools", taints.AddTaintToNodePool)
t.Get("/{id}/node_pools", taints.ListNodePoolsWithTaint)
t.Delete("/{id}/node_pools/{poolId}", taints.RemoveTaintFromNodePool)
})
v1.Route("/labels", func(l chi.Router) {
l.Use(authMW)
l.Get("/", labels.ListLabels)
l.Post("/", labels.CreateLabel)
l.Get("/{id}", labels.GetLabel)
l.Patch("/{id}", labels.UpdateLabel)
l.Delete("/{id}", labels.DeleteLabel)
l.Get("/{id}/node_pools", labels.ListNodePoolsWithLabel)
l.Post("/{id}/node_pools", labels.AddLabelToNodePool)
l.Delete("/{id}/node_pools/{poolId}", labels.RemoveLabelFromNodePool)
})
})
})
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"))
})
if config.IsUIDev() {
if h, err := ui.DevProxy("http://localhost:5173"); err == nil {
r.NotFound(h.ServeHTTP)
}
} else {
if h, err := ui.SPAHandler(); err == nil {
r.NotFound(h.ServeHTTP)
}
}
}