curlRequestService = $curlRequestService; $this->logger = $logger; } /*Tabla de Contenido Obtener configuración de ogboot - GET /ogboot/config x Obtener datos de rendimiento - GET /ogboot/status x Mostrar información de todos los clientes ogLive instalados - GET /ogboot/oglives x Mostrar información de un cliente ogLive instalado - GET /ogboot/oglives/{Index|Dir} x Mostrar información del cliente ogLive predeterminado - GET /ogboot/oglives/default x Cambiar ogLive predeterminado - POST /ogboot/oglives/default/{Index} x Instalar nuevo cliente ogLive desde imagen descargada - POST /ogboot/oglive/{Index/iso} ---- Desinstalar cliente ogLive y eliminar imagen - DELETE /ogboot/oglives/{Index/iso} ------- Regenerar archivo de información de los ogLive - PUT /ogboot/oglives Mostrar menú de descarga de imagen de ogLive - GET /ogboot/images/download X ///////////////////////////////////////////// Obtener todos los archivos de arranque - GET /ogboot/pxes Obtener archivo de arranque - GET /ogboot/clients/pxes/{mac} Crear archivo de arranque - POST /ogboot/pxes Eliminar archivo de arranque - DELETE /ogboot/clients/pxes Obtener todas las plantillas - GET /ogboot/pxe-templates Obtener contenido de la plantilla - GET /ogboot/pxe-templates/{nombre} Crear plantilla - POST /ogboot/pxe-templates Regenerar plantilla - PUT /ogboot/pxe-templates */ /** * @Route("/ogboot/help", name="help", methods={"GET"}) */ public function help(): Response { # $result = $this->curlRequestService->common_request(OG_REST_CMD_POWEROFF, POST, [OG_REST_PARAM_CLIENTS => $ips]); $result = $this->curlRequestService->callOgLive("help"); if ($result) { return new Response($result, Response::HTTP_OK); } else { return new Response('Failed', Response::HTTP_INTERNAL_SERVER_ERROR); } } /** * @Route("/ogboot/v1/status", name="getStatus", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/status", * summary="Get ogboot status", * @OA\Response( * response=200, * description="Status retrieved successfully", * @OA\JsonContent( * type="object", * @OA\Property(property="disk_usage", type="object", * @OA\Property(property="total", type="string"), * @OA\Property(property="used", type="string"), * @OA\Property(property="available", type="string"), * @OA\Property(property="percentage", type="string") * ), * @OA\Property(property="default_oglive", type="string"), * @OA\Property(property="installed_oglives", type="array", @OA\Items(type="string")) * ) * ) * ) */ public function getStatus(): Response { // Call oglivecli to get disk usage $diskUsageResult = $this->curlRequestService->callOgLive("disk_usage"); if (is_array($diskUsageResult) && isset($diskUsageResult['success']) && $diskUsageResult['success'] === false) { return new JsonResponse(['error' => 'Failed to retrieve disk usage', 'details' => $diskUsageResult['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } // Call oglivecli to get installed oglives and default oglives $ogLiveConfigResult = $this->curlRequestService->callOgLive("list_installed_oglives"); if (is_array($ogLiveConfigResult) && isset($ogLiveConfigResult['success']) && $ogLiveConfigResult['success'] === false) { return new JsonResponse(['error' => 'Failed to retrieve ogLive configuration', 'details' => $ogLiveConfigResult['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } // Call oglivecli to get installed oglives and default oglives $servicesStatusResult = $this->curlRequestService->callOgLive("check_services_status"); if (is_array($servicesStatusResult) && isset($servicesStatusResult['success']) && $servicesStatusResult['success'] === false) { return new JsonResponse(['error' => 'Failed to retrieve services status', 'details' => $servicesStatusResult['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } $response = [ 'disk_usage' => $diskUsageResult, 'default_oglive' => $ogLiveConfigResult['default_oglive'], 'installed_oglives' => $ogLiveConfigResult['installed_ogLives'], 'services_status' => $servicesStatusResult ]; return new JsonResponse($response, Response::HTTP_OK); } /** * @Route("/ogboot/v1/oglives/isos", name="getDownloadMenu", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/oglives/isos", * summary="Get ogLive downloads menu", * @OA\Response( * response=200, * description="Isos retrieved successfully", * @OA\JsonContent( * type="array", * @OA\Items(type="object", * @OA\Property(property="id", type="integer"), * @OA\Property(property="filename", type="string"), * @OA\Property(property="installed", type="boolean"), * @OA\Property(property="compatible", type="boolean") * ) * ) * ), * @OA\Response( * response=500, * description="Failed to retrieve isos", * @OA\JsonContent( * type="object", * @OA\Property(property="error", type="string"), * @OA\Property(property="details", type="string") * ) * ) * ) */ public function getDownloadMenu(): Response { $downloadsOutput = $this->curlRequestService->callOgLive("download"); if (is_array($downloadsOutput) && isset($downloadsOutput['success']) && $downloadsOutput['success'] === false) { return new JsonResponse(['error' => 'Failed to retrieve downloads', 'details' => $downloadsOutput['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } return new JsonResponse($downloadsOutput, Response::HTTP_OK); } /** * @Route("/ogboot/v1/oglives", name="getOglives", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/oglives", * summary="Get list of all installed ogLive clients", * @OA\Response( * response=200, * description="Successful operation", * @OA\JsonContent( * type="array", * @OA\Items( * type="object", * @OA\Property( * property="id", * type="string", * description="Unique identifier for the ogLive client, generated from linuxISO.sum", * example="9e49a085ba74f97a81bdf9b3d0785094" * ), * @OA\Property( * property="distribution", * type="string", * description="Distribution name of the installed ogLive client" * ), * @OA\Property( * property="kernel", * type="string", * description="Kernel version of the installed ogLive client" * ), * @OA\Property( * property="architecture", * type="string", * description="Architecture of the installed ogLive client" * ), * @OA\Property( * property="revision", * type="string", * description="Revision of the installed ogLive client" * ), * @OA\Property( * property="directory", * type="string", * description="Directory name of the installed ogLive client" * ), * @OA\Property( * property="iso", * type="string", * description="ISO file name of the installed ogLive client" * ) * ) * ) * ), * @OA\Response( * response=404, * description="No ogLive clients found" * ) * ) */ public function getOglives(): Response { $directoryPath = '/opt/ogboot/tftpboot/'; $pattern = '/^ogLive-([\w.-]+)-r(\d+)$/'; $ogLives = []; if ($handle = opendir($directoryPath)) { error_log("Opened directory: $directoryPath"); while (false !== ($entry = readdir($handle))) { error_log("Processing entry: $entry"); if ($entry != "." && $entry != ".." && is_dir($directoryPath . $entry)) { if (preg_match($pattern, $entry, $matches)) { error_log("Entry matches pattern: $entry"); // Evitar directorios .old if (substr($entry, -4) === '.old') { error_log("Ignoring old directory: $entry"); continue; } // Extraer detalles $distribution = $matches[1]; $revision = $matches[2]; $directory = $entry; $ogLivePath = $directoryPath . $entry; // Obtener el ID del archivo linuxISO.sum $sumFile = $ogLivePath . '/linuxISO.sum'; $id = ''; if (file_exists($sumFile)) { $id = trim(file_get_contents($sumFile)); } // Obtener el nombre del archivo ISO $iso = ''; $oldInfoFile = $ogLivePath . '/OLDINFOFILE'; if (file_exists($oldInfoFile)) { $iso = trim(file($oldInfoFile, FILE_USE_INCLUDE_PATH | FILE_IGNORE_NEW_LINES)[0]); } // Obtener la versión del kernel $kernelFile = $ogLivePath . '/ogvmlinuz'; $kernel = ''; if (file_exists($kernelFile)) { $fileOutput = shell_exec("file -bkr $kernelFile"); if (preg_match('/Linux kernel.*version (\d+\.\d+\.\d+)/', $fileOutput, $kernelMatches)) { $kernel = $kernelMatches[1]; } } // Asumir arquitectura como 'amd64'; puedes refinar esto si se necesita más lógica $architecture = 'amd64'; // Construir el objeto $ogLives[] = [ 'id' => $id, 'distribution' => $distribution, 'kernel' => $kernel, 'architecture' => $architecture, 'revision' => $revision, 'directory' => $directory, 'iso' => $iso ]; } else { error_log("Entry does not match pattern: $entry"); } } else { error_log("Entry is not a directory: $directoryPath$entry"); } } closedir($handle); error_log("Closed directory: $directoryPath"); } if (!empty($ogLives)) { error_log("Returning ogLives data"); return new JsonResponse($ogLives, Response::HTTP_OK); } else { error_log("No ogLive clients found"); return new JsonResponse(['error' => 'No ogLive clients found'], Response::HTTP_NOT_FOUND); } } /** * @Route("/ogboot/v1/oglives/default", name="getOgliveDefault", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/oglives/default", * summary="Get information of the default ogLive client", * @OA\Response( * response=200, * description="Successful operation", * @OA\JsonContent( * type="object", * @OA\Property( * property="distribution", * type="string", * description="Distribution name of the default ogLive client" * ), * @OA\Property( * property="kernel", * type="string", * description="Kernel version of the default ogLive client" * ), * @OA\Property( * property="architecture", * type="string", * description="Architecture of the default ogLive client" * ), * @OA\Property( * property="revision", * type="string", * description="Revision of the default ogLive client" * ), * @OA\Property( * property="directory", * type="string", * description="Directory name of the default ogLive client" * ), * @OA\Property( * property="iso", * type="string", * description="ISO file name of the default ogLive client" * ) * ) * ), * @OA\Response( * response=500, * description="Failed to retrieve information of the default ogLive client" * ) * ) */ public function getOgliveDefault(Request $request): Response { $result = $this->curlRequestService->callOgLive("get_default"); if (is_array($result) && isset($result['error'])) { return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } return new JsonResponse($result, Response::HTTP_OK); } /** * @Route("/ogboot/v1/oglives/{checksum}", name="getOglive", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/oglives/{checksum}", * summary="Get information of an installed ogLive client", * @OA\Parameter( * name="checksum", * in="path", * description="Checksum of the installed ogLive client", * required=true, * @OA\Schema( * type="string", * example="9e49a085ba74f97a81bdf9b3d0785094" * ) * ), * @OA\Response( * response=200, * description="Successful operation", * @OA\JsonContent( * type="object", * @OA\Property( * property="distribution", * type="string", * description="Distribution name of the installed ogLive client" * ), * @OA\Property( * property="kernel", * type="string", * description="Kernel version of the installed ogLive client" * ), * @OA\Property( * property="architecture", * type="string", * description="Architecture of the installed ogLive client" * ), * @OA\Property( * property="revision", * type="string", * description="Revision of the installed ogLive client" * ), * @OA\Property( * property="directory", * type="string", * description="Directory name of the installed ogLive client" * ), * @OA\Property( * property="iso", * type="string", * description="ISO file name of the installed ogLive client" * ) * ) * ), * @OA\Response( * response=404, * description="ogLive client not found" * ) * ) */ public function getOglive(string $checksum): Response { $result = $this->curlRequestService->callOgLive("get_info " . escapeshellarg($checksum)); if (is_array($result) && isset($result['error'])) { return new JsonResponse(['error' => $result['error']], Response::HTTP_NOT_FOUND); } return new JsonResponse($result, Response::HTTP_OK); } /** * @Route("/ogboot/v1/oglives/default", name="setOgliveDefault", methods={"POST"}) * @OA\Post( * path="/ogboot/v1/oglives/default", * summary="Set default ogLive client", * @OA\RequestBody( * required=true, * @OA\JsonContent( * type="object", * @OA\Property( * property="checksum", * type="string", * example="9e49a085ba74f97a81bdf9b3d0785094", * description="Checksum of the ogLive client to set as default" * ) * ) * ), * @OA\Response( * response=200, * description="ogLive client set as default successfully", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string") * ) * ), * @OA\Response( * response=404, * description="ogLive client not found" * ), * @OA\Response( * response=500, * description="Failed to set default ogLive client" * ) * ) */ public function setOgliveDefault(Request $request): Response { $data = json_decode($request->getContent(), true); if (!isset($data['checksum'])) { return new JsonResponse(['error' => 'Invalid input data'], Response::HTTP_BAD_REQUEST); } $checksum = $data['checksum']; // Establecer el ogLive como predeterminado utilizando el checksum proporcionado $result = $this->curlRequestService->callOgLive("set_default " . escapeshellarg($checksum)); if (is_array($result) && isset($result['error'])) { return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } return new JsonResponse(['message' => 'ogLive client set as default successfully'], Response::HTTP_OK); } /** * @Route("/ogboot/v1/oglives/install", name="installOglive", methods={"POST"}) * @OA\Post( * path="/ogboot/v1/oglives/install", * summary="Install an ogLive client", * @OA\RequestBody( * required=true, * @OA\JsonContent( * type="object", * @OA\Property( * property="isoname", * type="string", * example="ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso", * description="Name of the ogLive ISO to install" * ) * ) * ), * @OA\Response( * response=200, * description="ogLive client installed successfully", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string"), * @OA\Property(property="details", type="object") * ) * ), * @OA\Response( * response=400, * description="Invalid input data" * ), * @OA\Response( * response=500, * description="Failed to install ogLive client", * @OA\JsonContent( * type="object", * @OA\Property(property="error", type="string"), * @OA\Property(property="details", type="string") * ) * ) * ) */ public function installOglive(Request $request): Response { $data = json_decode($request->getContent(), true); if (!isset($data['isoname'])) { return new JsonResponse(['error' => 'Invalid input data'], Response::HTTP_BAD_REQUEST); } $isoname = $data['isoname']; $result = $this->curlRequestService->callOgLive("download " . escapeshellarg($isoname)); if (is_array($result) && isset($result['success']) && $result['success'] === false) { return new JsonResponse(['error' => 'Failed to install ogLive client', 'details' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } return new JsonResponse(['message' => 'ogLive client installed successfully', 'details' => $result], Response::HTTP_OK); } /** * @Route("/ogboot/v1/oglives/{checksum}", name="uninstallOglive", methods={"DELETE"}) * @OA\Delete( * path="/ogboot/v1/oglives/{checksum}", * summary="Uninstall an ogLive client", * @OA\Parameter( * name="checksum", * in="path", * description="Checksum of the ogLive client to uninstall", * required=true, * @OA\Schema(type="string", example="9e49a085ba74f97a81bdf9b3d0785094") * ), * @OA\Response( * response=200, * description="ogLive client uninstalled successfully", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string"), * @OA\Property(property="details", type="string") * ) * ), * @OA\Response( * response=404, * description="ogLive client not found" * ), * @OA\Response( * response=500, * description="Failed to uninstall ogLive client", * @OA\JsonContent( * type="object", * @OA\Property(property="error", type="string") * ) * ) * ) */ public function uninstallOglive(string $checksum): Response { // Llamada al servicio para desinstalar el cliente ogLive error_log("Calling curlRequestService with checksum: $checksum"); $result = $this->curlRequestService->callOgLive("uninstall " . escapeshellarg($checksum)); // Verificar la respuesta del servicio error_log("Service call result: " . print_r($result, true)); if (is_array($result) && isset($result['error'])) { // Error encontrado en la respuesta error_log("Error found in response: " . $result['error']); return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } elseif (is_array($result) && isset($result['message'])) { // Respuesta exitosa error_log("Success response: " . print_r($result, true)); return new JsonResponse([ 'message' => $result['message'], 'details' => $result['details'] ?? '' ], Response::HTTP_OK); } else { // Manejar el caso en que no se recibió una respuesta válida del servicio error_log("Failed to uninstall ogLive client, empty result from service"); return new JsonResponse(['error' => 'Failed to uninstall ogLive client'], Response::HTTP_INTERNAL_SERVER_ERROR); } } /** * @Route("/ogboot/v1/pxes", name="get_boot_files", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/pxes", * summary="Get all PXE boot files", * @OA\Response( * response=200, * description="Successful operation", * @OA\JsonContent( * type="object", * @OA\Property( * property="boot_files", * type="array", * @OA\Items( * type="string", * description="Boot file" * ) * ) * ) * ), * @OA\Response( * response=500, * description="Failed to retrieve boot files" * ) * ) */ public function getBootFiles(): JsonResponse { $directory = '/opt/ogboot/tftpboot/ipxe_scripts'; $files = scandir($directory); $bootFiles = array_filter($files, function ($file) use ($directory) { return !is_dir($directory . '/' . $file) && strpos($file, '01-') === 0; }); $response = [ 'boot_files' => array_values($bootFiles) ]; return new JsonResponse($response, Response::HTTP_OK); } /** * @Route("/ogboot/v1/pxes/{mac}", name="ogboot_get_boot_file_with_params", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/pxes/{mac}", * summary="Get boot file with parameters", * @OA\Parameter( * name="mac", * in="path", * description="MAC address", * required=true, * @OA\Schema(type="string", example="00:50:56:22:11:12") * ), * @OA\Response( * response=200, * description="Successful operation", * @OA\JsonContent( * type="object", * @OA\Property(property="template_name", type="string", description="Template name", example="pxe"), * @OA\Property(property="mac", type="string", description="MAC address", example="00:50:56:22:11:12"), * @OA\Property(property="lang", type="string", description="Language", example="es_ES.UTF-8"), * @OA\Property(property="ip", type="string", description="IP address", example="192.168.2.11"), * @OA\Property(property="server_ip", type="string", description="Server IP address", example="192.168.2.1"), * @OA\Property(property="router", type="string", description="Router", example="192.168.2.1"), * @OA\Property(property="netmask", type="string", description="Netmask", example="255.255.255.0"), * @OA\Property(property="computer_name", type="string", description="Computer name", example="pc11"), * @OA\Property(property="netiface", type="string", description="Network interface", example="eth0"), * @OA\Property(property="group", type="string", description="Group", example="Aula_virtual"), * @OA\Property(property="ogrepo", type="string", description="Repository IP", example="192.168.2.1"), * @OA\Property(property="oglive", type="string", description="Live server IP", example="192.168.2.1"), * @OA\Property(property="oglog", type="string", description="Log server IP", example="192.168.2.1"), * @OA\Property(property="ogshare", type="string", description="Share server IP", example="192.168.2.1"), * @OA\Property(property="oglivedir", type="string", description="Live directory", example="ogLive"), * @OA\Property(property="ogprof", type="string", description="Is professor", example="false"), * @OA\Property(property="hardprofile", type="string", description="Hardware profile", example=""), * @OA\Property(property="ogntp", type="string", description="NTP server", example=""), * @OA\Property(property="ogdns", type="string", description="DNS server", example=""), * @OA\Property(property="ogproxy", type="string", description="Proxy server", example=""), * @OA\Property(property="ogunit", type="string", description="Unit directory", example=""), * @OA\Property(property="resolution", type="string", description="Screen resolution", example="788") * ) * ), * @OA\Response( * response=500, * description="Failed to retrieve boot file" * ) * ) */ public function getBootFile(string $mac): Response { // Ruta donde están alojados los archivos de arranque $directory = '/opt/ogboot/tftpboot/ipxe_scripts'; // Genera el nombre del archivo basado en la dirección MAC $fileName = "01-" . $mac; $filePath = "$directory/$fileName"; if (!file_exists($filePath)) { return new JsonResponse(['error' => 'No se encontró ningún archivo de arranque con la dirección MAC especificada'], Response::HTTP_NOT_FOUND); } $content = file_get_contents($filePath); $templateName = ''; $contentLines = explode("\n", $content); foreach ($contentLines as $line) { if (strpos($line, '#template_name:') !== false) { $templateName = trim(str_replace('#template_name:', '', $line)); break; } } // Extraer los parámetros del contenido del archivo iPXE preg_match('/set kernelargs (.*)/', $content, $matches); if (isset($matches[1])) { $kernelargs = $matches[1]; parse_str(str_replace(' ', '&', $kernelargs), $params); $result = [ 'template_name' => $templateName, 'mac' => $mac, 'lang' => $params['LANG'] ?? '', 'ip' => explode(':', $params['ip'])[0] ?? '', 'server_ip' => explode(':', $params['ip'])[1] ?? '', 'router' => explode(':', $params['ip'])[2] ?? '', 'netmask' => explode(':', $params['ip'])[3] ?? '', 'computer_name' => explode(':', $params['ip'])[4] ?? '', 'netiface' => explode(':', $params['ip'])[5] ?? '', 'group' => $params['group'] ?? '', 'ogrepo' => $params['ogrepo'] ?? '', 'oglive' => $params['oglive'] ?? '', 'oglog' => $params['oglog'] ?? '', 'ogshare' => $params['ogshare'] ?? '', 'oglivedir' => $params['oglivedir'] ?? '', 'ogprof' => $params['ogprof'] ?? '', 'hardprofile' => $params['hardprofile'] ?? '', 'ogntp' => $params['ogntp'] ?? '', 'ogdns' => $params['ogdns'] ?? '', 'ogproxy' => $params['ogproxy'] ?? '', 'ogunit' => $params['ogunit'] ?? '', 'resolution' => $params['vga'] ?? '', ]; return new JsonResponse($result, Response::HTTP_OK); } return new JsonResponse(['error' => 'Failed to parse kernel arguments from the boot file'], Response::HTTP_INTERNAL_SERVER_ERROR); } /** * @Route("/ogboot/v1/pxes", name="create_boot_file", methods={"POST"}) * @OA\Post( * path="/ogboot/v1/pxes", * summary="Create a new PXE boot file", * @OA\RequestBody( * required=true, * @OA\JsonContent( * type="object", * @OA\Property(property="template_name", type="string", description="Template name", example="pxe"), * @OA\Property(property="mac", type="string", description="MAC address", example="00:50:56:22:11:12"), * @OA\Property(property="lang", type="string", description="Language", example="es_ES.UTF-8"), * @OA\Property(property="ip", type="string", description="IP address", example="192.168.2.11"), * @OA\Property(property="server_ip", type="string", description="Server IP address", example="192.168.2.1"), * @OA\Property(property="router", type="string", description="Router", example="192.168.2.1"), * @OA\Property(property="netmask", type="string", description="Netmask", example="255.255.255.0"), * @OA\Property(property="computer_name", type="string", description="Computer name", example="pc11"), * @OA\Property(property="netiface", type="string", description="Network interface", example="eth0"), * @OA\Property(property="group", type="string", description="Group", example="Aula_virtual"), * @OA\Property(property="ogrepo", type="string", description="Repository IP", example="192.168.2.1"), * @OA\Property(property="oglive", type="string", description="Live server IP", example="192.168.2.1"), * @OA\Property(property="oglog", type="string", description="Log server IP", example="192.168.2.1"), * @OA\Property(property="ogshare", type="string", description="Share server IP", example="192.168.2.1"), * @OA\Property(property="oglivedir", type="string", description="Live directory", example="ogLive"), * @OA\Property(property="ogprof", type="string", description="Is professor", example="false"), * @OA\Property(property="hardprofile", type="string", description="Hardware profile", example=""), * @OA\Property(property="ogntp", type="string", description="NTP server", example=""), * @OA\Property(property="ogdns", type="string", description="DNS server", example=""), * @OA\Property(property="ogproxy", type="string", description="Proxy server", example=""), * @OA\Property(property="ogunit", type="string", description="Unit directory", example=""), * @OA\Property(property="resolution", type="string", description="Screen resolution", example="788") * ) * ), * @OA\Response( * response=200, * description="PXE boot file created successfully", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string") * ) * ), * @OA\Response( * response=400, * description="Invalid input" * ), * @OA\Response( * response=404, * description="Template not found" * ), * @OA\Response( * response=500, * description="Internal server error" * ) * ) */ public function createBootFile(Request $request): JsonResponse { $data = json_decode($request->getContent(), true); $templateName = $data['template_name'] ?? null; $mac = $data['mac'] ?? null; $serverIp = $data['server_ip'] ?? null; $ogLiveDir = $data['oglivedir'] ?? 'ogLive'; if (!$templateName || !$mac || !$serverIp) { return new JsonResponse(['error' => 'Invalid input'], 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' => $data['ogrepo'] ?? '', 'oglive' => $data['oglive'] ?? $serverIp, 'oglog' => $data['oglog'] ?? $serverIp, 'ogshare' => $data['ogshare'] ?? $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 = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; $templatePath = $templateDir . '/' . $templateName; if (!file_exists($templatePath)) { return new JsonResponse(['error' => 'Template not found'], Response::HTTP_NOT_FOUND); } $templateContent = file_get_contents($templatePath); if ($templateContent === false) { return new JsonResponse(['error' => 'Failed to read template'], Response::HTTP_INTERNAL_SERVER_ERROR); } $kernelArgs = 'ro boot=oginit quiet splash irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=true ogdebug=true ogtmpfs=15 ' . 'oglivedir=' . $parameters['oglivedir'] . ' ' . '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'] . ' ' . 'oglive=' . $serverIp . ' ' . 'oglog=' . $serverIp . ' ' . 'ogshare=' . $serverIp . ' ' . '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'])); $pxeContent = str_replace(['__INFOHOST__', '__SERVERIP__', '__OGLIVE__'], [$kernelArgs, $serverIp, $ogLiveDir], $templateContent); $pxeFileName = '01-' . $mac; $pxeFilePath = '/opt/ogboot/tftpboot/ipxe_scripts/' . $pxeFileName; if (file_put_contents($pxeFilePath, $pxeContent) === false) { return new JsonResponse(['error' => 'Failed to create PXE boot file'], Response::HTTP_INTERNAL_SERVER_ERROR); } return new JsonResponse(['message' => 'PXE boot file created successfully'], Response::HTTP_OK); } /** * @Route("/ogboot/v1/pxes/{mac}", name="ogboot_delete_boot_file", methods={"DELETE"}) * @OA\Delete( * path="/ogboot/v1/pxes/{mac}", * summary="Eliminar archivo de arranque", * description="Elimina un archivo de arranque específico utilizando su dirección MAC.", * @OA\Parameter( * name="mac", * in="path", * description="La dirección MAC del cliente cuyo archivo de arranque se desea eliminar", * required=true, * @OA\Schema(type="string", example="00:11:22:33:44:55") * ), * @OA\Response( * response=200, * description="El archivo de arranque se eliminó correctamente", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string", example="El archivo de arranque se eliminó correctamente") * ) * ), * @OA\Response( * response=404, * description="No se encontró ningún archivo de arranque con la dirección MAC especificada", * @OA\JsonContent( * type="object", * @OA\Property(property="error", type="string", example="No se encontró ningún archivo de arranque con la dirección MAC especificada") * ) * ), * @OA\Response( * response=500, * description="Error al eliminar el archivo de arranque", * @OA\JsonContent( * type="object", * @OA\Property(property="error", type="string", example="Error al eliminar el archivo de arranque") * ) * ) * ) */ public function deleteBootFile(string $mac): Response { $directory = '/opt/ogboot/tftpboot/ipxe_scripts'; $fileName = "01-" . $mac; $filePath = "$directory/$fileName"; if (!file_exists($filePath)) { return new JsonResponse(['error' => 'No se encontró ningún archivo de arranque con la dirección MAC especificada'], Response::HTTP_NOT_FOUND); } if (!unlink($filePath)) { return new JsonResponse(['error' => 'Error al eliminar el archivo de arranque'], Response::HTTP_INTERNAL_SERVER_ERROR); } return new JsonResponse(['message' => 'El archivo de arranque se eliminó correctamente'], Response::HTTP_OK); } /** * @Route("/ogboot/v1/pxe-templates", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/pxe-templates", * summary="Obtener todas las plantillas PXE", * description="Obtiene una lista de todas las plantillas de arranque PXE disponibles.", * @OA\Response( * response=200, * description="Lista de plantillas de arranque PXE", * @OA\JsonContent( * type="object", * @OA\Property( * property="templates", * type="array", * @OA\Items(type="string", example="mi_plantilla.ipxe") * ) * ) * ), * @OA\Response( * response=500, * description="Error interno del servidor" * ) * ) */ public function getAllTemplates(): JsonResponse { $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; // Verificar si el directorio existe if (!is_dir($templateDir)) { return new JsonResponse(['error' => 'Directorio de plantillas no encontrado'], Response::HTTP_INTERNAL_SERVER_ERROR); } // 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); }); return new JsonResponse(['templates' => array_values($templates)], Response::HTTP_OK); } /** * @Route("/ogboot/v1/pxe-templates/{templateName}", name="get_template", methods={"GET"}) * @OA\Get( * path="/ogboot/v1/pxe-templates/{templateName}", * summary="Obtener contenido de una plantilla PXE", * description="Obtiene el contenido de una plantilla de arranque PXE específica por su nombre.", * @OA\Parameter( * name="templateName", * in="path", * required=true, * description="Nombre de la plantilla PXE", * @OA\Schema(type="string", example="mi_plantilla.ipxe") * ), * @OA\Response( * response=200, * description="Contenido de la plantilla de arranque PXE", * @OA\MediaType( * mediaType="text/plain", * @OA\Schema(type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR ogLive\nset default 0\nset kernelargs INFOHOST\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\nboot") * ) * ), * @OA\Response( * response=404, * description="Plantilla no encontrada" * ), * @OA\Response( * response=500, * description="Error interno del servidor" * ) * ) */ public function getTemplate(string $templateName): Response { $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; $filePath = "$templateDir/$templateName"; if (!file_exists($filePath)) { return new Response(null, Response::HTTP_NOT_FOUND); } $content = file_get_contents($filePath); if ($content === false) { return new Response('Error al leer la plantilla', Response::HTTP_INTERNAL_SERVER_ERROR); } return new Response($content, Response::HTTP_OK, ['Content-Type' => 'text/plain']); } /** * @Route("/ogboot/v1/pxe-templates", methods={"POST"}) * * @OA\Post( * path="/ogboot/v1/pxe-templates", * summary="Crear Plantilla", * description="Crea una nueva plantilla de arranque utilizando los datos proporcionados.", * @OA\RequestBody( * required=true, * @OA\JsonContent( * type="object", * @OA\Property(property="name_template", type="string", example="pxe"), * @OA\Property(property="content_template", type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR ogLive\nset default 0\nset kernelargs INFOHOST\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\nboot") * ) * ), * @OA\Response( * response=200, * description="La plantilla de arranque se creó exitosamente.", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string", example="Plantilla creada exitosamente."), * @OA\Property(property="template", type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR ogLive\nset default 0\nset kernelargs INFOHOST\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\nboot") * ) * ), * @OA\Response( * response=400, * description="La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud." * ), * @OA\Response( * response=500, * description="Ocurrió un error al crear la plantilla de arranque." * ) * ) */ public function createTemplate(Request $request) { $data = json_decode($request->getContent(), true); if (!isset($data['name_template']) || !isset($data['content_template'])) { return new Response('La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud.', 400); } $nameTemplate = $data['name_template']; $contentTemplate = $data['content_template']; $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; if (!preg_match('/^[a-zA-Z0-9._-]+$/', $nameTemplate)) { return new Response('Nombre de la plantilla no válido.', 400); } $filePath = $templateDir . '/' . $nameTemplate; $contentTemplate = str_replace("\\n", "\n", $contentTemplate); try { file_put_contents($filePath, $contentTemplate); } catch (\Exception $e) { return new Response('Ocurrió un error al crear la plantilla de arranque.', 500); } return new Response(json_encode([ 'message' => 'Plantilla creada exitosamente.', 'template' => $contentTemplate ]), 200, ['Content-Type' => 'application/json']); } /** * @Route("/ogboot/v1/pxe-templates/{name}", methods={"DELETE"}) * * @OA\Delete( * path="/ogboot/v1/pxe-templates/{name}", * summary="Eliminar Plantilla", * description="Elimina una plantilla de arranque específica utilizando su nombre.", * @OA\Parameter( * name="name", * in="path", * required=true, * description="El nombre de la plantilla de arranque que se desea eliminar.", * @OA\Schema(type="string") * ), * @OA\Response( * response=200, * description="La plantilla de arranque se eliminó correctamente.", * @OA\JsonContent( * type="object", * @OA\Property(property="message", type="string", example="Plantilla eliminada correctamente.") * ) * ), * @OA\Response( * response=404, * description="No se encontró ninguna plantilla de arranque con el nombre especificado." * ), * @OA\Response( * response=500, * description="Ocurrió un error al eliminar la plantilla de arranque." * ) * ) */ public function deleteTemplate($name) { $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; $filePath = $templateDir . '/' . $name; if (!file_exists($filePath)) { return new Response('No se encontró ninguna plantilla de arranque con el nombre especificado.', 404); } try { unlink($filePath); } catch (\Exception $e) { return new Response('Ocurrió un error al eliminar la plantilla de arranque.', 500); } return new Response(json_encode([ 'message' => 'Plantilla eliminada correctamente.' ]), 200, ['Content-Type' => 'application/json']); } }