refs #1740. Run assistant logic
testing/ogcore-api/pipeline/head This commit looks good Details

pull/27/head
Manuel Aranda Rosales 2025-04-01 10:58:55 +02:00
parent 2d6b058eaf
commit bc036b65cf
13 changed files with 171 additions and 16 deletions

View File

@ -50,6 +50,13 @@ resources:
uriTemplate: /clients/server/{uuid}/get-pxe
controller: App\Controller\OgBoot\PxeBootFile\GetAction
login_client:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\MultipleClientsInput
uriTemplate: /clients/server/login-client
controller: App\Controller\OgAgent\LoginAction
reboot_client:
class: ApiPlatform\Metadata\Post
method: POST

View File

@ -28,9 +28,8 @@ resources:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\CommandExecuteInput
uriTemplate: /commands/{uuid}/execute
controller: App\Controller\CommandExecuteAction
uriTemplate: /commands/run-script
controller: App\Controller\OgAgent\RunScriptAction
properties:
App\Entity\Command:
id:

View File

@ -42,7 +42,7 @@ services:
api_platform.filter.command.boolean:
parent: 'api_platform.doctrine.orm.boolean_filter'
arguments: [ { 'enabled': ~ } ]
arguments: [ { 'enabled': ~, 'readOnly': ~ } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.hardware.order:

View File

@ -0,0 +1,78 @@
<?php
namespace App\Controller\OgAgent;
use App\Dto\Input\CommandExecuteInput;
use App\Dto\Input\MultipleClientsInput;
use App\Entity\Client;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
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\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class RunScriptAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
public function __invoke(CommandExecuteInput $input): JsonResponse
{
/** @var Client $clientEntity */
foreach ($input->clients as $clientEntity) {
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new ValidatorException('IP is required');
}
//TODO: base64 script content
$data = [
'nfn' => 'EjecutarScript',
'scp' => $input->script,
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/EjecutarScript', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
]);
$this->logger->info('Rebooting client', ['client' => $client->getId()]);
} catch (TransportExceptionInterface $e) {
$this->logger->error('Error 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'];
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::RUN_SCRIPT, TraceStatus::SUCCESS, $jobId, []);
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -56,13 +56,16 @@ class SyncAction extends AbstractOgRepositoryController
if (!$imageImageRepositoryEntity) {
$imageImageRepositoryEntity = new ImageImageRepository();
$imageImageRepositoryEntity->setImageFullsum($image['fullsum']);
$imageImageRepositoryEntity->setStatus(ImageStatus::SUCCESS);
$imageImageRepositoryEntity->setImage($imageEntity);
$imageImageRepositoryEntity->setRepository($input);
$this->entityManager->persist($imageImageRepositoryEntity);
}
$imageImageRepositoryEntity->setImageFullsum($image['fullsum']);
$imageImageRepositoryEntity->setDatasize($image['datasize']);
$imageImageRepositoryEntity->setStatus(ImageStatus::SUCCESS);
$imageImageRepositoryEntity->setImage($imageEntity);
$imageImageRepositoryEntity->setRepository($input);
$this->entityManager->persist($imageImageRepositoryEntity);
}
foreach ($existingImages as $existingImage) {

View File

@ -14,4 +14,9 @@ final class CommandExecuteInput
#[Assert\NotNull]
#[Groups(['command:write'])]
public array $clients = [];
#[Assert\NotNull]
#[Groups(['command:write'])]
public string $script = '';
}

View File

@ -82,6 +82,9 @@ class Client extends AbstractEntity
#[ORM\Column(nullable: true)]
private ?bool $pxeSync = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $firmwareType = null;
public function __construct()
{
parent::__construct();
@ -335,4 +338,16 @@ class Client extends AbstractEntity
return $this;
}
public function getFirmwareType(): ?string
{
return $this->firmwareType;
}
public function setFirmwareType(?string $firmwareType): static
{
$this->firmwareType = $firmwareType;
return $this;
}
}

View File

