Add audit and snapshots tables to SQLite migrations; enhance audit_events table handling in migrations.go. Refactor admin routes in router.go for improved organization and clarity.
This commit is contained in:
@@ -64,21 +64,23 @@ func RegisterRoutes(r *chi.Mux, app *App) {
|
||||
r.With(RequirePermission(app, "iscsi.portal.create")).Post("/api/iscsi/add_portal", app.AddISCSIPortalHandler)
|
||||
r.With(RequirePermission(app, "iscsi.initiator.create")).Post("/api/iscsi/add_initiator", app.AddISCSIInitiatorHandler)
|
||||
|
||||
// Admin routes
|
||||
r.Route("/admin", func(r chi.Router) {
|
||||
// Admin routes - users
|
||||
r.Route("/admin/users", func(r chi.Router) {
|
||||
r.Use(RequirePermission(app, "users.manage"))
|
||||
r.Get("/users", app.UsersHandler)
|
||||
r.Get("/hx/users", app.HXUsersHandler)
|
||||
r.Post("/users/create", app.CreateUserHandler)
|
||||
r.Post("/users/{id}/delete", app.DeleteUserHandler)
|
||||
r.Post("/users/{id}/roles", app.UpdateUserRolesHandler)
|
||||
|
||||
r.Get("/", app.UsersHandler)
|
||||
r.Get("/hx", app.HXUsersHandler)
|
||||
r.Post("/create", app.CreateUserHandler)
|
||||
r.Post("/{id}/delete", app.DeleteUserHandler)
|
||||
r.Post("/{id}/roles", app.UpdateUserRolesHandler)
|
||||
})
|
||||
// Admin routes - roles
|
||||
r.Route("/admin/roles", func(r chi.Router) {
|
||||
r.Use(RequirePermission(app, "roles.manage"))
|
||||
r.Get("/roles", app.RolesHandler)
|
||||
r.Get("/hx/roles", app.HXRolesHandler)
|
||||
r.Post("/roles/create", app.CreateRoleHandler)
|
||||
r.Post("/roles/{id}/delete", app.DeleteRoleHandler)
|
||||
r.Post("/roles/{id}/permissions", app.UpdateRolePermissionsHandler)
|
||||
r.Get("/", app.RolesHandler)
|
||||
r.Get("/hx", app.HXRolesHandler)
|
||||
r.Post("/create", app.CreateRoleHandler)
|
||||
r.Post("/{id}/delete", app.DeleteRoleHandler)
|
||||
r.Post("/{id}/permissions", app.UpdateRolePermissionsHandler)
|
||||
})
|
||||
|
||||
r.Get("/static/*", StaticHandler)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/example/storage-appliance/internal/auth"
|
||||
)
|
||||
@@ -27,6 +28,10 @@ func MigrateAndSeed(ctx context.Context, db *sql.DB) error {
|
||||
`CREATE TABLE IF NOT EXISTS iscsi_portals (id TEXT PRIMARY KEY, target_id TEXT NOT NULL, address TEXT NOT NULL, port INTEGER DEFAULT 3260, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
`CREATE TABLE IF NOT EXISTS iscsi_initiators (id TEXT PRIMARY KEY, target_id TEXT NOT NULL, initiator_iqn TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
`CREATE TABLE IF NOT EXISTS iscsi_luns (id TEXT PRIMARY KEY, target_id TEXT NOT NULL, lun_id INTEGER NOT NULL, zvol TEXT NOT NULL, size INTEGER, blocksize INTEGER, mapped INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
// Audit and snapshots tables
|
||||
`CREATE TABLE IF NOT EXISTS audit_events (id TEXT PRIMARY KEY, ts DATETIME DEFAULT CURRENT_TIMESTAMP, user_id TEXT, action TEXT, resource_type TEXT, resource_id TEXT, success INTEGER DEFAULT 1, details TEXT, actor TEXT, resource TEXT, payload_hash TEXT, result TEXT, client_ip TEXT);`,
|
||||
`CREATE TABLE IF NOT EXISTS datasets (name TEXT PRIMARY KEY, pool TEXT, type TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
`CREATE TABLE IF NOT EXISTS snapshots (id TEXT PRIMARY KEY, dataset TEXT, name TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
// RBAC tables
|
||||
`CREATE TABLE IF NOT EXISTS roles (id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
`CREATE TABLE IF NOT EXISTS permissions (id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
|
||||
@@ -44,6 +49,7 @@ func MigrateAndSeed(ctx context.Context, db *sql.DB) error {
|
||||
}
|
||||
|
||||
// Enhance audit_events table if needed (add missing columns)
|
||||
// Note: audit_events table is now created with all columns above, but this handles upgrades
|
||||
enhanceAuditTable(ctx, tx)
|
||||
|
||||
// Seed default roles and permissions
|
||||
@@ -78,6 +84,14 @@ func MigrateAndSeed(ctx context.Context, db *sql.DB) error {
|
||||
}
|
||||
|
||||
func enhanceAuditTable(ctx context.Context, tx *sql.Tx) {
|
||||
// Check if table exists first
|
||||
var tableExists int
|
||||
err := tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='audit_events'`).Scan(&tableExists)
|
||||
if err != nil || tableExists == 0 {
|
||||
// Table doesn't exist, it will be created above with all columns
|
||||
return
|
||||
}
|
||||
|
||||
// Check if columns exist and add them if missing
|
||||
// SQLite doesn't support IF NOT EXISTS for ALTER TABLE, so we'll try-catch
|
||||
columns := []struct {
|
||||
@@ -94,8 +108,11 @@ func enhanceAuditTable(ctx context.Context, tx *sql.Tx) {
|
||||
for _, col := range columns {
|
||||
_, err := tx.ExecContext(ctx, col.stmt)
|
||||
if err != nil {
|
||||
// Column might already exist, ignore error
|
||||
log.Printf("Note: %s column may already exist: %v", col.name, err)
|
||||
// Column might already exist, ignore error silently
|
||||
// Only log if it's not a "duplicate column" error
|
||||
if !strings.Contains(err.Error(), "duplicate column") && !strings.Contains(err.Error(), "no such table") {
|
||||
log.Printf("Note: %s column may already exist: %v", col.name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user