@ -5,9 +5,11 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/seaweedfs/seaweedfs/weed/admin/dash"
"github.com/seaweedfs/seaweedfs/weed/admin/view/app"
"github.com/seaweedfs/seaweedfs/weed/admin/view/layout"
"github.com/seaweedfs/seaweedfs/weed/stats"
)
// AdminHandlers contains all the HTTP handlers for the admin interface
@ -44,10 +46,13 @@ func NewAdminHandlers(adminServer *dash.AdminServer) *AdminHandlers {
}
// SetupRoutes configures all the routes for the admin interface
func ( h * AdminHandlers ) SetupRoutes ( r * gin . Engine , authRequired bool , username , p assword string ) {
func ( h * AdminHandlers ) SetupRoutes ( r * gin . Engine , authRequired bool , adminUser , adminPassword , readOnlyUser , readOnlyP assword string ) {
// Health check (no auth required)
r . GET ( "/health" , h . HealthCheck )
// Prometheus metrics endpoint (no auth required)
r . GET ( "/metrics" , gin . WrapH ( promhttp . HandlerFor ( stats . Gather , promhttp . HandlerOpts { } ) ) )
// Favicon route (no auth required) - redirect to static version
r . GET ( "/favicon.ico" , func ( c * gin . Context ) {
c . Redirect ( http . StatusMovedPermanently , "/static/favicon.ico" )
@ -56,7 +61,7 @@ func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, username,
if authRequired {
// Authentication routes (no auth required)
r . GET ( "/login" , h . authHandlers . ShowLogin )
r . POST ( "/login" , h . authHandlers . HandleLogin ( username , p assword) )
r . POST ( "/login" , h . authHandlers . HandleLogin ( adminUser , adminPassword , readOnlyUser , readOnlyP assword) )
r . GET ( "/logout" , h . authHandlers . HandleLogout )
// Protected routes group
@ -96,9 +101,9 @@ func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, username,
protected . GET ( "/maintenance" , h . maintenanceHandlers . ShowMaintenanceQueue )
protected . GET ( "/maintenance/workers" , h . maintenanceHandlers . ShowMaintenanceWorkers )
protected . GET ( "/maintenance/config" , h . maintenanceHandlers . ShowMaintenanceConfig )
protected . POST ( "/maintenance/config" , h . maintenanceHandlers . UpdateMaintenanceConfig )
protected . POST ( "/maintenance/config" , dash . RequireWriteAccess ( ) , h . maintenanceHandlers . UpdateMaintenanceConfig )
protected . GET ( "/maintenance/config/:taskType" , h . maintenanceHandlers . ShowTaskConfig )
protected . POST ( "/maintenance/config/:taskType" , h . maintenanceHandlers . UpdateTaskConfig )
protected . POST ( "/maintenance/config/:taskType" , dash . RequireWriteAccess ( ) , h . maintenanceHandlers . UpdateTaskConfig )
protected . GET ( "/maintenance/tasks/:id" , h . maintenanceHandlers . ShowTaskDetail )
// API routes for AJAX calls
@ -115,45 +120,45 @@ func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, username,
s3Api := api . Group ( "/s3" )
{
s3Api . GET ( "/buckets" , h . adminServer . ListBucketsAPI )
s3Api . POST ( "/buckets" , h . adminServer . CreateBucket )
s3Api . DELETE ( "/buckets/:bucket" , h . adminServer . DeleteBucket )
s3Api . POST ( "/buckets" , dash . RequireWriteAccess ( ) , h . adminServer . CreateBucket )
s3Api . DELETE ( "/buckets/:bucket" , dash . RequireWriteAccess ( ) , h . adminServer . DeleteBucket )
s3Api . GET ( "/buckets/:bucket" , h . adminServer . ShowBucketDetails )
s3Api . PUT ( "/buckets/:bucket/quota" , h . adminServer . UpdateBucketQuota )
s3Api . PUT ( "/buckets/:bucket/owner" , h . adminServer . UpdateBucketOwner )
s3Api . PUT ( "/buckets/:bucket/quota" , dash . RequireWriteAccess ( ) , h . adminServer . UpdateBucketQuota )
s3Api . PUT ( "/buckets/:bucket/owner" , dash . RequireWriteAccess ( ) , h . adminServer . UpdateBucketOwner )
}
// User management API routes
usersApi := api . Group ( "/users" )
{
usersApi . GET ( "" , h . userHandlers . GetUsers )
usersApi . POST ( "" , h . userHandlers . CreateUser )
usersApi . POST ( "" , dash . RequireWriteAccess ( ) , h . userHandlers . CreateUser )
usersApi . GET ( "/:username" , h . userHandlers . GetUserDetails )
usersApi . PUT ( "/:username" , h . userHandlers . UpdateUser )
usersApi . DELETE ( "/:username" , h . userHandlers . DeleteUser )
usersApi . POST ( "/:username/access-keys" , h . userHandlers . CreateAccessKey )
usersApi . DELETE ( "/:username/access-keys/:accessKeyId" , h . userHandlers . DeleteAccessKey )
usersApi . PUT ( "/:username" , dash . RequireWriteAccess ( ) , h . userHandlers . UpdateUser )
usersApi . DELETE ( "/:username" , dash . RequireWriteAccess ( ) , h . userHandlers . DeleteUser )
usersApi . POST ( "/:username/access-keys" , dash . RequireWriteAccess ( ) , h . userHandlers . CreateAccessKey )
usersApi . DELETE ( "/:username/access-keys/:accessKeyId" , dash . RequireWriteAccess ( ) , h . userHandlers . DeleteAccessKey )
usersApi . GET ( "/:username/policies" , h . userHandlers . GetUserPolicies )
usersApi . PUT ( "/:username/policies" , h . userHandlers . UpdateUserPolicies )
usersApi . PUT ( "/:username/policies" , dash . RequireWriteAccess ( ) , h . userHandlers . UpdateUserPolicies )
}
// Object Store Policy management API routes
objectStorePoliciesApi := api . Group ( "/object-store/policies" )
{
objectStorePoliciesApi . GET ( "" , h . policyHandlers . GetPolicies )
objectStorePoliciesApi . POST ( "" , h . policyHandlers . CreatePolicy )
objectStorePoliciesApi . POST ( "" , dash . RequireWriteAccess ( ) , h . policyHandlers . CreatePolicy )
objectStorePoliciesApi . GET ( "/:name" , h . policyHandlers . GetPolicy )
objectStorePoliciesApi . PUT ( "/:name" , h . policyHandlers . UpdatePolicy )
objectStorePoliciesApi . DELETE ( "/:name" , h . policyHandlers . DeletePolicy )
objectStorePoliciesApi . PUT ( "/:name" , dash . RequireWriteAccess ( ) , h . policyHandlers . UpdatePolicy )
objectStorePoliciesApi . DELETE ( "/:name" , dash . RequireWriteAccess ( ) , h . policyHandlers . DeletePolicy )
objectStorePoliciesApi . POST ( "/validate" , h . policyHandlers . ValidatePolicy )
}
// File management API routes
filesApi := api . Group ( "/files" )
{
filesApi . DELETE ( "/delete" , h . fileBrowserHandlers . DeleteFile )
filesApi . DELETE ( "/delete-multiple" , h . fileBrowserHandlers . DeleteMultipleFiles )
filesApi . POST ( "/create-folder" , h . fileBrowserHandlers . CreateFolder )
filesApi . POST ( "/upload" , h . fileBrowserHandlers . UploadFile )
filesApi . DELETE ( "/delete" , dash . RequireWriteAccess ( ) , h . fileBrowserHandlers . DeleteFile )
filesApi . DELETE ( "/delete-multiple" , dash . RequireWriteAccess ( ) , h . fileBrowserHandlers . DeleteMultipleFiles )
filesApi . POST ( "/create-folder" , dash . RequireWriteAccess ( ) , h . fileBrowserHandlers . CreateFolder )
filesApi . POST ( "/upload" , dash . RequireWriteAccess ( ) , h . fileBrowserHandlers . UploadFile )
filesApi . GET ( "/download" , h . fileBrowserHandlers . DownloadFile )
filesApi . GET ( "/view" , h . fileBrowserHandlers . ViewFile )
filesApi . GET ( "/properties" , h . fileBrowserHandlers . GetFileProperties )
@ -162,32 +167,32 @@ func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, username,
// Volume management API routes
volumeApi := api . Group ( "/volumes" )
{
volumeApi . POST ( "/:id/:server/vacuum" , h . clusterHandlers . VacuumVolume )
volumeApi . POST ( "/:id/:server/vacuum" , dash . RequireWriteAccess ( ) , h . clusterHandlers . VacuumVolume )
}
// Maintenance API routes
maintenanceApi := api . Group ( "/maintenance" )
{
maintenanceApi . POST ( "/scan" , h . adminServer . TriggerMaintenanceScan )
maintenanceApi . POST ( "/scan" , dash . RequireWriteAccess ( ) , h . adminServer . TriggerMaintenanceScan )
maintenanceApi . GET ( "/tasks" , h . adminServer . GetMaintenanceTasks )
maintenanceApi . GET ( "/tasks/:id" , h . adminServer . GetMaintenanceTask )
maintenanceApi . GET ( "/tasks/:id/detail" , h . adminServer . GetMaintenanceTaskDetailAPI )
maintenanceApi . POST ( "/tasks/:id/cancel" , h . adminServer . CancelMaintenanceTask )
maintenanceApi . POST ( "/tasks/:id/cancel" , dash . RequireWriteAccess ( ) , h . adminServer . CancelMaintenanceTask )
maintenanceApi . GET ( "/workers" , h . adminServer . GetMaintenanceWorkersAPI )
maintenanceApi . GET ( "/workers/:id" , h . adminServer . GetMaintenanceWorker )
maintenanceApi . GET ( "/workers/:id/logs" , h . adminServer . GetWorkerLogs )
maintenanceApi . GET ( "/stats" , h . adminServer . GetMaintenanceStats )
maintenanceApi . GET ( "/config" , h . adminServer . GetMaintenanceConfigAPI )
maintenanceApi . PUT ( "/config" , h . adminServer . UpdateMaintenanceConfigAPI )
maintenanceApi . PUT ( "/config" , dash . RequireWriteAccess ( ) , h . adminServer . UpdateMaintenanceConfigAPI )
}
// Message Queue API routes
mqApi := api . Group ( "/mq" )
{
mqApi . GET ( "/topics/:namespace/:topic" , h . mqHandlers . GetTopicDetailsAPI )
mqApi . POST ( "/topics/create" , h . mqHandlers . CreateTopicAPI )
mqApi . POST ( "/topics/retention/update" , h . mqHandlers . UpdateTopicRetentionAPI )
mqApi . POST ( "/retention/purge" , h . adminServer . TriggerTopicRetentionPurgeAPI )
mqApi . POST ( "/topics/create" , dash . RequireWriteAccess ( ) , h . mqHandlers . CreateTopicAPI )
mqApi . POST ( "/topics/retention/update" , dash . RequireWriteAccess ( ) , h . mqHandlers . UpdateTopicRetentionAPI )
mqApi . POST ( "/retention/purge" , dash . RequireWriteAccess ( ) , h . adminServer . TriggerTopicRetentionPurgeAPI )
}
}
} else {