2199 lines
97 KiB
PHP
2199 lines
97 KiB
PHP
<?php
|
|
// src/DhcpBundle/Controller/DhcpController.php
|
|
|
|
namespace App\DhcpBundle\Controller;
|
|
|
|
use OpenApi\Annotations as OA;
|
|
use Psr\Log\LoggerInterface;
|
|
use App\DhcpBundle\Service\CurlKeaService;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
|
use Exception;
|
|
|
|
|
|
class DhcpController
|
|
{
|
|
private $logger;
|
|
|
|
private $curlKeaService;
|
|
private $backup_dir;
|
|
|
|
public function __construct(CurlKeaService $curlKeaService, LoggerInterface $logger, ParameterBagInterface $params)
|
|
{
|
|
$this->curlKeaService = $curlKeaService;
|
|
$this->logger = $logger;
|
|
$this->backup_dir = $params->get('backup_dir');
|
|
}
|
|
|
|
/**
|
|
* @Route("/ogdhcp/v1/status", name="getDhcpStatus", methods={"GET"})
|
|
* @OA\Get(
|
|
* path="/ogdhcp/v1/status",
|
|
* summary="Get ogDHCP status",
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Status retrieved successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="disk_usage", type="object",
|
|
* @OA\Property(property="total", type="string"),
|
|
* @OA\Property(property="used", type="string"),
|
|
* @OA\Property(property="available", type="string"),
|
|
* @OA\Property(property="percentage", type="string")
|
|
* ),
|
|
* @OA\Property(property="default_oglive", type="string"),
|
|
* @OA\Property(property="installed_oglives", type="array", @OA\Items(type="string")),
|
|
* @OA\Property(property="services_status", type="object",
|
|
* @OA\Property(property="dhcp_daemon", type="string"),
|
|
* @OA\Property(property="nginx", type="string"),
|
|
* @OA\Property(property="tftpboot", type="string")
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function getDhcpStatus(): Response
|
|
{
|
|
$operation = 'getDhcpStatus';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
// Obtener el uso de disco
|
|
$diskUsageResult = $this->getDiskUsage();
|
|
if (!$diskUsageResult) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'params' => [],
|
|
'desc' => 'Failed to retrieve disk usage'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
throw new \Exception('Failed to retrieve disk usage');
|
|
}
|
|
|
|
// Obtener el estado de los servicios de ogDHCP
|
|
$servicesStatusResult = $this->getServicesStatus();
|
|
if (!$servicesStatusResult) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'params' => [],
|
|
'desc' => 'Failed to retrieve services status'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
throw new \Exception('Failed to retrieve services status');
|
|
}
|
|
|
|
// Intentar obtener las subredes, pero si falla devolver un array vacío
|
|
$subnetsResult = [];
|
|
try {
|
|
$subnetsResult = $this->getSubnetsService();
|
|
} catch (\Exception $e) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'params' => [],
|
|
'desc' => 'Failed to retrieve subnets'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
$subnetsResult = [];
|
|
}
|
|
|
|
// Componer la respuesta
|
|
$response = [
|
|
'disk_usage' => $diskUsageResult,
|
|
'subnets' => $subnetsResult,
|
|
'services_status' => $servicesStatusResult
|
|
];
|
|
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'params' => [],
|
|
'desc' => 'DHCP status retrieved successfully'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['success' => "Información obtenida con éxito", 'message' => $response], Response::HTTP_OK);
|
|
|
|
} catch (\Exception $e) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'params' => [],
|
|
'desc' => $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
// Capturar la excepción y devolver el mensaje de error
|
|
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
private function getDiskUsage(): array
|
|
{
|
|
// Simular la salida del comando df para obtener el uso del disco
|
|
$output = shell_exec("df -h " . realpath($this->backup_dir) . " | tail -1 | awk '{print $2, $3, $4, $5}'");
|
|
if (!$output) {
|
|
$this->logger->error("Failed to execute disk usage command");
|
|
return [];
|
|
}
|
|
|
|
list($total, $used, $available, $percentage) = explode(' ', $output);
|
|
return [
|
|
'total' => trim($total),
|
|
'used' => trim($used),
|
|
'available' => trim($available),
|
|
'percentage' => trim($percentage),
|
|
];
|
|
}
|
|
|
|
|
|
private function getServicesStatus(): array
|
|
{
|
|
$services = [
|
|
'kea-dhcp4-server' => $this->getServiceStatus('kea-dhcp4-server.service'),
|
|
'kea-ctrl-agent' => $this->getServiceStatus('kea-ctrl-agent.service'),
|
|
'nginx' => $this->getServiceStatus('nginx.service')
|
|
];
|
|
|
|
return $services;
|
|
}
|
|
|
|
private function getServiceStatus(string $service): string
|
|
{
|
|
// Ejecutar el comando systemctl para verificar el estado del servicio
|
|
$output = shell_exec("systemctl is-active " . escapeshellarg($service));
|
|
|
|
// Si el comando retorna "active", el servicio está corriendo
|
|
if (trim($output) === 'active') {
|
|
return 'active';
|
|
} else {
|
|
return 'inactive';
|
|
}
|
|
}
|
|
|
|
private function getSubnetsService(): ?array
|
|
{
|
|
try {
|
|
// Ejecutar el comando para obtener la configuración
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
|
|
// Verificar si la respuesta es nula
|
|
if (!$response) {
|
|
throw new \Exception('Error: No se pudo acceder a la configuración de Kea. Respuesta nula.');
|
|
}
|
|
|
|
// Verificar el código de resultado
|
|
$result_code = $response[0]["result"];
|
|
if ($result_code != 0) {
|
|
throw new \Exception("Error en la configuración de Kea: " . $response[0]["text"]);
|
|
}
|
|
|
|
// Verificar si el campo 'subnet4' está presente en la respuesta
|
|
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
|
|
throw new \Exception("El campo 'subnet4' no está inicializado. Respuesta: " . json_encode($response[0]['arguments']));
|
|
}
|
|
|
|
// Subredes encontradas, devolver resultado
|
|
return $response[0]['arguments']['Dhcp4']['subnet4'];
|
|
|
|
} catch (\Exception $e) {
|
|
// Escalar la excepción para que sea gestionada por la función que llama
|
|
throw new \Exception("Error al obtener las subredes: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @OA\Schema(
|
|
* schema="Subnet",
|
|
* type="object",
|
|
* @OA\Property(property="id", type="integer", description="The ID of the subnet"),
|
|
* @OA\Property(property="subnet", type="string", description="The name of the subnet"),
|
|
* @OA\Property(property="next-server", type="string", description="The next server in the subnet"),
|
|
* @OA\Property(property="boot-file-name", type="string", description="The boot file name for the subnet"),
|
|
* @OA\Property(property="DNS", type="string", description="DNS subnet"),
|
|
* @OA\Property(property="subnetName", type="string", description="subnetName subnet"),
|
|
* @OA\Property(
|
|
* property="reservations",
|
|
* type="array",
|
|
* @OA\Items(type="object", description="The reservations in the subnet")
|
|
* )
|
|
* )
|
|
*/
|
|
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/ogdhcp/v1/subnets",
|
|
* summary="Obtiene todas las subredes DHCP",
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Devuelve todas las subredes",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Subredes obtenidas correctamente"),
|
|
* @OA\Property(property="message", type="array",
|
|
* @OA\Items(
|
|
* type="object",
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="subnet", type="string", example="192.168.1.0/24"),
|
|
* @OA\Property(property="next-server", type="string", example="192.168.1.1"),
|
|
* @OA\Property(property="DNS", type="string", example="192.168.1.1"),
|
|
* @OA\Property(property="boot-file-name", type="string", example="pxelinux.0"),
|
|
* @OA\Property(property="pools", type="array",
|
|
* @OA\Items(
|
|
* type="object",
|
|
* @OA\Property(property="pool", type="string", example="192.168.1.10-192.168.1.100")
|
|
* )
|
|
* ),
|
|
* @OA\Property(property="reservations", type="array",
|
|
* @OA\Items(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="ip-address", type="string", example="192.168.1.11"),
|
|
* @OA\Property(property="hw-address", type="string", example="00:0c:29:6b:5e:71"),
|
|
* @OA\Property(property="hostname", type="string", example="PC11")
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="No subnets found",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="El campo subnet4 no está inicializado")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="Error occurred in kea configuration",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No se pudo acceder al archivo de configuración de Kea")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error: La subred con el ID 'subnetId' ya existe.")
|
|
* )
|
|
* }
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="noResponse",
|
|
* summary="No response from kea configuration",
|
|
* value={"error": "No se pudo acceder al archivo de configuración de Kea"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="keaError",
|
|
* summary="Kea agent down",
|
|
* value={"error": "Error al obtener la configuración de Kea DHCP"}
|
|
* )
|
|
* ),
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets", methods={"GET"})
|
|
*/
|
|
|
|
public function getSubnets(): JsonResponse
|
|
{
|
|
$operation = 'getSubnets';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'params' => [],
|
|
'desc' => 'Iniciando la obtención de subredes.'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
|
|
if (!$response) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => 'No se pudo acceder al archivo de configuración de Kea.'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => 'No se pudo acceder al archivo de configuración de Kea'], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
$result_code = $response[0]["result"];
|
|
if ($result_code == 0) {
|
|
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => 'El campo "subnet4" no está inicializado.'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => 'El campo "subnet4" no está inicializado'], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$subnets = $response[0]['arguments']['Dhcp4']['subnet4'];
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'params' => ['subnets_count' => count($subnets)],
|
|
'desc' => 'Subredes obtenidas correctamente.'
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse([
|
|
'success' => 'Subredes obtenidas correctamente',
|
|
'message' => $subnets
|
|
], Response::HTTP_OK);
|
|
}
|
|
} else {
|
|
$errorText = $response[0]["text"] ?? 'Unknown error';
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => "Error al obtener la configuración de Kea DHCP: " . $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $errorText], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => "Excepción al obtener la configuración de Kea DHCP: " . $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/ogdhcp/v1/subnets",
|
|
* summary="Add a new DHCP subnet",
|
|
* @OA\RequestBody(
|
|
* description="JSON payload to create a new subnet",
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="subnetId", type="integer", example=2),
|
|
* @OA\Property(property="mask", type="string", example="255.255.255.0"),
|
|
* @OA\Property(property="address", type="string", example="192.168.1.0"),
|
|
* @OA\Property(property="nextServer", type="string", example="192.168.1.1"),
|
|
* @OA\Property(property="subnetName", type="string", example="Aula informatica"),
|
|
* @OA\Property(property="DNS", type="string", example="192.168.1.1"),
|
|
* @OA\Property(property="bootFileName", type="string", example="pxelinux.0"),
|
|
* @OA\Property(property="router", type="string", example="192.168.1.254")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Subnet added successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Subnet added successfully"),
|
|
* @OA\Property(property="message", ref="#/components/schemas/Subnet")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while adding the subnet",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="La subred con el nombre 'subnetName' ya existe.")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="La subred con el ID 'subnetId' ya existe.")
|
|
* )
|
|
* }
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="parameterMissing",
|
|
* summary="Missing required parameter",
|
|
* value={"error": "Falta un parámetro requerido: $paramFaltante"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="nameConflict",
|
|
* summary="Subnet name already exists",
|
|
* value={"error": "La subred con la ip 'subnetName' ya existe."}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="idConflict",
|
|
* summary="Subnet ID already exists",
|
|
* value={"error": "La subred con el ID 'subnetId' ya existe."}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="subnetCreatedNotFound",
|
|
* summary="Subnet created not found",
|
|
* value={"error": "No se pudo encontrar la subred creada"}
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="Server error",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP.")
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets", methods={"POST"})
|
|
*/
|
|
public function addDhcpSubnet(Request $request): JsonResponse
|
|
{
|
|
$operation = 'addDhcpSubnet';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$input = json_decode($request->getContent());
|
|
$subnetId = (int) htmlspecialchars($input->subnetId);
|
|
$mask = htmlspecialchars($input->mask);
|
|
$address = htmlspecialchars($input->address);
|
|
|
|
// Verificar si next-server, boot-file-name y router están presentes
|
|
$nextServer = isset($input->nextServer) ? htmlspecialchars($input->nextServer) : null;
|
|
$bootFileName = isset($input->bootFileName) ? htmlspecialchars($input->bootFileName) : null;
|
|
$router = isset($input->router) ? htmlspecialchars($input->router) : null;
|
|
$DNS = isset($input->DNS) ? htmlspecialchars($input->DNS) : null;
|
|
$subnetName = isset($input->subnetName) ? htmlspecialchars($input->subnetName) : null;
|
|
|
|
// Calcular el gatewayIP si no se proporciona el router
|
|
$gatewayIP = $router ?: substr($address, 0, strrpos($address, '.')) . '.1';
|
|
} catch (Exception $e) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => 'Error al procesar los datos de entrada para agregar una subred: ' . $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
if (strpos($e->getMessage(), 'Undefined property') !== false) {
|
|
preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches);
|
|
$paramFaltante = $matches[1] ?? 'desconocido';
|
|
|
|
return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$subnetCIDR = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask);
|
|
|
|
$newSubnet = [
|
|
"id" => $subnetId,
|
|
"subnet" => $subnetCIDR,
|
|
"reservations" => [],
|
|
"option-data" => [
|
|
[
|
|
"name" => "routers",
|
|
"code" => 3,
|
|
"data" => $gatewayIP
|
|
]
|
|
]
|
|
];
|
|
|
|
// Agregar "user-context" solo si $subnetName tiene valor
|
|
if (!empty($subnetName)) {
|
|
$newSubnet["user-context"] = [
|
|
"subnetName" => $subnetName
|
|
];
|
|
}
|
|
|
|
if (!empty($DNS)) {
|
|
$newSubnet["option-data"][] = [
|
|
"name" => "domain-name-servers",
|
|
"code" => 6,
|
|
"space" => "dhcp4",
|
|
"csv-format" => true,
|
|
"data" => $DNS
|
|
];
|
|
}
|
|
|
|
if ($nextServer) {
|
|
$newSubnet["next-server"] = $nextServer;
|
|
}
|
|
|
|
if ($bootFileName) {
|
|
$newSubnet["boot-file-name"] = $bootFileName;
|
|
}
|
|
|
|
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
|
|
$response[0]['arguments']['Dhcp4']['subnet4'] = [];
|
|
}
|
|
|
|
$subnets = $response[0]['arguments']['Dhcp4']['subnet4'];
|
|
|
|
$subnetNameExists = array_reduce($subnets, fn($exists, $subnetElement) => $exists || ($subnetElement['subnet'] === $subnetCIDR), false);
|
|
$subnetIdExists = array_reduce($subnets, fn($exists, $subnetElement) => $exists || ($subnetElement['id'] === $subnetId), false);
|
|
|
|
if ($subnetNameExists) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "La subred con la IP '$subnetCIDR' ya existe."
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "La subred con la ip '$subnetCIDR' ya existe."], Response::HTTP_BAD_REQUEST);
|
|
} elseif ($subnetIdExists) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "La subred con el ID '$subnetId' ya existe."
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "La subred con el ID '$subnetId' ya existe."], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$response[0]['arguments']['Dhcp4']['subnet4'][] = $newSubnet;
|
|
|
|
if (isset($response[0]['arguments']['hash'])) {
|
|
unset($response[0]['arguments']['hash']);
|
|
}
|
|
|
|
$array_encoded = json_encode($response[0]['arguments']);
|
|
$configurationParsed = str_replace('\\', '', $array_encoded);
|
|
$configuration = json_decode($configurationParsed);
|
|
|
|
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
|
|
|
|
if ($responseTest[0]["result"] == 0) {
|
|
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
|
|
if (!$responseSet || $responseSet[0]["result"] != 0) {
|
|
$errorText = $responseSet[0]["text"] ?? 'Unknown error';
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "Error al guardar la configuración en Kea DHCP: $errorText"
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: $errorText"], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
if (!$responseWrite || $responseWrite[0]["result"] != 0) {
|
|
$errorText = $responseWrite[0]["text"] ?? 'Unknown error';
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "Error al escribir la configuración en Kea DHCP: $errorText"
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "Error al escribir la configuración en Kea DHCP: $errorText"], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$configGetResponse = $this->curlKeaService->executeCurlCommand('config-get');
|
|
// Buscar la subred creada
|
|
$createdSubnet = null;
|
|
foreach ($configGetResponse[0]['arguments']['Dhcp4']['subnet4'] as $subnet) {
|
|
if ($subnet['id'] == $subnetId) {
|
|
$createdSubnet = $subnet;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$createdSubnet) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "No se pudo encontrar la subred creada."
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "No se pudo encontrar la subred creada"], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => 'Subred agregada correctamente.',
|
|
'params' => ['subnet' => $createdSubnet]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['success' => "Subred agregada correctamente", 'message' => $createdSubnet], Response::HTTP_OK);
|
|
}
|
|
}
|
|
} else {
|
|
$errorText = $responseTest[0]["text"] ?? 'Unknown error';
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "Error en la configuración de Kea: $errorText"
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "Error en la configuración de Kea: $errorText"], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => "Excepción al obtener la configuración de Kea DHCP: " . $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @OA\Delete(
|
|
* path="/ogdhcp/v1/subnets/{subnetId}",
|
|
* summary="Delete a DHCP subnet",
|
|
* @OA\Parameter(
|
|
* name="subnetId",
|
|
* in="path",
|
|
* description="ID of the subnet to delete",
|
|
* required=true,
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Subnet deleted successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Subred eliminada correctamente")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while deleting the subnet",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No hay subredes definidas")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error configuracion de kea invalido")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al escribir en la configuración en Kea DHCP")
|
|
* )
|
|
* }
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="noSubnets",
|
|
* summary="Subnet name already exists",
|
|
* value={"error": "No hay subredes definidas"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="invalidKea",
|
|
* summary="Error in config-test in kea",
|
|
* value={"error": "Error configuracion de kea invalido"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="saveKea",
|
|
* summary="Error in config-set in kea",
|
|
* value={"error": "Error al guardar la configuración en Kea DHCP"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="writeKea",
|
|
* summary="Error in config-write in kea",
|
|
* value={"error": "Error al escribir en la configuración en Kea DHCP"}
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="Subnet not found",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="La subred con el id '2' no existe")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="Error saving configuration in Kea DHCP",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="Error al obtener la configuración de Kea DHCP")
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets/{subnetId}", methods={"DELETE"})
|
|
*/
|
|
|
|
|
|
public function deleteDhcpSubnet(Request $request): JsonResponse
|
|
{
|
|
$operation = 'deleteDhcpSubnet';
|
|
$component = 'ogdhcp';
|
|
$subnetId = (int) $request->get('subnetId');
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
|
|
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
|
|
$responseError = "No hay subredes definidas";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
$subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));
|
|
|
|
if ($subnetIndex === false) {
|
|
$responseError = "La subred con el id '$subnetId' no existe";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_NOT_FOUND,
|
|
'desc' => $responseError,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_NOT_FOUND);
|
|
} else {
|
|
unset($response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex]);
|
|
|
|
if (isset($response[0]['arguments']['hash'])) {
|
|
unset($response[0]['arguments']['hash']);
|
|
}
|
|
|
|
$response[0]['arguments']['Dhcp4']['subnet4'] = array_values($response[0]['arguments']['Dhcp4']['subnet4']);
|
|
$array_encoded = json_encode($response[0]['arguments']);
|
|
$configurationParsed = str_replace('\\', '', $array_encoded);
|
|
$configuration = json_decode($configurationParsed);
|
|
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
|
|
|
|
if ($responseTest[0]["result"] == 0) {
|
|
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
|
|
|
|
if ($responseSet == false || $responseSet[0]["result"] != 0) {
|
|
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
|
|
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
|
|
$responseError = "Error al escribir en la configuración en Kea DHCP: " . $responseWrite[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseSuccess = "Subred eliminada correctamente";
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => $responseSuccess,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['success' => $responseSuccess], Response::HTTP_OK);
|
|
}
|
|
}
|
|
} else {
|
|
$responseError = "Error configuración de Kea inválido: " . $responseTest[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @Route("/ogdhcp/v1/subnets/{subnetId}", methods={"PUT"})
|
|
* @OA\Put(
|
|
* path="/ogdhcp/v1/subnets/{subnetId}",
|
|
* summary="Modify a DHCP subnet",
|
|
* @OA\Parameter(
|
|
* name="subnetId",
|
|
* in="path",
|
|
* description="ID of the subnet to modify",
|
|
* required=true,
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* description="Data to modify the subnet",
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="mask", type="string"),
|
|
* @OA\Property(property="address", type="string"),
|
|
* @OA\Property(property="DNS", type="string"),
|
|
* @OA\Property(property="subnetName", type="string"),
|
|
* @OA\Property(property="router", type="string", example="192.168.1.254"),
|
|
* @OA\Property(property="nextServer", type="string"),
|
|
* @OA\Property(property="bootFileName", type="string")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Subnet modified successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while modifying the subnet",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(@OA\Property(property="error", type="string", example="Falta un parámetro requerido: $paramFaltante")),
|
|
* @OA\Schema(@OA\Property(property="error", type="string", example="No hay subredes definidas")),
|
|
* @OA\Schema(@OA\Property(property="error", type="string", example="Error configuración de Kea inválido")),
|
|
* @OA\Schema(@OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")),
|
|
* @OA\Schema(@OA\Property(property="error", type="string", example="Error al escribir en la configuración en Kea DHCP"))
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="Subnet not found",
|
|
* @OA\JsonContent(type="object", @OA\Property(property="error", type="string", example="La subred con el id '2' no existe"))
|
|
* ),
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="Error saving configuration in Kea DHCP",
|
|
* @OA\JsonContent(type="object", @OA\Property(property="error", type="string", example="Error al obtener la configuración de Kea DHCP"))
|
|
* )
|
|
* )
|
|
*/
|
|
|
|
public function modifyDhcpSubnet(Request $request): JsonResponse
|
|
{
|
|
$subnetId = (int) $request->get('subnetId');
|
|
$operation = 'modifyDhcpSubnet';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$input = json_decode($request->getContent());
|
|
$mask = htmlspecialchars($input->mask);
|
|
$address = htmlspecialchars($input->address);
|
|
|
|
// Verificar si next-server, boot-file-name y router están presentes
|
|
$nextServer = isset($input->nextServer) ? htmlspecialchars($input->nextServer) : null;
|
|
$bootFileName = isset($input->bootFileName) ? htmlspecialchars($input->bootFileName) : null;
|
|
$router = isset($input->router) ? htmlspecialchars($input->router) : null;
|
|
$DNS = isset($input->DNS) ? htmlspecialchars($input->DNS) : null;
|
|
$subnetName = isset($input->subnetName) ? htmlspecialchars($input->subnetName) : null;
|
|
|
|
// Calcular el gateway añadiendo .1 al final de la subred si no se proporciona el router
|
|
$gateway = $router ?: preg_replace('/\d+$/', '1', $address);
|
|
} catch (Exception $e) {
|
|
if (strpos($e->getMessage(), 'Undefined property') !== false) {
|
|
preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches);
|
|
$paramFaltante = $matches[1] ?? 'desconocido';
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => "Falta un parámetro requerido: $paramFaltante"
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$subnetCIDR = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask);
|
|
|
|
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
|
|
$errorText = "No hay subredes definidas";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
$subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));
|
|
|
|
if ($subnetIndex === false) {
|
|
$errorText = "La subred con el id '$subnetId' no existe";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_NOT_FOUND,
|
|
'desc' => $errorText,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_NOT_FOUND);
|
|
} else {
|
|
// Obtener la subred actual para mantener las reservas existentes
|
|
$existingSubnet = $response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex];
|
|
|
|
// Modificar la subred existente
|
|
$newSubnet = [
|
|
"id" => $subnetId,
|
|
"subnet" => $subnetCIDR,
|
|
"reservations" => $existingSubnet['reservations'], // Mantener las reservas existentes
|
|
"option-data" => [
|
|
[
|
|
"name" => "routers",
|
|
"code" => 3,
|
|
"data" => $gateway
|
|
]
|
|
]
|
|
];
|
|
|
|
// Agregar "user-context" solo si $subnetName tiene valor
|
|
if (!empty($subnetName)) {
|
|
$newSubnet["user-context"] = [
|
|
"subnetName" => $subnetName
|
|
];
|
|
}
|
|
|
|
// Agregar DNS si está presente
|
|
if (!empty($DNS)) {
|
|
$newSubnet["option-data"][] = [
|
|
"name" => "domain-name-servers",
|
|
"code" => 23,
|
|
"space" => "dhcp4",
|
|
"csv-format" => true,
|
|
"data" => $DNS
|
|
];
|
|
}
|
|
|
|
// Añadir next-server si está presente, o eliminarlo de las reservas si no está
|
|
if ($nextServer) {
|
|
$newSubnet["next-server"] = $nextServer;
|
|
} else {
|
|
foreach ($newSubnet['reservations'] as &$reservation) {
|
|
unset($reservation['next-server']);
|
|
}
|
|
}
|
|
|
|
// Añadir boot-file-name si está presente, o eliminarlo de las reservas si no está
|
|
if ($bootFileName) {
|
|
$newSubnet["boot-file-name"] = $bootFileName;
|
|
} else {
|
|
foreach ($newSubnet['reservations'] as &$reservation) {
|
|
unset($reservation['boot-file-name']);
|
|
}
|
|
}
|
|
|
|
// Actualizar las reservas con los nuevos valores de next-server y boot-file-name
|
|
foreach ($newSubnet['reservations'] as &$reservation) {
|
|
if ($nextServer) {
|
|
$reservation['next-server'] = $nextServer;
|
|
}
|
|
if ($bootFileName) {
|
|
$reservation['boot-file-name'] = $bootFileName;
|
|
}
|
|
}
|
|
|
|
// Reemplazar la subred en la configuración
|
|
$response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex] = $newSubnet;
|
|
|
|
// Eliminar el campo 'hash' si existe
|
|
if (isset($response[0]['arguments']['hash'])) {
|
|
unset($response[0]['arguments']['hash']);
|
|
}
|
|
|
|
$array_encoded = json_encode($response[0]['arguments']);
|
|
$configurationParsed = str_replace('\\', '', $array_encoded);
|
|
$configuration = json_decode($configurationParsed);
|
|
|
|
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
|
|
|
|
if ($responseTest[0]["result"] == 0) {
|
|
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
|
|
if ($responseSet == false || $responseSet[0]["result"] != 0) {
|
|
$errorText = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
|
|
return new JsonResponse(['error' => "Error al escribir en la configuración en Kea DHCP: " . $responseWrite[0]["text"]], 400);
|
|
} else {
|
|
// Volvemos a consultar la configuración para devolver la subred modificada
|
|
$updatedResponse = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$updatedSubnet = array_filter($updatedResponse[0]['arguments']['Dhcp4']['subnet4'], function ($subnet) use ($subnetId) {
|
|
return $subnet['id'] == $subnetId;
|
|
});
|
|
|
|
$responseSuccess = "Subred modificada correctamente";
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => $responseSuccess,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['success' => $responseSuccess], Response::HTTP_OK);
|
|
}
|
|
}
|
|
} else {
|
|
$errorText = "Error configuración de Kea inválida: " . $responseTest[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
|
|
* summary="Get all hosts in a subnet",
|
|
* @OA\Parameter(
|
|
* name="subnetId",
|
|
* in="path",
|
|
* description="The ID of the subnet",
|
|
* required=true,
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="List of hosts in the subnet",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Hosts obtenidos correctamente"),
|
|
* @OA\Property(property="message", type="array",
|
|
* @OA\Items(ref="#/components/schemas/Host")
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="Error: La subred con el id 'subnetId' no existe.")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="Server error when loading Kea DHCP configuration",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="Error al obtener la configuración de Kea DHCP")
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"GET"})
|
|
*/
|
|
public function getHosts($subnetId): JsonResponse
|
|
{
|
|
$operation = 'getHosts';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
|
|
if (!$response) {
|
|
$responseError = "No hay subredes definidas";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
$result_code = $response[0]["result"];
|
|
if ($result_code == 0) {
|
|
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
|
|
$errorText = "El campo 'subnet4' no está inicializado.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
throw new \Exception($errorText);
|
|
}
|
|
|
|
$subnets = $response[0]['arguments']['Dhcp4']['subnet4'];
|
|
foreach ($subnets as $subnet) {
|
|
if ($subnet['id'] == $subnetId) {
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => 'Hosts obtenidos correctamente.',
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse([
|
|
'success' => 'Hosts obtenidos correctamente',
|
|
'message' => $subnet['reservations']
|
|
], Response::HTTP_OK);
|
|
}
|
|
}
|
|
|
|
$errorText = "La subred con el id '$subnetId' no existe.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseError = "No hay subredes definidas";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $responseError
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
} catch (\Exception $e) {
|
|
$errorText = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
|
|
* summary="Add a DHCP host to a subnet",
|
|
* @OA\Parameter(
|
|
* name="subnetId",
|
|
* in="path",
|
|
* description="ID of the subnet to add the host to",
|
|
* required=true,
|
|
* @OA\Schema(
|
|
* type="integer"
|
|
* )
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* description="Data for the new host",
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="host", type="string", example="pc11"),
|
|
* @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:00:4f"),
|
|
* @OA\Property(property="address", type="string", example="172.30.4.11")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Host added successfully and returns the new host details",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Host added successfully"),
|
|
* @OA\Property(property="message", ref="#/components/schemas/Host")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while adding the host",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No hay subredes definidas")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="El host con el hostname 'host' ya existe en las reservaciones.")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error configuracion de kea invalido")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al escribir en la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No se pudo encontrar el host recién creado")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Falta un parámetro requerido: $paramFaltante")
|
|
* )
|
|
* }
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="parameterMissing",
|
|
* summary="Missing required parameter",
|
|
* value={"error": "Falta un parámetro requerido: $paramFaltante"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="noSubnet",
|
|
* summary="No subnets initialized",
|
|
* value={"error": "No se encontró la subnet con id '$subnetId'"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="hostExists",
|
|
* summary="Host already exists",
|
|
* value={"error": "El host con el hostname '$host' ya existe en las reservaciones."}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="invalidKea",
|
|
* summary="Error in config-test in kea",
|
|
* value={"error": "Error configuracion de kea invalido"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="saveKea",
|
|
* summary="Error in config-set in kea",
|
|
* value={"error": "Error al guardar la configuración en Kea DHCP"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="writeKea",
|
|
* summary="Error in config-write in kea",
|
|
* value={"error": "Error al escribir en la configuración en Kea DHCP"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="notFound",
|
|
* summary="Host created not found",
|
|
* value={"error": "No se pudo encontrar el host recién creado"}
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"POST"})
|
|
*/
|
|
public function addDhcpHost(Request $request, $subnetId): JsonResponse
|
|
{
|
|
$operation = 'addDhcpHost';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$input = json_decode($request->getContent());
|
|
$host = htmlspecialchars($input->host);
|
|
$macAddress = htmlspecialchars($input->macAddress);
|
|
$address = htmlspecialchars($input->address);
|
|
} catch (Exception $e) {
|
|
$errorText = $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
if (strpos($errorText, 'Undefined property') !== false) {
|
|
preg_match('/Undefined property: stdClass::\$(\w+)/', $errorText, $matches);
|
|
$paramFaltante = $matches[1] ?? 'desconocido';
|
|
return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$newHost = [
|
|
"hostname" => $host,
|
|
"hw-address" => $macAddress,
|
|
"ip-address" => $address
|
|
];
|
|
|
|
$subnetFound = false;
|
|
|
|
foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
|
|
if ($subnet['id'] == $subnetId) {
|
|
$subnetFound = true;
|
|
|
|
if (isset($subnet['boot-file-name'])) {
|
|
$newHost['boot-file-name'] = $subnet['boot-file-name'];
|
|
}
|
|
if (isset($subnet['next-server'])) {
|
|
$newHost['next-server'] = $subnet['next-server'];
|
|
}
|
|
|
|
if (!isset($subnet['reservations'])) {
|
|
$subnet['reservations'] = [];
|
|
}
|
|
|
|
$exists = array_reduce($subnet['reservations'], function ($exists, $reservation) use ($host) {
|
|
return $exists || ($reservation['hostname'] === $host);
|
|
});
|
|
|
|
if ($exists) {
|
|
$errorText = "El host con el hostname '$host' ya existe en las reservaciones.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['host' => $host, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$subnet['reservations'][] = $newHost;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$subnetFound) {
|
|
$errorText = "No se encontró la subnet con id '$subnetId'.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
if (isset($response[0]['arguments']['hash'])) {
|
|
unset($response[0]['arguments']['hash']);
|
|
}
|
|
|
|
$array_encoded = json_encode($response[0]['arguments']);
|
|
$configurationParsed = str_replace('\\', '', $array_encoded);
|
|
$configuration = json_decode($configurationParsed);
|
|
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
|
|
|
|
if ($responseTest[0]["result"] == 0) {
|
|
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
|
|
if ($responseSet == false || $responseSet[0]["result"] != 0) {
|
|
$errorText = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
|
|
$errorText = "Error al escribir en la configuración en Kea DHCP: " . $responseWrite[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$updatedResponse = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$createdHost = null;
|
|
|
|
foreach ($updatedResponse[0]['arguments']['Dhcp4']['subnet4'] as $subnet) {
|
|
if ($subnet['id'] == $subnetId) {
|
|
foreach ($subnet['reservations'] as $reservation) {
|
|
if ($reservation['hw-address'] === $macAddress) {
|
|
$createdHost = $reservation;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($createdHost) {
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => 'Host agregado correctamente.',
|
|
'params' => ['host' => $host, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['success' => "Host agregado correctamente", 'message' => $createdHost], Response::HTTP_OK);
|
|
} else {
|
|
$errorText = "No se pudo encontrar el host recién creado.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['host' => $host, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$errorText = "Error configuración de Kea inválida: " . $responseTest[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
} catch (Exception $e) {
|
|
$errorText = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @OA\Delete(
|
|
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
|
|
* summary="Delete a DHCP host from a specific subnet",
|
|
* @OA\Parameter(
|
|
* name="subnetId",
|
|
* in="path",
|
|
* description="The ID of the subnet",
|
|
* required=true,
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* description="Data for the host to delete",
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:00:4f")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Host deleted successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="Host or subnet not found",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while adding the host",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No se encontró la subnet con id '$subnetId'")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="El host con la MAC '$mac' no existe en las reservaciones")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error configuracion de kea invalido")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al escribir en la configuración en Kea DHCP")
|
|
* )
|
|
* }
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="noSubnet",
|
|
* summary="No subnets initialized",
|
|
* value={"error": "No se encontró la subnet con id '$subnetId'"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="hostNotFound",
|
|
* summary="Host not found",
|
|
* value={"error": "El host con la MAC '$mac' no existe en las reservaciones"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="invalidKea",
|
|
* summary="Error in config-test in kea",
|
|
* value={"error": "Error configuracion de kea invalido"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="saveKea",
|
|
* summary="Error in config-set in kea",
|
|
* value={"error": "Error al guardar la configuración en Kea DHCP"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="writeKea",
|
|
* summary="Error in config-write in kea",
|
|
* value={"error": "Error al escribir en la configuración en Kea DHCP"}
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"DELETE"})
|
|
*/
|
|
public function deleteDhcpHost(Request $request, $subnetId): JsonResponse
|
|
{
|
|
$operation = 'deleteDhcpHost';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$input = json_decode($request->getContent());
|
|
$macAddress = htmlspecialchars($input->macAddress);
|
|
} catch (Exception $e) {
|
|
$errorText = $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$subnetFound = false;
|
|
$hostFound = false;
|
|
|
|
foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
|
|
if ($subnet['id'] == $subnetId) {
|
|
$subnetFound = true;
|
|
if (!isset($subnet['reservations'])) {
|
|
$subnet['reservations'] = [];
|
|
}
|
|
|
|
foreach ($subnet['reservations'] as $key => $reservation) {
|
|
if ($reservation['hw-address'] === $macAddress) {
|
|
unset($subnet['reservations'][$key]);
|
|
$subnet['reservations'] = array_values($subnet['reservations']);
|
|
$hostFound = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$subnetFound) {
|
|
$errorText = "No se encontró la subnet con id '$subnetId'";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
if (!$hostFound) {
|
|
$errorText = "El host con la MAC '$macAddress' no existe en las reservaciones";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['mac_address' => $macAddress, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
if (isset($response[0]['arguments']['hash'])) {
|
|
unset($response[0]['arguments']['hash']);
|
|
}
|
|
|
|
$array_encoded = json_encode($response[0]['arguments']);
|
|
$configurationParsed = str_replace('\\', '', $array_encoded);
|
|
$configuration = json_decode($configurationParsed);
|
|
|
|
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
|
|
if ($responseTest[0]["result"] == 0) {
|
|
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
|
|
if ($responseSet == false || $responseSet[0]["result"] != 0) {
|
|
$errorText = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
|
|
$errorText = "Error al escribir en la configuración en Kea DHCP: " . $responseWrite[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => 'Host eliminado correctamente.',
|
|
'params' => ['mac_address' => $macAddress, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['success' => "Host eliminado correctamente"], Response::HTTP_OK);
|
|
}
|
|
}
|
|
} else {
|
|
$errorText = "Error configuración de Kea inválida: " . $responseTest[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
} catch (Exception $e) {
|
|
$errorText = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @OA\Put(
|
|
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
|
|
* summary="Update a DHCP host",
|
|
* @OA\Parameter(
|
|
* name="subnetId",
|
|
* in="path",
|
|
* description="The ID of the subnet",
|
|
* required=true,
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* description="Data for the host to update",
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="oldMacAddress", type="string", example="56:6f:c7:4f:00:4f", description="Old MAC address of the host to update"),
|
|
* @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:01:01", description="New MAC address"),
|
|
* @OA\Property(property="address", type="string", example="192.168.1.11", description="New IP address"),
|
|
* @OA\Property(property="hostname", type="string", example="PC11", description="New or existing hostname")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Host updated successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Host updated successfully"),
|
|
* @OA\Property(property="message", ref="#/components/schemas/Host")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while updating the host",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No se encontró la subnet con id '$subnetId'")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="El host con la MAC '$oldMacAddress' no existe en las reservaciones")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error configuración de kea inválida")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al escribir la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Falta un parámetro requerido: $paramFaltante")
|
|
* )
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="Server error",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="Internal server error")
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"PUT"})
|
|
*/
|
|
public function updateDhcpHost(Request $request, $subnetId): JsonResponse
|
|
{
|
|
$operation = 'updateDhcpHost';
|
|
$component = 'ogdhcp';
|
|
|
|
try {
|
|
$input = json_decode($request->getContent());
|
|
$host = htmlspecialchars($input->hostname);
|
|
$oldMacAddress = htmlspecialchars($input->oldMacAddress);
|
|
$macAddress = htmlspecialchars($input->macAddress);
|
|
$address = htmlspecialchars($input->address);
|
|
} catch (Exception $e) {
|
|
$errorText = $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
if (strpos($e->getMessage(), 'Undefined property') !== false) {
|
|
preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches);
|
|
$paramFaltante = $matches[1] ?? 'desconocido';
|
|
return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
try {
|
|
$response = $this->curlKeaService->executeCurlCommand('config-get');
|
|
$subnetFound = false;
|
|
$hostFound = false;
|
|
$updatedHost = null;
|
|
|
|
foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
|
|
if ($subnet['id'] == $subnetId) {
|
|
$subnetFound = true;
|
|
if (!isset($subnet['reservations'])) {
|
|
$subnet['reservations'] = [];
|
|
}
|
|
|
|
foreach ($subnet['reservations'] as &$reservation) {
|
|
if ($reservation['hw-address'] == $oldMacAddress) {
|
|
$hostFound = true;
|
|
|
|
$bootFileName = $reservation['boot-file-name'] ?? $subnet['boot-file-name'] ?? null;
|
|
$nextServer = $reservation['next-server'] ?? $subnet['next-server'] ?? null;
|
|
|
|
$reservation['hw-address'] = $macAddress;
|
|
$reservation['ip-address'] = $address;
|
|
$reservation['hostname'] = $host;
|
|
|
|
if ($bootFileName !== null) {
|
|
$reservation['boot-file-name'] = $bootFileName;
|
|
}
|
|
if ($nextServer !== null) {
|
|
$reservation['next-server'] = $nextServer;
|
|
}
|
|
|
|
$updatedHost = $reservation;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($subnetFound && $hostFound) {
|
|
if (isset($response[0]['arguments']['hash'])) {
|
|
unset($response[0]['arguments']['hash']);
|
|
}
|
|
|
|
$array_encoded = json_encode($response[0]['arguments']);
|
|
$configurationParsed = str_replace('\\', '', $array_encoded);
|
|
$configuration = json_decode($configurationParsed);
|
|
|
|
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
|
|
if ($responseTest[0]["result"] == 0) {
|
|
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
|
|
if ($responseSet == false || $responseSet[0]["result"] != 0) {
|
|
$errorText = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
|
|
$errorText = "Error al escribir la configuración en Kea DHCP: " . $responseWrite[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} else {
|
|
$this->logger->info(json_encode([
|
|
'severity' => 'INFO',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_OK,
|
|
'desc' => 'Host actualizado correctamente.',
|
|
'params' => ['host' => $host, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['success' => "Host actualizado correctamente", 'message' => $updatedHost], Response::HTTP_OK);
|
|
}
|
|
}
|
|
} else {
|
|
$errorText = "Error en la configuración de Kea: " . $responseTest[0]["text"];
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
} elseif (!$subnetFound) {
|
|
$errorText = "Error: La subred con el id '$subnetId' no existe.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
} elseif (!$hostFound) {
|
|
$errorText = "Error: El host con la MAC '$oldMacAddress' no existe en las reservaciones.";
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_BAD_REQUEST,
|
|
'desc' => $errorText,
|
|
'params' => ['old_mac_address' => $oldMacAddress, 'subnet_id' => $subnetId]
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST);
|
|
}
|
|
} catch (Exception $e) {
|
|
$errorText = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
|
|
$this->logger->error(json_encode([
|
|
'severity' => 'ERROR',
|
|
'operation' => $operation,
|
|
'component' => $component,
|
|
'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
|
'desc' => $errorText
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
return new JsonResponse(['error' => $errorText], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
return new JsonResponse(['error' => 'Unexpected error occurred'], Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/ogdhcp/v1/backup",
|
|
* summary="Get the latest backup configuration of Kea DHCP (only subnet4)",
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Latest backup configuration of Kea DHCP",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Backup obtenido con exito"),
|
|
* @OA\Property(property="message", type="array",
|
|
* @OA\Items(ref="#/components/schemas/Host")
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while retrieving the backup",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="error", type="string", example="No se encontraron archivos de backup")
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/backup", methods={"GET"})
|
|
*/
|
|
public function getLatestBackupConfiguration(): JsonResponse
|
|
{
|
|
#$backup_dir = '/opt/ogdhcp/etc/kea/backup';
|
|
$backup_dir = $this->backup_dir;
|
|
try {
|
|
// Obtener los archivos de backup
|
|
$backup_files = glob($backup_dir . '/*.conf');
|
|
if (empty($backup_files)) {
|
|
$responseError = "No se encontraron archivos de backup";
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
}
|
|
|
|
// Ordenar por fecha de modificación y obtener el más reciente
|
|
usort($backup_files, function ($a, $b) {
|
|
return filemtime($b) - filemtime($a);
|
|
});
|
|
|
|
// Leer el archivo más reciente
|
|
$backup_file = reset($backup_files);
|
|
$config = file_get_contents($backup_file);
|
|
$configuration = json_decode($config, true);
|
|
|
|
if (!isset($configuration['Dhcp4']['subnet4'])) {
|
|
$responseError = "No se encontró el parámetro 'subnet4' en el backup";
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
}
|
|
|
|
$responseSuccess = "Backup obtenido con exito";
|
|
return new JsonResponse(['success' => $responseSuccess, 'message' => ['subnet4' => $configuration['Dhcp4']['subnet4']]], 200);
|
|
} catch (Exception $e) {
|
|
$responseError = "Error al obtener la configuración de backup: " . $e->getMessage();
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/ogdhcp/v1/backup",
|
|
* summary="Restore the latest DHCP configuration from backup",
|
|
* description="This endpoint restores the last saved DHCP configuration from a backup file and applies it to the Kea DHCP server, returning all currently loaded subnets.",
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Configuration restored successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="success", type="string", example="Configuración cargada correctamente"),
|
|
* @OA\Property(property="message", type="array",
|
|
* @OA\Items(ref="#/components/schemas/Host")
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=400,
|
|
* description="Error occurred while restoring the configuration",
|
|
* @OA\JsonContent(
|
|
* oneOf={
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="No se encontraron archivos de backup")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error configuracion de kea invalido")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al guardar la configuración en Kea DHCP")
|
|
* ),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="error", type="string", example="Error al escribir en la configuración en Kea DHCP")
|
|
* )
|
|
* }
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="noBackup",
|
|
* summary="No backup files found",
|
|
* value={"error": "No se encontraron archivos de backup"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="invalidKea",
|
|
* summary="Error in config-test in kea",
|
|
* value={"error": "Error configuracion de kea invalido"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="saveKea",
|
|
* summary="Error in config-set in kea",
|
|
* value={"error": "Error al guardar la configuración en Kea DHCP"}
|
|
* ),
|
|
* @OA\Examples(
|
|
* example="writeKea",
|
|
* summary="Error in config-write in kea",
|
|
* value={"error": "Error al escribir en la configuración en Kea DHCP"}
|
|
* )
|
|
* )
|
|
* )
|
|
* @Route("/ogdhcp/v1/backup", methods={"POST"})
|
|
*/
|
|
public function restoreDhcpConfiguration(): JsonResponse
|
|
{
|
|
#$backup_dir = '/opt/ogdhcp/etc/kea/backup';
|
|
$backup_dir = $this->backup_dir;
|
|
try {
|
|
$backup_files = glob($backup_dir . '/*.conf');
|
|
if (empty($backup_files)) {
|
|
$response = "No se encontraron archivos de backup";
|
|
return new JsonResponse(['error' => $response], 400);
|
|
} else {
|
|
usort($backup_files, function ($a, $b) {
|
|
return filemtime($b) - filemtime($a);
|
|
});
|
|
$backup_file = reset($backup_files);
|
|
$config = file_get_contents($backup_file);
|
|
// Eliminar el campo 'hash' si existe
|
|
$configuration = json_decode($config);
|
|
if (isset($configuration->hash)) {
|
|
unset($configuration->hash);
|
|
}
|
|
|
|
$test_command = 'config-test';
|
|
$test_output = $this->curlKeaService->executeCurlCommand($test_command, $configuration);
|
|
if ($test_output == false || $test_output[0]["result"] != 0) {
|
|
$responseError = "Error al comprobar la configuración de Kea: " . $test_output[0]["text"];
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
} else {
|
|
$set_command = 'config-set';
|
|
$set_output = $this->curlKeaService->executeCurlCommand($set_command, $configuration, false);
|
|
if ($set_output == false || $set_output[0]["result"] != 0) {
|
|
$responseError = "Error al guardar la última configuración de Kea: " . $set_output[0]["text"];
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
} else {
|
|
unlink($backup_file);
|
|
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
|
|
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
|
|
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
} else {
|
|
// Consultar las subredes cargadas
|
|
$config_get = $this->curlKeaService->executeCurlCommand('config-get');
|
|
if ($config_get == false || $config_get[0]["result"] != 0) {
|
|
return new JsonResponse(['error' => 'Error al obtener la configuración de Kea DHCP'], 500);
|
|
}
|
|
|
|
$subnets = $config_get[0]['arguments']['Dhcp4']['subnet4'] ?? [];
|
|
return new JsonResponse(['success' => "Configuración cargada correctamente", 'subnets' => $subnets], 200);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$responseError = "Error al restaurar la configuración: " . $e->getMessage();
|
|
return new JsonResponse(['error' => $responseError], 400);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|