Files
wevads-platform/scripts/api_auto-provisioner.php
2026-02-26 04:53:11 +01:00

220 lines
9.0 KiB
PHP
Executable File

<?php
/**
* AUTO SERVER PROVISIONER
* Autonomous Huawei T6 Deployment + PMTA Setup
*/
header('Content-Type: application/json');
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$pdo->exec("
CREATE TABLE IF NOT EXISTS admin.auto_servers (
id SERIAL PRIMARY KEY,
server_id VARCHAR(100),
name VARCHAR(255),
ip_address VARCHAR(50),
provider VARCHAR(50) DEFAULT 'huawei',
region VARCHAR(50),
flavor VARCHAR(50) DEFAULT 't6.medium.2',
status VARCHAR(50) DEFAULT 'pending',
pmta_status VARCHAR(50) DEFAULT 'not_installed',
assigned_campaign INTEGER,
daily_limit INTEGER DEFAULT 15000,
sent_today INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ready_at TIMESTAMP
);
CREATE TABLE IF NOT EXISTS admin.server_templates (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE,
provider VARCHAR(50),
flavor VARCHAR(100),
image_id VARCHAR(255),
region VARCHAR(50),
vpc_id VARCHAR(255),
subnet_id VARCHAR(255),
security_group VARCHAR(255),
user_data TEXT,
is_default BOOLEAN DEFAULT false
);
");
class AutoProvisioner {
private $pdo;
private $huaweiApi = 'http://localhost:5821/api/huawei.php';
public function __construct($pdo) {
$this->pdo = $pdo;
$this->initTemplates();
}
private function initTemplates() {
$templates = [
['Huawei_T6_Africa', 'huawei', 't6.medium.2', '', 'af-south-1', '', '', '', $this->getPMTAUserData(), true],
['Huawei_T6_Europe', 'huawei', 't6.medium.2', '', 'eu-west-0', '', '', '', $this->getPMTAUserData(), false],
['Huawei_T6_Asia', 'huawei', 't6.medium.2', '', 'ap-southeast-1', '', '', '', $this->getPMTAUserData(), false]
];
foreach ($templates as $t) {
$this->pdo->prepare("INSERT INTO admin.server_templates (name, provider, flavor, image_id, region, vpc_id, subnet_id, security_group, user_data, is_default) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT (name) DO NOTHING")
->execute($t);
}
}
private function getPMTAUserData() {
return base64_encode('#!/bin/bash
apt-get update && apt-get install -y wget curl nano net-tools postfix
# PMTA will be installed via API after server is ready
echo "SERVER_READY" > /tmp/server_status
');
}
public function provisionForCampaign($campaignId, $count = 5, $region = 'af-south-1') {
$results = [];
// Get template
$template = $this->pdo->query("SELECT * FROM admin.server_templates WHERE region = '$region' OR is_default = true ORDER BY is_default DESC LIMIT 1")->fetch(PDO::FETCH_ASSOC);
for ($i = 1; $i <= $count; $i++) {
$name = "mta-camp{$campaignId}-" . str_pad($i, 3, '0', STR_PAD_LEFT);
// Create server record
$this->pdo->prepare("INSERT INTO admin.auto_servers (name, provider, region, flavor, status, assigned_campaign) VALUES (?, ?, ?, ?, 'provisioning', ?)")
->execute([$name, 'huawei', $region, $template['flavor'] ?? 't6.medium.2', $campaignId]);
$serverId = $this->pdo->lastInsertId();
// Call Huawei API (simulated - replace with real call)
$apiResult = $this->callHuaweiCreate($name, $template);
if ($apiResult['success'] ?? false) {
$this->pdo->prepare("UPDATE admin.auto_servers SET server_id = ?, status = 'created' WHERE id = ?")
->execute([$apiResult['server_id'] ?? uniqid(), $serverId]);
}
$results[] = ['name' => $name, 'id' => $serverId, 'status' => 'provisioning'];
}
return ['success' => true, 'servers' => $results, 'campaign_id' => $campaignId];
}
private function callHuaweiCreate($name, $template) {
// Real implementation would call Huawei API
// For now, simulate success
return ['success' => true, 'server_id' => 'hw-' . uniqid()];
}
public function checkServerStatus($serverId) {
$stmt = $this->pdo->prepare("SELECT * FROM admin.auto_servers WHERE id = ?");
$stmt->execute([$serverId]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function installPMTA($serverId) {
$server = $this->checkServerStatus($serverId);
if (!$server || !$server['ip_address']) {
return ['success' => false, 'error' => 'Server not ready or no IP'];
}
// Update status
$this->pdo->prepare("UPDATE admin.auto_servers SET pmta_status = 'installing' WHERE id = ?")->execute([$serverId]);
// Call PMTA installer API
$ch = curl_init('http://localhost:5821/api/pmta-installer.php');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'action' => 'install',
'ip' => $server['ip_address'],
'domain' => 'mta' . $serverId . '.sendcloud.com'
])
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($result['success'] ?? false) {
$this->pdo->prepare("UPDATE admin.auto_servers SET pmta_status = 'installed', status = 'ready', ready_at = NOW() WHERE id = ?")->execute([$serverId]);
}
return $result;
}
public function getAvailableServers($count = 5) {
return $this->pdo->query("SELECT * FROM admin.auto_servers WHERE status = 'ready' AND sent_today < daily_limit ORDER BY sent_today ASC LIMIT $count")->fetchAll(PDO::FETCH_ASSOC);
}
public function releaseServers($campaignId) {
$this->pdo->prepare("UPDATE admin.auto_servers SET assigned_campaign = NULL, status = 'available' WHERE assigned_campaign = ?")->execute([$campaignId]);
return ['success' => true];
}
public function terminateServers($campaignId) {
$servers = $this->pdo->query("SELECT * FROM admin.auto_servers WHERE assigned_campaign = $campaignId")->fetchAll(PDO::FETCH_ASSOC);
foreach ($servers as $server) {
// Call Huawei delete API
$this->pdo->prepare("UPDATE admin.auto_servers SET status = 'terminated' WHERE id = ?")->execute([$server['id']]);
}
return ['success' => true, 'terminated' => count($servers)];
}
public function autoScale($campaignId, $targetVolume) {
$currentServers = $this->pdo->query("SELECT COUNT(*) FROM admin.auto_servers WHERE assigned_campaign = $campaignId AND status = 'ready'")->fetchColumn();
$neededServers = ceil($targetVolume / 15000);
if ($neededServers > $currentServers) {
return $this->provisionForCampaign($campaignId, $neededServers - $currentServers);
}
return ['success' => true, 'message' => 'No scaling needed', 'current' => $currentServers, 'needed' => $neededServers];
}
public function getStats() {
return [
'total' => $this->pdo->query("SELECT COUNT(*) FROM admin.auto_servers")->fetchColumn(),
'ready' => $this->pdo->query("SELECT COUNT(*) FROM admin.auto_servers WHERE status = 'ready'")->fetchColumn(),
'provisioning' => $this->pdo->query("SELECT COUNT(*) FROM admin.auto_servers WHERE status = 'provisioning'")->fetchColumn(),
'by_region' => $this->pdo->query("SELECT region, COUNT(*) as count FROM admin.auto_servers GROUP BY region")->fetchAll(PDO::FETCH_ASSOC)
];
}
}
$provisioner = new AutoProvisioner($pdo);
$action = $_POST['action'] ?? $_GET['action'] ?? '';
switch ($action) {
case 'provision':
echo json_encode($provisioner->provisionForCampaign($_POST['campaign_id'], $_POST['count'] ?? 5, $_POST['region'] ?? 'af-south-1'));
break;
case 'status':
echo json_encode($provisioner->checkServerStatus($_GET['server_id']));
break;
case 'install_pmta':
echo json_encode($provisioner->installPMTA($_POST['server_id']));
break;
case 'available':
echo json_encode(['servers' => $provisioner->getAvailableServers($_GET['count'] ?? 5)]);
break;
case 'release':
echo json_encode($provisioner->releaseServers($_POST['campaign_id']));
break;
case 'terminate':
echo json_encode($provisioner->terminateServers($_POST['campaign_id']));
break;
case 'autoscale':
echo json_encode($provisioner->autoScale($_POST['campaign_id'], $_POST['volume']));
break;
case 'stats':
echo json_encode($provisioner->getStats());
break;
case 'templates':
echo json_encode(['templates' => $pdo->query("SELECT * FROM admin.server_templates")->fetchAll(PDO::FETCH_ASSOC)]);
break;
default:
echo json_encode(['name' => 'Auto Provisioner', 'actions' => ['provision','status','install_pmta','available','release','terminate','autoscale','stats','templates']]);
}