252 lines
8.8 KiB
PHP
252 lines
8.8 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Models\Server;
|
|
use App\Models\Client;
|
|
use App\Utils\View;
|
|
use App\Services\ASNService;
|
|
|
|
class ServerController
|
|
{
|
|
public function index()
|
|
{
|
|
$serverModel = new Server();
|
|
$sql = "SELECT s.*, c.name as client_name FROM servers s JOIN clients c ON s.client_id = c.id";
|
|
$stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
|
|
$stmt->execute();
|
|
$servers = $stmt->fetchAll();
|
|
|
|
View::render('layouts.admin', [
|
|
'title' => 'Gerenciar Servidores',
|
|
'content' => __DIR__ . '/../../resources/views/admin/servers/index.php',
|
|
'servers' => $servers
|
|
]);
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
$clientModel = new Client();
|
|
$clients = $clientModel->where('status', 'active');
|
|
|
|
View::render('layouts.admin', [
|
|
'title' => 'Novo Servidor',
|
|
'content' => __DIR__ . '/../../resources/views/admin/servers/form.php',
|
|
'clients' => $clients
|
|
]);
|
|
}
|
|
|
|
public function store()
|
|
{
|
|
$clientModel = new Client();
|
|
$client = $clientModel->find($_POST['client_id']);
|
|
|
|
if (!$client) {
|
|
View::redirect('/admin/servers');
|
|
return;
|
|
}
|
|
|
|
// Validate IP vs ASN
|
|
if (!ASNService::validateIP($_POST['ip_v4'], $client['asn'])) {
|
|
$_SESSION['flash_error'] = "O IP informado não pertence ao ASN do cliente ({$client['asn']}).";
|
|
// Keep input data
|
|
$_SESSION['old_input'] = $_POST;
|
|
View::redirect('/admin/servers/create');
|
|
return;
|
|
}
|
|
|
|
$data = [
|
|
'client_id' => $_POST['client_id'],
|
|
'name' => $_POST['name'],
|
|
'ip_v4' => $_POST['ip_v4'],
|
|
'ip_v6' => $_POST['ip_v6'] ?? null,
|
|
'serial_key' => bin2hex(random_bytes(16)),
|
|
'status' => 'active'
|
|
];
|
|
|
|
$sql = "INSERT INTO servers (client_id, name, ip_v4, ip_v6, serial_key, status) VALUES (:client_id, :name, :ip_v4, :ip_v6, :serial_key, :status)";
|
|
$stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
|
|
$stmt->execute($data);
|
|
|
|
// Pangolin Integration - Sincroniza o cliente após adicionar servidor
|
|
try {
|
|
$pangolinService = new \App\Services\PangolinService();
|
|
if ($pangolinService->isEnabled() && $client['status'] === 'active') {
|
|
$pangolinService->syncClient($_POST['client_id'], 'add');
|
|
}
|
|
} catch (\Exception $e) {
|
|
error_log("Pangolin Sync Error (Server Create): " . $e->getMessage());
|
|
}
|
|
|
|
View::redirect('/admin/servers');
|
|
}
|
|
|
|
public function edit($id)
|
|
{
|
|
$serverModel = new Server();
|
|
$server = $serverModel->find($id);
|
|
|
|
if (!$server) {
|
|
View::redirect('/admin/servers');
|
|
}
|
|
|
|
$clientModel = new Client();
|
|
$clients = $clientModel->where('status', 'active');
|
|
|
|
View::render('layouts.admin', [
|
|
'title' => 'Editar Servidor',
|
|
'content' => __DIR__ . '/../../resources/views/admin/servers/form.php',
|
|
'server' => $server,
|
|
'clients' => $clients
|
|
]);
|
|
}
|
|
|
|
public function update($id)
|
|
{
|
|
$serverModel = new Server();
|
|
$server = $serverModel->find($id);
|
|
|
|
if (!$server) {
|
|
View::redirect('/admin/servers');
|
|
return;
|
|
}
|
|
|
|
// If IP changed, validate again
|
|
if ($_POST['ip_v4'] !== $server['ip_v4']) {
|
|
$clientModel = new Client();
|
|
$client = $clientModel->find($_POST['client_id']);
|
|
|
|
if (!ASNService::validateIP($_POST['ip_v4'], $client['asn'])) {
|
|
$_SESSION['flash_error'] = "O IP informado não pertence ao ASN do cliente ({$client['asn']}).";
|
|
View::redirect('/admin/servers/edit/' . $id);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Guardar IPs antigos para remover do Pangolin se mudaram
|
|
$oldIpV4 = $server['ip_v4'];
|
|
$oldIpV6 = $server['ip_v6'];
|
|
$oldClientId = $server['client_id'];
|
|
$oldStatus = $server['status'];
|
|
|
|
$data = [
|
|
'id' => $id,
|
|
'client_id' => $_POST['client_id'],
|
|
'name' => $_POST['name'],
|
|
'ip_v4' => $_POST['ip_v4'],
|
|
'ip_v6' => $_POST['ip_v6'] ?? null,
|
|
'status' => $_POST['status']
|
|
];
|
|
|
|
$sql = "UPDATE servers SET client_id=:client_id, name=:name, ip_v4=:ip_v4, ip_v6=:ip_v6, status=:status WHERE id=:id";
|
|
$stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
|
|
$stmt->execute($data);
|
|
|
|
// Pangolin Integration - Sincroniza se IP, status ou cliente mudou
|
|
try {
|
|
$pangolinService = new \App\Services\PangolinService();
|
|
if ($pangolinService->isEnabled()) {
|
|
$clientModel = new Client();
|
|
$client = $clientModel->find($_POST['client_id']);
|
|
|
|
// Coletar IPs que mudaram para remover
|
|
$ipsToRemove = [];
|
|
if ($oldIpV4 !== $_POST['ip_v4']) {
|
|
$ipsToRemove[] = $oldIpV4;
|
|
}
|
|
if ($oldIpV6 !== ($_POST['ip_v6'] ?? null)) {
|
|
$ipsToRemove[] = $oldIpV6;
|
|
}
|
|
|
|
// Se o servidor era ativo e agora está inativo, remove os IPs
|
|
if ($oldStatus === 'active' && $_POST['status'] === 'inactive') {
|
|
$pangolinService->removeServerIps([$_POST['ip_v4'], $_POST['ip_v6'] ?? null]);
|
|
}
|
|
// Se o servidor era inativo e agora está ativo, adiciona os IPs
|
|
elseif ($oldStatus === 'inactive' && $_POST['status'] === 'active') {
|
|
if ($client && $client['status'] === 'active') {
|
|
$pangolinService->syncClient($_POST['client_id'], 'add');
|
|
}
|
|
}
|
|
// Se os IPs mudaram
|
|
elseif (!empty($ipsToRemove) && $_POST['status'] === 'active') {
|
|
$pangolinService->removeServerIps($ipsToRemove);
|
|
if ($client && $client['status'] === 'active') {
|
|
$pangolinService->syncClient($_POST['client_id'], 'add');
|
|
}
|
|
}
|
|
|
|
// Se o cliente mudou, sincroniza o cliente antigo também
|
|
if ($oldClientId != $_POST['client_id']) {
|
|
$oldClient = $clientModel->find($oldClientId);
|
|
if ($oldClient && $oldClient['status'] === 'active') {
|
|
$pangolinService->removeServerIps([$oldIpV4, $oldIpV6]);
|
|
}
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
error_log("Pangolin Sync Error (Server Update): " . $e->getMessage());
|
|
}
|
|
|
|
View::redirect('/admin/servers');
|
|
}
|
|
|
|
public function delete($id)
|
|
{
|
|
$serverModel = new Server();
|
|
$server = $serverModel->find($id);
|
|
|
|
if (!$server) {
|
|
View::redirect('/admin/servers');
|
|
return;
|
|
}
|
|
|
|
// Capturar IPs antes de deletar
|
|
$ipsToRemove = [$server['ip_v4']];
|
|
if (!empty($server['ip_v6'])) {
|
|
$ipsToRemove[] = $server['ip_v6'];
|
|
}
|
|
|
|
// Pangolin Integration - Remove os IPs do servidor antes de deletá-lo
|
|
try {
|
|
$pangolinService = new \App\Services\PangolinService();
|
|
if ($pangolinService->isEnabled() && $server['status'] === 'active') {
|
|
$clientModel = new Client();
|
|
$client = $clientModel->find($server['client_id']);
|
|
if ($client && $client['status'] === 'active') {
|
|
$pangolinService->removeServerIps($ipsToRemove);
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
error_log("Pangolin Sync Error (Server Delete): " . $e->getMessage());
|
|
}
|
|
|
|
// Delete the server
|
|
$serverModel->delete($id);
|
|
|
|
View::redirect('/admin/servers');
|
|
}
|
|
|
|
public function resetMachineId($id)
|
|
{
|
|
$serverModel = new Server();
|
|
$server = $serverModel->find($id);
|
|
|
|
if ($server) {
|
|
$sql = "UPDATE servers SET machine_id = NULL WHERE id = :id";
|
|
$stmt = \App\Config\Database::getInstance()->getConnection()->prepare($sql);
|
|
$stmt->execute(['id' => $id]);
|
|
|
|
// Log action
|
|
$logSql = "INSERT INTO api_logs (server_id, action, message, ip_address) VALUES (:sid, 'reset_machine', 'Machine ID reset by admin', :ip)";
|
|
$logStmt = \App\Config\Database::getInstance()->getConnection()->prepare($logSql);
|
|
$logStmt->execute([
|
|
'sid' => $id,
|
|
'ip' => $_SERVER['REMOTE_ADDR'] ?? null
|
|
]);
|
|
}
|
|
|
|
View::redirect('/admin/servers/edit/' . $id);
|
|
}
|
|
}
|