refs #949 #943 #969 fix Command output return, add Command in the services.yaml, adds url to the oglives downloables
parent
21409e850b
commit
8264459a6b
|
@ -205,13 +205,14 @@ function downloadMenu() {
|
|||
fi
|
||||
ISOREL=${OGLIVE[i-1]##*-r}; ISOREL=${ISOREL%%.*}
|
||||
[ $ISOREL -ge $MINREL ] && compatible=true
|
||||
|
||||
url="$DOWNLOADURL/${OGLIVE[i-1]}"
|
||||
local DATA=$(jq -n \
|
||||
--arg id "$i" \
|
||||
--arg filename "${OGLIVE[i-1]}" \
|
||||
--arg url "$url" \
|
||||
--argjson installed "$installed" \
|
||||
--argjson compatible "$compatible" \
|
||||
'{id: $id, filename: $filename, installed: $installed, compatible: $compatible}')
|
||||
'{id: $id, filename: $filename, url: $url, installed: $installed, compatible: $compatible}')
|
||||
|
||||
downloads+=("$DATA")
|
||||
done
|
||||
|
|
|
@ -26,5 +26,5 @@ services:
|
|||
resource: '../src/OgBootBundle/Controller'
|
||||
tags: ['controller.service_arguments']
|
||||
# Register the OgLiveInstallCommand explicitly to ensure it's detected
|
||||
OgBootBundle\Command\OgLiveInstallCommand:
|
||||
App\OgBootBundle\Command\OgLiveInstallCommand:
|
||||
tags: ['console.command']
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
namespace App\OgBootBundle\Command;
|
||||
use App\OgBootBundle\Service\CurlRequestService;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class OgLiveInstallCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'oglive:install';
|
||||
private $curlRequestService;
|
||||
private $httpClient;
|
||||
private $params;
|
||||
private $logger;
|
||||
|
||||
public function __construct(CurlRequestService $curlRequestService, HttpClientInterface $httpClient, ParameterBagInterface $params, LoggerInterface $logger)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->curlRequestService = $curlRequestService;
|
||||
#$this->httpClient = $httpClient;
|
||||
$this->httpClient = HttpClient::create([
|
||||
'verify_peer' => false, // Ignorar la verificación del certificado SSL
|
||||
'verify_host' => false, // Ignorar la verificación del nombre del host
|
||||
]);
|
||||
$this->params = $params;
|
||||
$this->logger = $logger; // Añadimos el logger
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setDescription('Instala un ogLive en segundo plano')
|
||||
->addArgument('isoUrl', InputArgument::REQUIRED, 'URL del ISO de ogLive')
|
||||
->addArgument('transactionId', InputArgument::REQUIRED, 'ID de la transacción');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
ini_set('max_execution_time', '3000');
|
||||
$isoUrl = $input->getArgument('isoUrl');
|
||||
|
||||
$transactionId = $input->getArgument('transactionId');
|
||||
|
||||
// Iniciamos los logs para rastrear el proceso
|
||||
$this->logger->info('Starting ogLive installation', ['transactionId' => $transactionId]);
|
||||
|
||||
try {
|
||||
// Log: comenzando la descarga del ISO
|
||||
$this->logger->info('Starting download', ['isoUrl' => $isoUrl]);
|
||||
|
||||
// Llamar al servicio para iniciar la instalación
|
||||
$installResult = $this->curlRequestService->callOgLive("download " . escapeshellarg($isoUrl));
|
||||
|
||||
// Log: descarga finalizada
|
||||
$this->logger->info('Download finished', ['transactionId' => $transactionId, 'installResult' => $installResult]);
|
||||
|
||||
// Verificar el resultado de la instalación basado en el output del comando
|
||||
$status = 'success';
|
||||
$messageText = 'ogLive client installed successfully';
|
||||
$exitCode = $installResult['exitCode'];
|
||||
|
||||
if (isset($installResult['output']['error'])) {
|
||||
// Si hay un error, asignar el estado y mensaje adecuado
|
||||
$status = $installResult['output']['error'];
|
||||
$messageText = $installResult['output']['message'];
|
||||
|
||||
// Log: la instalación falló
|
||||
$this->logger->error('Installation failed', ['transactionId' => $transactionId, 'error' => $messageText]);
|
||||
} elseif ($installResult['exitCode'] !== 0) {
|
||||
// Si hubo un exitCode distinto de 0, manejar como error desconocido
|
||||
$status = 'UNKNOWN_ERROR';
|
||||
$messageText = 'An unknown error occurred during the installation process.';
|
||||
$this->logger->error('Unknown installation error', ['transactionId' => $transactionId, 'exitCode' => $installResult['exitCode']]);
|
||||
} else {
|
||||
// Log: instalación completada con éxito
|
||||
$messageText = $installResult['output']['message'];
|
||||
$this->logger->info('Installation completed successfully', ['transactionId' => $transactionId]);
|
||||
}
|
||||
|
||||
// Preparar los datos para el webhook según el resultado
|
||||
$webhookData = [
|
||||
'ogCoreId' => $transactionId,
|
||||
'status' => $status,
|
||||
'code' => ($exitCode === 0) ? 200 : $exitCode, // Cambiar a 200 si es éxito
|
||||
'message' => $messageText ,
|
||||
];
|
||||
|
||||
$this->logger->info('Installation completed with details', ['installResult' => $installResult]);
|
||||
$this->logger->info('Webhook data to be sent: ', ['webhookData' => $webhookData]);
|
||||
|
||||
// Obtener la URL del webhook desde el archivo .env
|
||||
$webhookUrl = "https://172.17.8.90:8443/og-lives/install/webhook";
|
||||
|
||||
// Log: enviando datos al webhook
|
||||
$this->logger->info('Sending data to webhook', ['webhookUrl' => $webhookUrl, 'webhookData' => $webhookData]);
|
||||
|
||||
// Llamar al webhook para notificar el resultado
|
||||
$this->notifyWebhook($webhookUrl, $webhookData);
|
||||
$this->logger->info('Notify webhook con exito');
|
||||
// Log: notificación al webhook finalizada
|
||||
$this->logger->info('Webhook notification sent', ['transactionId' => $transactionId]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Log: error en la instalación
|
||||
$this->logger->error('Failed to complete ogLive installation', ['transactionId' => $transactionId, 'exception' => $e->getMessage()]);
|
||||
|
||||
// Manejar errores y enviar notificación de fallo al webhook
|
||||
$webhookData = [
|
||||
'ogCoreId' => $transactionId,
|
||||
'status' => 'failure',
|
||||
'code' => 500,
|
||||
'message' => $e->getMessage()
|
||||
];
|
||||
|
||||
$webhookUrl = "https://172.17.8.90:8443/og-lives/install/webhook";
|
||||
$this->notifyWebhook($webhookUrl, $webhookData);
|
||||
$this->logger->info('Notify webhook terminado con errores');
|
||||
// Log: notificación de error enviada al webhook
|
||||
$this->logger->info('Failure notification sent to webhook', ['transactionId' => $transactionId]);
|
||||
}
|
||||
|
||||
// Log: proceso de instalación terminado
|
||||
$this->logger->info('Installation process ended', ['transactionId' => $transactionId]);
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar el resultado al webhook
|
||||
*/
|
||||
private function notifyWebhook(string $webhookUrl, array $webhookData): void
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Enter notify webhook');
|
||||
$this->logger->info('Data to be sent', ['webhookData' => $webhookData]);
|
||||
$this->httpClient->request('POST', $webhookUrl, [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => json_encode(['webhookData' => $webhookData]),
|
||||
]);
|
||||
|
||||
// Log: éxito al enviar la notificación
|
||||
$this->logger->info('Webhook data sent successfully', ['webhookUrl' => $webhookUrl, 'webhookData' => $webhookData]);
|
||||
} catch (Exception $e) {
|
||||
// Log: error al enviar al webhook
|
||||
$this->logger->error('Error sending webhook notification', ['webhookUrl' => $webhookUrl, 'exception' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,13 +168,15 @@ public function getStatus(): Response
|
|||
);
|
||||
}
|
||||
|
||||
// Formatear la respuesta final con todos los datos
|
||||
$response = [
|
||||
'success' => 'Status retrieved successfully',
|
||||
'message' => [
|
||||
'disk_usage' => $diskUsageResult,
|
||||
'default_oglive' => $defaultOglive,
|
||||
'installed_oglives' => $installedOglives,
|
||||
'services_status' => $servicesStatusResult
|
||||
];
|
||||
]
|
||||
]; // Formatear la respuesta final con todos los datos
|
||||
|
||||
return new JsonResponse($response, Response::HTTP_OK);
|
||||
}
|
||||
|
@ -319,7 +321,6 @@ public function getOglives(): Response
|
|||
return new JsonResponse($response, Response::HTTP_OK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Route("/ogboot/v1/oglives/default", name="getOgliveDefault", methods={"GET"})
|
||||
* @OA\Get(
|
||||
|
@ -330,27 +331,41 @@ public function getOglives(): Response
|
|||
* description="Successful operation",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="success", type="string", example="Se han obtenido la lista de oglives instalados correctamente"),
|
||||
* @OA\Property(property="success", type="string", example="se ha obtenido el oglive por defecto"),
|
||||
* @OA\Property(property="message", ref="#/components/schemas/OgLive")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=500,
|
||||
* description="Failed to retrieve information of the default ogLive client"
|
||||
* description="Failed to retrieve information of the default ogLive client",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="error", type="string", example="SERVER_ERROR"),
|
||||
* @OA\Property(property="message", type="string", example="Failed to retrieve default ogLive.")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function getOgliveDefault(Request $request): Response
|
||||
{
|
||||
$result = $this->curlRequestService->callOgLive("get_default");
|
||||
$response = $this->curlRequestService->callOgLive("get_default");
|
||||
$result = $response['output'];
|
||||
$exitCode = $response['exitCode'];
|
||||
|
||||
if (is_array($result) && isset($result['error'])) {
|
||||
return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
// Verificar si hay un error basado en el código de salida
|
||||
if ($exitCode !== 0) {
|
||||
return new JsonResponse(
|
||||
['error' => 'SERVER_ERROR', 'message' => $result['error'] ?? 'Failed to retrieve default ogLive.'],
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return new JsonResponse($result, Response::HTTP_OK);
|
||||
// Devolver la respuesta en el formato solicitado
|
||||
return new JsonResponse(
|
||||
['success' => 'se ha obtenido el oglive por defecto', 'message' => $result],
|
||||
Response::HTTP_OK
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/ogboot/v1/oglives/{checksum}", name="getOglive", methods={"GET"})
|
||||
* @OA\Get(
|
||||
|
@ -368,32 +383,61 @@ public function getOgliveDefault(Request $request): Response
|
|||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Successful operation",
|
||||
* description="ogLive client retrieved successfully",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="success", type="string", example="Se han obtenido la lista de oglives instalados correctamente"),
|
||||
* @OA\Property(property="success", type="string", example="ogLive client retrieved successfully"),
|
||||
* @OA\Property(property="message", ref="#/components/schemas/OgLive")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=404,
|
||||
* description="ogLive client not found"
|
||||
* description="ogLive client not found",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="error", type="string", example="NOT_FOUND"),
|
||||
* @OA\Property(property="message", type="string", example="ogLive client with checksum 9e49a085ba74f97a81bdf9b3d0785094 not found.")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=500,
|
||||
* description="Failed to retrieve ogLive client",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="error", type="string", example="SERVER_ERROR"),
|
||||
* @OA\Property(property="message", type="string", example="Failed to retrieve ogLive client.")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function getOglive(string $checksum): Response
|
||||
{
|
||||
$result = $this->curlRequestService->callOgLive("get_info " . escapeshellarg($checksum));
|
||||
// Llamar al servicio ogLive para obtener la información del ogLive correspondiente al checksum proporcionado
|
||||
$response = $this->curlRequestService->callOgLive("get_info " . escapeshellarg($checksum));
|
||||
$result = $response['output'];
|
||||
$exitCode = $response['exitCode'];
|
||||
|
||||
if (is_array($result) && isset($result['error'])) {
|
||||
return new JsonResponse(['error' => $result['error']], Response::HTTP_NOT_FOUND);
|
||||
// Verificar si hay un error basado en el código de salida
|
||||
if ($exitCode === 404) {
|
||||
return new JsonResponse(
|
||||
['error' => 'NOT_FOUND', 'message' => "ogLive client with checksum $checksum not found."],
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
} elseif ($exitCode !== 0) {
|
||||
return new JsonResponse(
|
||||
['error' => 'SERVER_ERROR', 'message' => 'Failed to retrieve ogLive client.'],
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return new JsonResponse($result, Response::HTTP_OK);
|
||||
// Formatear la respuesta de éxito con el ogLive encontrado
|
||||
return new JsonResponse(
|
||||
['success' => 'ogLive client retrieved successfully', 'message' => $result],
|
||||
Response::HTTP_OK
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Route("/ogboot/v1/oglives/default", name="setOgliveDefault", methods={"PUT"})
|
||||
* @OA\Put(
|
||||
|
@ -416,16 +460,27 @@ public function getOglive(string $checksum): Response
|
|||
* description="ogLive client set as default successfully",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="message", type="string")
|
||||
* @OA\Property(property="success", type="string", example="ogLive client set as default successfully"),
|
||||
* @OA\Property(property="message", ref="#/components/schemas/OgLive")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=404,
|
||||
* description="ogLive client not found"
|
||||
* response=400,
|
||||
* description="Invalid input data",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="error", type="string", example="INVALID_INPUT"),
|
||||
* @OA\Property(property="message", type="string", example="Invalid input data: checksum is required.")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=500,
|
||||
* description="Failed to set default ogLive client"
|
||||
* description="Failed to set default ogLive client",
|
||||
* @OA\JsonContent(
|
||||
* type="object",
|
||||
* @OA\Property(property="error", type="string", example="SERVER_ERROR"),
|
||||
* @OA\Property(property="message", type="string", example="Failed to set ogLive as default.")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
|
@ -433,20 +488,34 @@ public function setOgliveDefault(Request $request): Response
|
|||
{
|
||||
$data = json_decode($request->getContent(), true);
|
||||
|
||||
// Validar que el checksum está presente en los datos de entrada
|
||||
if (!isset($data['checksum'])) {
|
||||
return new JsonResponse(['error' => 'Invalid input data'], Response::HTTP_BAD_REQUEST);
|
||||
return new JsonResponse(
|
||||
['error' => 'INVALID_INPUT', 'message' => 'Invalid input data: checksum is required.'],
|
||||
Response::HTTP_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$checksum = $data['checksum'];
|
||||
|
||||
// Establecer el ogLive como predeterminado utilizando el checksum proporcionado
|
||||
$result = $this->curlRequestService->callOgLive("set_default " . escapeshellarg($checksum));
|
||||
// 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'];
|
||||
|
||||
if (is_array($result) && isset($result['error'])) {
|
||||
return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
// Verificar si hay un error basado en el código de salida
|
||||
if ($exitCode !== 0) {
|
||||
return new JsonResponse(
|
||||
['error' => 'SERVER_ERROR', 'message' => $result['error'] ?? 'Failed to set ogLive as default.'],
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return new JsonResponse(['message' => 'ogLive client set as default successfully'], Response::HTTP_OK);
|
||||
// Devolver la respuesta en el formato solicitado
|
||||
return new JsonResponse(
|
||||
['success' => 'ogLive client set as default successfully', 'message' => $result],
|
||||
Response::HTTP_OK
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -502,8 +571,8 @@ public function setOgliveDefault(Request $request): Response
|
|||
* )
|
||||
*/
|
||||
|
||||
public function installOglive(Request $request): JsonResponse
|
||||
{
|
||||
public function installOglive(Request $request): JsonResponse
|
||||
{
|
||||
// Obtener los datos del cuerpo de la petición
|
||||
$data = json_decode($request->getContent(), true);
|
||||
|
||||
|
@ -520,19 +589,28 @@ public function installOglive(Request $request): JsonResponse
|
|||
$consolePath = $this->params->get('kernel.project_dir') . '/bin/console';
|
||||
$this->logger->info($consolePath);
|
||||
$process = new Process([
|
||||
'php',
|
||||
$consolePath,
|
||||
'oglive:install',
|
||||
$isoUrl, // Sin escapeshellarg
|
||||
$transactionId // Sin escapeshellarg,
|
||||
]);
|
||||
$command = sprintf(
|
||||
'php %s oglive:install %s %s > /dev/null 2>&1 ',
|
||||
escapeshellarg($consolePath),
|
||||
escapeshellarg($isoUrl),
|
||||
escapeshellarg($transactionId)
|
||||
);
|
||||
$commandLine = $process->getCommandLine();
|
||||
$this->logger->info('Command to be executed: ' . $commandLine);
|
||||
$process = Process::fromShellCommandline($command);
|
||||
#$process->start(); // Ejecuta en segundo plano
|
||||
$process->setTimeout(null);
|
||||
$process->disableOutput();
|
||||
try {
|
||||
$process->start();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error starting process: ' . $e->getMessage());
|
||||
}
|
||||
return new JsonResponse([
|
||||
'success' => 'ogLive client installation started',
|
||||
'transaction_id' => $transactionId
|
||||
|
@ -545,7 +623,8 @@ public function installOglive(Request $request): JsonResponse
|
|||
'details' => $e->getMessage()
|
||||
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar el resultado al webhook
|
||||
*
|
||||
|
@ -619,8 +698,8 @@ public function uninstallOglive(string $checksum): Response
|
|||
$exitCode = $response['exitCode'];
|
||||
|
||||
// Verificar la respuesta del servicio según el código de salida
|
||||
error_log("Service call result: " . print_r($result, true));
|
||||
error_log("Exit code: " . $exitCode);
|
||||
$this->logger->info("Service call result: " . print_r($result, true));
|
||||
$this->logger->info("Exit code: " . $exitCode);
|
||||
|
||||
if ($exitCode === 404) {
|
||||
// ogLive client no encontrado
|
||||
|
@ -758,6 +837,7 @@ public function getBootFile(string $mac): Response
|
|||
$directory = '/opt/ogboot/tftpboot/ipxe_scripts';
|
||||
|
||||
// Genera el nombre del archivo basado en la dirección MAC
|
||||
$mac = $this->validateAndFormatMac($mac ?? null);
|
||||
$fileName = "01-" . $mac;
|
||||
|
||||
$filePath = "$directory/$fileName";
|
||||
|
@ -767,21 +847,33 @@ public function getBootFile(string $mac): Response
|
|||
}
|
||||
|
||||
$content = file_get_contents($filePath);
|
||||
$templateName = '';
|
||||
$templateName = 'desconocido'; // Valor por defecto si no se encuentra la plantilla
|
||||
$contentLines = explode("\n", $content);
|
||||
|
||||
// Buscar la plantilla utilizada
|
||||
foreach ($contentLines as $line) {
|
||||
if (strpos($line, '#template_name:') !== false) {
|
||||
$templateName = trim(str_replace('#template_name:', '', $line));
|
||||
if (strpos($line, '#Template:') !== false) {
|
||||
$templateName = trim(str_replace('#Template:', '', $line));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Extraer los parámetros del contenido del archivo iPXE
|
||||
preg_match('/set kernelargs (.*)/', $content, $matches);
|
||||
if (isset($matches[1])) {
|
||||
|
||||
// Si no encontramos 'kernelargs', podría ser un archivo de arranque por disco
|
||||
if (!isset($matches[1])) {
|
||||
return new JsonResponse([
|
||||
'template_name' => $templateName,
|
||||
'mac' => $mac,
|
||||
'message' => 'Archivo de arranque sin parámetros, posiblemente una plantilla de arranque por disco'
|
||||
], Response::HTTP_OK);
|
||||
}
|
||||
|
||||
$kernelargs = $matches[1];
|
||||
parse_str(str_replace(' ', '&', $kernelargs), $params);
|
||||
|
||||
// Crear la estructura del resultado, incluso si los parámetros son opcionales
|
||||
$result = [
|
||||
'template_name' => $templateName,
|
||||
'mac' => $mac,
|
||||
|
@ -808,42 +900,41 @@ public function getBootFile(string $mac): Response
|
|||
];
|
||||
|
||||
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",
|
||||
* description="Creates a PXE boot file based on the provided template and parameters. All parameters except 'template_name' and 'mac' are optional.",
|
||||
* @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\Property(property="template_name", type="string", description="Template name (required)", example="pxe"),
|
||||
* @OA\Property(property="mac", type="string", description="MAC address (required)", example="00:50:56:22:11:12"),
|
||||
* @OA\Property(property="lang", type="string", description="Language (optional)", example="es_ES.UTF-8"),
|
||||
* @OA\Property(property="ip", type="string", description="IP address (optional)", example="192.168.2.11"),
|
||||
* @OA\Property(property="server_ip", type="string", description="Server IP address (optional)", example="192.168.2.1"),
|
||||
* @OA\Property(property="router", type="string", description="Router (optional)", example="192.168.2.1"),
|
||||
* @OA\Property(property="netmask", type="string", description="Netmask (optional)", example="255.255.255.0"),
|
||||
* @OA\Property(property="computer_name", type="string", description="Computer name (optional)", example="pc11"),
|
||||
* @OA\Property(property="netiface", type="string", description="Network interface (optional)", example="eth0"),
|
||||
* @OA\Property(property="group", type="string", description="Group (optional)", example="Aula_virtual"),
|
||||
* @OA\Property(property="ogrepo", type="string", description="Repository IP (optional)", example="192.168.2.1"),
|
||||
* @OA\Property(property="oglive", type="string", description="Live server IP (optional)", example="192.168.2.1"),
|
||||
* @OA\Property(property="oglog", type="string", description="Log server IP (optional)", example="192.168.2.1"),
|
||||
* @OA\Property(property="ogshare", type="string", description="Share server IP (optional)", example="192.168.2.1"),
|
||||
* @OA\Property(property="oglivedir", type="string", description="Live directory (optional)", example="ogLive"),
|
||||
* @OA\Property(property="ogprof", type="string", description="Is professor (optional)", example="false"),
|
||||
* @OA\Property(property="hardprofile", type="string", description="Hardware profile (optional)", example=""),
|
||||
* @OA\Property(property="ogntp", type="string", description="NTP server (optional)", example=""),
|
||||
* @OA\Property(property="ogdns", type="string", description="DNS server (optional)", example=""),
|
||||
* @OA\Property(property="ogproxy", type="string", description="Proxy server (optional)", example=""),
|
||||
* @OA\Property(property="ogunit", type="string", description="Unit directory (optional)", example=""),
|
||||
* @OA\Property(property="resolution", type="string", description="Screen resolution (optional)", example="788")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
|
@ -856,31 +947,64 @@ public function getBootFile(string $mac): Response
|
|||
* ),
|
||||
* @OA\Response(
|
||||
* response=400,
|
||||
* description="Invalid input"
|
||||
* description="Invalid input",
|
||||
* @OA\JsonContent(
|
||||
* oneOf={
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="error", type="string", example="Missing required fields"),
|
||||
* @OA\Property(property="details", type="string", example="MAC and template_name are required")
|
||||
* ),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="error", type="string", example="Invalid MAC address"),
|
||||
* @OA\Property(property="details", type="string", example="MAC address contains invalid characters")
|
||||
* ),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="error", type="string", example="Template not found"),
|
||||
* @OA\Property(property="details", type="string", example="The specified template does not exist")
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=404,
|
||||
* description="Template not found"
|
||||
* description="Template not found",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="error", type="string", example="Template not found")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=500,
|
||||
* description="Internal server error"
|
||||
* description="Internal server error",
|
||||
* @OA\JsonContent(
|
||||
* oneOf={
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="error", type="string", example="Failed to create PXE boot file"),
|
||||
* @OA\Property(property="details", type="string", example="Error writing to file system")
|
||||
* ),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(property="error", type="string", example="Failed to read template"),
|
||||
* @OA\Property(property="details", type="string", example="Could not access the template file")
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function createBootFile(Request $request): JsonResponse
|
||||
{
|
||||
public function createBootFile(Request $request): JsonResponse
|
||||
{
|
||||
$data = json_decode($request->getContent(), true);
|
||||
|
||||
$templateName = $data['template_name'] ?? null;
|
||||
$mac = $data['mac'] ?? null;
|
||||
$mac = $this->validateAndFormatMac($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);
|
||||
// Verificación de los campos obligatorios
|
||||
if (!$templateName || !$mac) {
|
||||
return new JsonResponse(['error' => 'Missing required fields: mac and template_name'], Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Parámetros opcionales
|
||||
$parameters = [
|
||||
'LANG' => $data['lang'] ?? 'es_ES.UTF-8',
|
||||
'ip' => $data['ip'] ?? '',
|
||||
|
@ -906,6 +1030,7 @@ public function getBootFile(string $mac): Response
|
|||
$templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
|
||||
$templatePath = $templateDir . '/' . $templateName;
|
||||
|
||||
// Verificar si la plantilla existe
|
||||
if (!file_exists($templatePath)) {
|
||||
return new JsonResponse(['error' => 'Template not found'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
@ -915,6 +1040,7 @@ public function getBootFile(string $mac): Response
|
|||
return new JsonResponse(['error' => 'Failed to read template'], Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// 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=' . $parameters['oglivedir'] . ' ' .
|
||||
'LANG=' . $parameters['LANG'] . ' ' .
|
||||
|
@ -933,19 +1059,47 @@ public function getBootFile(string $mac): Response
|
|||
(is_numeric($parameters['resolution']) && $parameters['resolution'] <= 999 ? 'vga=' . $parameters['resolution'] :
|
||||
(strpos($parameters['resolution'], ':') !== false ? 'video=' . $parameters['resolution'] : ' ' . $parameters['resolution']));
|
||||
|
||||
// Insertar un comentario al principio del archivo con el nombre de la plantilla usada
|
||||
$pxeContent = "#Template: $templateName\n" .
|
||||
str_replace(['__INFOHOST__', '__SERVERIP__', '__OGLIVE__'], [$kernelArgs, $serverIp, $ogLiveDir], $templateContent);
|
||||
|
||||
$pxeContent = str_replace(['__INFOHOST__', '__SERVERIP__', '__OGLIVE__'], [$kernelArgs, $serverIp, $ogLiveDir], $templateContent);
|
||||
|
||||
|
||||
// Nombre del archivo PXE basado en la MAC
|
||||
$pxeFileName = '01-' . $mac;
|
||||
|
||||
// Ruta para guardar el archivo PXE
|
||||
$pxeFilePath = '/opt/ogboot/tftpboot/ipxe_scripts/' . $pxeFileName;
|
||||
|
||||
// Crear el archivo PXE
|
||||
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);
|
||||
// Retornar la plantilla creada en el formato solicitado
|
||||
return new JsonResponse([
|
||||
'success' => 'Plantilla creada con exito',
|
||||
'message' => $pxeContent
|
||||
], Response::HTTP_OK);
|
||||
}
|
||||
|
||||
|
||||
function validateAndFormatMac($mac)
|
||||
{
|
||||
// Primero, convertir a mayúsculas para facilitar la comparación
|
||||
$mac = strtoupper($mac);
|
||||
|
||||
// Comprobar si la MAC tiene el formato correcto con dos puntos (ej. FC:AA:14:21:55:B9)
|
||||
if (preg_match('/^([0-9A-F]{2}:){5}[0-9A-F]{2}$/', $mac)) {
|
||||
return $mac; // MAC ya está en el formato correcto
|
||||
}
|
||||
|
||||
// Comprobar si la MAC tiene el formato sin los dos puntos (ej. FCAA142155B9)
|
||||
if (preg_match('/^[0-9A-F]{12}$/', $mac)) {
|
||||
// Insertar los dos puntos en la MAC y devolverla en el formato correcto
|
||||
return strtoupper(implode(':', str_split($mac, 2)));
|
||||
}
|
||||
|
||||
// Si no cumple con ninguno de los formatos, devolver un error
|
||||
return false; // MAC no válida
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -991,6 +1145,8 @@ public function getBootFile(string $mac): Response
|
|||
{
|
||||
$directory = '/opt/ogboot/tftpboot/ipxe_scripts';
|
||||
|
||||
$mac = $this->validateAndFormatMac($mac ?? null);
|
||||
|
||||
$fileName = "01-" . $mac;
|
||||
|
||||
$filePath = "$directory/$fileName";
|
||||
|
@ -1052,7 +1208,7 @@ public function getBootFile(string $mac): Response
|
|||
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}",
|
||||
|
@ -1068,38 +1224,62 @@ public function getBootFile(string $mac): Response
|
|||
* @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\JsonContent(
|
||||
* @OA\Property(property="success", type="string", example="Plantilla obtenida con éxito"),
|
||||
* @OA\Property(property="template_name", type="string", example="mi_plantilla.ipxe"),
|
||||
* @OA\Property(property="template_content", 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"
|
||||
* description="Plantilla no encontrada",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="error", type="string", example="TEMPLATE_NOT_FOUND"),
|
||||
* @OA\Property(property="message", type="string", example="No se encontró la plantilla especificada")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=500,
|
||||
* description="Error interno del servidor"
|
||||
* description="Error interno del servidor",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="error", type="string", example="FAILED_TO_READ_TEMPLATE"),
|
||||
* @OA\Property(property="message", type="string", example="Error al leer la plantilla")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
|
||||
public function getTemplate(string $templateName): Response
|
||||
{
|
||||
$templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
|
||||
$filePath = "$templateDir/$templateName";
|
||||
|
||||
// Comprobar si el archivo de plantilla existe
|
||||
if (!file_exists($filePath)) {
|
||||
return new Response(null, Response::HTTP_NOT_FOUND);
|
||||
return new Response(json_encode([
|
||||
'error' => 'TEMPLATE_NOT_FOUND',
|
||||
'message' => 'No se encontró la plantilla especificada'
|
||||
]), Response::HTTP_NOT_FOUND, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
// Intentar leer el contenido de la plantilla
|
||||
$content = file_get_contents($filePath);
|
||||
if ($content === false) {
|
||||
return new Response('Error al leer la plantilla', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
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']);
|
||||
}
|
||||
|
||||
return new Response($content, Response::HTTP_OK, ['Content-Type' => 'text/plain']);
|
||||
// Devolver la respuesta con el nombre y contenido de la plantilla
|
||||
return new Response(json_encode([
|
||||
'success' => 'Plantilla obtenida con éxito',
|
||||
'template_name' => $templateName,
|
||||
'template_content' => $content
|
||||
]), Response::HTTP_OK, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Route("/ogboot/v1/pxe-templates", methods={"POST"})
|
||||
*
|
||||
|
@ -1173,17 +1353,18 @@ public function createTemplate(Request $request)
|
|||
return new Response('Ocurrió un error al crear la plantilla de arranque. ' . $e->getMessage(), 500);
|
||||
}
|
||||
|
||||
// Retornar el nombre de la plantilla y su contenido en el formato solicitado
|
||||
return new Response(json_encode([
|
||||
'message' => 'Plantilla creada exitosamente.',
|
||||
'template' => $contentTemplate
|
||||
'success' => 'Plantilla creada con éxito',
|
||||
'template_name' => $nameTemplate,
|
||||
'template_content' => $contentTemplate
|
||||
]), 200, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* @Route("/ogboot/v1/pxe-templates/{name}", methods={"DELETE"})
|
||||
*
|
||||
* @OA\Delete(
|
||||
|
@ -1201,40 +1382,61 @@ public function createTemplate(Request $request)
|
|||
* 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\Property(property="success", type="string", example="Plantilla eliminada"),
|
||||
* @OA\Property(property="message", type="string", example="La plantilla mi_plantilla se ha borrado correctamente.")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=404,
|
||||
* description="No se encontró ninguna plantilla de arranque con el nombre especificado."
|
||||
* description="No se encontró ninguna plantilla de arranque con el nombre especificado.",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="error", type="string", example="TEMPLATE_NOT_FOUND"),
|
||||
* @OA\Property(property="message", type="string", example="No se encontró la plantilla especificada")
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=500,
|
||||
* description="Ocurrió un error al eliminar la plantilla de arranque."
|
||||
* description="Ocurrió un error al eliminar la plantilla de arranque.",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="error", type="string", example="FAILED_TO_DELETE_TEMPLATE"),
|
||||
* @OA\Property(property="message", type="string", example="Ocurrió un error al intentar eliminar la plantilla")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function deleteTemplate($name)
|
||||
{
|
||||
public function deleteTemplate($name): Response
|
||||
{
|
||||
$templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates';
|
||||
$filePath = $templateDir . '/' . $name;
|
||||
|
||||
// Comprobar si la plantilla existe
|
||||
if (!file_exists($filePath)) {
|
||||
return new Response('No se encontró ninguna plantilla de arranque con el nombre especificado.', 404);
|
||||
return new Response(json_encode([
|
||||
'error' => 'TEMPLATE_NOT_FOUND',
|
||||
'message' => 'No se encontró la plantilla especificada'
|
||||
]), Response::HTTP_NOT_FOUND, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
// Intentar eliminar la plantilla
|
||||
try {
|
||||
unlink($filePath);
|
||||
} catch (\Exception $e) {
|
||||
return new Response('Ocurrió un error al eliminar la plantilla de arranque.', 500);
|
||||
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']);
|
||||
}
|
||||
|
||||
// Devolver respuesta exitosa
|
||||
return new Response(json_encode([
|
||||
'message' => 'Plantilla eliminada correctamente.'
|
||||
]), 200, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
'success' => 'Plantilla eliminada',
|
||||
'message' => "La plantilla $name se ha borrado correctamente"
|
||||
]), Response::HTTP_OK, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue