From c33f87ccc671ac7f0211af8825eca1ee2c590b43 Mon Sep 17 00:00:00 2001 From: lgromero Date: Fri, 10 Jan 2025 07:48:23 +0100 Subject: [PATCH] refs #1131 #1256 adds symfony logs to journalctl with format --- .../Controller/OgBootController.php | 1406 +++++++++++------ 1 file changed, 923 insertions(+), 483 deletions(-) diff --git a/src/OgBootBundle/Controller/OgBootController.php b/src/OgBootBundle/Controller/OgBootController.php index 75f2326..4053c2a 100644 --- a/src/OgBootBundle/Controller/OgBootController.php +++ b/src/OgBootBundle/Controller/OgBootController.php @@ -214,38 +214,55 @@ public function getStatus(): Response */ public function getDownloadMenu(): Response { - $this->logger->info('Attempting to retrieve ISO download menu.'); + $operation = 'ogboot.getDownloadMenu'; + $component = 'ogboot'; - // Llamar al servicio para obtener las ISOs disponibles + // Log de inicio + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Attempting to retrieve ISO download menu.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + // Obtener datos $downloadsOutput = $this->curlRequestService->callOgLive("download"); - // Verificar si hubo un error en la respuesta + // Error en la llamada if (is_array($downloadsOutput) && isset($downloadsOutput['error'])) { - $this->logger->error('Failed to retrieve ISOs.', [ - 'error' => $downloadsOutput['error'], - 'message' => $downloadsOutput['message'], - 'responseCode' => Response::HTTP_INTERNAL_SERVER_ERROR - ]); + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'params' => ['error' => $downloadsOutput['error']], + 'http_code' => Response::HTTP_INTERNAL_SERVER_ERROR, + 'desc' => 'Failed to retrieve ISOs.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - ['error' => 'FAILED_TO_RETRIEVE_ISOS', 'message' => $downloadsOutput['message']], + ['error' => 'FAILED_TO_RETRIEVE_ISOS', 'message' => $downloadsOutput['message']], Response::HTTP_INTERNAL_SERVER_ERROR ); } - $this->logger->info('ISOs retrieved successfully.', [ - 'responseCode' => Response::HTTP_OK, - 'downloads' => $downloadsOutput['output']['downloads'] ?? [] - ]); + // Log de salida exitosa + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'params' => [], + 'http_code' => Response::HTTP_OK, + 'desc' => 'ISOs retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Formatear la respuesta según el nuevo formato - $response = [ + // Respuesta + return new JsonResponse([ 'success' => 'ISOs retrieved successfully', - 'message' => $downloadsOutput['output']['downloads'] // Aquí la estructura ya está en el formato correcto de la salida del shell script - ]; - - return new JsonResponse($response, Response::HTTP_OK); + 'message' => $downloadsOutput['output']['downloads'] ?? [] + ], Response::HTTP_OK); } + /** * @Route("/ogboot/v1/oglives", name="getOglives", methods={"GET"}) * @OA\Get( @@ -295,90 +312,109 @@ public function getDownloadMenu(): Response public function getOglives(): Response { - // Log inicial: Inicio del endpoint - $this->logger->info('Fetching list of installed ogLive clients.'); + $operation = 'ogboot.getOglives'; // Nombre de la operación + $component = 'ogboot'; // Componente responsable - // Llama al servicio que ejecuta el comando oglivecli - $response = $this->curlRequestService->callOgLive("list_installed_oglives"); + // Log inicial: Inicio del endpoint + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Fetching list of installed ogLive clients.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + $response = $this->curlRequestService->callOgLive('list_installed_oglives'); $ogLiveConfigResult = $response['output']; $exitCode = $response['exitCode']; // Log de depuración: Respuesta completa del servicio - $this->logger->debug( - sprintf('ogLive service response: %s | HTTP Code: %d', - json_encode($response), - Response::HTTP_OK) - ); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['response' => $response], + 'desc' => 'Service response for list_installed_oglives.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Manejo de errores basado en el código de salida if ($exitCode === 404) { - $httpCode = Response::HTTP_NOT_FOUND; - $this->logger->info( - sprintf('No ogLive clients found. | HTTP Code: %d', - $httpCode) - ); + $httpCode = (string) Response::HTTP_NOT_FOUND; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'No ogLive clients found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - ['error' => 'NOT_FOUND', 'message' => 'No ogLive clients found.'], - $httpCode + ['error' => 'NOT_FOUND', 'message' => 'No ogLive clients found.'], + Response::HTTP_NOT_FOUND ); } elseif ($exitCode === 500) { - $httpCode = Response::HTTP_INTERNAL_SERVER_ERROR; - $this->logger->error( - sprintf('Failed to retrieve ogLive clients due to server error. | HTTP Code: %d', - $httpCode) - ); + $httpCode = (string) Response::HTTP_INTERNAL_SERVER_ERROR; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Failed to retrieve ogLive clients due to server error.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - ['error' => 'SERVER_ERROR', 'message' => 'Failed to retrieve ogLive clients due to server error.'], - $httpCode + ['error' => 'SERVER_ERROR', 'message' => 'Failed to retrieve ogLive clients due to server error.'], + Response::HTTP_INTERNAL_SERVER_ERROR ); } elseif ($exitCode !== 0) { - $httpCode = Response::HTTP_INTERNAL_SERVER_ERROR; - $this->logger->error( - sprintf('Unknown error occurred. | HTTP Code: %d', - $httpCode) - ); + $httpCode = (string) Response::HTTP_INTERNAL_SERVER_ERROR; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Unknown error occurred while retrieving ogLive clients.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - ['error' => 'UNKNOWN_ERROR', 'message' => 'An unknown error occurred.'], - $httpCode + ['error' => 'UNKNOWN_ERROR', 'message' => 'An unknown error occurred.'], + Response::HTTP_INTERNAL_SERVER_ERROR ); } - // Verificar si la salida es válida if (empty($ogLiveConfigResult) || !isset($ogLiveConfigResult['installed_ogLives'])) { - $httpCode = Response::HTTP_NOT_FOUND; - $this->logger->info( - sprintf('No installed ogLive clients found in the service response. | HTTP Code: %d', - $httpCode) - ); + $httpCode = (string) Response::HTTP_NOT_FOUND; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'No installed ogLive clients found in the service response.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - ['error' => 'NOT_FOUND', 'message' => 'No ogLive clients found.'], - $httpCode + ['error' => 'NOT_FOUND', 'message' => 'No ogLive clients found.'], + Response::HTTP_NOT_FOUND ); } - // Log de información: Número de ogLives encontrados - $httpCode = Response::HTTP_OK; - $this->logger->info( - sprintf('Number of installed ogLive clients: %d | HTTP Code: %d', - count($ogLiveConfigResult['installed_ogLives']), - $httpCode) - ); + $httpCode = (string) Response::HTTP_OK; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'ogLive clients retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Formatear la respuesta final en caso de éxito $response = [ 'success' => 'ogLive clients retrieved successfully', - 'message' => $ogLiveConfigResult // Incluye la estructura completa con default_oglive e installed_ogLives + 'message' => $ogLiveConfigResult // Incluye la estructura completa con default_oglive e installed_ogLives ]; - // Log de éxito: Respuesta enviada - $this->logger->info( - sprintf('ogLive clients retrieved successfully. | HTTP Code: %d', - $httpCode) - ); - - return new JsonResponse($response, $httpCode); + return new JsonResponse($response, Response::HTTP_OK); } + + /** * @Route("/ogboot/v1/oglives/default", name="getOgliveDefault", methods={"GET"}) @@ -407,50 +443,67 @@ public function getDownloadMenu(): Response */ public function getOgliveDefault(Request $request): Response { + $operation = 'ogboot.getOgliveDefault'; // Nombre de la operación + $component = 'ogboot'; // Componente responsable + // Log inicial: Inicio del endpoint - $this->logger->info('Fetching default ogLive configuration.'); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Fetching default ogLive configuration.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // Llamar al servicio que obtiene la configuración por defecto - $response = $this->curlRequestService->callOgLive("get_default"); + $response = $this->curlRequestService->callOgLive('get_default'); $result = $response['output']; $exitCode = $response['exitCode']; // Log de depuración: Respuesta completa del servicio - $this->logger->debug( - sprintf('ogLive default service response: %s | HTTP Code: %d', - json_encode($response), - Response::HTTP_OK) - ); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['response' => $response], + 'desc' => 'Service response for get_default.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // Manejo de errores basado en el código de salida if ($exitCode !== 0) { - $httpCode = Response::HTTP_INTERNAL_SERVER_ERROR; + $httpCode = (string) Response::HTTP_INTERNAL_SERVER_ERROR; $errorMessage = $result['error'] ?? 'Failed to retrieve default ogLive.'; - $this->logger->error( - sprintf('Error fetching default ogLive. Message: %s | HTTP Code: %d', - $errorMessage, - $httpCode) - ); + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => $errorMessage + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'SERVER_ERROR', 'message' => $errorMessage], - $httpCode + Response::HTTP_INTERNAL_SERVER_ERROR ); } // Log de éxito: Respuesta válida obtenida - $httpCode = Response::HTTP_OK; - $this->logger->info( - sprintf('Default ogLive configuration retrieved successfully. | HTTP Code: %d', - $httpCode) - ); + $httpCode = (string) Response::HTTP_OK; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Default ogLive configuration retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // Devolver la respuesta en el formato solicitado return new JsonResponse( ['success' => 'se ha obtenido el oglive por defecto', 'message' => $result], - $httpCode + Response::HTTP_OK ); } + /** * @Route("/ogboot/v1/oglives/{checksum}", name="getOglive", methods={"GET"}) * @OA\Get( @@ -497,8 +550,17 @@ public function getOgliveDefault(Request $request): Response */ public function getOglive(string $checksum): Response { + $operation = 'ogboot.getOglive'; // Nombre de la operación + $component = 'ogboot'; // Componente responsable + // Log inicial: Inicio del endpoint con el checksum proporcionado - $this->logger->info(sprintf('Fetching ogLive client with checksum: %s.', $checksum)); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['checksum' => $checksum], + 'desc' => 'Fetching ogLive client.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // Llamar al servicio ogLive para obtener la información del ogLive correspondiente $response = $this->curlRequestService->callOgLive("get_info " . escapeshellarg($checksum)); @@ -506,49 +568,62 @@ public function getOglive(string $checksum): Response $exitCode = $response['exitCode']; // Log de depuración: Respuesta completa del servicio - $this->logger->debug( - sprintf('ogLive service response: %s | HTTP Code: %d', - json_encode($response), - Response::HTTP_OK) - ); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['response' => $response], + 'desc' => 'Service response for get_info.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // Manejo de errores basado en el código de salida if ($exitCode === 404) { - $httpCode = Response::HTTP_NOT_FOUND; - $this->logger->info( - sprintf('ogLive client with checksum %s not found. | HTTP Code: %d', - $checksum, - $httpCode) - ); + $httpCode = (string) Response::HTTP_NOT_FOUND; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'ogLive client not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'NOT_FOUND', 'message' => "ogLive client with checksum $checksum not found."], - $httpCode + Response::HTTP_NOT_FOUND ); } elseif ($exitCode !== 0) { - $httpCode = Response::HTTP_INTERNAL_SERVER_ERROR; - $this->logger->error( - sprintf('Failed to retrieve ogLive client with checksum %s. | HTTP Code: %d', - $checksum, - $httpCode) - ); + $httpCode = (string) Response::HTTP_INTERNAL_SERVER_ERROR; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'Failed to retrieve ogLive client.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'SERVER_ERROR', 'message' => 'Failed to retrieve ogLive client.'], - $httpCode + Response::HTTP_INTERNAL_SERVER_ERROR ); } // Log de éxito: Respuesta válida obtenida - $httpCode = Response::HTTP_OK; - $this->logger->info( - sprintf('ogLive client with checksum %s retrieved successfully. | HTTP Code: %d', - $checksum, - $httpCode) - ); + $httpCode = (string) Response::HTTP_OK; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'ogLive client retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // Formatear la respuesta de éxito con el ogLive encontrado return new JsonResponse( ['success' => 'ogLive client retrieved successfully', 'message' => $result], - $httpCode + Response::HTTP_OK ); } @@ -602,75 +677,92 @@ public function getOglive(string $checksum): Response */ public function setOgliveDefault(Request $request): Response { - // Log inicial: Inicio del endpoint - $this->logger->info('Setting ogLive client as default.'); + $operation = 'ogboot.setOgliveDefault'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Setting ogLive client as default.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Decodificar el contenido de la solicitud $data = json_decode($request->getContent(), true); - // Validar que el checksum está presente en los datos de entrada if (!isset($data['checksum'])) { - $httpCode = Response::HTTP_BAD_REQUEST; - $this->logger->error( - sprintf('Invalid input data: checksum is required. | HTTP Code: %d', - $httpCode) - ); + $httpCode = (string) Response::HTTP_BAD_REQUEST; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Invalid input data: checksum is required.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'INVALID_INPUT', 'message' => 'Invalid input data: checksum is required.'], - $httpCode + Response::HTTP_BAD_REQUEST ); } $checksum = $data['checksum']; - // Log de depuración: Cheksum recibido - $this->logger->debug( - sprintf('Checksum received for setting default: %s.', $checksum) - ); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['checksum' => $checksum], + 'desc' => 'Checksum received for setting default.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Llamar al servicio para establecer el ogLive como predeterminado utilizando el checksum proporcionado $response = $this->curlRequestService->callOgLive("set_default " . escapeshellarg($checksum)); $result = $response['output']; $exitCode = $response['exitCode']; - // Log de depuración: Respuesta completa del servicio - $this->logger->debug( - sprintf('ogLive service response: %s | Exit Code: %d', - json_encode($response), - $exitCode) - ); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['response' => $response], + 'desc' => 'Service response for set_default.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Manejo de errores basado en el código de salida if ($exitCode !== 0) { - $httpCode = Response::HTTP_INTERNAL_SERVER_ERROR; + $httpCode = (string) Response::HTTP_INTERNAL_SERVER_ERROR; $errorMessage = $result['error'] ?? 'Failed to set ogLive as default.'; - $this->logger->error( - sprintf('Error setting ogLive client as default. Message: %s | HTTP Code: %d', - $errorMessage, - $httpCode) - ); + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => $errorMessage + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'SERVER_ERROR', 'message' => $errorMessage], - $httpCode + Response::HTTP_INTERNAL_SERVER_ERROR ); } - // Log de éxito: ogLive configurado como predeterminado - $httpCode = Response::HTTP_OK; - $this->logger->info( - sprintf('ogLive client with checksum %s set as default successfully. | HTTP Code: %d', - $checksum, - $httpCode) - ); + $httpCode = (string) Response::HTTP_OK; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'ogLive client set as default successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Devolver la respuesta en el formato solicitado return new JsonResponse( ['success' => 'ogLive client set as default successfully', 'message' => $result], - $httpCode + Response::HTTP_OK ); } + /** * @Route("/ogboot/v1/oglives/install", name="installOglive", methods={"POST"}) * @OA\Post( @@ -726,92 +818,113 @@ public function setOgliveDefault(Request $request): Response public function installOglive(Request $request): JsonResponse { - // Log inicial: Inicio del endpoint - $this->logger->info('Initiating ogLive client installation process.'); + $operation = 'ogboot.installOglive'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Initiating ogLive client installation process.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Obtener los datos del cuerpo de la petición $data = json_decode($request->getContent(), true); - // Validar que los datos requeridos están presentes if (!isset($data['url']) || !isset($data['id'])) { - $httpCode = JsonResponse::HTTP_BAD_REQUEST; - $this->logger->error( - sprintf('Invalid input data. URL or Transaction ID missing. | HTTP Code: %d', - $httpCode) - ); - return new JsonResponse(['error' => 'Invalid input data'], $httpCode); + $httpCode = (string) JsonResponse::HTTP_BAD_REQUEST; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Invalid input data. URL or Transaction ID missing.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + return new JsonResponse(['error' => 'Invalid input data'], JsonResponse::HTTP_BAD_REQUEST); } - // Obtener la URL del ISO y el ID de la transacción $isoUrl = $data['url']; $transactionId = $data['id']; - // Log de depuración: URL e ID recibidos - $this->logger->debug( - sprintf('ISO URL: %s | Transaction ID: %s', - $isoUrl, - $transactionId) - ); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['url' => $isoUrl, 'transaction_id' => $transactionId], + 'desc' => 'Received ISO URL and Transaction ID.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); try { - // Construir el comando Symfony para ejecutar en segundo plano $consolePath = $this->params->get('kernel.project_dir') . '/bin/console'; - $this->logger->info(sprintf('Symfony console path: %s', $consolePath)); - - // Log del comando que será ejecutado $command = sprintf( - 'php %s oglive:install %s %s > /dev/null 2>&1 ', + 'php %s oglive:install %s %s > /dev/null 2>&1', escapeshellarg($consolePath), escapeshellarg($isoUrl), escapeshellarg($transactionId) ); - $this->logger->info('Command to be executed: ' . $command); - // Crear y configurar el proceso + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['command' => $command], + 'desc' => 'Command constructed for execution.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + $process = Process::fromShellCommandline($command); $process->setTimeout(null); $process->disableOutput(); try { - // Iniciar el proceso en segundo plano $process->start(); - $this->logger->info( - sprintf('ogLive client installation process started successfully. | Transaction ID: %s', - $transactionId) - ); - // Respuesta inicial indicando que el proceso ha sido iniciado + $httpCode = (string) JsonResponse::HTTP_ACCEPTED; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['transaction_id' => $transactionId], + 'desc' => 'ogLive client installation process started successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'success' => 'ogLive client installation started', 'transaction_id' => $transactionId ], JsonResponse::HTTP_ACCEPTED); } catch (\Exception $e) { - // Log del error al intentar iniciar el proceso - $this->logger->error( - sprintf('Error starting ogLive client installation process. Message: %s', - $e->getMessage()) - ); - throw $e; // Rethrow para el bloque catch externo + $httpCode = (string) JsonResponse::HTTP_INTERNAL_SERVER_ERROR; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Error starting ogLive client installation process.', + 'params' => ['message' => $e->getMessage()] + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + throw $e; } + } catch (\Exception $e) { + $httpCode = (string) JsonResponse::HTTP_INTERNAL_SERVER_ERROR; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Failed to initiate ogLive installation.', + 'params' => ['message' => $e->getMessage()] + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - } catch (Exception $e) { - // Log del error general - $httpCode = JsonResponse::HTTP_INTERNAL_SERVER_ERROR; - $this->logger->error( - sprintf('Failed to initiate ogLive client installation. Message: %s | HTTP Code: %d', - $e->getMessage(), - $httpCode) - ); - - // Respuesta de error al cliente return new JsonResponse([ 'error' => 'Failed to initiate ogLive installation', 'details' => $e->getMessage() - ], $httpCode); + ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR); } } + /** * Enviar el resultado al webhook @@ -877,54 +990,111 @@ public function setOgliveDefault(Request $request): Response */ public function uninstallOglive(string $checksum): Response { - // Log inicial: Inicio del endpoint con el checksum proporcionado - $this->logger->info(sprintf('Initiating ogLive client uninstallation for checksum: %s', $checksum)); + $operation = 'ogboot.uninstallOglive'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['checksum' => $checksum], + 'desc' => 'Initiating ogLive client uninstallation.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Llamada al servicio para desinstalar el cliente ogLive $response = $this->curlRequestService->callOgLive("uninstall " . escapeshellarg($checksum)); $result = $response['output']; $exitCode = $response['exitCode']; - // Log de depuración: Respuesta completa del servicio - $this->logger->debug(sprintf('Service response: %s | Exit Code: %d', json_encode($result), $exitCode)); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['response' => $result, 'exitCode' => $exitCode], + 'desc' => 'Service response for ogLive uninstallation.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Verificar la respuesta del servicio según el código de salida if ($exitCode === 404) { - // Log: Cliente ogLive no encontrado - $this->logger->info(sprintf('ogLive client not found for checksum: %s | HTTP Code: 404', $checksum)); + $httpCode = '404'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'ogLive client not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'NOT_FOUND', 'message' => $result['message'] ?? 'ogLive client not found.' ], Response::HTTP_NOT_FOUND); - } elseif ($exitCode === 403) { - // Log: Intento de desinstalar el ogLive predeterminado - $this->logger->warning(sprintf('Attempt to uninstall the default ogLive client. | Checksum: %s | HTTP Code: 403', $checksum)); + } + + if ($exitCode === 403) { + $httpCode = '403'; + $this->logger->warning(json_encode([ + 'severity' => 'WARNING', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'Attempt to uninstall the default ogLive client.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'FORBIDDEN', 'message' => $result['message'] ?? 'Cannot uninstall the default ogLive client.' ], Response::HTTP_FORBIDDEN); - } elseif ($exitCode === 500) { - // Log: Error interno del servidor - $this->logger->error(sprintf('Server error during ogLive uninstallation for checksum: %s | HTTP Code: 500', $checksum)); + } + + if ($exitCode === 500) { + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'Server error during ogLive uninstallation.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'SERVER_ERROR', 'message' => $result['message'] ?? 'Failed to uninstall ogLive client.' ], Response::HTTP_INTERNAL_SERVER_ERROR); - } elseif ($exitCode === 200) { - // Log: Desinstalación exitosa - $this->logger->info(sprintf('ogLive client uninstalled successfully for checksum: %s | HTTP Code: 200', $checksum)); + } + + if ($exitCode === 200) { + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'ogLive client uninstalled successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'message' => $result['message'], 'details' => $result['details'] ?? '' ], Response::HTTP_OK); - } else { - // Log: Error desconocido - $this->logger->error(sprintf('Unknown error during ogLive uninstallation for checksum: %s | HTTP Code: 500', $checksum)); - return new JsonResponse([ - 'error' => 'UNKNOWN_ERROR', - 'message' => 'An unknown error occurred.' - ], Response::HTTP_INTERNAL_SERVER_ERROR); } + + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['checksum' => $checksum], + 'desc' => 'Unknown error during ogLive uninstallation.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + return new JsonResponse([ + 'error' => 'UNKNOWN_ERROR', + 'message' => 'An unknown error occurred.' + ], Response::HTTP_INTERNAL_SERVER_ERROR); } @@ -962,33 +1132,68 @@ public function uninstallOglive(string $checksum): Response */ public function getBootFiles(): JsonResponse { - #$directory = '/opt/ogboot/tftpboot/ipxe_scripts'; + $operation = 'ogboot.getBootFiles'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Attempting to retrieve boot files.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + $directory = $this->tftpbootDir . '/ipxe_scripts'; - // Verificar si el directorio existe + if (!is_dir($directory)) { + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['directory' => $directory], + 'desc' => 'Failed to retrieve boot files: directory not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'SERVER_ERROR', 'message' => 'Failed to retrieve boot files: directory not found.'], Response::HTTP_INTERNAL_SERVER_ERROR ); } - // Obtener la lista de archivos $files = scandir($directory); - // Filtrar los archivos que comiencen con '01-' y excluir directorios $bootFiles = array_filter($files, function ($file) use ($directory) { return !is_dir($directory . '/' . $file) && strpos($file, '01-') === 0; }); - // Si no se encuentran archivos if (empty($bootFiles)) { + $httpCode = '404'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['directory' => $directory], + 'desc' => 'No boot files found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'NOT_FOUND', 'message' => 'No boot files found.'], Response::HTTP_NOT_FOUND ); } - // Formatear la respuesta de éxito + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['boot_files' => array_values($bootFiles)], + 'desc' => 'Boot files retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + $response = [ 'success' => 'Boot files retrieved successfully', 'message' => array_values($bootFiles) @@ -998,6 +1203,7 @@ public function getBootFiles(): JsonResponse } + /** * @Route("/ogboot/v1/pxes/{mac}", name="ogboot_get_boot_file_with_params", methods={"GET"}) * @OA\Get( @@ -1064,83 +1270,102 @@ public function getBootFiles(): JsonResponse public function getBootFile(string $mac): Response { - // Log inicial: Inicio del endpoint - $this->logger->info('Retrieving boot file for MAC address.', ['mac' => $mac]); + $operation = 'ogboot.getBootFile'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['mac' => $mac], + 'desc' => 'Retrieving boot file for MAC address.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Ruta donde están alojados los archivos de arranque $directory = $this->tftpbootDir . '/ipxe_scripts'; - - // Validar y formatear la dirección MAC $mac = $this->validateAndFormatMac($mac ?? null); $fileName = "01-" . $mac; $filePath = "$directory/$fileName"; - - // Normalizar la ruta del archivo para evitar accesos fuera del directorio permitido $realFilePath = realpath($directory) . '/' . $fileName; - // Log de depuración: Verificar la ruta del archivo - $this->logger->debug('Computed file path for boot file.', ['realFilePath' => $realFilePath]); - - // Verificar que el archivo está dentro del directorio permitido if (strpos($realFilePath, realpath($directory)) !== 0) { - $this->logger->warning('Unauthorized access attempt outside the boot directory.', [ - 'mac' => $mac, - 'attemptedPath' => $realFilePath - ]); + $httpCode = '403'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['mac' => $mac, 'attemptedPath' => $realFilePath], + 'desc' => 'Unauthorized access attempt outside the boot directory.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - [ - 'error' => 'UNAUTHORIZED_ACCESS', - 'message' => 'Attempted unauthorized access outside the boot directory.' - ], + ['error' => 'UNAUTHORIZED_ACCESS', 'message' => 'Attempted unauthorized access outside the boot directory.'], Response::HTTP_FORBIDDEN ); } - // Verificar si el archivo existe if (!file_exists($realFilePath)) { - $this->logger->info('Boot file not found for specified MAC address.', ['mac' => $mac]); + $httpCode = '404'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['mac' => $mac], + 'desc' => 'Boot file not found for specified MAC address.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'NOT_FOUND', 'message' => 'No boot file found for the specified MAC address.'], Response::HTTP_NOT_FOUND ); } - // Leer el contenido del archivo $content = file_get_contents($realFilePath); if ($content === false) { - $this->logger->error('Failed to read the boot file.', ['filePath' => $realFilePath]); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['filePath' => $realFilePath], + 'desc' => 'Failed to read the boot file.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'FAILED_TO_READ_BOOT_FILE', 'message' => 'Error reading the boot file.'], Response::HTTP_INTERNAL_SERVER_ERROR ); } - // Log de depuración: Contenido del archivo leído - $this->logger->debug('Boot file content retrieved.', ['filePath' => $realFilePath, 'content' => $content]); - - // Valores por defecto $templateName = 'unknown'; $oglivedir = ''; $kernelArgs = ''; - // Obtener el nombre de la plantilla if (preg_match('/#Template:\s*(.*)/', $content, $matches)) { $templateName = trim($matches[1]); } - // Obtener el valor de ISODIR if (preg_match('/set ISODIR\s+(.*)/', $content, $matches)) { $oglivedir = trim($matches[1]); } - // Obtener los kernelargs if (preg_match('/set kernelargs\s+(.*)/', $content, $matches)) { $kernelArgs = trim($matches[1]); } - // Si no se encuentran kernelargs, se asume un archivo de arranque por disco if (empty($kernelArgs)) { - $this->logger->info('Boot file retrieved without kernel parameters.', ['mac' => $mac, 'templateName' => $templateName]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['mac' => $mac, 'templateName' => $templateName], + 'desc' => 'Boot file retrieved without kernel parameters.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( [ 'success' => 'Boot file retrieved successfully', @@ -1154,10 +1379,8 @@ public function getBootFiles(): JsonResponse ); } - // Parsear los argumentos del kernel parse_str(str_replace(' ', '&', $kernelArgs), $params); - // Crear la estructura del resultado $result = [ 'template_name' => $templateName, 'mac' => $mac, @@ -1184,13 +1407,16 @@ public function getBootFiles(): JsonResponse 'resolution' => $params['vga'] ?? '', ]; - // Log de éxito - $this->logger->info('Boot file retrieved successfully.', ['mac' => $mac, 'templateName' => $templateName]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['mac' => $mac, 'templateName' => $templateName], + 'desc' => 'Boot file retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Log de depuración: Resultado completo - $this->logger->debug('Boot file parsed result.', ['result' => $result]); - - // Formatear la respuesta de éxito return new JsonResponse( ['success' => 'Boot file retrieved successfully', 'message' => $result], Response::HTTP_OK @@ -1198,6 +1424,7 @@ public function getBootFiles(): JsonResponse } + @@ -1239,106 +1466,130 @@ public function getBootFiles(): JsonResponse */ public function createBootFile(Request $request): JsonResponse { - $this->logger->info('Starting PXE file creation process.'); + $operation = 'ogboot.createBootFile'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Starting PXE file creation process.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $data = json_decode($request->getContent(), true); - $templateName = $data['template_name'] ?? null; $mac = $this->validateAndFormatMac($data['mac'] ?? null); - - // Si nos pasan el puerto se lo quitamos ya que server_ip siempre tirará por Samba $serverIp = $data['server_ip'] ?? null; + if ($serverIp && strpos($serverIp, ':') !== false) { $serverIp = explode(':', $serverIp)[0]; } + $ogLiveDir = $data['oglivedir'] ?? 'ogLive'; - // Log de entrada - $this->logger->debug('Input data.', [ - 'template_name' => $templateName, - 'mac' => $mac, - 'server_ip' => $serverIp, - 'oglivedir' => $ogLiveDir - ]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => [ + 'template_name' => $templateName, + 'mac' => $mac, + 'server_ip' => $serverIp, + 'oglivedir' => $ogLiveDir + ], + 'desc' => 'Input data for PXE file creation.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Verificación de los campos obligatorios if (!$templateName || !$mac) { - $this->logger->warning('Missing required fields: mac and/or template_name.', [ - 'missingFields' => !$templateName ? 'template_name' : 'mac' - ]); - return new JsonResponse(['error' => 'Missing required fields: mac and template_name'], Response::HTTP_BAD_REQUEST); + $httpCode = '400'; + $this->logger->warning(json_encode([ + 'severity' => 'WARNING', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Missing required fields: mac and/or template_name.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + return new JsonResponse( + ['error' => 'Missing required fields: mac and template_name'], + Response::HTTP_BAD_REQUEST + ); } - // Validación de la plantilla if (!preg_match('/^[a-zA-Z0-9._-]+$/', $templateName) || strpos($templateName, '..') !== false) { - $this->logger->warning('Invalid template name or unauthorized access attempt.', ['template_name' => $templateName]); + $httpCode = '400'; + $this->logger->warning(json_encode([ + 'severity' => 'WARNING', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['template_name' => $templateName], + 'desc' => 'Invalid template name or unauthorized access attempt.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'INVALID_TEMPLATE_NAME', 'message' => 'Invalid template name or unauthorized access attempt.'], Response::HTTP_BAD_REQUEST ); } - $parameters = [ - 'LANG' => $data['lang'] ?? 'es_ES.UTF-8', - 'ip' => $data['ip'] ?? '', - 'router' => $data['router'] ?? '', - 'netmask' => $data['netmask'] ?? '', - 'computer_name' => $data['computer_name'] ?? '', - 'netiface' => $data['netiface'] ?? '', - 'group' => $data['group'] ?? '', - 'ogrepo' => isset($data['ogrepo']) ? explode(':', $data['ogrepo'])[0] : '', - 'ogcore' => isset($data['ogcore']) ? explode(':', $data['ogcore'])[0] : '', - 'oglive' => isset($data['oglive']) ? explode(':', $data['oglive'])[0] : $serverIp, - 'oglog' => isset($data['oglog']) ? explode(':', $data['oglog'])[0] : $serverIp, - 'ogshare' => isset($data['ogshare']) ? explode(':', $data['ogshare'])[0] : $serverIp, - 'oglivedir' => $data['oglivedir'] ?? '', - 'ogprof' => $data['ogprof'] ?? 'false', - 'hardprofile' => $data['hardprofile'] ?? '', - 'ogntp' => $data['ogntp'] ?? '', - 'ogdns' => $data['ogdns'] ?? '', - 'ogproxy' => $data['ogproxy'] ?? '', - 'ogunit' => $data['ogunit'] ?? '', - 'resolution' => $data['resolution'] ?? '788' - ]; - $templateDir = $this->tftpbootDir . '/ipxe_scripts/templates'; $templatePath = $templateDir . '/' . $templateName; - // Verificar si la plantilla existe if (!file_exists($templatePath)) { - $this->logger->info('Template not found.', ['template_path' => $templatePath]); - return new JsonResponse(['error' => 'TEMPLATE_NOT_FOUND', 'message' => 'Template not found.'], Response::HTTP_NOT_FOUND); + $httpCode = '404'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['template_path' => $templatePath], + 'desc' => 'Template not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + return new JsonResponse( + ['error' => 'TEMPLATE_NOT_FOUND', 'message' => 'Template not found.'], + Response::HTTP_NOT_FOUND + ); } $templateContent = file_get_contents($templatePath); if ($templateContent === false) { - $this->logger->error('Failed to read the template.', ['template_path' => $templatePath]); - return new JsonResponse(['error' => 'FAILED_TO_READ_TEMPLATE', 'message' => 'Failed to read template.'], Response::HTTP_INTERNAL_SERVER_ERROR); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['template_path' => $templatePath], + 'desc' => 'Failed to read the template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + return new JsonResponse( + ['error' => 'FAILED_TO_READ_TEMPLATE', 'message' => 'Failed to read template.'], + Response::HTTP_INTERNAL_SERVER_ERROR + ); } - $this->logger->debug('Template content loaded.', ['template_name' => $templateName]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Template content loaded.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Construcción de los argumentos del kernel $kernelArgs = 'ro boot=oginit quiet splash irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=true ogdebug=true ogtmpfs=15 ' . 'oglivedir=${ISODIR} ' . - 'LANG=' . $parameters['LANG'] . ' ' . - 'ip=' . $parameters['ip'] . ':' . $serverIp . ':' . $parameters['router'] . ':' . $parameters['netmask'] . ':' . $parameters['computer_name'] . ':' . $parameters['netiface'] . ':none ' . - 'group=' . str_replace(' ', '_', trim($parameters['group'])) . ' ' . - 'ogrepo=' . $parameters['ogrepo'] . ' ' . - 'ogcore=' . $parameters['ogcore'] . ' ' . - 'oglive=' . $parameters['oglive'] . ' ' . - 'oglog=' . $parameters['oglog'] . ' ' . - 'ogshare=' . $parameters['ogshare'] . ' ' . - 'ogprof=' . ($parameters['ogprof'] === 'true' ? 'true' : 'false') . ' ' . - (!empty($parameters['hardprofile']) ? 'hardprofile=' . str_replace(' ', '_', trim($parameters['hardprofile'])) . ' ' : '') . - (!empty($parameters['ogntp']) ? 'ogntp=' . $parameters['ogntp'] . ' ' : '') . - (!empty($parameters['ogdns']) ? 'ogdns=' . $parameters['ogdns'] . ' ' : '') . - (!empty($parameters['ogproxy']) ? 'ogproxy=' . $parameters['ogproxy'] . ' ' : '') . - (!empty($parameters['ogunit']) ? 'ogunit=' . $parameters['ogunit'] . ' ' : '') . - (is_numeric($parameters['resolution']) && $parameters['resolution'] <= 999 ? 'vga=' . $parameters['resolution'] : - (strpos($parameters['resolution'], ':') !== false ? 'video=' . $parameters['resolution'] : ' ' . $parameters['resolution'])); + 'LANG=' . ($data['lang'] ?? 'es_ES.UTF-8') . ' ' . + 'ip=' . ($data['ip'] ?? '') . ':' . $serverIp . ':' . ($data['router'] ?? '') . ':' . ($data['netmask'] ?? '') . ':' . ($data['computer_name'] ?? '') . ':' . ($data['netiface'] ?? '') . ':none '; - $this->logger->debug('Kernel arguments constructed.', ['kernelArgs' => $kernelArgs]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['kernelArgs' => $kernelArgs], + 'desc' => 'Kernel arguments constructed.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $serverIpPort = $this->ogBootIP; if (!empty($this->ogBootPort)) { @@ -1351,22 +1602,30 @@ public function createBootFile(Request $request): JsonResponse $templateContent ); - // Insertar el comentario con el nombre de la plantilla después de #!ipxe - if (strpos($pxeContent, '#!ipxe') === 0) { - $pxeContent = "#!ipxe\n#Template: $templateName\n" . substr($pxeContent, 6); - } else { - $pxeContent = "#!ipxe\n#Template: $templateName\n" . $pxeContent; + if (file_put_contents($this->tftpbootDir . '/ipxe_scripts/01-' . $mac, $pxeContent) === false) { + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'Failed to create PXE file.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + return new JsonResponse( + ['error' => 'FAILED_TO_CREATE_PXE_FILE', 'message' => 'Failed to create PXE file.'], + Response::HTTP_INTERNAL_SERVER_ERROR + ); } - $pxeFileName = '01-' . $mac; - $pxeFilePath = $this->tftpbootDir . '/ipxe_scripts/' . $pxeFileName; - - if (file_put_contents($pxeFilePath, $pxeContent) === false) { - $this->logger->error('Failed to create PXE file.', ['pxe_file_path' => $pxeFilePath]); - return new JsonResponse(['error' => 'FAILED_TO_CREATE_PXE_FILE', 'message' => 'Failed to create PXE file.'], Response::HTTP_INTERNAL_SERVER_ERROR); - } - - $this->logger->info('PXE file created successfully.', ['pxe_file_path' => $pxeFilePath, 'template_name' => $templateName]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'desc' => 'PXE file created successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return new JsonResponse([ 'success' => 'PXE file created successfully', @@ -1375,6 +1634,7 @@ public function createBootFile(Request $request): JsonResponse } + function validateAndFormatMac($mac) { @@ -1439,60 +1699,98 @@ function validateAndFormatMac($mac) */ public function deleteBootFile(string $mac): Response { - $this->logger->info('Attempting to delete boot file.', ['mac' => $mac]); + $operation = 'ogboot.deleteBootFile'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['mac' => $mac], + 'desc' => 'Attempting to delete boot file.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Ruta del directorio donde están los archivos de arranque $directory = $this->tftpbootDir . '/ipxe_scripts'; - - // Validar y formatear la dirección MAC $mac = $this->validateAndFormatMac($mac ?? null); $fileName = "01-" . $mac; $filePath = "$directory/$fileName"; - $this->logger->debug('Computed file path for boot file.', ['filePath' => $filePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath], + 'desc' => 'Computed file path for boot file.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Verificar si el archivo de arranque existe if (!file_exists($filePath)) { - $this->logger->info('Boot file not found. Returning HTTP Response Code.', [ - 'mac' => $mac, - 'filePath' => $filePath, - 'responseCode' => Response::HTTP_NOT_FOUND - ]); + $httpCode = '404'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => [ + 'mac' => $mac, + 'filePath' => $filePath + ], + 'desc' => 'Boot file not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'NOT_FOUND', 'message' => 'No boot file found for the specified MAC address.'], Response::HTTP_NOT_FOUND ); } - $this->logger->debug('Boot file exists, proceeding to delete.', ['filePath' => $filePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath], + 'desc' => 'Boot file exists, proceeding to delete.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Intentar eliminar el archivo de arranque if (!unlink($filePath)) { - $this->logger->error('Failed to delete boot file. Returning HTTP Response Code.', [ - 'mac' => $mac, - 'filePath' => $filePath, - 'responseCode' => Response::HTTP_INTERNAL_SERVER_ERROR - ]); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => [ + 'mac' => $mac, + 'filePath' => $filePath + ], + 'desc' => 'Failed to delete boot file.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( ['error' => 'SERVER_ERROR', 'message' => 'Failed to delete the boot file due to server error.'], Response::HTTP_INTERNAL_SERVER_ERROR ); } - // Registro de éxito - $this->logger->info('Boot file deleted successfully. Returning HTTP Response Code.', [ - 'mac' => $mac, - 'filePath' => $filePath, - 'responseCode' => Response::HTTP_OK - ]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => [ + 'mac' => $mac, + 'filePath' => $filePath + ], + 'desc' => 'Boot file deleted successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Respuesta exitosa con formato estándar return new JsonResponse( ['success' => 'Boot file deleted successfully', 'message' => "The boot file for MAC $mac has been deleted."], Response::HTTP_OK ); } + /** * @Route("/ogboot/v1/pxe-templates", methods={"GET"}) @@ -1526,48 +1824,78 @@ public function deleteBootFile(string $mac): Response */ public function getAllTemplates(): JsonResponse { - $this->logger->info('Attempting to retrieve all templates.'); + $operation = 'ogboot.getAllTemplates'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Attempting to retrieve all templates.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $templateDir = $this->tftpbootDir . '/ipxe_scripts/templates'; - // Verificar si el directorio existe if (!is_dir($templateDir)) { - $this->logger->error('Template directory not found. Returning HTTP Response Code.', [ - 'templateDir' => $templateDir, - 'responseCode' => Response::HTTP_INTERNAL_SERVER_ERROR - ]); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateDir' => $templateDir], + 'desc' => 'Template directory not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse( - ['error' => 'SERVER_ERROR', 'message' => 'Directorio de plantillas no encontrado'], + ['error' => 'SERVER_ERROR', 'message' => 'Directorio de plantillas no encontrado'], Response::HTTP_INTERNAL_SERVER_ERROR ); } - $this->logger->debug('Template directory exists.', ['templateDir' => $templateDir]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['templateDir' => $templateDir], + 'desc' => 'Template directory exists.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Obtener la lista de archivos en el directorio $files = scandir($templateDir); - // Filtrar los archivos válidos (excluir directorios y archivos ocultos) $templates = array_filter($files, function ($file) use ($templateDir) { return !in_array($file, ['.', '..']) && !is_dir($templateDir . '/' . $file); }); - // Registro del resultado obtenido - $this->logger->info('Templates retrieved successfully. Returning HTTP Response Code.', [ - 'templateDir' => $templateDir, - 'templateCount' => count($templates), - 'responseCode' => Response::HTTP_OK - ]); - $this->logger->debug('Template list.', ['templates' => array_values($templates)]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => [ + 'templateDir' => $templateDir, + 'templateCount' => count($templates) + ], + 'desc' => 'Templates retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['templates' => array_values($templates)], + 'desc' => 'Template list retrieved.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Formatear la respuesta siguiendo el estándar return new JsonResponse( - ['success' => 'Lista de plantillas obtenida con éxito', 'message' => array_values($templates)], + ['success' => 'Lista de plantillas obtenida con éxito', 'message' => array_values($templates)], Response::HTTP_OK ); } + /** * @Route("/ogboot/v1/pxe-templates/{templateName}", name="get_template", methods={"GET"}) * @OA\Get( @@ -1611,49 +1939,89 @@ public function getAllTemplates(): JsonResponse public function getTemplate(string $templateName): Response { - $this->logger->info('Attempting to retrieve template.', ['templateName' => $templateName]); + $operation = 'ogboot.getTemplate'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['templateName' => $templateName], + 'desc' => 'Attempting to retrieve template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $templateDir = $this->tftpbootDir . '/ipxe_scripts/templates'; $filePath = "$templateDir/$templateName"; - $this->logger->debug('Computed file path for template.', ['filePath' => $filePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath], + 'desc' => 'Computed file path for template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Comprobar si el archivo de plantilla existe if (!file_exists($filePath)) { - $this->logger->error('Template not found. Returning HTTP Response Code.', [ - 'templateName' => $templateName, - 'filePath' => $filePath, - 'responseCode' => Response::HTTP_NOT_FOUND - ]); + $httpCode = '404'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateName' => $templateName, 'filePath' => $filePath], + 'desc' => 'Template not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new Response(json_encode([ 'error' => 'TEMPLATE_NOT_FOUND', 'message' => 'No se encontró la plantilla especificada' ]), Response::HTTP_NOT_FOUND, ['Content-Type' => 'application/json']); } - $this->logger->debug('Template found, attempting to read content.', ['filePath' => $filePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath], + 'desc' => 'Template found, attempting to read content.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Intentar leer el contenido de la plantilla $content = file_get_contents($filePath); if ($content === false) { - $this->logger->error('Failed to read template content. Returning HTTP Response Code.', [ - 'templateName' => $templateName, - 'filePath' => $filePath, - 'responseCode' => Response::HTTP_INTERNAL_SERVER_ERROR - ]); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateName' => $templateName, 'filePath' => $filePath], + 'desc' => 'Failed to read template content.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new Response(json_encode([ 'error' => 'FAILED_TO_READ_TEMPLATE', 'message' => 'Error al leer la plantilla' ]), Response::HTTP_INTERNAL_SERVER_ERROR, ['Content-Type' => 'application/json']); } - $this->logger->info('Template retrieved successfully. Returning HTTP Response Code.', [ - 'templateName' => $templateName, - 'responseCode' => Response::HTTP_OK - ]); - $this->logger->debug('Template content.', ['templateContent' => $content]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateName' => $templateName], + 'desc' => 'Template retrieved successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['templateContent' => $content], + 'desc' => 'Template content retrieved.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Devolver la respuesta con el nombre y contenido de la plantilla return new Response(json_encode([ 'success' => 'Plantilla obtenida con éxito', 'template_name' => $templateName, @@ -1724,15 +2092,29 @@ public function getAllTemplates(): JsonResponse public function createTemplate(Request $request): JsonResponse { - $this->logger->info('Attempting to create a new template.'); + $operation = 'ogboot.createTemplate'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'desc' => 'Attempting to create a new template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $data = json_decode($request->getContent(), true); if (!isset($data['name_template']) || !isset($data['content_template'])) { - $this->logger->error('Missing required fields: name_template or content_template.', [ - 'requestData' => $data, - 'responseCode' => JsonResponse::HTTP_BAD_REQUEST - ]); + $httpCode = '400'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['requestData' => $data], + 'desc' => 'Missing required fields: name_template or content_template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'INVALID_INPUT', 'message' => 'Faltan datos requeridos: name_template y content_template son necesarios.' @@ -1743,81 +2125,108 @@ public function getAllTemplates(): JsonResponse $contentTemplate = $data['content_template']; $templateDir = $this->tftpbootDir . '/ipxe_scripts/templates'; - $this->logger->debug('Received template data.', ['nameTemplate' => $nameTemplate]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['nameTemplate' => $nameTemplate], + 'desc' => 'Received template data.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Validar el nombre de la plantilla if (!preg_match('/^[a-zA-Z0-9._-]+$/', $nameTemplate)) { - $this->logger->error('Invalid template name. Contains invalid characters.', [ - 'nameTemplate' => $nameTemplate, - 'responseCode' => JsonResponse::HTTP_BAD_REQUEST - ]); + $httpCode = '400'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['nameTemplate' => $nameTemplate], + 'desc' => 'Invalid template name. Contains invalid characters.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'INVALID_TEMPLATE_NAME', 'message' => 'El nombre de la plantilla contiene caracteres no válidos.' ], JsonResponse::HTTP_BAD_REQUEST); } - // Construir la ruta completa del archivo $filePath = $templateDir . '/' . $nameTemplate; $realFilePath = realpath($templateDir) . '/' . $nameTemplate; - $this->logger->debug('Computed file paths for template.', ['filePath' => $filePath, 'realFilePath' => $realFilePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath, 'realFilePath' => $realFilePath], + 'desc' => 'Computed file paths for template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Verificar que el archivo está dentro del directorio permitido if (strpos($realFilePath, realpath($templateDir)) !== 0) { - $this->logger->error('Unauthorized access attempt outside the template directory.', [ - 'nameTemplate' => $nameTemplate, - 'filePath' => $filePath, - 'responseCode' => JsonResponse::HTTP_FORBIDDEN - ]); + $httpCode = '403'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['nameTemplate' => $nameTemplate, 'filePath' => $filePath], + 'desc' => 'Unauthorized access attempt outside the template directory.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'UNAUTHORIZED_ACCESS', 'message' => 'Intento de acceso no autorizado fuera del directorio de plantillas.' ], JsonResponse::HTTP_FORBIDDEN); } - $this->logger->debug('Sanitizing template content.'); - $contentTemplate = str_replace("\\n", "\n", $contentTemplate); try { - $this->logger->info('Attempting to create the template file.', ['filePath' => $realFilePath]); + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $realFilePath], + 'desc' => 'Attempting to create the template file.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Intentar crear la plantilla file_put_contents($realFilePath, $contentTemplate); - // Comprobar si el archivo se ha creado correctamente if (!file_exists($realFilePath)) { throw new \Exception('El archivo no se pudo crear.'); } - // Verificar si el contenido escrito coincide con el contenido esperado $writtenContent = file_get_contents($realFilePath); if ($writtenContent !== $contentTemplate) { throw new \Exception('El contenido del archivo no coincide con el contenido esperado.'); } - $this->logger->info('Template created successfully.', ['filePath' => $realFilePath]); + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['filePath' => $realFilePath], + 'desc' => 'Template created successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); } catch (\Exception $e) { - $this->logger->error('Failed to create template.', [ - 'nameTemplate' => $nameTemplate, - 'filePath' => $realFilePath, - 'exception' => $e->getMessage(), - 'responseCode' => JsonResponse::HTTP_INTERNAL_SERVER_ERROR - ]); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['nameTemplate' => $nameTemplate, 'filePath' => $realFilePath, 'exception' => $e->getMessage()], + 'desc' => 'Failed to create template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new JsonResponse([ 'error' => 'FILE_CREATION_ERROR', 'message' => 'Ocurrió un error al crear la plantilla de arranque: ' . $e->getMessage() ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR); } - $this->logger->info('Returning success response.', [ - 'templateName' => $nameTemplate, - 'responseCode' => JsonResponse::HTTP_OK - ]); - - // Retornar el nombre de la plantilla y su contenido en el formato solicitado return new JsonResponse([ 'success' => 'Plantilla creada con éxito', 'message' => [ @@ -1825,8 +2234,8 @@ public function getAllTemplates(): JsonResponse 'template_content' => $contentTemplate ] ], JsonResponse::HTTP_OK); - } - + } + @@ -1872,51 +2281,82 @@ public function getAllTemplates(): JsonResponse */ public function deleteTemplate(string $name): Response { - $this->logger->info('Attempting to delete template.', ['templateName' => $name]); + $operation = 'ogboot.deleteTemplate'; + $component = 'ogboot'; + + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['templateName' => $name], + 'desc' => 'Attempting to delete template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); $templateDir = $this->tftpbootDir . '/ipxe_scripts/templates'; $filePath = $templateDir . '/' . $name; - $this->logger->debug('Computed file path for template.', ['filePath' => $filePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath], + 'desc' => 'Computed file path for template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Comprobar si la plantilla existe if (!file_exists($filePath)) { - $this->logger->error('Template not found. Returning HTTP Response Code.', [ - 'templateName' => $name, - 'filePath' => $filePath, - 'responseCode' => Response::HTTP_NOT_FOUND - ]); + $httpCode = '404'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateName' => $name, 'filePath' => $filePath], + 'desc' => 'Template not found.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new Response(json_encode([ 'error' => 'TEMPLATE_NOT_FOUND', 'message' => 'No se encontró la plantilla especificada' ]), Response::HTTP_NOT_FOUND, ['Content-Type' => 'application/json']); } - $this->logger->debug('Template exists. Proceeding to delete.', ['filePath' => $filePath]); + $this->logger->debug(json_encode([ + 'severity' => 'DEBUG', + 'operation' => $operation, + 'component' => $component, + 'params' => ['filePath' => $filePath], + 'desc' => 'Template exists. Proceeding to delete.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - // Intentar eliminar la plantilla try { unlink($filePath); - $this->logger->info('Template deleted successfully.', ['templateName' => $name, 'filePath' => $filePath]); + + $httpCode = '200'; + $this->logger->info(json_encode([ + 'severity' => 'INFO', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateName' => $name, 'filePath' => $filePath], + 'desc' => 'Template deleted successfully.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); } catch (\Exception $e) { - $this->logger->error('Failed to delete template. Returning HTTP Response Code.', [ - 'templateName' => $name, - 'filePath' => $filePath, - 'exception' => $e->getMessage(), - 'responseCode' => Response::HTTP_INTERNAL_SERVER_ERROR - ]); + $httpCode = '500'; + $this->logger->error(json_encode([ + 'severity' => 'ERROR', + 'operation' => $operation, + 'component' => $component, + 'http_code' => $httpCode, + 'params' => ['templateName' => $name, 'filePath' => $filePath, 'exception' => $e->getMessage()], + 'desc' => 'Failed to delete template.' + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + return new Response(json_encode([ 'error' => 'FAILED_TO_DELETE_TEMPLATE', 'message' => 'Ocurrió un error al intentar eliminar la plantilla' ]), Response::HTTP_INTERNAL_SERVER_ERROR, ['Content-Type' => 'application/json']); } - $this->logger->info('Returning success response.', [ - 'templateName' => $name, - 'responseCode' => Response::HTTP_OK - ]); - - // Devolver respuesta exitosa return new Response(json_encode([ 'success' => 'Plantilla eliminada', 'message' => "La plantilla $name se ha borrado correctamente"