@ -35,6 +35,9 @@ class Command extends AbstractEntity
#[ORM\ManyToMany(targetEntity: CommandTask::class, mappedBy: 'commands')]
private Collection $commandTasks;
#[ORM\Column(nullable: true)]
private ?bool $parameters = null;
public function __construct()
{
parent::__construct();
@ -131,4 +134,16 @@ class Command extends AbstractEntity
return $this;
}
public function isParameters(): ?bool
{
return $this->parameters;
}
public function setParameters(?bool $parameters): static
{
$this->parameters = $parameters;
return $this;
}
}

View File

@ -28,6 +28,9 @@ class ImageImageRepository extends AbstractEntity
#[ORM\Column(length: 255, nullable: true)]
private ?string $imageFullsum = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $datasize = null;
public function getImage(): ?Image
{
return $this->image;
@ -87,4 +90,16 @@ class ImageImageRepository extends AbstractEntity
return $this;
}
public function getDatasize(): ?string
{
return $this->datasize;
}
public function setDatasize(?string $datasize): static
{
$this->datasize = $datasize;
return $this;
}
}

View File

@ -42,7 +42,7 @@ class TraceStatusProgressNotifier
{
$update = new Update(
'traces',
json_encode(['@id' => '/traces/' . $trace->getUuid(), 'status' => $trace->getStatus(), 'progress' => $trace->getProgress() / 100])
json_encode(['@id' => '/traces/' . $trace->getUuid(), 'status' => $trace->getStatus(), 'progress' => $trace->getProgress()])
);
$this->hub->publish($update);

View File

@ -58,12 +58,18 @@ final readonly class OrganizationalUnitSubscriber implements EventSubscriberInte
{
/** @var OrganizationalUnit $childUnit */
foreach ($parentUnit->getOrganizationalUnits() as $childUnit) {
//var_dump($childUnit->getNetworkSettings()->getMcastPort());
if ($childUnit->isExcludeParentChanges()) {
$childUnit->setNetworkSettings(null);
} else{
$childUnit->setNetworkSettings($networkSettings);
foreach ($childUnit->getClients() as $client) {
$client->setOgLive($networkSettings->getOgLive());
$client->setMenu($networkSettings->getMenu());
$client->setRepository($networkSettings->getRepository());
$this->entityManager->persist($client);
}
}
$this->entityManager->persist($childUnit);

View File

@ -21,6 +21,7 @@ final class CommandTypes
public const string LOGOUT = 'logout';
public const string PARTITION_AND_FORMAT = 'partition-and-format';
public const string INSTALL_OGLIVE = 'install-oglive';
public const string RUN_SCRIPT = 'run-script';
private const array COMMAND_TYPES = [
self::DEPLOY_IMAGE => 'Deploy Image',
@ -40,6 +41,7 @@ final class CommandTypes
self::PARTITION_AND_FORMAT => 'Partition and Format',
self::TRANSFER_IMAGE => 'Transfer Image',
self::INSTALL_OGLIVE => 'Instalar OgLive',
self::RUN_SCRIPT => 'Run Script',
];
public static function getCommandTypes(): array

View File

@ -26,11 +26,19 @@ class CreatePartitionService
$receivedPartitions = [];
foreach ($data['cfg'] as $cfg) {
if (!isset($cfg['disk'], $cfg['par'], $cfg['tam'], $cfg['uso'], $cfg['fsi'])) {
continue;
}
$filteredCfg = array_filter($data['cfg'], function ($cfg) {
return isset($cfg['disk'], $cfg['par'], $cfg['tam'], $cfg['uso'], $cfg['fsi']);
});
foreach ($data['cfg'] as $cfg) {
if (!empty($cfg['fwt'])) {
$clientEntity->setFirmwareType($cfg['fwt']);
$this->entityManager->persist($clientEntity);
break;
}
}
foreach ($filteredCfg as $cfg) {
$partitionEntity = $this->entityManager->getRepository(Partition::class)
->findOneBy(['client' => $clientEntity, 'diskNumber' => $cfg['disk'], 'partitionNumber' => $cfg['par']]);
@ -38,6 +46,8 @@ class CreatePartitionService
$partitionEntity = new Partition();
}
$partitionEntity->setOperativeSystem(null);
if (isset($cfg['soi']) && $cfg['soi'] !== '') {
$operativeSystem = $this->entityManager->getRepository(OperativeSystem::class)
->findOneBy(['name' => $cfg['soi']]);