refs #1794. Updted assistants endpoints

pull/27/head
Manuel Aranda Rosales 2025-04-01 10:58:11 +02:00
parent 3eca490d0a
commit 2d6b058eaf
18 changed files with 234 additions and 20 deletions

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250325075647 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client ADD firmware_type VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client DROP firmware_type');
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250326061450 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command ADD parameters TINYINT(1) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command DROP parameters');
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250331144522 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository ADD datasize VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository DROP datasize');
}
}

View File

@ -90,7 +90,7 @@ class CreateImageAction extends AbstractController
try {
$this->logger->info('Creating image', ['image' => $image->getId()]);
$response = $this->httpClient->request('POST', 'https://'.$image->getClient()->getIp().':8000/CloningEngine/CrearImagen', [
$response = $this->httpClient->request('POST', 'https://'.$image->getClient()->getIp().':8000/opengnsys/CrearImagen', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [

View File

@ -92,7 +92,7 @@ class DeployImageAction extends AbstractController
];
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/CloningEngine/RestaurarImagen', [
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [

View File

@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
use App\Dto\Input\MultipleClientsInput;
use App\Entity\Client;
use App\Entity\Command;
use App\Entity\Image;
use App\Entity\Trace;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
use App\Model\ImageStatus;
use App\Model\TraceStatus;
use App\Service\Trace\CreateService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
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;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class LoginAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
public function __invoke(MultipleClientsInput $input): JsonResponse
{
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
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');
}
$data = [
'nfn' => 'IniciarSesion',
'dsk' => '1',
'par' => '1',
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/IniciarSesion', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
]);
$this->logger->info('Login client', ['client' => $client->getId()]);
} catch (TransportExceptionInterface $e) {
$this->logger->error('Login rebooting client', ['client' => $client->getId(), 'error' => $e->getMessage()]);
return new JsonResponse(
data: ['error' => $e->getMessage()],
status: Response::HTTP_INTERNAL_SERVER_ERROR
);
}
$jobId = json_decode($response->getContent(), true)['job_id'];
$client->setStatus(ClientStatus::INITIALIZING);
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::REBOOT, TraceStatus::SUCCESS, $jobId, []);
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -48,6 +48,7 @@ class PartitionAssistantAction extends AbstractController
}
foreach ($input->clients as $clientInput) {
/** @var Client $client */
$client = $clientInput->getEntity();
$disks = [];
@ -72,13 +73,10 @@ class PartitionAssistantAction extends AbstractController
];
}
if ($partition->filesystem === 'CACHE') {
$disks[$diskNumber]['diskData'] = [
'dis' => (string) $diskNumber,
'che' => "0",
'tch' => (string) ($partition->size * 1024),
];
}
$disks[$diskNumber]['diskData'] = [
'dis' => (string) $diskNumber,
'tch' => (string) ($partition->size * 1024),
];
$disks[$diskNumber]['partitionData'][] = [
'par' => (string) $partition->partitionNumber,
@ -104,7 +102,7 @@ class PartitionAssistantAction extends AbstractController
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/CloningEngine/Configurar', [
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/opengnsys/Configurar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
@ -130,5 +128,4 @@ class PartitionAssistantAction extends AbstractController
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -53,13 +53,15 @@ class PowerOffAction extends AbstractController
continue;
}
$endpoint = $client->getStatus() === ClientStatus::OG_LIVE ? 'opengnsys/Apagar' : 'opengnsys/poweroff';
$data = [
'nfn' => 'Apagar',
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/ogAdmClient/Apagar', [
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/'.$endpoint, [
'verify_peer' => false,
'verify_host' => false,
'headers' => [

View File

@ -41,6 +41,7 @@ class RebootAction extends AbstractController
public function __invoke(MultipleClientsInput $input): JsonResponse
{
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
@ -48,13 +49,15 @@ class RebootAction extends AbstractController
throw new ValidatorException('IP is required');
}
$endpoint = $client->getStatus() === ClientStatus::OG_LIVE ? 'opengnsys/Reiniciar' : '/opengnsys/reboot';
$data = [
'nfn' => 'Reiniciar',
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/Reiniciar', [
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/'.$endpoint, [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
@ -62,6 +65,7 @@ class RebootAction extends AbstractController
],
'json' => $data,
]);
$this->logger->info('Rebooting client', ['client' => $client->getId()]);
} catch (TransportExceptionInterface $e) {

View File

@ -70,6 +70,10 @@ class StatusAction extends AbstractController
{
$this->logger->info('Checking client status', ['client' => $client->getId()]);
$params = [
'full-config' => true,
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/status', [
'verify_peer' => false,
@ -78,7 +82,7 @@ class StatusAction extends AbstractController
'headers' => [
'Content-Type' => 'application/json',
],
'json' => [],
'json' => $params,
]);
$statusCode = $response->getStatusCode();
$client->setStatus($statusCode === Response::HTTP_OK ? ClientStatus::OG_LIVE : ClientStatus::OFF);

View File

@ -32,7 +32,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
#[AsController]
class ClientsController extends AbstractController
class StatusController extends AbstractController
{
const string CREATE_IMAGE = 'RESPUESTA_CrearImagen';
const string RESTORE_IMAGE = 'RESPUESTA_RestaurarImagen';
@ -72,7 +72,7 @@ class ClientsController extends AbstractController
if (isset($data['progress'])){
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
if ($trace){
$trace->setProgress($data['progress'] * 1000);
$trace->setProgress($data['progress'] * 100);
$this->entityManager->persist($trace);
$this->entityManager->flush();
}

View File

@ -40,7 +40,7 @@ class PostAction extends AbstractOgBootController
'json' => [
'template_name' => $pxeTemplate->getName(),
'mac' => strtolower($client->getMac()),
'lang' => 'es_ES.UTF_8',
'lang' => 'es_ES.UTF-8',
'ip' => $client->getIp(),
'server_ip' => $this->ogBootApiUrl,
'router' => $client->getOrganizationalUnit()->getNetworkSettings()->getRouter(),

View File

@ -45,9 +45,9 @@ class DeployImageAction extends AbstractOgRepositoryController
];
$type = match ($input->method) {
'udpcast', 'udpcast_direct' => DeployMethodTypes::MULTICAST_UDPCAST,
'udpcast', 'udpcast-direct' => DeployMethodTypes::MULTICAST_UDPCAST,
'p2p' => DeployMethodTypes::TORRENT,
default => DeployMethodTypes::MULTICAST_UFTP,
default => null,
};
$repository = $client->getRepository();

View File

@ -40,6 +40,13 @@ final class CommandInput
)]
public ?bool $enabled = true;
#[Groups(['command:write'])]
#[ApiProperty(
description: 'Tiene parámetros?',
example: 'true',
)]
public ?bool $parameters = true;
#[Groups(['command:write'])]
#[ApiProperty(
description: 'Los comentarios del comando',
@ -57,6 +64,7 @@ final class CommandInput
$this->script = $command->getScript();
$this->enabled = $command->isEnabled();
$this->readOnly = $command->isReadOnly();
$this->parameters = $command->isParameters();
$this->comments = $command->getComments();
}
@ -70,6 +78,7 @@ final class CommandInput
$command->setScript($this->script);
$command->setEnabled($this->enabled);
$command->setReadOnly($this->readOnly);
$command->setParameters($this->parameters);
$command->setComments($this->comments);
return $command;

