235 lines
8.9 KiB
PHP
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();
|