refs #812 adds some unset hash, fix a bug in restore backup, adds in the 200 response the new subnets in the backup restore endpoint. Adds a new schema in nelmio yaml configuration and changes the project name
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details

nginx_conf
Luis Gerardo Romero Garcia 2024-10-08 16:55:13 +02:00
parent d68208357c
commit db9ce9c90e
3 changed files with 126 additions and 79 deletions

View File

@ -1,9 +1,32 @@
nelmio_api_doc:
documentation:
info:
title: My App
description: This is an awesome app!
title: OgDHCP API
description: OgDHCP API documentation
version: 1.0.0
components:
schemas:
Subnet:
type: object
properties:
id:
type: integer
description: The ID of the subnet
subnet:
type: string
description: The name of the subnet
nextServer:
type: string
description: The next server in the subnet
bootFileName:
type: string
description: The boot file name for the subnet
reservations:
type: array
items:
type: object
description: The reservations in the subnet
areas: # to filter documented areas
path_patterns:
- ^/ogdhcp/ # Accepts routes under /api except /api/doc

View File

@ -16,25 +16,7 @@ use Exception;
class DhcpController
{
private $logger;
/**
* @OA\Info(title="Ogdhcp API", version="1.0")
*/
/**
* @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="reservations",
* type="array",
* @OA\Items(type="object", description="The reservations in the subnet")
* )
* )
*/
private $curlKeaService;
public function __construct(CurlKeaService $curlKeaService, LoggerInterface $logger)
@ -42,6 +24,8 @@ class DhcpController
$this->curlKeaService = $curlKeaService;
$this->logger = $logger;
}
/**
* @Route("/ogdhcp/v1/status", name="getDhcpStatus", methods={"GET"})
* @OA\Get(
@ -337,22 +321,27 @@ public function getSubnets(): JsonResponse
* @OA\JsonContent(
* oneOf={
* @OA\Schema(
* @OA\Property(property="error", type="string", example="Error: La subred con el nombre 'subnetName' ya existe.")
* @OA\Property(property="error", type="string", example="La subred con el nombre 'subnetName' ya existe.")
* ),
* @OA\Schema(
* @OA\Property(property="error", type="string", example="Error: La subred con el ID 'subnetId' ya existe.")
* @OA\Property(property="error", type="string", example="La subred con el ID 'subnetId' ya existe.")
* )
* }
* ),
* @OA\Examples(
* example="nameConflict",
* summary="Subnet name already exists",
* value={"error": "Error: La subred con el nombre 'subnetName' ya existe."}
* value={"error": "La subred con la ip 'subnetName' ya existe."}
* ),
* @OA\Examples(
* example="idConflict",
* summary="Subnet ID already exists",
* value={"error": "Error: La subred con el ID 'subnetId' ya existe."}
* 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(
@ -408,9 +397,9 @@ public function addDhcpSubnet(Request $request): JsonResponse
}, false);
if ($subnetNameExists) {
return new JsonResponse(['error' => "Error: La subred con el nombre '$subnetName' ya existe."], 400);
return new JsonResponse(['error' => "La subred con la ip '$subnetName' ya existe."], 400);
} elseif ($subnetIdExists) {
return new JsonResponse(['error' => "Error: La subred con el ID '$subnetId' ya existe."], 400);
return new JsonResponse(['error' => "La subred con el ID '$subnetId' ya existe."], 400);
} else {
$response[0]['arguments']['Dhcp4']['subnet4'][] = $newSubnet;
@ -446,7 +435,7 @@ public function addDhcpSubnet(Request $request): JsonResponse
}
if ($createdSubnet === null) {
return new JsonResponse(['error' => "Error: No se pudo encontrar la subred creada."], 400);
return new JsonResponse(['error' => "No se pudo encontrar la subred creada"], 400);
}
return new JsonResponse(['success' => "Subred agregada correctamente", 'message' => $createdSubnet], 200);
@ -525,7 +514,7 @@ public function addDhcpSubnet(Request $request): JsonResponse
* description="Subnet not found",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string", example="Error: La subred con el id '2' no existe")
* @OA\Property(property="error", type="string", example="La subred con el id '2' no existe")
* )
* ),
* @OA\Response(
@ -556,7 +545,7 @@ public function addDhcpSubnet(Request $request): JsonResponse
$subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));
if ($subnetIndex === false) {
$responseError = "Error: La subred con el id '$subnetId' no existe";
$responseError = "La subred con el id '$subnetId' no existe";
return new JsonResponse(['error' => $responseError], 404);
} else {
//Borramos la subred con ese id
@ -726,9 +715,14 @@ public function addDhcpSubnet(Request $request): JsonResponse
"boot-file-name" => $bootFileName,
"reservations" => []
];
// 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) {
@ -742,8 +736,14 @@ public function addDhcpSubnet(Request $request): JsonResponse
$responseError = "Error al escribir en la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 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";
return new JsonResponse(['success' => $responseSuccess], 200);
return new JsonResponse(['success' => $responseSuccess,'subnet' => reset($updatedSubnet)], 200);
}
}
} else {
@ -1262,7 +1262,7 @@ public function updateDhcpHost(Request $request, $subnetId): JsonResponse
{
try {
$input = json_decode($request->getContent());
$host = htmlspecialchars($input->host);
$host = htmlspecialchars($input->hostname);
$oldMacAddress = htmlspecialchars($input->oldMacAddress);
$macAddress = htmlspecialchars($input->macAddress);
$address = htmlspecialchars($input->address);
@ -1422,27 +1422,44 @@ public function getLatestBackupConfiguration(): JsonResponse
* @OA\Post(
* path="/ogdhcp/v1/backup/restore",
* 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.",
* 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="success", type="string", example="Configuración cargada correctamente"),
* @OA\Property(property="subnets", 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="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.20"),
* @OA\Property(property="hw-address", type="string", example="00:0c:29:6b:5e:71")
* )
* )
* )
* )
* )
* ),
* @OA\Response(
* @OA\Response(
* response=400,
* description="Error occurred while adding the host",
* 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="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(
@ -1459,11 +1476,6 @@ public function getLatestBackupConfiguration(): JsonResponse
* value={"error": "No se encontraron archivos de backup"}
* ),
* @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"}
@ -1478,55 +1490,66 @@ public function getLatestBackupConfiguration(): JsonResponse
* summary="Error in config-write in kea",
* value={"error": "Error al escribir en la configuración en Kea DHCP"}
* )
* ),
* )
* )
* @Route("/ogdhcp/v1/backup/restore", methods={"POST"})
*/
public function restoreDhcpConfiguration(): JsonResponse
{
$backup_dir = '/opt/ogdhcp/etc/kea/backup';
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);
}
public function restoreDhcpConfiguration(): JsonResponse
{
$backup_dir = '/opt/opengnsys/etc/kea/backup';
try {
$backup_files = glob($backup_dir . '/*.conf');
if (empty($backup_files)) {
$response = "No se encontraron archivos de backup";
return new JsonResponse(['error' => $response], 400);
$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 {
usort($backup_files, function ($a, $b) {
return filemtime($b) - filemtime($a);
});
$backup_file = reset($backup_files);
$config = file_get_contents($backup_file);
$configuration = json_decode($config);
$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"];
$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 {
$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);
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 {
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 {
$responseSuccess = "Configuración cargada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
// 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);
}
} catch (Exception $e) {
$responseError = "Error al restaurar la configuración: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
}

View File

@ -28,7 +28,8 @@ class CurlKeaService
} else {
return "Error: Comando no válido";
}
if (($command == 'config-set' || $command == 'config-write') && $create_backup) {
//f (($command == 'config-set' || $command == 'config-write') && $create_backup) {
if ($command == 'config-set' && $create_backup) {
$this->backupConfig();
}
$jsonData = json_encode($requestData);