diff --git a/src/DhcpBundle/Controller/DhcpController.php b/src/DhcpBundle/Controller/DhcpController.php index ee3677c..3805f61 100644 --- a/src/DhcpBundle/Controller/DhcpController.php +++ b/src/DhcpBundle/Controller/DhcpController.php @@ -57,16 +57,33 @@ class DhcpController */ 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'); } @@ -75,7 +92,13 @@ class DhcpController try { $subnetsResult = $this->getSubnetsService(); } catch (\Exception $e) { - // Si ocurre un error, simplemente dejar $subnetsResult vacío + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'params' => [], + 'desc' => 'Failed to retrieve subnets' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $subnetsResult = []; } @@ -86,14 +109,31 @@ class DhcpController '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 @@ -260,31 +300,55 @@ class DhcpController public function getSubnets(): JsonResponse { + $operation = 'getSubnets'; + $component = 'ogdhcp'; + try { - $this->logger->info('Iniciando la obtención de subredes.'); + $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('No se pudo acceder al archivo de configuración de Kea.', [ - 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR - ]); + $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('El campo "subnet4" no está inicializado.', [ - 'http_code' => Response::HTTP_BAD_REQUEST - ]); + $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('Subredes obtenidas correctamente.', [ + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_OK, - 'subnets_count' => count($subnets) - ]); + 'params' => ['subnets_count' => count($subnets)], + 'desc' => 'Subredes obtenidas correctamente.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'success' => 'Subredes obtenidas correctamente', 'message' => $subnets @@ -292,17 +356,25 @@ class DhcpController } } else { $errorText = $response[0]["text"] ?? 'Unknown error'; - $this->logger->error('Error al obtener la configuración de Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $errorText - ]); + '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('Excepción al obtener la configuración de Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $e->getMessage() - ]); + '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); } } @@ -382,6 +454,9 @@ class DhcpController */ public function addDhcpSubnet(Request $request): JsonResponse { + $operation = 'addDhcpSubnet'; + $component = 'ogdhcp'; + try { $input = json_decode($request->getContent()); $subnetId = (int) htmlspecialchars($input->subnetId); @@ -396,15 +471,21 @@ public function addDhcpSubnet(Request $request): JsonResponse // Calcular el gatewayIP si no se proporciona el router $gatewayIP = $router ?: substr($address, 0, strrpos($address, '.')) . '.1'; } catch (Exception $e) { - $this->logger->error('Error al procesar los datos de entrada para agregar una subred.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $e->getMessage() - ]); + '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); } @@ -412,7 +493,6 @@ public function addDhcpSubnet(Request $request): JsonResponse $response = $this->curlKeaService->executeCurlCommand('config-get'); $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask); - // Crear el array newSubnet con los valores obligatorios $newSubnet = [ "id" => $subnetId, "subnet" => $subnetName, @@ -426,12 +506,10 @@ public function addDhcpSubnet(Request $request): JsonResponse ] ]; - // Añadir next-server si está presente if ($nextServer) { $newSubnet["next-server"] = $nextServer; } - // Añadir boot-file-name si está presente if ($bootFileName) { $newSubnet["boot-file-name"] = $bootFileName; } @@ -442,31 +520,32 @@ public function addDhcpSubnet(Request $request): JsonResponse $subnets = $response[0]['arguments']['Dhcp4']['subnet4']; - // Verificar si el nombre de la subred o el ID ya existe - $subnetNameExists = array_reduce($subnets, function ($exists, $subnetElement) use ($subnetName) { - return $exists || ($subnetElement['subnet'] === $subnetName); - }, false); - - $subnetIdExists = array_reduce($subnets, function ($exists, $subnetElement) use ($subnetId) { - return $exists || ($subnetElement['id'] === $subnetId); - }, false); + $subnetNameExists = array_reduce($subnets, fn($exists, $subnetElement) => $exists || ($subnetElement['subnet'] === $subnetName), false); + $subnetIdExists = array_reduce($subnets, fn($exists, $subnetElement) => $exists || ($subnetElement['id'] === $subnetId), false); if ($subnetNameExists) { - $this->logger->error('La subred con la IP ya existe.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'subnet_name' => $subnetName - ]); + 'desc' => "La subred con la IP '$subnetName' ya existe." + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse(['error' => "La subred con la ip '$subnetName' ya existe."], Response::HTTP_BAD_REQUEST); } elseif ($subnetIdExists) { - $this->logger->error('La subred con el ID ya existe.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'subnet_id' => $subnetId - ]); + '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; - // Eliminar el campo 'hash' si existe if (isset($response[0]['arguments']['hash'])) { unset($response[0]['arguments']['hash']); } @@ -474,30 +553,37 @@ public function addDhcpSubnet(Request $request): JsonResponse $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) { + if (!$responseSet || $responseSet[0]["result"] != 0) { $errorText = $responseSet[0]["text"] ?? 'Unknown error'; - $this->logger->error('Error al guardar la configuración en Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $errorText], 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 == false || $responseWrite[0]["result"] != 0) { + if (!$responseWrite || $responseWrite[0]["result"] != 0) { $errorText = $responseWrite[0]["text"] ?? 'Unknown error'; - $this->logger->error('Error al escribir la configuración en Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); - return new JsonResponse(['error' => "Error al escribir la configuración en Kea DHCP: " . $errorText], Response::HTTP_BAD_REQUEST); - } else { - // Realizar una nueva consulta a Kea para obtener la subred recién creada - $configGetResponse = $this->curlKeaService->executeCurlCommand('config-get'); + '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) { @@ -507,40 +593,58 @@ public function addDhcpSubnet(Request $request): JsonResponse } } - if ($createdSubnet === null) { - $this->logger->error('No se pudo encontrar la subred creada.', [ + if (!$createdSubnet) { + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'subnet_id' => $subnetId - ]); + '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('Subred agregada correctamente.', [ + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_OK, - 'subnet' => $createdSubnet - ]); + '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('Error en la configuración de Kea.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); - return new JsonResponse(['error' => "Error en la configuración de Kea: " . $errorText], 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('Excepción al obtener la configuración de Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $e->getMessage() - ]); + '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); } } + /** @@ -625,6 +729,8 @@ public function addDhcpSubnet(Request $request): JsonResponse public function deleteDhcpSubnet(Request $request): JsonResponse { + $operation = 'deleteDhcpSubnet'; + $component = 'ogdhcp'; $subnetId = (int) $request->get('subnetId'); try { @@ -632,10 +738,14 @@ public function addDhcpSubnet(Request $request): JsonResponse if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) { $responseError = "No hay subredes definidas"; - $this->logger->error('No se encontraron subredes definidas.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $responseError - ]); + 'desc' => $responseError + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse(['error' => $responseError], Response::HTTP_BAD_REQUEST); } @@ -643,19 +753,23 @@ public function addDhcpSubnet(Request $request): JsonResponse if ($subnetIndex === false) { $responseError = "La subred con el id '$subnetId' no existe"; - $this->logger->error('La subred no existe.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_NOT_FOUND, - 'subnet_id' => $subnetId, - 'error_text' => $responseError - ]); + 'desc' => $responseError, + 'params' => ['subnet_id' => $subnetId] + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse(['error' => $responseError], Response::HTTP_NOT_FOUND); } else { - // Borramos la subred con ese id unset($response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex]); - // Eliminar el campo 'hash' si existe + 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); @@ -664,50 +778,74 @@ public function addDhcpSubnet(Request $request): JsonResponse 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('Error al guardar la configuración.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $responseError - ]); + '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('Error al escribir la configuración.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $responseError - ]); + '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('Subred eliminada con éxito.', [ + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_OK, - 'subnet_id' => $subnetId - ]); + '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('Error en la configuración de Kea.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $responseError - ]); + '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('Excepción al obtener la configuración de Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $e->getMessage() - ]); + '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"}) @@ -768,10 +906,12 @@ public function addDhcpSubnet(Request $request): JsonResponse */ public function modifyDhcpSubnet(Request $request): JsonResponse { + $operation = 'modifyDhcpSubnet'; + $component = 'ogdhcp'; $subnetId = (int) $request->get('subnetId'); try { - $input = json_decode($request->getContent()); + $input = json_decode($request->getContent(), false); $mask = htmlspecialchars($input->mask); $address = htmlspecialchars($input->address); @@ -786,16 +926,23 @@ public function modifyDhcpSubnet(Request $request): JsonResponse if (strpos($e->getMessage(), 'Undefined property') !== false) { preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches); $paramFaltante = $matches[1] ?? 'desconocido'; - $this->logger->error('Falta un parámetro requerido.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => "Falta un parámetro requerido: $paramFaltante" - ]); + '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('Error al procesar la solicitud.', [ + + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $e->getMessage() - ]); + 'desc' => $e->getMessage() + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $e->getMessage()], Response::HTTP_BAD_REQUEST); } @@ -805,10 +952,13 @@ public function modifyDhcpSubnet(Request $request): JsonResponse if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) { $errorText = "No hay subredes definidas"; - $this->logger->error('Error al obtener subredes.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + 'desc' => $errorText + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } @@ -816,11 +966,14 @@ public function modifyDhcpSubnet(Request $request): JsonResponse if ($subnetIndex === false) { $errorText = "La subred con el id '$subnetId' no existe"; - $this->logger->error('Subred no encontrada.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_NOT_FOUND, - 'subnet_id' => $subnetId, - 'error_text' => $errorText - ]); + '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 @@ -830,7 +983,7 @@ public function modifyDhcpSubnet(Request $request): JsonResponse $newSubnet = [ "id" => $subnetId, "subnet" => $subnetName, - "reservations" => $existingSubnet['reservations'], // Mantener las reservas existentes + "reservations" => $existingSubnet['reservations'], "option-data" => [ [ "name" => "routers", @@ -840,38 +993,15 @@ public function modifyDhcpSubnet(Request $request): JsonResponse ] ]; - // 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']); } @@ -886,49 +1016,53 @@ public function modifyDhcpSubnet(Request $request): JsonResponse $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('Error al guardar la configuración.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + '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('Error al escribir la configuración.', [ - 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); - return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); - } else { - $responseSuccess = "Subred modificada correctamente"; - $this->logger->info('Subred modificada con éxito.', [ - 'http_code' => Response::HTTP_OK, - 'subnet_id' => $subnetId - ]); - return new JsonResponse(['success' => $responseSuccess], Response::HTTP_OK); - } + $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('Error en la configuración de Kea.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + 'desc' => $errorText + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } } } catch (Exception $e) { - $this->logger->error('Excepción al modificar la subred.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $e->getMessage() - ]); + '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( @@ -973,36 +1107,49 @@ public function modifyDhcpSubnet(Request $request): JsonResponse */ public function getHosts($subnetId): JsonResponse { + $operation = 'getHosts'; + $component = 'ogdhcp'; + try { $response = $this->curlKeaService->executeCurlCommand('config-get'); if (!$response) { - $responseError = "Error: No hay subredes definidas"; - $this->logger->error('Error al obtener la configuración de Kea DHCP.', [ + $responseError = "No hay subredes definidas"; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $responseError - ]); + '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 = "Error: El campo 'subnet4' no está inicializado."; - $this->logger->error('Error al obtener las subredes.', [ + $errorText = "El campo 'subnet4' no está inicializado."; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + '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('Hosts obtenidos correctamente.', [ + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_OK, - 'subnet_id' => $subnetId - ]); + 'desc' => 'Hosts obtenidos correctamente.', + 'params' => ['subnet_id' => $subnetId] + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse([ 'success' => 'Hosts obtenidos correctamente', 'message' => $subnet['reservations'] @@ -1010,33 +1157,43 @@ public function getHosts($subnetId): JsonResponse } } - $errorText = "Error: La subred con el id '$subnetId' no existe."; - $this->logger->error('Subred no encontrada.', [ + $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, - 'subnet_id' => $subnetId, - 'error_text' => $errorText - ]); + 'desc' => $errorText, + 'params' => ['subnet_id' => $subnetId] + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } else { - $responseError = "Error: No hay subredes definidas"; - $this->logger->error('Error al obtener las subredes.', [ + $responseError = "No hay subredes definidas"; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $responseError - ]); + '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('Excepción al obtener la configuración de Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $errorText - ]); + '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", @@ -1138,24 +1295,31 @@ public function getHosts($subnetId): JsonResponse */ 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) { - $this->logger->error('Falta un parámetro requerido.', [ + $errorText = $e->getMessage(); + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $e->getMessage() - ]); + 'desc' => $errorText + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - if (strpos($e->getMessage(), 'Undefined property') !== false) { - preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches); + 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' => $e->getMessage()], Response::HTTP_BAD_REQUEST); + return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } try { @@ -1172,7 +1336,6 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse if ($subnet['id'] == $subnetId) { $subnetFound = true; - // Añadir boot-file-name y next-server de la subred si están definidos if (isset($subnet['boot-file-name'])) { $newHost['boot-file-name'] = $subnet['boot-file-name']; } @@ -1189,12 +1352,16 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse }); if ($exists) { - $this->logger->error('Host duplicado.', [ + $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, - 'host' => $host, - 'subnet_id' => $subnetId - ]); - return new JsonResponse(['error' => "Error: El host con el hostname '$host' ya existe en las reservaciones."], 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; @@ -1203,16 +1370,18 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse } if (!$subnetFound) { - $errorText = "Error: No se encontró la subnet con id '$subnetId'."; - $this->logger->error('Subred no encontrada.', [ + $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, - 'subnet_id' => $subnetId, - 'error_text' => $errorText - ]); + 'desc' => $errorText, + 'params' => ['subnet_id' => $subnetId] + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } - // Eliminar el campo 'hash' si existe if (isset($response[0]['arguments']['hash'])) { unset($response[0]['arguments']['hash']); } @@ -1226,22 +1395,27 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse $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('Error al guardar la configuración.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + '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('Error al escribir la configuración.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + 'desc' => $errorText + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } else { - // Ahora volvemos a consultar el host recién creado $updatedResponse = $this->curlKeaService->executeCurlCommand('config-get'); $createdHost = null; @@ -1256,38 +1430,49 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse } } if ($createdHost) { - $this->logger->info('Host agregado correctamente.', [ + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_OK, - 'host' => $host, - 'subnet_id' => $subnetId - ]); + '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('Host recién creado no encontrado.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'host' => $host, - 'subnet_id' => $subnetId, - 'error_text' => $errorText - ]); + '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('Configuración inválida.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_BAD_REQUEST, - 'error_text' => $errorText - ]); + '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('Excepción al obtener la configuración de Kea DHCP.', [ + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, - 'error_text' => $errorText - ]); + 'desc' => $errorText + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse(['error' => $errorText], Response::HTTP_INTERNAL_SERVER_ERROR); } } @@ -1382,11 +1567,22 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse */ public function deleteDhcpHost(Request $request, $subnetId): JsonResponse { + $operation = 'deleteDhcpHost'; + $component = 'ogdhcp'; + try { $input = json_decode($request->getContent()); $macAddress = htmlspecialchars($input->macAddress); } catch (Exception $e) { - return new JsonResponse(['error' => $e->getMessage()], 400); + $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 { @@ -1413,14 +1609,31 @@ public function deleteDhcpHost(Request $request, $subnetId): JsonResponse } if (!$subnetFound) { - return new JsonResponse(['error' => "No se encontró la subnet con id '$subnetId'"], 400); + $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) { - return new JsonResponse(['error' => "El host con la MAC '$macAddress' no existe en las reservaciones"], 400); + $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); } - // Eliminar el campo 'hash' si existe if (isset($response[0]['arguments']['hash'])) { unset($response[0]['arguments']['hash']); } @@ -1433,21 +1646,60 @@ public function deleteDhcpHost(Request $request, $subnetId): JsonResponse if ($responseTest[0]["result"] == 0) { $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration); if ($responseSet == false || $responseSet[0]["result"] != 0) { - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"]], 400); + $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); + $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 { - return new JsonResponse(['success' => "Host eliminado correctamente"], 200); + $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 { - return new JsonResponse(['error' => "Error configuracion de kea invalido: " . $responseTest[0]["text"]], 400); + $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) { - $responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage(); - return new JsonResponse(['error' => $responseError], 500); + $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); } } @@ -1522,6 +1774,9 @@ public function deleteDhcpHost(Request $request, $subnetId): JsonResponse */ public function updateDhcpHost(Request $request, $subnetId): JsonResponse { + $operation = 'updateDhcpHost'; + $component = 'ogdhcp'; + try { $input = json_decode($request->getContent()); $host = htmlspecialchars($input->hostname); @@ -1529,16 +1784,25 @@ public function updateDhcpHost(Request $request, $subnetId): JsonResponse $macAddress = htmlspecialchars($input->macAddress); $address = htmlspecialchars($input->address); } catch (Exception $e) { - $response["message"] = $e->getMessage(); + $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"], 400); + return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], Response::HTTP_BAD_REQUEST); } + + return new JsonResponse(['error' => $errorText], Response::HTTP_BAD_REQUEST); } try { - // Ejecutar el comando para obtener la configuración actual $response = $this->curlKeaService->executeCurlCommand('config-get'); $subnetFound = false; $hostFound = false; @@ -1555,16 +1819,13 @@ public function updateDhcpHost(Request $request, $subnetId): JsonResponse if ($reservation['hw-address'] == $oldMacAddress) { $hostFound = true; - // Conservar boot-file-name y next-server si existen en el host original $bootFileName = $reservation['boot-file-name'] ?? $subnet['boot-file-name'] ?? null; $nextServer = $reservation['next-server'] ?? $subnet['next-server'] ?? null; - // Actualizar los valores del host $reservation['hw-address'] = $macAddress; $reservation['ip-address'] = $address; $reservation['hostname'] = $host; - // Restaurar boot-file-name y next-server si estaban definidos if ($bootFileName !== null) { $reservation['boot-file-name'] = $bootFileName; } @@ -1580,46 +1841,99 @@ public function updateDhcpHost(Request $request, $subnetId): JsonResponse } if ($subnetFound && $hostFound) { - // Eliminar el campo 'hash' si existe if (isset($response[0]['arguments']['hash'])) { unset($response[0]['arguments']['hash']); } - // Preparar la configuración modificada $array_encoded = json_encode($response[0]['arguments']); $configurationParsed = str_replace('\\', '', $array_encoded); $configuration = json_decode($configurationParsed); - // Test de la configuración $responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration); if ($responseTest[0]["result"] == 0) { - // Guardar la configuración $responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration); if ($responseSet == false || $responseSet[0]["result"] != 0) { - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"]], 400); + $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 { - // Escribir la configuración en disco $responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration); if ($responseWrite == false || $responseWrite[0]["result"] != 0) { - return new JsonResponse(['error' => "Error al escribir la configuración en Kea DHCP: " . $responseWrite[0]["text"]], 400); + $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 { - // Devolver el host actualizado - return new JsonResponse(['success' => "Host actualizado correctamente", 'message' => $updatedHost], 200); + $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 { - return new JsonResponse(['error' => "Error en la configuración de Kea: " . $responseTest[0]["text"]], 400); + $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) { - return new JsonResponse(['error' => "Error: La subred con el id '$subnetId' no existe."], 400); + $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) { - return new JsonResponse(['error' => "Error: El host con la MAC '$oldMacAddress' no existe en las reservaciones."], 400); + $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) { - return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], 500); + $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\Get( * path="/ogdhcp/v1/backup",