View File

@ -25,6 +25,9 @@ final class ClientOutput extends AbstractOutput
#[Groups(['client:read', 'organizational-unit:read', 'pxe-template:read', 'trace:read', 'subnet:read'])]
public ?string $mac = '';
#[Groups(['client:read'])]
public ?string $firmwareType = '';
#[Groups(['client:read', 'organizational-unit:read', 'trace:read'])]
public ?string $serialNumber = '';
@ -91,6 +94,7 @@ final class ClientOutput extends AbstractOutput
$this->ip = $client->getIp();
$this->netiface = $client->getNetiface();
$this->netDriver = $client->getNetDriver();
$this->firmwareType = $client->getFirmwareType();
if ($client->getOrganizationalUnit()) {
$this->organizationalUnit = new OrganizationalUnitOutput($client->getOrganizationalUnit());

View File

@ -21,6 +21,9 @@ final class CommandOutput extends AbstractOutput
#[Groups(['command:read'])]
public ?bool $enabled = true;
#[Groups(['command:read'])]
public ?bool $parameters = true;
#[Groups(['command:read'])]
public ?string $comments = '';
@ -37,6 +40,7 @@ final class CommandOutput extends AbstractOutput
$this->name = $command->getName();
$this->script = $command->getScript();
$this->readOnly = $command->isReadOnly();
$this->parameters = $command->isParameters();
$this->enabled = $command->isEnabled();
$this->comments = $command->getComments();
$this->createdAt = $command->getCreatedAt();

View File

@ -21,6 +21,9 @@ class ImageImageRepositoryOutput extends AbstractOutput
#[Groups(['image-image-repository:read', 'image:read'])]
public ?string $imageFullsum = null;
#[Groups(['image-image-repository:read', 'image:read'])]
public ?string $datasize = null;
#[Groups(['image-image-repository:read', 'image:read'])]
public \DateTime $createdAt;
@ -43,6 +46,7 @@ class ImageImageRepositoryOutput extends AbstractOutput
$this->status = $imageImageRepository->getStatus();
$this->imageFullsum = $imageImageRepository->getImageFullsum();
$this->datasize = $imageImageRepository->getDatasize();
$this->createdAt = $imageImageRepository->getCreatedAt();
$this->createdBy = $imageImageRepository->getCreatedBy();
}

View File

@ -59,7 +59,7 @@ final class TraceOutput extends AbstractOutput
$this->output = $trace->getOutput();
$this->input = $trace->getInput();
$this->finishedAt = $trace->getFinishedAt();
$this->progress = $trace->getProgress() / 100;
$this->progress = $trace->getProgress();
$this->createdAt = $trace->getCreatedAt();
$this->createdBy = $trace->getCreatedBy();
}