-- ============================================================================ -- ServerManager Database Schema -- MySQL/MariaDB 10.5+ -- ============================================================================ CREATE DATABASE IF NOT EXISTS `servermanager` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE `servermanager`; -- ============================================================================ -- Users Table -- ============================================================================ CREATE TABLE IF NOT EXISTS `users` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `email` VARCHAR(255) NOT NULL, `password_hash` VARCHAR(255) NOT NULL, `role` ENUM('super_admin', 'admin', 'operator') NOT NULL DEFAULT 'operator', `api_token` VARCHAR(64) DEFAULT NULL, `is_active` TINYINT(1) NOT NULL DEFAULT 1, `last_login_at` DATETIME DEFAULT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`), UNIQUE KEY `uk_email` (`email`), UNIQUE KEY `uk_api_token` (`api_token`), KEY `idx_role` (`role`), KEY `idx_is_active` (`is_active`), KEY `idx_created_at` (`created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Servers Table -- ============================================================================ CREATE TABLE IF NOT EXISTS `servers` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `description` TEXT DEFAULT NULL, `ip_address` VARCHAR(255) NOT NULL, `ssh_port` INT UNSIGNED NOT NULL DEFAULT 22, `ssh_user` VARCHAR(50) NOT NULL, `ssh_password` TEXT DEFAULT NULL COMMENT 'AES-256-CBC encrypted', `ssh_key` TEXT DEFAULT NULL COMMENT 'AES-256-CBC encrypted', `group_name` VARCHAR(50) DEFAULT NULL, `is_active` TINYINT(1) NOT NULL DEFAULT 1, `current_status` ENUM('online', 'offline', 'unknown') NOT NULL DEFAULT 'unknown', `cpu_usage` DECIMAL(5,2) DEFAULT NULL, `ram_usage` DECIMAL(5,2) DEFAULT NULL, `disk_usage` DECIMAL(5,2) DEFAULT NULL, `load_average` DECIMAL(8,4) DEFAULT NULL, `uptime` VARCHAR(50) DEFAULT NULL, `last_check_at` DATETIME DEFAULT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_name` (`name`), KEY `idx_ip_address` (`ip_address`), KEY `idx_group_name` (`group_name`), KEY `idx_is_active` (`is_active`), KEY `idx_current_status` (`current_status`), KEY `idx_last_check_at` (`last_check_at`), KEY `idx_created_at` (`created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Command History Table -- ============================================================================ CREATE TABLE IF NOT EXISTS `command_history` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `server_id` INT UNSIGNED NOT NULL, `user_id` INT UNSIGNED NOT NULL, `command` TEXT NOT NULL, `output` MEDIUMTEXT DEFAULT NULL, `exit_status` INT NOT NULL DEFAULT 0, `executed_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_server_id` (`server_id`), KEY `idx_user_id` (`user_id`), KEY `idx_executed_at` (`executed_at`), CONSTRAINT `fk_command_history_server` FOREIGN KEY (`server_id`) REFERENCES `servers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `fk_command_history_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Audit Logs Table -- ============================================================================ CREATE TABLE IF NOT EXISTS `audit_logs` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT UNSIGNED DEFAULT NULL, `username` VARCHAR(50) DEFAULT NULL, `action` VARCHAR(100) NOT NULL, `entity_type` VARCHAR(50) DEFAULT NULL, `entity_id` INT UNSIGNED DEFAULT NULL, `details` JSON DEFAULT NULL, `ip_address` VARCHAR(45) DEFAULT NULL, `user_agent` VARCHAR(500) DEFAULT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_action` (`action`), KEY `idx_entity_type` (`entity_type`), KEY `idx_entity_id` (`entity_id`), KEY `idx_created_at` (`created_at`), KEY `idx_action_entity` (`action`, `entity_type`), CONSTRAINT `fk_audit_logs_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Monitoring History Table -- ============================================================================ CREATE TABLE IF NOT EXISTS `monitoring_history` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `server_id` INT UNSIGNED NOT NULL, `status` ENUM('online', 'offline') NOT NULL DEFAULT 'offline', `cpu_usage` DECIMAL(5,2) NOT NULL DEFAULT 0, `ram_usage` DECIMAL(5,2) NOT NULL DEFAULT 0, `disk_usage` DECIMAL(5,2) NOT NULL DEFAULT 0, `load_average` DECIMAL(8,4) NOT NULL DEFAULT 0, `uptime` VARCHAR(50) DEFAULT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_server_id` (`server_id`), KEY `idx_created_at` (`created_at`), KEY `idx_server_created` (`server_id`, `created_at`), CONSTRAINT `fk_monitoring_history_server` FOREIGN KEY (`server_id`) REFERENCES `servers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- API Tokens Table (for rate limiting and token management) -- ============================================================================ CREATE TABLE IF NOT EXISTS `api_tokens` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT UNSIGNED NOT NULL, `name` VARCHAR(100) NOT NULL, `token` VARCHAR(64) NOT NULL, `last_used_at` DATETIME DEFAULT NULL, `expires_at` DATETIME DEFAULT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_token` (`token`), KEY `idx_user_id` (`user_id`), KEY `idx_expires_at` (`expires_at`), CONSTRAINT `fk_api_tokens_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Rate Limiting Table -- ============================================================================ CREATE TABLE IF NOT EXISTS `rate_limits` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(255) NOT NULL, `action` VARCHAR(100) NOT NULL, `attempts` INT UNSIGNED NOT NULL DEFAULT 1, `first_attempt_at` DATETIME NOT NULL, `last_attempt_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_identifier_action` (`identifier`, `action`), KEY `idx_last_attempt_at` (`last_attempt_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Session Table (for server-side session storage) -- ============================================================================ CREATE TABLE IF NOT EXISTS `sessions` ( `id` VARCHAR(128) NOT NULL, `user_id` INT UNSIGNED DEFAULT NULL, `ip_address` VARCHAR(45) DEFAULT NULL, `user_agent` TEXT DEFAULT NULL, `payload` LONGTEXT NOT NULL, `last_activity` INT UNSIGNED NOT NULL, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_last_activity` (`last_activity`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Events table for scheduled tasks and cron jobs tracking -- ============================================================================ CREATE TABLE IF NOT EXISTS `scheduled_tasks` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `description` VARCHAR(255) DEFAULT NULL, `command` VARCHAR(500) NOT NULL, `interval_seconds` INT UNSIGNED NOT NULL DEFAULT 3600, `last_run_at` DATETIME DEFAULT NULL, `next_run_at` DATETIME DEFAULT NULL, `is_active` TINYINT(1) NOT NULL DEFAULT 1, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_next_run_at` (`next_run_at`), KEY `idx_is_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- Seed Data: Default Super Admin User -- Password: Admin@123 (change immediately after first login) -- Argon2id hash for 'Admin@123' -- ============================================================================ INSERT INTO `users` (`username`, `email`, `password_hash`, `role`, `is_active`, `api_token`, `created_at`) VALUES ( 'admin', 'admin@localhost', '$argon2id$v=19$m=65536,t=4,p=3$Y0hBM2QxZ1R4V1pLY2xPTw$iT3DnBqG8pGkOZ7j6QFUwL5XhR0sMvW3a2eX4bN1c8Y', 'super_admin', 1, 'sample_token_replace_in_production_please_change_me_1234567890ab', NOW() ); -- ============================================================================ -- Seed Data: Sample Scheduled Task (Monitoring) -- ============================================================================ INSERT INTO `scheduled_tasks` (`name`, `description`, `command`, `interval_seconds`, `next_run_at`, `is_active`) VALUES ( 'collect_metrics', 'Collect monitoring metrics from all active servers', 'php bin/monitor.php', 30, NOW(), 1 ); -- ============================================================================ -- Cleanup: Create event to auto-clean old monitoring data -- ============================================================================ DELIMITER // CREATE EVENT IF NOT EXISTS `cleanup_monitoring_history` ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP DO BEGIN DELETE FROM `monitoring_history` WHERE `created_at` < DATE_SUB(NOW(), INTERVAL 30 DAY); DELETE FROM `rate_limits` WHERE `last_attempt_at` < DATE_SUB(NOW(), INTERVAL 24 HOUR); DELETE FROM `sessions` WHERE `last_activity` < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 24 HOUR)); END// DELIMITER ; -- ============================================================================ -- Verify setup -- ============================================================================ SELECT 'ServerManager database created successfully!' AS status; SELECT 'Default admin user: admin / Admin@123 (CHANGE IMMEDIATELY)' AS note; SELECT 'IMPORTANT: Generate master encryption key before use!' AS warning;