UNPKG

iop

Version:
205 lines 8.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkProxyStatus = checkProxyStatus; exports.formatProxyStatus = formatProxyStatus; const docker_1 = require("../docker"); const proxy_1 = require("../proxy"); /** * Gets port mappings for the proxy container */ async function getProxyPorts(sshClient, containerName, verbose = false) { try { const inspectOutput = await sshClient.exec(`docker inspect ${containerName} --format='{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$p}} -> {{(index $conf 0).HostPort}}{{println}}{{end}}{{end}}'`); return inspectOutput .split("\n") .filter((line) => line.trim()) .map((line) => line.trim()); } catch (error) { if (verbose) { console.warn(`Failed to get port mappings for ${containerName}: ${error}`); } return []; } } /** * Gets certificate queue status from the proxy */ async function getCertificateQueueStatus(sshClient, verbose = false) { try { const statusOutput = await sshClient.exec(`docker exec iop-proxy /usr/local/bin/iop-proxy status 2>/dev/null || echo "PROXY_NOT_AVAILABLE"`); if (statusOutput.includes("PROXY_NOT_AVAILABLE") || !statusOutput.trim()) { return []; } // Parse the status output to extract certificate queue information const entries = []; const lines = statusOutput.split("\n"); // Look for the specific output format from iop-proxy status let foundCertSection = false; for (const line of lines) { const trimmedLine = line.trim(); // Check for "No domains pending certificate provisioning" message if (trimmedLine.includes("No domains pending certificate provisioning")) { return []; } // Look for certificate retry queue section if (trimmedLine.includes("Certificate Retry Queue")) { foundCertSection = true; continue; } // If we're in the certificate section, parse entries if (foundCertSection) { // Look for status lines with emojis or specific patterns if (trimmedLine.match(/^(Pending|Retrying)/) || trimmedLine.includes("Pending") || trimmedLine.includes("Retrying")) { // Extract hostname (last word on the line) const parts = trimmedLine.split(" "); const hostname = parts[parts.length - 1]; const status = trimmedLine.includes("Retrying") ? "retrying" : "pending"; // Extract attempt count if present const attemptMatch = trimmedLine.match(/attempt (\d+)/); const attempts = attemptMatch ? parseInt(attemptMatch[1]) : 0; entries.push({ hostname, status, attempts, email: "", addedAt: "", }); } } } return entries; } catch (error) { if (verbose) { console.warn(`Failed to get certificate queue status: ${error}`); } return []; } } /** * Checks the overall proxy status for a server */ async function checkProxyStatus(serverHostname, sshClient, verbose = false) { try { const dockerClient = new docker_1.DockerClient(sshClient, serverHostname, verbose); const proxyClient = new proxy_1.IopProxyClient(dockerClient, serverHostname, verbose); const containerName = "iop-proxy"; // Use the existing IopProxyClient to check if proxy is running const isRunning = await proxyClient.isProxyRunning(); // Get port mappings const ports = isRunning ? await getProxyPorts(sshClient, containerName, verbose) : []; // Get certificate queue status const certificateQueue = isRunning ? await getCertificateQueueStatus(sshClient, verbose) : []; // Get recent proxy logs to show domain activity and configuration issues let configurations = []; let configurationIssues = []; if (isRunning) { try { // Get more recent logs to analyze domain activity const recentLogs = await sshClient.exec(`docker logs ${containerName} --tail 10 2>/dev/null`); if (recentLogs && recentLogs.trim()) { const domains = new Set(); const logLines = recentLogs.split("\n"); for (const line of logLines) { // Look for domain patterns in logs const hostMatch = line.match(/Host: ([^,\s)]+)/); if (hostMatch) { const domain = hostMatch[1]; if (domain && !domain.match(/^\d+\.\d+\.\d+\.\d+$/)) { // Skip IP addresses domains.add(domain); } } // Look for configuration issues if (line.includes("not configured in iop proxy")) { const domainMatch = line.match(/domain "([^"]+)" not configured/); if (domainMatch) { configurationIssues.push(`${domainMatch[1]} not configured`); } } // Look for TLS handshake errors without domain names (general SSL issues) if (line.includes("TLS handshake error") && line.includes("missing server name")) { configurationIssues.push("SSL handshake errors (missing SNI)"); } } configurations = Array.from(domains); } } catch (error) { if (verbose) { console.warn(`Failed to get proxy activity: ${error}`); } } } return { running: isRunning, containerName, serverId: serverHostname, ports, certificateQueue, configurations, error: configurationIssues.length > 0 ? configurationIssues.join("; ") : undefined, }; } catch (error) { return { running: false, containerName: "iop-proxy", serverId: serverHostname, ports: [], error: `Failed to check proxy status: ${error}`, }; } } /** * Formats proxy status for display */ function formatProxyStatus(proxyStatus) { const lines = []; const statusIcon = proxyStatus.running ? "[✓]" : "[✗]"; const statusText = proxyStatus.running ? "RUNNING" : "STOPPED"; lines.push(` └─ Proxy: ${proxyStatus.containerName}`); lines.push(` ├─ Status: ${statusIcon} ${statusText}`); lines.push(` ├─ Server: ${proxyStatus.serverId}`); if (proxyStatus.running && proxyStatus.ports.length > 0) { lines.push(` ├─ Ports: ${proxyStatus.ports.join(", ")}`); } if (proxyStatus.configurations && proxyStatus.configurations.length > 0) { lines.push(` ├─ Recent Domain Activity: ${proxyStatus.configurations.length} domain(s) detected`); // Show the domains that have been seen in recent logs for (const domain of proxyStatus.configurations) { lines.push(` │ ├─ ${domain}`); } } else if (proxyStatus.running) { lines.push(` ├─ Recent Domain Activity: No domain traffic detected`); } if (proxyStatus.certificateQueue && proxyStatus.certificateQueue.length > 0) { lines.push(` ├─ Certificate Queue: ${proxyStatus.certificateQueue.length} pending`); for (const entry of proxyStatus.certificateQueue) { const entryStatusIcon = entry.status === "pending" ? "PENDING" : "RETRYING"; const attemptText = entry.attempts > 0 ? ` (attempt ${entry.attempts})` : ""; lines.push(` │ ├─ ${entryStatusIcon} ${entry.hostname}${attemptText}`); } } else if (proxyStatus.running) { lines.push(` ├─ Certificate Queue: Empty`); } if (proxyStatus.error) { lines.push(` ├─ WARNING: Configuration Issues: ${proxyStatus.error}`); } return lines; } //# sourceMappingURL=proxy-checker.js.map