Files
atlas/internal/httpapp/routes.go
2025-12-23 07:50:08 +00:00

325 lines
12 KiB
Go

package httpapp
import (
"net/http"
"gitea.avt.data-center.id/othman.suseno/atlas/internal/models"
)
func (a *App) routes() {
// Static files
fs := http.FileServer(http.Dir(a.cfg.StaticDir))
a.mux.Handle("/static/", http.StripPrefix("/static/", fs))
// Web UI
a.mux.HandleFunc("/", a.handleDashboard) // Redirects to login
a.mux.HandleFunc("/dashboard", a.handleDashboardPage) // Actual dashboard page
a.mux.HandleFunc("/login", a.handleLoginPage)
a.mux.HandleFunc("/storage", a.handleStorage)
a.mux.HandleFunc("/shares", a.handleShares)
a.mux.HandleFunc("/iscsi", a.handleISCSI)
a.mux.HandleFunc("/protection", a.handleProtection)
a.mux.HandleFunc("/management", a.handleManagement)
a.mux.HandleFunc("/vtl", a.handleVTL)
// Health & metrics
a.mux.HandleFunc("/healthz", a.handleHealthz)
a.mux.HandleFunc("/health", a.handleHealthCheck) // Detailed health check
a.mux.HandleFunc("/metrics", a.handleMetrics)
// Diagnostics
a.mux.HandleFunc("/api/v1/system/info", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleSystemInfo(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/system/logs", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleLogs(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/system/gc", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) { a.handleGC(w, r) },
nil, nil, nil,
))
// Maintenance Mode (requires authentication, admin-only for enable/disable)
a.mux.HandleFunc("/api/v1/maintenance", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleGetMaintenanceStatus(w, r) },
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleEnableMaintenance)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/maintenance/disable", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleDisableMaintenance)).ServeHTTP(w, r)
},
nil, nil, nil,
))
// API Documentation
a.mux.HandleFunc("/api/docs", a.handleAPIDocs)
a.mux.HandleFunc("/api/openapi.yaml", a.handleOpenAPISpec)
// Backup & Restore
// Define allowed roles for storage operations (Administrator and Operator, not Viewer)
storageRoles := []models.Role{models.RoleAdministrator, models.RoleOperator}
a.mux.HandleFunc("/api/v1/backups", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListBackups(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateBackup)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/backups/", a.handleBackupOps)
// Dashboard API
a.mux.HandleFunc("/api/v1/dashboard", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleDashboardAPI(w, r) },
nil, nil, nil, nil,
))
// API v1 routes - ZFS Management
a.mux.HandleFunc("/api/v1/disks", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListDisks(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/pools", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListPools(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreatePool)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/pools/available", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListAvailablePools(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/pools/import", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleImportPool)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/pools/", a.handlePoolOps)
a.mux.HandleFunc("/api/v1/datasets", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListDatasets(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateDataset)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/datasets/", a.handleDatasetOps)
a.mux.HandleFunc("/api/v1/zvols", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListZVOLs(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateZVOL)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/zvols/", a.handleZVOLOps)
// Snapshot Management
a.mux.HandleFunc("/api/v1/snapshots", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListSnapshots(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateSnapshot)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/snapshots/", a.handleSnapshotOps)
a.mux.HandleFunc("/api/v1/snapshot-policies", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListSnapshotPolicies(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateSnapshotPolicy)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/snapshot-policies/", a.handleSnapshotPolicyOps)
// Storage Services - SMB
a.mux.HandleFunc("/api/v1/shares/smb", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListSMBShares(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateSMBShare)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/shares/smb/", a.handleSMBShareOps)
// Storage Services - NFS
a.mux.HandleFunc("/api/v1/exports/nfs", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListNFSExports(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateNFSExport)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/exports/nfs/", a.handleNFSExportOps)
// Storage Services - iSCSI
a.mux.HandleFunc("/api/v1/iscsi/targets", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListISCSITargets(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateISCSITarget)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/iscsi/targets/", a.handleISCSITargetOps)
// Storage Services - VTL (Virtual Tape Library)
a.mux.HandleFunc("/api/v1/vtl/status", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleGetVTLStatus(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/drives", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListVTLDrives(w, r) },
func(w http.ResponseWriter, r *http.Request) {
storageRoles := []models.Role{models.RoleAdministrator, models.RoleOperator}
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateVTLDrive)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/drives/", a.handleVTLDriveOps)
a.mux.HandleFunc("/api/v1/vtl/tapes", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListVTLTapes(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateVTLTape)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/tapes/", a.handleVTLTapeOps)
a.mux.HandleFunc("/api/v1/vtl/service", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleVTLServiceControl)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/changers", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListVTLMediaChangers(w, r) },
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleCreateMediaChanger)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/changers/", a.handleMediaChangerOps)
a.mux.HandleFunc("/api/v1/vtl/devices/iscsi", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListVTLDevicesForISCSI(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/changer/status", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleGetVTLMediaChangerStatus(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/tape/load", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleLoadTape)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/vtl/tape/eject", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
a.requireRole(storageRoles...)(http.HandlerFunc(a.handleEjectTape)).ServeHTTP(w, r)
},
nil, nil, nil,
))
// Job Management
a.mux.HandleFunc("/api/v1/jobs", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListJobs(w, r) },
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/jobs/", a.handleJobOps)
// Authentication & Authorization (public endpoints)
a.mux.HandleFunc("/api/v1/auth/login", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) { a.handleLogin(w, r) },
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/auth/logout", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) { a.handleLogout(w, r) },
nil, nil, nil,
))
// User Management (requires authentication, admin-only for create/update/delete)
a.mux.HandleFunc("/api/v1/users", methodHandler(
func(w http.ResponseWriter, r *http.Request) { a.handleListUsers(w, r) },
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleCreateUser)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/users/", a.handleUserOpsWithAuth)
// Service Management (requires authentication, admin-only)
a.mux.HandleFunc("/api/v1/services", methodHandler(
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleListServices)).ServeHTTP(w, r)
},
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/services/status", methodHandler(
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleServiceStatus)).ServeHTTP(w, r)
},
nil, nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/services/start", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleServiceStart)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/services/stop", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleServiceStop)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/services/restart", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleServiceRestart)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/services/reload", methodHandler(
nil,
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleServiceReload)).ServeHTTP(w, r)
},
nil, nil, nil,
))
a.mux.HandleFunc("/api/v1/services/logs", methodHandler(
func(w http.ResponseWriter, r *http.Request) {
adminRole := models.RoleAdministrator
a.requireRole(adminRole)(http.HandlerFunc(a.handleServiceLogs)).ServeHTTP(w, r)
},
nil, nil, nil, nil,
))
// Audit Logs
a.mux.HandleFunc("/api/v1/audit", a.handleListAuditLogs)
}