UNPKG

@aerocorp/cli

Version:

AeroCorp CLI 5.1.0 - Future-Proofed Enterprise Infrastructure with Live Preview, Tunneling & Advanced DevOps

234 lines (192 loc) • 7.78 kB
import axios from 'axios'; import chalk from 'chalk'; import ora from 'ora'; import { AuthService } from './auth'; import { ConfigService } from './config'; export class HealthService { private authService = new AuthService(); private configService = new ConfigService(); async checkHealth() { console.log(chalk.cyan('šŸ„ AeroCorp System Health Check')); console.log(chalk.cyan('================================')); const checks = [ { name: 'Authentication', check: () => this.checkAuth() }, { name: 'Coolify API', check: () => this.checkCoolifyAPI() }, { name: 'AI-Proxy', check: () => this.checkAIProxy() }, { name: 'Server Connection', check: () => this.checkServerConnection() }, { name: 'Configuration', check: () => this.checkConfiguration() } ]; const results: any[] = []; for (const healthCheck of checks) { const spinner = ora(`Checking ${healthCheck.name}...`).start(); try { const result = await healthCheck.check(); spinner.succeed(`${healthCheck.name}: ${result.status}`); results.push({ name: healthCheck.name, status: 'healthy', details: result }); } catch (error) { spinner.fail(`${healthCheck.name}: ${error.message}`); results.push({ name: healthCheck.name, status: 'unhealthy', error: error.message }); } } // Summary const healthy = results.filter(r => r.status === 'healthy').length; const total = results.length; console.log(chalk.cyan(`\nšŸ“Š Health Summary: ${healthy}/${total} checks passed`)); if (healthy === total) { console.log(chalk.green('āœ… All systems operational')); } else { console.log(chalk.yellow('āš ļø Some issues detected')); const unhealthy = results.filter(r => r.status === 'unhealthy'); console.log(chalk.red('\nāŒ Issues:')); unhealthy.forEach(issue => { console.log(chalk.red(` • ${issue.name}: ${issue.error}`)); }); } return results; } async showStatus() { console.log(chalk.cyan('šŸ“Š AeroCorp System Status')); console.log(chalk.cyan('==========================')); try { // System info console.log(chalk.blue('\nšŸ–„ļø System Information:')); console.log(chalk.white(` Server IP: ${this.configService.get('server_ip') || '128.140.35.238'}`)); console.log(chalk.white(` Environment: ${this.configService.get('environment') || 'production'}`)); console.log(chalk.white(` CLI Version: 2.1.0`)); // Authentication status console.log(chalk.blue('\nšŸ” Authentication:')); const isAuth = this.authService.isAuthenticated(); console.log(chalk[isAuth ? 'green' : 'red'](` Status: ${isAuth ? 'Authenticated' : 'Not authenticated'}`)); if (isAuth) { const coolifyUrl = this.authService.getCoolifyUrl(); console.log(chalk.white(` Coolify URL: ${coolifyUrl}`)); const hasRootToken = !!process.env.AEROCORP_CLI_ROOT_API_TOKEN; if (hasRootToken) { console.log(chalk.red(' Root Access: ENABLED')); } } // Configuration console.log(chalk.blue('\nāš™ļø Configuration:')); const config = this.configService.getAll(); Object.entries(config).forEach(([key, value]) => { let displayValue = value; if (key.includes('token') || key.includes('password')) { displayValue = typeof value === 'string' ? '*'.repeat(Math.min(value.toString().length, 10)) : value; } console.log(chalk.white(` ${key}: ${displayValue}`)); }); // Services status await this.checkServicesStatus(); } catch (error) { console.error(chalk.red(`Error getting status: ${error.message}`)); } } private async checkAuth(): Promise<any> { const isAuthenticated = this.authService.isAuthenticated(); if (!isAuthenticated) { throw new Error('Not authenticated'); } const hasRootToken = !!process.env.AEROCORP_CLI_ROOT_API_TOKEN; return { status: 'Authenticated', rootAccess: hasRootToken, coolifyUrl: this.authService.getCoolifyUrl() }; } private async checkCoolifyAPI(): Promise<any> { if (!this.authService.isAuthenticated()) { throw new Error('Not authenticated'); } const coolifyUrl = this.authService.getCoolifyUrl(); const headers = this.authService.getAuthHeaders(); const response = await axios.get(`${coolifyUrl}/api/v1/projects`, { headers, timeout: 10000 }); if (response.status !== 200) { throw new Error(`API returned status ${response.status}`); } return { status: 'API accessible', projects: response.data.length, responseTime: response.headers['x-response-time'] || 'N/A' }; } private async checkAIProxy(): Promise<any> { const serverIP = this.configService.get('server_ip') || '128.140.35.238'; try { const response = await axios.get(`http://${serverIP}:8082/api/health`, { timeout: 5000 }); if (response.status === 200 && response.data.status === 'healthy') { return { status: 'AI-Proxy healthy', version: response.data.version, endpoints: Object.keys(response.data.endpoints || {}).length }; } else { throw new Error('AI-Proxy not healthy'); } } catch (error) { throw new Error(`AI-Proxy unreachable: ${error.message}`); } } private async checkServerConnection(): Promise<any> { const serverIP = this.configService.get('server_ip') || '128.140.35.238'; try { // Check if we can reach the server const response = await axios.get(`http://${serverIP}:8000`, { timeout: 5000, validateStatus: () => true // Accept any status code }); return { status: 'Server reachable', serverIP, responseCode: response.status }; } catch (error) { if (error.code === 'ECONNREFUSED') { throw new Error('Connection refused'); } else if (error.code === 'ETIMEDOUT') { throw new Error('Connection timeout'); } else { throw new Error(`Network error: ${error.message}`); } } } private async checkConfiguration(): Promise<any> { const config = this.configService.getAll(); const requiredKeys = ['coolify_url', 'server_ip']; const missing = requiredKeys.filter(key => !config[key]); if (missing.length > 0) { throw new Error(`Missing configuration: ${missing.join(', ')}`); } return { status: 'Configuration valid', configPath: this.configService.getConfigPath(), keys: Object.keys(config).length }; } private async checkServicesStatus() { console.log(chalk.blue('\nšŸš€ Services Status:')); const services = [ { name: 'Coolify', url: 'https://coolify.aerocorpindustries.org', port: 8000 }, { name: 'AI-Proxy', url: 'http://128.140.35.238:8082', port: 8082 }, { name: 'CapRover', url: 'http://client.aerocorpindustries.org:10000', port: 10000 }, { name: 'Ollama', url: 'http://128.140.35.238:11434', port: 11434 } ]; for (const service of services) { try { const response = await axios.get(service.url, { timeout: 3000, validateStatus: () => true }); const status = response.status < 400 ? 'healthy' : 'issues'; const color = status === 'healthy' ? 'green' : 'yellow'; console.log(chalk[color](` āœ“ ${service.name}: ${status} (${response.status})`)); } catch (error) { console.log(chalk.red(` āœ— ${service.name}: unreachable`)); } } } }