Files
wevads-platform/brain/cloud/auto_provision.php
2026-02-26 04:53:11 +01:00

235 lines
8.9 KiB
PHP

<?php
/**
* BRAIN AUTO-PROVISIONER
* Travaille en autonomie pour maintenir le pool de serveurs
*/
require_once __DIR__ . '/orchestrator.php';
class BrainAutoProvisioner {
private $brain;
private $db;
private $minServers = 3; // Minimum de serveurs actifs
public function __construct() {
$this->brain = new BrainCloudOrchestrator();
$this->db = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123");
$this->db->exec("SET search_path TO admin, public");
}
public function run() {
echo "🧠 BRAIN AUTO-PROVISIONER DÉMARRÉ\n";
echo str_repeat("=", 50) . "\n\n";
// 1. Analyser l'état actuel
$status = $this->analyzeCurrentState();
// 2. Vérifier les providers disponibles
$providers = $this->checkProviders();
// 3. Décider des actions
$actions = $this->decideActions($status, $providers);
// 4. Exécuter les actions
$results = $this->executeActions($actions);
// 5. Rapport
$this->generateReport($status, $providers, $actions, $results);
return $results;
}
private function analyzeCurrentState() {
echo "📊 ANALYSE ÉTAT ACTUEL\n";
// Serveurs actifs
$active = $this->db->query("SELECT COUNT(*) FROM mta_servers WHERE status IN ('Activated', 'Active', 'Running')")->fetchColumn();
$creating = $this->db->query("SELECT COUNT(*) FROM mta_servers WHERE status = 'Creating'")->fetchColumn();
$deleted = $this->db->query("SELECT COUNT(*) FROM mta_servers WHERE status = 'Deleted'")->fetchColumn();
echo " • Serveurs actifs: $active\n";
echo " • En création: $creating\n";
echo " • Supprimés: $deleted\n";
echo " • Minimum requis: {$this->minServers}\n";
echo " • Besoin: " . max(0, $this->minServers - $active) . " serveurs\n\n";
return [
'active' => $active,
'creating' => $creating,
'deleted' => $deleted,
'needed' => max(0, $this->minServers - $active - $creating)
];
}
private function checkProviders() {
echo "🔌 VÉRIFICATION PROVIDERS\n";
$allProviders = $this->brain->getAllProvidersStatus();
$available = [];
$needConfig = [];
foreach ($allProviders as $name => $info) {
if ($info['configured']) {
$available[] = ['name' => $name, 'price' => $info['price'], 'currency' => $info['currency']];
echo "$name - {$info['currency']} {$info['price']}/mois\n";
} else {
$needConfig[] = ['name' => $name, 'price' => $info['price'], 'url' => $info['signup_url']];
echo " ⚠️ $name - Non configuré ({$info['signup_url']})\n";
}
}
echo "\n";
return [
'available' => $available,
'need_config' => $needConfig,
'total' => count($allProviders),
'configured' => count($available)
];
}
private function decideActions($status, $providers) {
echo "🎯 DÉCISION DU BRAIN\n";
$actions = [];
// Besoin de serveurs ?
if ($status['needed'] > 0) {
if (count($providers['available']) > 0) {
// Choisir le moins cher
usort($providers['available'], fn($a, $b) => $a['price'] - $b['price']);
$best = $providers['available'][0];
$actions[] = [
'type' => 'create_servers',
'provider' => $best['name'],
'count' => $status['needed'],
'reason' => "Pool insuffisant ({$status['active']}/{$this->minServers})"
];
echo " → CRÉER {$status['needed']} serveur(s) sur {$best['name']}\n";
} else {
$actions[] = [
'type' => 'need_provider',
'recommendation' => $providers['need_config'][0] ?? null,
'reason' => 'Aucun provider configuré'
];
echo " → BESOIN: Configurer un provider\n";
// Recommandation
if (!empty($providers['need_config'])) {
usort($providers['need_config'], fn($a, $b) => $a['price'] - $b['price']);
$rec = $providers['need_config'][0];
echo " → RECOMMANDÉ: {$rec['name']} ({$rec['price']}€/mois)\n";
echo " → URL: {$rec['url']}\n";
}
}
} else {
$actions[] = [
'type' => 'nothing',
'reason' => 'Pool de serveurs suffisant'
];
echo " → Aucune action nécessaire\n";
}
echo "\n";
return $actions;
}
private function executeActions($actions) {
echo "⚡ EXÉCUTION\n";
$results = [];
foreach ($actions as $action) {
switch ($action['type']) {
case 'create_servers':
echo " Création de {$action['count']} serveur(s) sur {$action['provider']}...\n";
for ($i = 0; $i < $action['count']; $i++) {
$result = $this->brain->createServer('default', []);
$results[] = $result;
if ($result['success']) {
$ip = $result['server']['public_net']['ipv4']['ip'] ??
$result['server']['main_ip'] ?? 'Pending';
echo " ✅ Serveur créé: $ip\n";
} else {
echo " ❌ Échec: {$result['error']}\n";
}
sleep(2); // Pause entre créations
}
break;
case 'need_provider':
echo " ⚠️ Action manuelle requise: configurer un provider\n";
$results[] = ['success' => false, 'error' => 'No provider configured', 'action_required' => 'configure_provider'];
break;
case 'nothing':
echo " ✓ Rien à faire\n";
$results[] = ['success' => true, 'message' => 'No action needed'];
break;
}
}
echo "\n";
return $results;
}
private function generateReport($status, $providers, $actions, $results) {
echo str_repeat("=", 50) . "\n";
echo "📋 RAPPORT BRAIN\n";
echo str_repeat("=", 50) . "\n";
$success = count(array_filter($results, fn($r) => $r['success'] ?? false));
$failed = count($results) - $success;
echo "Serveurs actifs: {$status['active']}\n";
echo "Providers configurés: {$providers['configured']}/{$providers['total']}\n";
echo "Actions exécutées: " . count($actions) . "\n";
echo "Succès: $success | Échecs: $failed\n";
if ($providers['configured'] == 0) {
echo "\n⚠️ ATTENTION: Aucun provider cloud configuré!\n";
echo "Le Brain ne peut pas créer de serveurs.\n\n";
echo "SOLUTIONS:\n";
$cheapest = $providers['need_config'];
usort($cheapest, fn($a, $b) => $a['price'] - $b['price']);
foreach (array_slice($cheapest, 0, 3) as $i => $p) {
echo ($i+1) . ". {$p['name']} - {$p['price']}€/mois\n";
echo "{$p['url']}\n";
}
echo "\nPuis configurer via:\n";
echo "curl -X POST 'http://127.0.0.1:5821/api/cloud_orchestrator.php' \\\n";
echo " -d '{\"action\":\"save_credentials\",\"provider\":\"hetzner\",\"api_key\":\"YOUR_KEY\"}'\n";
}
// Log to DB
$report = json_encode([
'timestamp' => date('Y-m-d H:i:s'),
'status' => $status,
'providers' => $providers['configured'],
'actions' => count($actions),
'success' => $success,
'failed' => $failed
]);
$this->db->exec("INSERT INTO brain_logs (message, created_at) VALUES ('Auto-provision: $report', NOW()) ON CONFLICT DO NOTHING");
}
}
// Créer table logs si nécessaire
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123");
$pdo->exec("SET search_path TO admin, public");
$pdo->exec("CREATE TABLE IF NOT EXISTS brain_logs (id SERIAL PRIMARY KEY, message TEXT, created_at TIMESTAMP DEFAULT NOW())");
// Exécuter
$provisioner = new BrainAutoProvisioner();
$provisioner->run();