commit
150b437656
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -1,4 +1,19 @@
|
|||
# Changelog
|
||||
## [0.14.0] - 2025-06-02
|
||||
### Added
|
||||
- Se ha añadido la funcionalidad de mover equipos entre aulas y grupos.
|
||||
- Se ha añadido la funcionalidad para eliminar imagen cache.
|
||||
- Se ha añadido la funcionalidad para iniciar sesion.
|
||||
|
||||
### Improved
|
||||
- Se ha cambiado la restriccion que comprobaba los puertos de MULTICAST.
|
||||
- Se ha modificado el tiempo en el script, que se encarga de comprobar el estado de los equipos. Ahora es de 1 min en lugar de 3.
|
||||
|
||||
### Fixed
|
||||
- Se ha corregido un bug que hacia que al modificar un cliente o eliminarlo, no se actualizaba su estado en la subred.
|
||||
- Se ha corregido un bug que hacia que al modificar un cliente, no se actualizara su fichero de arranque.
|
||||
|
||||
---
|
||||
## [0.13.1] - 2025-05-23
|
||||
### Fixed
|
||||
- Variable de entorno "SSl_ENABLED" desactivada por defecto.
|
||||
|
|
|
@ -32,7 +32,7 @@ resources:
|
|||
class: ApiPlatform\Metadata\Post
|
||||
method: POST
|
||||
input: App\Dto\Input\ChangeOrganizationalUnitInput
|
||||
uriTemplate: /clients/change-organizational-units
|
||||
uriTemplate: /clients/change-organizational-unit
|
||||
controller: App\Controller\ChangeOrganizationalUnitAction
|
||||
|
||||
agent_status:
|
||||
|
@ -50,13 +50,20 @@ resources:
|
|||
uriTemplate: /clients/server/{uuid}/get-pxe
|
||||
controller: App\Controller\OgBoot\PxeBootFile\GetAction
|
||||
|
||||
login_client:
|
||||
boot_client:
|
||||
class: ApiPlatform\Metadata\Post
|
||||
method: POST
|
||||
input: App\Dto\Input\MultipleClientsInput
|
||||
uriTemplate: /clients/server/login-client
|
||||
input: App\Dto\Input\BootClientsInput
|
||||
uriTemplate: /clients/server/boot-client
|
||||
controller: App\Controller\OgAgent\LoginAction
|
||||
|
||||
remove_cache_image:
|
||||
class: ApiPlatform\Metadata\Post
|
||||
method: POST
|
||||
input: App\Dto\Input\BootClientsInput
|
||||
uriTemplate: /clients/server/remove-cache-image
|
||||
controller: App\Controller\OgAgent\RemoveCacheImageAction
|
||||
|
||||
reboot_client:
|
||||
class: ApiPlatform\Metadata\Post
|
||||
method: POST
|
||||
|
|
|
@ -4,6 +4,7 @@ resources:
|
|||
input: App\Dto\Input\PartitionPostInput
|
||||
output: App\Dto\Output\PartitionOutput
|
||||
order:
|
||||
diskNumber: 'ASC'
|
||||
partitionNumber: 'ASC'
|
||||
normalizationContext:
|
||||
groups: ['default', 'partition:read']
|
||||
|
|
|
@ -9,6 +9,8 @@ resources:
|
|||
filters:
|
||||
- 'api_platform.filter.trace.order'
|
||||
- 'api_platform.filter.trace.search'
|
||||
- 'api_platform.filter.trace.date'
|
||||
|
||||
ApiPlatform\Metadata\Get:
|
||||
provider: App\State\Provider\TraceProvider
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ security:
|
|||
- { path: ^/og-repository/webhook, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/og-lives/install/webhook, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/auth/refresh, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/validate, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/menu-browser, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/menu/, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
|
||||
|
|
|
@ -304,6 +304,11 @@ services:
|
|||
$orderParameterName: 'order'
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.trace.date:
|
||||
parent: 'api_platform.doctrine.orm.date_filter'
|
||||
arguments: [ { 'executedAt': ~, 'createdAt': ~ } ]
|
||||
tags: [ 'api_platform.filter' ]
|
||||
|
||||
api_platform.filter.user.order:
|
||||
parent: 'api_platform.doctrine.orm.order_filter'
|
||||
arguments:
|
||||
|
|
5
env.json
5
env.json
|
@ -8,6 +8,9 @@
|
|||
"UDS_AUTH_USERNAME": "test",
|
||||
"UDS_AUTH_PASSWORD": "test",
|
||||
"UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/",
|
||||
"SSL_ENABLED": "false"
|
||||
"SSL_ENABLED": "true",
|
||||
"OG_BOOT_IP": "127.0.0.1",
|
||||
"OG_BOOT_API_PORT": "8082",
|
||||
"OG_BOOT_PXE_PORT": "8085"
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ use Symfony\Component\Mercure\Update;
|
|||
#[AsCommand(name: 'opengnsys:check-client-availability', description: 'Check client availability')]
|
||||
class CheckClientAvailability extends Command
|
||||
{
|
||||
const int THRESHOLD_MINUTES = 3;
|
||||
const int THRESHOLD_MINUTES = 1;
|
||||
|
||||
public function __construct(
|
||||
private readonly HubInterface $hub,
|
||||
|
@ -34,16 +34,18 @@ class CheckClientAvailability extends Command
|
|||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$threshold = (new \DateTime())->modify(' - '.self::THRESHOLD_MINUTES . ' minutes');
|
||||
|
||||
$startQueryTime = microtime(true);
|
||||
|
||||
$validStatuses = [ClientStatus::OG_LIVE, ClientStatus::WINDOWS, ClientStatus::LINUX, ClientStatus::MACOS];
|
||||
|
||||
$query = $this->entityManager->createQuery(
|
||||
'UPDATE App\Entity\Client c
|
||||
SET c.status = :status
|
||||
WHERE c.status = :currentStatus AND c.updatedAt < :threshold'
|
||||
SET c.status = :status
|
||||
WHERE c.status IN (:currentStatuses)
|
||||
AND c.updatedAt < :threshold'
|
||||
);
|
||||
$query->setParameter('status', ClientStatus::DISCONNECTED);
|
||||
$query->setParameter('currentStatus', ClientStatus::OG_LIVE);
|
||||
$query->setParameter('currentStatuses', $validStatuses);
|
||||
$query->setParameter('threshold', $threshold);
|
||||
$updatedCount = $query->execute();
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\OgBoot\PxeBootFile\PostAction;
|
||||
use App\Dto\Input\ChangeOrganizationalUnitInput;
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Entity\Client;
|
||||
use App\Repository\ClientRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
@ -10,29 +12,37 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
|
||||
class ChangeOrganizationalUnitAction extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClientRepository $clientRepository,
|
||||
private readonly EntityManagerInterface $entityManager
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private PostAction $postAction,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(ChangeOrganizationalUnitInput $input): JsonResponse
|
||||
{
|
||||
foreach ($input->clients as $client) {
|
||||
/** @var Client $client */
|
||||
$clientEntity = $this->clientRepository->find($client->getEntity()->getId());
|
||||
if (!$clientEntity) {
|
||||
throw new NotFoundHttpException('Client not found');
|
||||
}
|
||||
/** @var Client $clientEntity */
|
||||
$clientEntity = $client->getEntity();
|
||||
|
||||
$organizationalUnit = $input->organizationalUnit->getEntity();
|
||||
$clientEntity->setOrganizationalUnit($organizationalUnit);
|
||||
|
||||
$this->entityManager->persist($clientEntity);
|
||||
$this->postAction->__invoke($clientEntity, $clientEntity->getTemplate());
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
|
|
@ -4,10 +4,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Controller\OgAgent;
|
||||
|
||||
use App\Dto\Input\BootClientsInput;
|
||||
use App\Dto\Input\MultipleClientsInput;
|
||||
use App\Entity\Client;
|
||||
use App\Entity\Command;
|
||||
use App\Entity\Image;
|
||||
use App\Entity\Partition;
|
||||
use App\Entity\Trace;
|
||||
use App\Model\ClientStatus;
|
||||
use App\Model\CommandTypes;
|
||||
|
@ -35,8 +37,11 @@ class LoginAction extends AbstractOgAgentController
|
|||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(MultipleClientsInput $input): JsonResponse
|
||||
public function __invoke(BootClientsInput $input): JsonResponse
|
||||
{
|
||||
/** @var Partition $partition */
|
||||
$partition = $input->partition->getEntity();
|
||||
|
||||
foreach ($input->clients as $clientEntity) {
|
||||
/** @var Client $client */
|
||||
$client = $clientEntity->getEntity();
|
||||
|
@ -52,17 +57,18 @@ class LoginAction extends AbstractOgAgentController
|
|||
|
||||
$data = [
|
||||
'nfn' => 'IniciarSesion',
|
||||
'dsk' => '1',
|
||||
'par' => '1',
|
||||
'dsk' => (string) $partition->getDiskNumber(),
|
||||
'par' => (string) $partition->getPartitionNumber(),
|
||||
'ids' => '0'
|
||||
];
|
||||
|
||||
$response = $this->createRequest(
|
||||
method: 'POST',
|
||||
url: 'http://'.$client->getIp().':8000/opengnsys/IniciarSesion',
|
||||
url: 'https://'.$client->getIp().':8000/opengnsys/IniciarSesion',
|
||||
params: [
|
||||
'json' => $data,
|
||||
]
|
||||
],
|
||||
token: $client->getToken(),
|
||||
);
|
||||
|
||||
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
|
@ -77,7 +83,7 @@ class LoginAction extends AbstractOgAgentController
|
|||
$this->entityManager->persist($client);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->createService->__invoke($client, CommandTypes::REBOOT, TraceStatus::SUCCESS, $jobId, []);
|
||||
$this->createService->__invoke($client, CommandTypes::LOGIN, TraceStatus::SUCCESS, $jobId, []);
|
||||
}
|
||||
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
|
|
|
@ -55,7 +55,7 @@ class RebootAction extends AbstractOgAgentController
|
|||
|
||||
$response = $this->createRequest(
|
||||
method: 'POST',
|
||||
url: 'http://'.$client->getIp().':8000/'.$endpoint,
|
||||
url: 'https://'.$client->getIp().':8000/'.$endpoint,
|
||||
params: [
|
||||
'json' => $data,
|
||||
],
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\OgAgent;
|
||||
|
||||
use App\Dto\Input\BootClientsInput;
|
||||
use App\Entity\Client;
|
||||
use App\Entity\Partition;
|
||||
use App\Model\ClientStatus;
|
||||
use App\Model\CommandTypes;
|
||||
use App\Model\TraceStatus;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
|
||||
class RemoveCacheImageAction extends AbstractOgAgentController
|
||||
{
|
||||
/**
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(BootClientsInput $input): JsonResponse
|
||||
{
|
||||
/** @var Partition $partition */
|
||||
$partition = $input->partition->getEntity();
|
||||
|
||||
foreach ($input->clients as $clientEntity) {
|
||||
/** @var Client $client */
|
||||
$client = $clientEntity->getEntity();
|
||||
|
||||
if (!$partition->getImage()) {
|
||||
throw new ValidatorException('Image is required');
|
||||
}
|
||||
|
||||
if (!$client->getIp()) {
|
||||
throw new ValidatorException('IP is required');
|
||||
}
|
||||
|
||||
if ($client->getStatus() !== ClientStatus::OG_LIVE) {
|
||||
throw new ValidatorException('Client is not in OG_LIVE status');
|
||||
}
|
||||
|
||||
$script = `rm%20-r%20/opt/opengnsys/cache/opt/opengnsys/images/{$partition->getImage()->getName()}.*@'`;
|
||||
|
||||
$data = [
|
||||
'nfn' => 'EjecutarScript',
|
||||
'scp' => base64_encode($script),
|
||||
'ids' => '0'
|
||||
];
|
||||
|
||||
$response = $this->createRequest(
|
||||
method: 'POST',
|
||||
url: 'https://'.$client->getIp().':8000/opengnsys/EjecutarScript',
|
||||
params: [
|
||||
'json' => $data,
|
||||
],
|
||||
token: $client->getToken(),
|
||||
);
|
||||
|
||||
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
throw new ValidatorException('Error logging in: '.$response['error']);
|
||||
}
|
||||
|
||||
$this->logger->info('Login client', ['client' => $client->getId()]);
|
||||
|
||||
$jobId = $response['job_id'];
|
||||
|
||||
$this->entityManager->persist($client);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$inputData = [
|
||||
'script' => $script,
|
||||
];
|
||||
|
||||
$this->createService->__invoke($client, CommandTypes::RUN_SCRIPT, TraceStatus::SUCCESS, $jobId, $inputData);
|
||||
}
|
||||
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ use App\Service\Trace\CreateService;
|
|||
use App\Service\Utils\ExtractOgLiveFilenameDateService;
|
||||
use App\Service\Utils\SimplifyOgLiveFilenameService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
@ -25,8 +26,12 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|||
abstract class AbstractOgBootController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
#[Autowire(env: 'OG_BOOT_API_URL')]
|
||||
protected string $ogBootApiUrl,
|
||||
#[Autowire(env: 'OG_BOOT_IP')]
|
||||
protected string $ogBootIp,
|
||||
#[Autowire(env: 'OG_BOOT_PXE_PORT')]
|
||||
protected string $ogBootPxePort,
|
||||
#[Autowire(env: 'OG_BOOT_API_PORT')]
|
||||
protected string $ogBootApiPort,
|
||||
#[Autowire(env: 'OG_CORE_IP')]
|
||||
protected string $ogCoreIP,
|
||||
#[Autowire(env: 'OG_LOG_IP')]
|
||||
|
@ -36,6 +41,8 @@ abstract class AbstractOgBootController extends AbstractController
|
|||
protected readonly CreateService $createService,
|
||||
protected readonly SimplifyOgLiveFilenameService $simplifyOgLiveFilenameService,
|
||||
protected readonly ExtractOgLiveFilenameDateService $extractOgLiveFilenameDateService,
|
||||
protected readonly LoggerInterface $logger,
|
||||
|
||||
)
|
||||
{
|
||||
}
|
||||
|
@ -56,15 +63,25 @@ abstract class AbstractOgBootController extends AbstractController
|
|||
]);
|
||||
|
||||
try {
|
||||
$response = $this->httpClient->request($method, $url, $params);
|
||||
$response = $this->httpClient->request($method, 'http://'.$this->ogBootIp.':'.$this->ogBootApiPort.$url, $params);
|
||||
|
||||
return json_decode($response->getContent(), true);
|
||||
} catch (ClientExceptionInterface | ServerExceptionInterface $e) {
|
||||
$response = $e->getResponse();
|
||||
$content = json_decode($response->getContent(false), true);
|
||||
throw new HttpException($response->getStatusCode(), $content['error'] ?? 'An error occurred');
|
||||
$this->logger->error(sprintf('Client/Server error in request to %s: %s', $url, $e->getMessage()));
|
||||
|
||||
return [
|
||||
'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'error' => 'Client/Server error',
|
||||
'details' => $e->getMessage(),
|
||||
];
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, $e->getMessage());
|
||||
$this->logger->error(sprintf('Transport error in request to %s: %s', $url, $e->getMessage()));
|
||||
|
||||
return [
|
||||
'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'error' => 'Transport error',
|
||||
'details' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,11 @@ class GetAction extends AbstractOgBootController
|
|||
throw new ValidatorException('Checksum is required');
|
||||
}
|
||||
|
||||
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum());
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/oglives/'.$data->getChecksum());
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
return new JsonResponse(data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,11 @@ class GetCollectionAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(): JsonResponse
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives');
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/oglives');
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
return new JsonResponse(data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use App\Controller\OgBoot\AbstractOgBootController;
|
|||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
|
@ -22,7 +23,11 @@ class GetDefaultAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(): JsonResponse
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/default');
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/oglives/default');
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
return new JsonResponse(status: Response::HTTP_OK);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class GetIsosAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(): JsonResponse
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/isos');
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/oglives/isos');
|
||||
|
||||
if (!isset($content['message']) || !is_array($content['message'])) {
|
||||
return new JsonResponse(data: ['error' => 'Invalid response'], status: Response::HTTP_BAD_REQUEST);
|
||||
|
|
|
@ -45,7 +45,11 @@ class InstallAction extends AbstractOgBootController
|
|||
'uuid' => 'InstallOgLive_'.$data->getUuid()
|
||||
];
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/install', $params);
|
||||
$content = $this->createRequest('POST', '/ogboot/v1/oglives/install', $params);
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$this->createService->__invoke(null, CommandTypes::INSTALL_OGLIVE, TraceStatus::IN_PROGRESS, 'InstallOgLive_'.$data->getUuid(), $inputData);
|
||||
|
||||
|
|
|
@ -36,7 +36,11 @@ class SetDefaultAction extends AbstractOgBootController
|
|||
]
|
||||
];
|
||||
|
||||
$content = $this->createRequest('PUT', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/default', $params);
|
||||
$content = $this->createRequest('PUT', '/ogboot/v1/oglives/default', $params);
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$oldDefaultOgLive = $this->entityManager->getRepository(OgLive::class)->findBy(['isDefault' => true]);
|
||||
|
||||
|
|
|
@ -30,7 +30,11 @@ class SyncAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(): JsonResponse
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl . '/ogboot/v1/oglives');
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/oglives');
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$allOgLives = $this->entityManager->getRepository(OgLive::class)->findAll();
|
||||
$apiChecksums = array_map(fn($ogLive) => $ogLive['id'], $content['message']['installed_ogLives']);
|
||||
|
@ -76,7 +80,9 @@ class SyncAction extends AbstractOgBootController
|
|||
*/
|
||||
private function extracted(OgLive $ogLiveEntity, mixed $ogLive): void
|
||||
{
|
||||
$ogLiveEntity->setName($this->simplifyOgLiveFilenameService->__invoke(str_replace(self::OG_BOOT_DIRECTORY, '', $ogLive['directory'])));
|
||||
$name = $this->simplifyOgLiveFilenameService->__invoke(str_replace(self::OG_BOOT_DIRECTORY, '', $ogLive['directory']));
|
||||
|
||||
$ogLiveEntity->setName($name ? $name : str_replace(self::OG_BOOT_DIRECTORY, '', $ogLive['directory']));
|
||||
$ogLiveEntity->setDate(new \DateTime($this->extractOgLiveFilenameDateService->__invoke(str_replace(self::OG_BOOT_DIRECTORY, '', $ogLive['directory']))));
|
||||
$ogLiveEntity->setInstalled(true);
|
||||
$ogLiveEntity->setArchitecture($ogLive['architecture']);
|
||||
|
|
|
@ -31,7 +31,11 @@ class UninstallAction extends AbstractOgBootController
|
|||
throw new ValidatorException('Checksum is required');
|
||||
}
|
||||
|
||||
$content = $this->createRequest( 'DELETE', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum());
|
||||
$content = $this->createRequest( 'DELETE', '/ogboot/v1/oglives/'.$data->getChecksum());
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$this->entityManager->remove($data);
|
||||
$this->entityManager->flush();
|
||||
|
|
|
@ -23,19 +23,13 @@ class DeleteAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(string $mac): JsonResponse
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->request('DELETE', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxes/'.$mac, [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
],
|
||||
]);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$response = $this->createRequest('DELETE', '/ogboot/v1/pxes/'.$mac);
|
||||
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$data = json_decode($response->getContent(), true);
|
||||
|
||||
return new JsonResponse( data: $data, status: Response::HTTP_OK);
|
||||
return new JsonResponse( data: [], status: Response::HTTP_OK);
|
||||
|
||||
}
|
||||
}
|
|
@ -26,18 +26,12 @@ class GetAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(Client $client): JsonResponse
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->request('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxes/'.$client->getMac(), [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
],
|
||||
]);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$response = $this->createRequest('GET', '/ogboot/v1/pxes/'.$client->getName());
|
||||
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$data = json_decode($response->getContent(), true);
|
||||
|
||||
return new JsonResponse( data: $data, status: Response::HTTP_OK);
|
||||
return new JsonResponse( data: $response, status: Response::HTTP_OK);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ class GetCollectionAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(HttpClientInterface $httpClient): JsonResponse
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxes');
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/pxes');
|
||||
|
||||
return new JsonResponse(data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
|
|
|
@ -28,13 +28,13 @@ class PostAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(Client $client, PxeTemplate $pxeTemplate): JsonResponse
|
||||
{
|
||||
$ogRepoIp = $this->ogBootApiUrl;
|
||||
$ogRepoIp = $this->ogBootIp;
|
||||
|
||||
$ogRepoIp = $client->getRepository()?->getIp()
|
||||
?? $client->getOrganizationalUnit()?->getNetworkSettings()?->getRepository()?->getIp();
|
||||
|
||||
$ogLive = $client->getOgLive()?->getFilename()
|
||||
?? $client->getOrganizationalUnit()?->getNetworkSettings()?->getOgLive()->getFilename();
|
||||
?? $client->getOrganizationalUnit()?->getNetworkSettings()?->getOgLive()?->getFilename();
|
||||
|
||||
$params = [
|
||||
'json' => [
|
||||
|
@ -42,7 +42,9 @@ class PostAction extends AbstractOgBootController
|
|||
'mac' => strtolower($client->getMac()),
|
||||
'lang' => 'es_ES.UTF-8',
|
||||
'ip' => $client->getIp(),
|
||||
'server_ip' => $this->ogBootApiUrl,
|
||||
'server_ip' => $this->ogBootIp,
|
||||
'server_api_port' => $this->ogBootApiPort,
|
||||
'server_pxe_port' => $this->ogBootPxePort,
|
||||
'router' => $client->getOrganizationalUnit()->getNetworkSettings()->getRouter(),
|
||||
'netmask' => $client->getOrganizationalUnit()->getNetworkSettings() ? $client->getOrganizationalUnit()->getNetworkSettings()->getNetmask() : '255.255.255.0',
|
||||
'computer_name' => $client->getName(),
|
||||
|
@ -50,10 +52,10 @@ class PostAction extends AbstractOgBootController
|
|||
'group' => $client->getOrganizationalUnit()->getName(),
|
||||
'ogrepo' => $ogRepoIp,
|
||||
'ogcore' => $this->ogCoreIP,
|
||||
'oglive' => $this->ogBootApiUrl,
|
||||
'oglive' => $this->ogBootIp,
|
||||
'oglog' => $this->ogLogIp,
|
||||
'ogshare' => $client->getOrganizationalUnit()->getNetworkSettings()?->getOgShare()
|
||||
? $client->getOrganizationalUnit()->getNetworkSettings()?->getOgShare(): $this->ogBootApiUrl,
|
||||
? $client->getOrganizationalUnit()->getNetworkSettings()?->getOgShare(): $this->ogBootIp,
|
||||
'oglivedir' => $ogLive,
|
||||
'ogprof' => 'false',
|
||||
'hardprofile' => $client->getHardwareProfile() ? $client->getHardwareProfile()->getDescription() : 'default',
|
||||
|
@ -64,7 +66,7 @@ class PostAction extends AbstractOgBootController
|
|||
]
|
||||
];
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxes', $params);
|
||||
$content = $this->createRequest('POST', '/ogboot/v1/pxes', $params);
|
||||
|
||||
$client->setPxeSync(true);
|
||||
$this->entityManager->persist($client);
|
||||
|
|
|
@ -10,6 +10,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
|
@ -30,7 +31,11 @@ class DeleteAction extends AbstractOgBootController
|
|||
$this->entityManager->remove($data);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$content = $this->createRequest('DELETE', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxe-templates/'.$data->getName());
|
||||
$content = $this->createRequest('DELETE', '/ogboot/v1/pxe-templates/'.$data->getName());
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$defaultTemplateEntity = $this->entityManager->getRepository(PxeTemplate::class)->findOneBy(['isDefault' => true]);
|
||||
|
||||
|
|
|
@ -25,13 +25,9 @@ class GetAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(PxeTemplate $template, HttpClientInterface $httpClient): JsonResponse
|
||||
{
|
||||
try {
|
||||
$response = $httpClient->request('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxe-templates/'.$template->getName(), [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
],
|
||||
]);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$response = $this->createRequest('GET', '/ogboot/v1/pxe-templates/'.$template->getName());
|
||||
|
||||
if ($response->getStatusCode() !== Response::HTTP_OK) {
|
||||
return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
|
@ -24,18 +25,12 @@ class GetCollectionAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(HttpClientInterface $httpClient): JsonResponse
|
||||
{
|
||||
try {
|
||||
$response = $httpClient->request('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxe-templates', [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
],
|
||||
]);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/pxe-templates');
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$data = json_decode($response->getContent(), true);
|
||||
|
||||
return new JsonResponse( data: $data, status: Response::HTTP_OK);
|
||||
return new JsonResponse( data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
|
@ -33,7 +34,11 @@ class PostAction extends AbstractOgBootController
|
|||
]
|
||||
];
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxe-templates' , $params);
|
||||
$content = $this->createRequest('POST', '/ogboot/v1/pxe-templates' , $params);
|
||||
|
||||
if (isset($content['error']) && $content['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $content['error']);
|
||||
}
|
||||
|
||||
$data->setSynchronized(true);
|
||||
$this->entityManager->persist($data);
|
||||
|
|
|
@ -28,7 +28,7 @@ class SyncAction extends AbstractOgBootController
|
|||
*/
|
||||
public function __invoke(): JsonResponse
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://' . $this->ogBootApiUrl . '/ogboot/v1/pxe-templates');
|
||||
$content = $this->createRequest('GET', '/ogboot/v1/pxe-templates');
|
||||
$templateNamesFromApi = $content['message'];
|
||||
|
||||
$existingTemplates = $this->entityManager->getRepository(PxeTemplate::class)->findAll();
|
||||
|
@ -49,7 +49,11 @@ class SyncAction extends AbstractOgBootController
|
|||
$templateEntity->setName($templateName);
|
||||
}
|
||||
|
||||
$templateContent = $this->createRequest('GET', 'http://' . $this->ogBootApiUrl . '/ogboot/v1/pxe-templates/' . $templateEntity->getName());
|
||||
$templateContent = $this->createRequest('GET', '/ogboot/v1/pxe-templates/' . $templateEntity->getName());
|
||||
|
||||
if (isset($templateContent['error']) && $templateContent['error'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new ValidatorException('An error occurred: ' . $templateContent['error']);
|
||||
}
|
||||
|
||||
$templateEntity->setTemplateContent($templateContent['template_content']);
|
||||
$templateEntity->setSynchronized(true);
|
||||
|
|
|
@ -7,6 +7,7 @@ use App\Entity\Subnet;
|
|||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
|
@ -29,11 +30,23 @@ class DeleteAction extends AbstractOgDhcpController
|
|||
throw new ValidatorException('Data Id is required');
|
||||
}
|
||||
|
||||
$content = $this->createRequest('DELETE', 'http://'.$this->ogDhcpApiUrl.'/ogdhcp/v1/subnets/'.$data->getServerId());
|
||||
try {
|
||||
$content = $this->createRequest(
|
||||
'DELETE',
|
||||
'http://' . $this->ogDhcpApiUrl . '/ogdhcp/v1/subnets/' . $data->getServerId()
|
||||
);
|
||||
} catch (HttpException $e) {
|
||||
if ($e->getStatusCode() === 404) {
|
||||
$content = ['message' => 'Subnet not found on external API, proceeding with local deletion'];
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->entityManager->remove($data);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse(data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
|
||||
}
|
|
@ -53,17 +53,15 @@ class PostHostAction extends AbstractOgDhcpController
|
|||
$params
|
||||
);
|
||||
|
||||
// Guardar resultado exitoso
|
||||
$success[] = [
|
||||
'client' => $clientEntity->getName(),
|
||||
'response' => $content
|
||||
];
|
||||
|
||||
// Persistir solo si la llamada fue exitosa
|
||||
$subnet->addClient($clientEntity);
|
||||
$this->entityManager->persist($subnet);
|
||||
$this->entityManager->flush();
|
||||
} catch (\Throwable $e) { // Capturar cualquier error sin interrumpir
|
||||
} catch (\Throwable $e) {
|
||||
$errors[] = [
|
||||
'client' => $clientEntity->getName(),
|
||||
'error' => $e->getMessage()
|
||||
|
|
|
@ -24,26 +24,23 @@ class PutHostAction extends AbstractOgDhcpController
|
|||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(SubnetAddHostInput $input, Subnet $subnet): JsonResponse
|
||||
public function __invoke(string $mac, Client $client): JsonResponse
|
||||
{
|
||||
$clients = $input->clients;
|
||||
$subnet = $client->getSubnet();
|
||||
|
||||
foreach ($clients as $client) {
|
||||
/** @var Client $clientEntity */
|
||||
$clientEntity = $client->getEntity();
|
||||
$data = [
|
||||
'host' => $clientEntity->getName(),
|
||||
'oldMacAddress' => '',
|
||||
'macAddress' => '',
|
||||
'address' => '',
|
||||
];
|
||||
/** @var Client $clientEntity */
|
||||
$data = [
|
||||
'hostname' => $client->getName(),
|
||||
'oldMacAddress' => strtolower($mac),
|
||||
'macAddress' => strtolower($client->getMac()),
|
||||
'address' => $client->getIp(),
|
||||
];
|
||||
|
||||
$params = [
|
||||
'json' => $data
|
||||
];
|
||||
$params = [
|
||||
'json' => $data
|
||||
];
|
||||
|
||||
$content = $this->createRequest('PUT', 'http://'.$this->ogDhcpApiUrl.'/ogdhcp/v1/subnets/'.$subnet->getId().'/hosts', $params);
|
||||
}
|
||||
$content = $this->createRequest('PUT', 'http://'.$this->ogDhcpApiUrl.'/ogdhcp/v1/subnets/'.$subnet->getServerId().'/hosts', $params);
|
||||
|
||||
return new JsonResponse(status: Response::HTTP_OK);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Dto\Input;
|
||||
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Dto\Output\PartitionOutput;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
final class BootClientsInput
|
||||
{
|
||||
/**
|
||||
* @var ClientOutput[]
|
||||
*/
|
||||
#[Groups(['client:write'])]
|
||||
public array $clients = [];
|
||||
|
||||
|
||||
#[Groups(['client:write'])]
|
||||
public ?PartitionOutput $partition = null;
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Dto\Input;
|
||||
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Dto\Output\OrganizationalUnitOutput;
|
||||
use App\Entity\Client;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
@ -10,13 +11,13 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
final class ChangeOrganizationalUnitInput
|
||||
{
|
||||
/**
|
||||
* @var Client[]
|
||||
* @var ClientOutput[]
|
||||
*/
|
||||
#[Assert\GreaterThan(1)]
|
||||
#[Groups(['user-group:write'])]
|
||||
#[Groups(['client:write'])]
|
||||
public ?array $clients = [];
|
||||
|
||||
#[Assert\NotNull]
|
||||
#[Groups(['user-group:write'])]
|
||||
#[Groups(['client:write'])]
|
||||
public ?OrganizationalUnitOutput $organizationalUnit = null;
|
||||
}
|
|
@ -18,7 +18,7 @@ class ImageImageRepositoryOutput extends AbstractOutput
|
|||
#[Groups(['image-image-repository:read', 'image:read'])]
|
||||
public string $status;
|
||||
|
||||
#[Groups(['image-image-repository:read', 'image:read', 'partition:read'])]
|
||||
#[Groups(['image-image-repository:read', 'image:read', 'partition:read', 'client:read'])]
|
||||
public string $name;
|
||||
|
||||
#[Groups(['image-image-repository:read', 'image:read'])]
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\EventListener;
|
|||
|
||||
use App\Controller\OgBoot\PxeBootFile\DeleteAction;
|
||||
use App\Controller\OgBoot\PxeBootFile\PostAction;
|
||||
use App\Controller\OgDhcp\Subnet\PutHostAction;
|
||||
use App\Entity\Client;
|
||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
|
||||
use Doctrine\ORM\Event\PreUpdateEventArgs;
|
||||
|
@ -18,6 +19,7 @@ readonly class ClientMacListener
|
|||
{
|
||||
public function __construct(
|
||||
private DeleteAction $deleteAction,
|
||||
private PutHostAction $putHostAction,
|
||||
)
|
||||
{
|
||||
|
||||
|
@ -45,7 +47,7 @@ readonly class ClientMacListener
|
|||
return;
|
||||
}
|
||||
|
||||
$this->putHostAction->__invoke($oldMac, $client);
|
||||
$this->deleteAction->__invoke($oldMac);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,8 +4,11 @@ namespace App\EventSubscriber;
|
|||
|
||||
use ApiPlatform\Symfony\EventListener\EventPriorities;
|
||||
use App\Controller\OgBoot\PxeBootFile\PostAction;
|
||||
use App\Controller\OgDhcp\Subnet\PutHostAction;
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Entity\Client;
|
||||
use App\Entity\PxeTemplate;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Event\ViewEvent;
|
||||
|
@ -18,7 +21,9 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|||
final readonly class ClientSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private PostAction $postAction,
|
||||
private PutHostAction $putHostAction,
|
||||
)
|
||||
{
|
||||
|
||||
|
@ -49,14 +54,19 @@ final readonly class ClientSubscriber implements EventSubscriberInterface
|
|||
/** @var Client $client */
|
||||
$client = $clientOutput->getEntity();
|
||||
|
||||
$template = !$client->getTemplate() ?
|
||||
$template = $client->getTemplate() ?
|
||||
$client->getTemplate() :
|
||||
$client->getOrganizationalUnit()?->getNetworkSettings()?->getPxeTemplate();
|
||||
|
||||
if ($template === null) {
|
||||
return;
|
||||
$template = $this->entityManager->getRepository(PxeTemplate::class)->findOneBy(['isDefault' => true]);
|
||||
|
||||
if ($template === null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->postAction->__invoke($client, $template);
|
||||
$this->putHostAction->__invoke($client->getMac(), $client);
|
||||
}
|
||||
}
|
|
@ -63,15 +63,25 @@ class MercureSubscriber implements EventSubscriberInterface
|
|||
'status' => $client->getStatus(),
|
||||
];
|
||||
|
||||
$update = new Update(
|
||||
'clients',
|
||||
json_encode($data)
|
||||
);
|
||||
$this->hub->publish($update);
|
||||
try {
|
||||
$update = new Update(
|
||||
'clients',
|
||||
json_encode($data)
|
||||
);
|
||||
|
||||
$this->logger->info('Evento Mercure disparado', [
|
||||
'method' => $method,
|
||||
'path' => $request->getPathInfo()
|
||||
]);
|
||||
$this->hub->publish($update);
|
||||
|
||||
$this->logger->info('Evento Mercure disparado', [
|
||||
'method' => $method,
|
||||
'path' => $request->getPathInfo()
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error setting method for Mercure update', [
|
||||
'method' => $method,
|
||||
'path' => $request->getPathInfo(),
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,12 @@ use Symfony\Component\HttpClient\HttpClient;
|
|||
readonly class StatusService
|
||||
{
|
||||
public function __construct(
|
||||
#[Autowire(env: 'OG_BOOT_API_URL')]
|
||||
private string $ogBootApiUrl
|
||||
#[Autowire(env: 'OG_BOOT_IP')]
|
||||
protected string $ogBootIp,
|
||||
#[Autowire(env: 'OG_BOOT_PXE_PORT')]
|
||||
protected string $ogBootPxePort,
|
||||
#[Autowire(env: 'OG_BOOT_API_PORT')]
|
||||
protected string $ogBootApiPort,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
@ -31,12 +35,12 @@ readonly class StatusService
|
|||
public function __invoke()
|
||||
{
|
||||
$httpClient = HttpClient::create([
|
||||
'verify_peer' => false, // Ignorar la verificación del certificado SSL
|
||||
'verify_host' => false, // Ignorar la verificación del nombre del host
|
||||
'verify_peer' => false,
|
||||
'verify_host' => false,
|
||||
]);
|
||||
|
||||
try {
|
||||
$response = $httpClient->request('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/status', [
|
||||
$response = $httpClient->request('GET', 'http://'.$this->ogBootIp.':'.$this->ogBootApiPort.'/ogboot/v1/status', [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
],
|
||||
|
|
|
@ -9,18 +9,34 @@ use ApiPlatform\Metadata\Post;
|
|||
use ApiPlatform\Metadata\Put;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use ApiPlatform\Validator\ValidatorInterface;
|
||||
use App\Controller\OgBoot\PxeBootFile\DeleteAction;
|
||||
use App\Controller\OgDhcp\Subnet\DeleteHostAction;
|
||||
use App\Dto\Input\ClientInput;
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Dto\Output\UserGroupOutput;
|
||||
use App\Entity\OgLive;
|
||||
use App\Entity\PxeTemplate;
|
||||
use App\Repository\ClientRepository;
|
||||
use App\Repository\MenuRepository;
|
||||
use App\Repository\OgLiveRepository;
|
||||
use App\Repository\PxeTemplateRepository;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
|
||||
readonly class ClientProcessor implements ProcessorInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ClientRepository $clientRepository,
|
||||
private MenuRepository $menuRepository,
|
||||
private ValidatorInterface $validator
|
||||
private ClientRepository $clientRepository,
|
||||
private MenuRepository $menuRepository,
|
||||
private PxeTemplateRepository $pxeTemplateRepository,
|
||||
private OgLiveRepository $ogLiveRepository,
|
||||
private ValidatorInterface $validator,
|
||||
private DeleteHostAction $deleteHostAction,
|
||||
private DeleteAction $deletePxeAction,
|
||||
private KernelInterface $kernel,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
@ -55,6 +71,8 @@ readonly class ClientProcessor implements ProcessorInterface
|
|||
}
|
||||
|
||||
$defaultMenu = $this->menuRepository->findOneBy(['isDefault' => true]);
|
||||
$defaultPxe = $this->pxeTemplateRepository->findOneBy(['isDefault' => true]);
|
||||
$defaultPxeOgLive = $this->ogLiveRepository->findOneBy(['isDefault' => true]);
|
||||
|
||||
$client = $data->createOrUpdateEntity($entity);
|
||||
|
||||
|
@ -62,16 +80,35 @@ readonly class ClientProcessor implements ProcessorInterface
|
|||
$client->setMenu($defaultMenu);
|
||||
}
|
||||
|
||||
if ($defaultPxe) {
|
||||
$client->setTemplate($defaultPxe);
|
||||
}
|
||||
|
||||
if ($defaultPxeOgLive) {
|
||||
$client->setOgLive($defaultPxeOgLive);
|
||||
}
|
||||
|
||||
$this->validator->validate($client);
|
||||
$this->clientRepository->save($client);
|
||||
|
||||
return new ClientOutput($client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null
|
||||
{
|
||||
$user = $this->clientRepository->findOneByUuid($uriVariables['uuid']);
|
||||
$this->clientRepository->delete($user);
|
||||
$client = $this->clientRepository->findOneByUuid($uriVariables['uuid']);
|
||||
$this->clientRepository->delete($client);
|
||||
|
||||
if ($this->kernel->getEnvironment() !== 'test') {
|
||||
$this->deleteHostAction->__invoke($client->getSubnet(), $client->getUuid());
|
||||
$this->deletePxeAction->__invoke($client->getUuid());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ use Symfony\Component\Validator\ConstraintValidator;
|
|||
|
||||
class OrganizationalUnitMulticastPortValidator extends ConstraintValidator
|
||||
{
|
||||
CONST int minPort = 9000;
|
||||
CONST int maxPort = 9050;
|
||||
public const int minPort = 9000;
|
||||
public const int maxPort = 9098;
|
||||
|
||||
public function validate($value, Constraint $constraint): void
|
||||
{
|
||||
|
@ -18,9 +18,14 @@ class OrganizationalUnitMulticastPortValidator extends ConstraintValidator
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(self::minPort <= $value) && ($value <= self::maxPort)) {
|
||||
if ($value % 2 !== 0) {
|
||||
$this->context->buildViolation('El puerto debe ser un número par y encontrarse entre el 9000 y el 9098.')->addViolation();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value < self::minPort || $value > self::maxPort) {
|
||||
$this->context->buildViolation($constraint->message)->addViolation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue