diff --git a/config/packages/monolog.yaml b/config/packages/monolog.yaml index 8c9efa9..d13d79d 100644 --- a/config/packages/monolog.yaml +++ b/config/packages/monolog.yaml @@ -22,6 +22,11 @@ when@dev: type: console process_psr_3_messages: false channels: ["!event", "!doctrine", "!console"] + syslog: + type: syslog + ident: "ogdhcp" + level: info + channels: ["!event"] when@test: monolog: diff --git a/src/DhcpBundle/Controller/DhcpController.php b/src/DhcpBundle/Controller/DhcpController.php index efa0ff6..4156ea8 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 @@ -258,33 +298,88 @@ class DhcpController * @Route("/ogdhcp/v1/subnets", methods={"GET"}) */ -public function getSubnets(): JsonResponse -{ - try { - $response = $this->curlKeaService->executeCurlCommand('config-get'); - - if (!$response) { - return new JsonResponse(['error' => 'No se pudo acceder al archivo de configuración de Kea'], 500); - } - - $result_code = $response[0]["result"]; - if ($result_code == 0) { - if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) { - return new JsonResponse(['error' => 'El campo "subnet4" no está inicializado'], 400); - } else { - $subnets = $response[0]['arguments']['Dhcp4']['subnet4']; - return new JsonResponse([ - 'success' => 'Subredes obtenidas correctamente', - 'message' => $subnets - ], 200); - } - } else { - return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $response[0]["text"]], 500); - } - } catch (Exception $e) { - return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], 500); - } -} + 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( @@ -359,6 +454,9 @@ public function getSubnets(): JsonResponse */ public function addDhcpSubnet(Request $request): JsonResponse { + $operation = 'addDhcpSubnet'; + $component = 'ogdhcp'; + try { $input = json_decode($request->getContent()); $subnetId = (int) htmlspecialchars($input->subnetId); @@ -373,19 +471,28 @@ 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) { - $response["message"] = $e->getMessage(); + $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"], 400); + + 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'); $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask); - // Crear el array newSubnet con los valores obligatorios $newSubnet = [ "id" => $subnetId, "subnet" => $subnetName, @@ -399,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; } @@ -415,23 +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) { - return new JsonResponse(['error' => "La subred con la ip '$subnetName' ya existe."], 400); + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => Response::HTTP_BAD_REQUEST, + '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) { - return new JsonResponse(['error' => "La subred con el ID '$subnetId' ya existe."], 400); + $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; - // Eliminar el campo 'hash' si existe if (isset($response[0]['arguments']['hash'])) { unset($response[0]['arguments']['hash']); } @@ -439,20 +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) { - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"]], 400); + 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 == false || $responseWrite[0]["result"] != 0) { - return new JsonResponse(['error' => "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"]], 400); - } else { - // Realizar una nueva consulta a Kea para obtener la subred recién creada - $configGetResponse = $this->curlKeaService->executeCurlCommand('config-get'); + 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) { @@ -462,22 +593,58 @@ public function addDhcpSubnet(Request $request): JsonResponse } } - if ($createdSubnet === null) { - return new JsonResponse(['error' => "No se pudo encontrar la subred creada"], 400); + 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); } - return new JsonResponse(['success' => "Subred agregada correctamente", 'message' => $createdSubnet], 200); + $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 { - return new JsonResponse(['error' => "Error en la configuración de Kea: " . $responseTest[0]["text"]], 400); + $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) { - return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], 500); + $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); } } + + /** @@ -562,59 +729,123 @@ public function addDhcpSubnet(Request $request): JsonResponse 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"; - return new JsonResponse(['error' => $responseError], 400); + $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"; - return new JsonResponse(['error' => $responseError], 404); + $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 { - //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); $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"]; - return new JsonResponse(['error' => $responseError], 400); + $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"]; - return new JsonResponse(['error' => $responseError], 400); + $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"; - return new JsonResponse(['success' => $responseSuccess], 200); + $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 configuracion de kea invalido: " . $responseTest[0]["text"]; - return new JsonResponse(['error' => $responseError], 400); + $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(); - return new JsonResponse(['error' => $responseError], 500); + $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"}) @@ -673,9 +904,12 @@ public function addDhcpSubnet(Request $request): JsonResponse * ) * ) */ + public function modifyDhcpSubnet(Request $request): JsonResponse { $subnetId = (int) $request->get('subnetId'); + $operation = 'modifyDhcpSubnet'; + $component = 'ogdhcp'; try { $input = json_decode($request->getContent()); @@ -693,9 +927,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'; - return new JsonResponse(['error' => "Falta un parámetro requerido: $paramFaltante"], 400); + $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); } - return new JsonResponse(['error' => $e->getMessage()], 400); + $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 { @@ -703,13 +951,30 @@ public function modifyDhcpSubnet(Request $request): JsonResponse $subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask); if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) { - return new JsonResponse(['error' => "No hay subredes definidas"], 400); + $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) { - return new JsonResponse(['error' => "La subred con el id '$subnetId' no existe"], 400); + $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]; @@ -773,7 +1038,15 @@ public function modifyDhcpSubnet(Request $request): 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) { @@ -785,15 +1058,39 @@ public function modifyDhcpSubnet(Request $request): JsonResponse return $subnet['id'] == $subnetId; }); - return new JsonResponse(['success' => "Subred modificada correctamente", 'message' => reset($updatedSubnet)], 200); + $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 { - return new JsonResponse(['error' => "Error configuración de Kea inválida: " . $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) { - return new JsonResponse(['error' => "Error al obtener la configuración de Kea DHCP: " . $e->getMessage()], 500); + $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); } } @@ -843,42 +1140,93 @@ 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"; - return new JsonResponse(['error' => $responseError], 400); + $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'])) { - throw new \Exception('Error: El campo \'subnet4\' no está inicializado.'); + $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 correctamente', + 'success' => 'Hosts obtenidos correctamente', 'message' => $subnet['reservations'] - ], 200); + ], Response::HTTP_OK); } } - return new JsonResponse(['error' => 'Error: La subred con el id \'' . $subnetId . '\' no existe.'], 400); + $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 = "Error: No hay subredes definidas"; - return new JsonResponse(['error' => $responseError], 400); + $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) { - $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); } } + + /** * @OA\Post( * path="/ogdhcp/v1/subnets/{subnetId}/hosts", @@ -980,18 +1328,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) { - $response["message"] = $e->getMessage(); - if (strpos($e->getMessage(), 'Undefined property') !== false) { - preg_match('/Undefined property: stdClass::\$(\w+)/', $e->getMessage(), $matches); + $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"], 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 { @@ -1008,7 +1369,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']; } @@ -1025,7 +1385,16 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse }); if ($exists) { - return new JsonResponse(['error' => "Error: El host con el hostname '$host' ya existe en las reservaciones."], 400); + $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; @@ -1034,10 +1403,18 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse } if (!$subnetFound) { - return new JsonResponse(['error' => "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); } - // Eliminar el campo 'hash' si existe if (isset($response[0]['arguments']['hash'])) { unset($response[0]['arguments']['hash']); } @@ -1050,13 +1427,28 @@ public function addDhcpHost(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 { - // Ahora volvemos a consultar el host recién creado $updatedResponse = $this->curlKeaService->executeCurlCommand('config-get'); $createdHost = null; @@ -1071,18 +1463,50 @@ public function addDhcpHost(Request $request, $subnetId): JsonResponse } } if ($createdHost) { - return new JsonResponse(['success' => "Host agregado correctamente", 'message' => $createdHost], 200); + $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 { - return new JsonResponse(['error' => "No se pudo encontrar el host recién creado"], 400); + $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 { - return new JsonResponse(['error' => "Error kea configuration invalid: " . $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); } } @@ -1176,11 +1600,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 { @@ -1207,14 +1642,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']); } @@ -1227,21 +1679,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); } } @@ -1316,6 +1807,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); @@ -1323,16 +1817,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; @@ -1349,16 +1852,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; } @@ -1374,46 +1874,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",