true, 'host_id' => $hostId, 'domains' => $domains, 'warn_days' => (int)($w[1] ?? 30), 'crit_days' => (int)($c[1] ?? 7), ]); exit; } // ── Run cert_monitor.sh now ─────────────────────────────────────────────────── if ($action === 'run') { $script = SCRIPTS_DIR . '/Monitors/cert_monitor.sh'; if (!file_exists($script)) { echo json_encode(['ok' => false, 'error' => 'cert_monitor.sh not found']); exit; } set_time_limit(180); exec('bash ' . escapeshellarg($script) . ' 2>&1', $out, $rc); // Read freshly written cache $data = file_exists($cacheFile) ? (json_decode(file_get_contents($cacheFile), true) ?: null) : null; echo json_encode([ 'ok' => true, 'data' => $data, 'output' => array_slice(array_filter(array_map('trim', $out)), 0, 30), 'rc' => $rc, ]); exit; } // ── Default: return cached status ───────────────────────────────────────────── if (!file_exists($cacheFile)) { // No cache yet — return configured domains so UI can show them unchecked $hostId = vv_detect_host(); $hostIdUp = strtoupper($hostId); $confRaw = ($hostId !== 'unknown') ? vv_read_conf_raw($hostId . '.conf') : ''; $master = vv_read_conf_raw('master.conf'); preg_match('/^\s*CERT_WARN_DAYS\s*=\s*(\d+)/m', $master, $w); preg_match('/^\s*CERT_CRIT_DAYS\s*=\s*(\d+)/m', $master, $c); $domains = []; if (preg_match('/' . $hostIdUp . '_CERT_MONITOR_DOMAINS\s*=\s*\(([^)]*)\)/s', $confRaw, $dm)) { preg_match_all('/"([^"]+)"/', $dm[1], $dd); foreach ($dd[1] ?? [] as $d) { $domains[] = ['domain' => $d, 'status' => 'UNKN', 'days' => null, 'expires' => '']; } } echo json_encode([ 'ok' => true, 'checked_at' => null, 'host' => $hostId !== 'unknown' ? strtoupper($hostId) : null, 'warn_days' => (int)($w[1] ?? 30), 'crit_days' => (int)($c[1] ?? 7), 'domains' => $domains, ]); exit; } $data = json_decode(file_get_contents($cacheFile), true) ?: []; echo json_encode(array_merge(['ok' => true], $data));