false, 'error' => $message], JSON_UNESCAPED_SLASHES); exit; } if ($_SERVER['REQUEST_METHOD'] !== 'POST') { ingestError(405, 'method not allowed'); } $allowedIp = env('BOKA_IP'); if ($allowedIp !== null && $allowedIp !== '') { $remoteAddr = $_SERVER['REMOTE_ADDR'] ?? ''; if (!hash_equals($allowedIp, $remoteAddr)) { ingestError(403, 'forbidden'); } } $raw = file_get_contents('php://input'); if ($raw === false || $raw === '') { ingestError(400, 'empty body'); } $data = json_decode($raw, true); if (!is_array($data)) { ingestError(400, 'invalid json'); } $expectedToken = env('MONITOR_INGEST_TOKEN') ?? ''; $token = isset($data['token']) && is_string($data['token']) ? $data['token'] : ''; if ($expectedToken === '' || !hash_equals($expectedToken, $token)) { ingestError(403, 'forbidden'); } if (!isset($data['load']) || !is_array($data['load'])) { ingestError(400, 'missing load'); } foreach (['disk_percent', 'mem_available_mb', 'containers_running', 'containers_unhealthy'] as $field) { if (!isset($data[$field]) || !is_numeric($data[$field])) { ingestError(400, "missing {$field}"); } } $load = array_map(static fn (mixed $v): float => (float) $v, $data['load']); $backupLastSuccess = null; if (isset($data['backup_last_success']) && is_string($data['backup_last_success']) && $data['backup_last_success'] !== '') { $backupLastSuccess = $data['backup_last_success']; } $host = isset($data['host']) && is_string($data['host']) ? $data['host'] : 'boka'; $clientTimestamp = isset($data['timestamp']) && is_string($data['timestamp']) ? $data['timestamp'] : null; $status = [ 'last_push' => gmdate('c'), 'received_from' => $_SERVER['REMOTE_ADDR'] ?? null, 'host' => $host, 'client_timestamp' => $clientTimestamp, 'load' => $load, 'disk_percent' => (int) $data['disk_percent'], 'mem_available_mb' => (int) $data['mem_available_mb'], 'containers_running' => (int) $data['containers_running'], 'containers_unhealthy' => (int) $data['containers_unhealthy'], 'backup_last_success' => $backupLastSuccess, ]; try { writeJsonFile(privateDataDir() . '/boka-status.json', $status); } catch (Throwable $e) { ingestError(500, 'storage error'); } echo json_encode(['ok' => true], JSON_UNESCAPED_SLASHES);