220 lines
9.0 KiB
PHP
Executable File
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']]);
|
|
}
|
|
|