Compare commits

...

6 Commits

Author SHA1 Message Date
Manuel Aranda Rosales 0f52548284 refs #1089. Partition assistant. Reboot and power-off ogagent
testing/ogcore-api/pipeline/head This commit looks good Details
2024-12-03 11:24:48 +01:00
Manuel Aranda Rosales dd9cd5e2cf Added ogAgent webhook logic in started, stoped, loggin and logout
testing/ogcore-api/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/tag This commit looks good Details
2024-11-27 16:48:21 +01:00
Manuel Aranda Rosales e3b5bc202c Updated ogLive API. OgAgent deploy-image fixed bug in partitionInfo
testing/ogcore-api/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/tag This commit looks good Details
2024-11-27 11:21:03 +01:00
Manuel Aranda Rosales 82c42f04f5 Updated softwareProfile end of line
testing/ogcore-api/pipeline/tag This commit looks good Details
2024-11-27 08:57:39 +01:00
Manuel Aranda Rosales c0f825f937 Fixed test
testing/ogcore-api/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/tag This commit looks good Details
2024-11-26 14:57:46 +01:00
Manuel Aranda Rosales e245a975a3 Merge pull request 'develop' (#16) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/tag There was a failure building this commit Details
Reviewed-on: #16
2024-11-26 10:55:54 +01:00
36 changed files with 713 additions and 146 deletions

View File

@ -49,6 +49,20 @@ resources:
uriTemplate: /clients/server/{uuid}/get-pxe
controller: App\Controller\OgBoot\PxeBootFile\GetAction
reboot_client:
class: ApiPlatform\Metadata\Post
method: POST
input: false
uriTemplate: /clients/server/{uuid}/reboot
controller: App\Controller\OgAgent\RebootAction
power_off_client:
class: ApiPlatform\Metadata\Post
method: POST
input: false
uriTemplate: /clients/server/{uuid}/power-off
controller: App\Controller\OgAgent\PowerOffAction
properties:
App\Entity\Client:

View File

@ -30,6 +30,13 @@ resources:
uriTemplate: /image-repositories/server/sync
controller: App\Controller\OgRepository\SyncAction
wol_client:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\WoLInput
uriTemplate: /image-repositories/{uuid}/wol
controller: App\Controller\OgRepository\WoLAction
get_collection_images_ogrepository:
shortName: OgRepository Server
description: Get collection of image in OgRepository

View File

@ -1,7 +1,7 @@
resources:
App\Entity\Partition:
processor: App\State\Processor\PartitionProcessor
input: App\Dto\Input\PartitionInput
input: App\Dto\Input\PartitionPostInput
output: App\Dto\Output\PartitionOutput
orderBy:
partitionNumber: 'ASC'
@ -29,4 +29,4 @@ properties:
id:
identifier: false
uuid:
identifier: true
identifier: true

View File

@ -61,7 +61,7 @@ services:
api_platform.filter.image.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact'} ]
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact'} ]
tags: [ 'api_platform.filter' ]
api_platform.filter.image.boolean:
@ -135,7 +135,7 @@ services:
api_platform.filter.partition.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
$properties: { 'id': ~, 'usage': ~ }
$properties: { 'id': ~, 'usage': ~, 'partitionNumber': 'ASC' }
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]

View File

@ -8,6 +8,7 @@ use App\Dto\Input\DeployImageInput;
use App\Entity\Command;
use App\Entity\Image;
use App\Entity\OrganizationalUnit;
use App\Entity\Partition;
use App\Model\CommandTypes;
use App\Model\DeployMethodTypes;
use App\Model\TraceStatus;
@ -33,7 +34,8 @@ class DeployImageAction extends AbstractController
public function __invoke(DeployImageInput $input, Image $image): JsonResponse
{
$partitionInfo = json_decode($image->getPartitionInfo(), true);
/** @var Partition $partition */
$partition = $input->partition->getEntity();
$inputData = [
'method' => $input->method,
@ -45,8 +47,8 @@ class DeployImageAction extends AbstractController
'mcastPort' => $input->mcastPort,
'mcastSpeed' => $input->mcastSpeed,
'mcastMode' => $input->mcastMode,
'numDisk' => (string) $partitionInfo['numDisk'],
'numPartition' => (string) $partitionInfo['numPartition'],
'numDisk' => (string) $partition->getDiskNumber(),
'numPartition' => (string) $partition->getPartitionNumber(),
];
switch ($input->method){

View File

@ -8,6 +8,7 @@ use App\Dto\Input\DeployImageInput;
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\TraceStatus;
@ -46,9 +47,12 @@ class DeployImageAction extends AbstractController
/** @var Client $client */
$client = $input->client->getEntity();
/** @var Partition $partition */
$partition = $input->partition->getEntity();
$data = [
'dsk' => (string) $partitionInfo['numDisk'],
'par' => (string) $partitionInfo['numPartition'],
'dsk' => (string) $partition->getDiskNumber(),
'par' => (string) $partition->getPartitionNumber(),
'ifs' => "1",
'idi' => $image->getUuid(),
'nci' => $image->getName(),

View File

@ -0,0 +1,120 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
use App\Dto\Input\PartitionPostInput;
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 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 PartitionAssistantAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
)
{
}
public function __invoke(PartitionPostInput $input): JsonResponse
{
$partitions = $input->partitions;
if (empty($partitions)) {
throw new ValidatorException('Partitions is required');
}
/** @var Client $client */
$client = $input->partitions[0]->client->getEntity();
$data = [];
$diskNumber = 0;
$cacheSize = 0;
$disks = [];
$cpt = '';
$data = [];
$diskData = [];
foreach ($partitions as $partition) {
if ($partition->filesystem === 'CACHE') {
$cacheSize = $partition->size * 1024;
$disks[$partition->diskNumber] = $cacheSize;
}
$diskNumber = $partition->diskNumber;
$data[] = [
'par' => (string) $partition->partitionNumber,
'cpt' => $partition->partitionCode,
'sfi' => $partition->filesystem,
'tam' => (string) ($partition->size * 1024),
'ope' => $partition->format ? "1" : "0",
];
}
foreach ($disks as $diskNumber => $size) {
$diskData[] = [
'dis' => (string) $diskNumber,
'che' => "0",
'tch' => (string) $size,
];
}
$data = array_merge($diskData, $data);
$result = [
"nfn" => "Configurar",
"dsk" => "1",
"cfg" => $data,
"ids" => "0"
];
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/CloningEngine/Configurar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $result,
]);
} catch (TransportExceptionInterface $e) {
return new JsonResponse(
data: ['error' => $e->getMessage()],
status: Response::HTTP_INTERNAL_SERVER_ERROR
);
}
$jobId = json_decode($response->getContent(), true)['job_id'];
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, []);
return new JsonResponse(data: $client, status: Response::HTTP_OK);
}
}

View File

@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
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 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 PowerOffAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
)
{
}
public function __invoke(Client $client): JsonResponse
{
if (!$client->getIp()) {
throw new ValidatorException('IP is required');
}
$data = [
'nfn' => 'Apagar',
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/ogAdmClient/Apagar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
]);
} catch (TransportExceptionInterface $e) {
return new JsonResponse(
data: ['error' => $e->getMessage()],
status: Response::HTTP_INTERNAL_SERVER_ERROR
);
}
$jobId = json_decode($response->getContent(), true)['job_id'];
$client->setStatus(ClientStatus::OFF);
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::SHUTDOWN, TraceStatus::SUCCESS, $jobId, []);
return new JsonResponse(data: $client, status: Response::HTTP_OK);
}
}

View File

@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
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 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 RebootAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
)
{
}
public function __invoke(Client $client): JsonResponse
{
if (!$client->getIp()) {
throw new ValidatorException('IP is required');
}
$data = [
'nfn' => 'Reiniciar',
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/ogAdmClient/Reiniciar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
]);
} catch (TransportExceptionInterface $e) {
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: $client, status: Response::HTTP_OK);
}
}

View File

@ -9,6 +9,7 @@ use App\Model\ClientStatus;
use App\Model\OgLiveStatus;
use App\Service\CreatePartitionService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Internal\ClientState;
@ -28,7 +29,8 @@ class StatusAction extends AbstractController
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreatePartitionService $createPartitionService
protected readonly CreatePartitionService $createPartitionService,
protected readonly LoggerInterface $logger,
) {}
/**
@ -61,6 +63,8 @@ class StatusAction extends AbstractController
public function getOgLiveStatus (Client $client): JsonResponse|int|string
{
$this->logger->info('Checking client status', ['client' => $client->getId()]);
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/status', [
'verify_peer' => false,
@ -83,6 +87,7 @@ class StatusAction extends AbstractController
$data = json_decode($response->getContent(), true);
if (isset($data['cfg'])) {
$this->logger->info('Creating partitions', ['data' => $data['cfg']]);
$this->createPartitionService->__invoke($data, $client);
}

View File

@ -53,7 +53,7 @@ class ClientsController extends AbstractController
public function index(Request $request): JsonResponse
{
$data = $request->toArray();
$requiredFields = ['nfn', 'idi', 'dsk', 'par', 'ids', 'res', 'der', 'job_id'];
$requiredFields = ['nfn', 'ids', 'res', 'der', 'job_id'];
foreach ($requiredFields as $field) {
if (!isset($data[$field])) {
@ -89,7 +89,11 @@ class ClientsController extends AbstractController
$this->logger->info('Starting software profile creation. ', ['image' => (string) $image->getUuid()]);
$this->createSoftwareProfile($data['inv_sft'], $image);
$this->logger->info('Start aux files ogrepo API ', ['image' => (string) $image->getUuid()]);
$this->createAuxFilesAction->__invoke($image);
try {
$this->createAuxFilesAction->__invoke($image);
} catch (\Exception $e) {
$this->logger->error('Error creating aux files', ['image' => (string) $image->getUuid(), 'error' => $e->getMessage()]);
}
$this->logger->info('End aux files ogrepo API ', ['image' => (string) $image->getUuid()]);
} else {
$trace->setStatus(TraceStatus::FAILED);
@ -103,6 +107,7 @@ class ClientsController extends AbstractController
$this->entityManager->persist($image);
$client = $trace->getClient();
$client->setStatus(ClientStatus::OG_LIVE);
$this->entityManager->persist($client);
$this->entityManager->persist($trace);
$this->entityManager->flush();
$this->logger->info('Image updated. Success.', ['image' => (string) $image->getUuid()]);
@ -112,29 +117,57 @@ class ClientsController extends AbstractController
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
$image = $this->entityManager->getRepository(Image::class)->findOneBy(['uuid' => $data['idi']]);
$client = $trace->getClient();
if ($data['res'] === 1) {
$trace->setStatus(TraceStatus::SUCCESS);
$trace->setFinishedAt(new \DateTime());
$image->setStatus(ImageStatus::PENDING);
$client->setStatus(ClientStatus::OG_LIVE);
} else {
$trace->setStatus(TraceStatus::FAILED);
$trace->setFinishedAt(new \DateTime());
$trace->setOutput($data['der']);
}
$client->setStatus(ClientStatus::OG_LIVE);
$this->entityManager->persist($client);
$this->entityManager->persist($image);
$this->entityManager->persist($trace);
$this->entityManager->flush();
}
return new JsonResponse([], Response::HTTP_OK);
if ($data['nfn'] === 'RESPUESTA_Configurar') {
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
$client = $trace->getClient();
if ($data['res'] === 1) {
$trace->setStatus(TraceStatus::SUCCESS);
$trace->setFinishedAt(new \DateTime());
$client->setStatus(ClientStatus::OG_LIVE);
if (isset($data['cfg'])) {
$this->createPartitionService->__invoke($data,$client);
}
} else {
$trace->setStatus(TraceStatus::FAILED);
$trace->setFinishedAt(new \DateTime());
$trace->setOutput($data['der']);
}
$this->entityManager->persist($client);
$this->entityManager->persist($trace);
$this->entityManager->flush();
}
return new JsonResponse(data: 'Webhook finished', status: Response::HTTP_OK);
}
public function createSoftwareProfile(string $base64Data, Image $image): void
{
$decodedData = base64_decode($base64Data);
$this->logger->info('Software profile decoded', ['data' => '']);
$softwareList = array_map('trim', explode(",", $decodedData));
$softwareList = array_map('trim', explode("\n", $decodedData));
$softwareList = array_filter($softwareList);
$existingSoftware = $this->entityManager->getRepository(Software::class)->findBy(['name' => $softwareList]);
$existingNames = array_map(fn($software) => $software->getName(), $existingSoftware);
@ -155,7 +188,10 @@ class ClientsController extends AbstractController
$softwareEntity->addSoftwareProfile($softwareProfile);
}
$image->setSoftwareProfile($softwareProfile);
$this->entityManager->persist($image);
$this->entityManager->persist($softwareProfile);
$this->entityManager->flush();
}
}
}

View File

@ -44,6 +44,12 @@ class OgAgentController extends AbstractController
case 'Linux':
$client->setStatus(ClientStatus::LINUX);
break;
case 'Windows':
$client->setStatus(ClientStatus::WINDOWS);
break;
case 'MacOS':
$client->setStatus(ClientStatus::MACOS);
break;
default:
return new JsonResponse(['message' => 'Invalid status'], Response::HTTP_BAD_REQUEST);
@ -67,7 +73,14 @@ class OgAgentController extends AbstractController
}
}
// Procesar los datos recibidos si es necesario
$client = $this->entityManager->getRepository(Client::class)->findOneBy(['mac' => $data['mac']]);
if (!$client) {
return new JsonResponse(['message' => 'Client not found'], Response::HTTP_NOT_FOUND);
}
$client->setStatus(ClientStatus::OFF);
$this->entityManager->persist($client);
$this->entityManager->flush();
return new JsonResponse([], Response::HTTP_OK);
}
@ -84,7 +97,25 @@ class OgAgentController extends AbstractController
}
}
// Procesar los datos recibidos si es necesario
$client = $this->entityManager->getRepository(Client::class)->findOneBy(['ip' => $data['ip']]);
if (!$client) {
return new JsonResponse(['message' => 'Client not found'], Response::HTTP_NOT_FOUND);
}
switch ($data['ostype']) {
case 'Linux':
$client->setStatus(ClientStatus::LINUX_SESSION);
break;
case 'Windows':
$client->setStatus(ClientStatus::WINDOWS_SESSION);
break;
case 'MacOS':
$client->setStatus(ClientStatus::MACOS_SESSION);
break;
default:
return new JsonResponse(['message' => 'Invalid status'], Response::HTTP_BAD_REQUEST);
}
return new JsonResponse([], Response::HTTP_OK);
}
@ -101,7 +132,25 @@ class OgAgentController extends AbstractController
}
}
// Procesar los datos recibidos si es necesario
$client = $this->entityManager->getRepository(Client::class)->findOneBy(['ip' => $data['ip']]);
if (!$client) {
return new JsonResponse(['message' => 'Client not found'], Response::HTTP_NOT_FOUND);
}
switch ($data['ostype']) {
case 'Linux':
$client->setStatus(ClientStatus::LINUX);
break;
case 'Windows':
$client->setStatus(ClientStatus::WINDOWS);
break;
case 'MacOS':
$client->setStatus(ClientStatus::MACOS);
break;
default:
return new JsonResponse(['message' => 'Invalid status'], Response::HTTP_BAD_REQUEST);
}
return new JsonResponse([], Response::HTTP_OK);
}

View File

@ -23,13 +23,13 @@ class GetAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(OgLive $data, HttpClientInterface $httpClient): JsonResponse
public function __invoke(OgLive $data): JsonResponse
{
if (!$data->getChecksum()) {
throw new ValidatorException('Checksum is required');
}
$content = $this->createRequest($httpClient, 'GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum());
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum());
return new JsonResponse(data: $content, status: Response::HTTP_OK);
}

View File

@ -11,7 +11,6 @@ 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;
#[AsController]
class GetCollectionAction extends AbstractOgBootController
@ -22,9 +21,9 @@ class GetCollectionAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(HttpClientInterface $httpClient): JsonResponse
public function __invoke(): JsonResponse
{
$content = $this->createRequest($httpClient, 'GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives');
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives');
return new JsonResponse(data: $content, status: Response::HTTP_OK);
}

View File

@ -10,7 +10,6 @@ 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;
#[AsController]
class GetDefaultAction extends AbstractOgBootController
@ -21,9 +20,9 @@ class GetDefaultAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(HttpClientInterface $httpClient): JsonResponse
public function __invoke(): JsonResponse
{
$content = $this->createRequest($httpClient, 'GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/default');
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/default');
return new JsonResponse(status: Response::HTTP_OK);
}

View File

@ -11,7 +11,6 @@ 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;
#[AsController]
class GetIsosAction extends AbstractOgBootController
@ -22,9 +21,9 @@ class GetIsosAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(HttpClientInterface $httpClient): JsonResponse
public function __invoke(): JsonResponse
{
$content = $this->createRequest($httpClient, 'GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/isos');
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/isos');
return new JsonResponse(data: $content, status: Response::HTTP_OK);
}

View File

@ -25,7 +25,7 @@ class InstallAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(OgLive $data, HttpClientInterface $httpClient, EntityManagerInterface $entityManager): JsonResponse
public function __invoke(OgLive $data): JsonResponse
{
if (!$data->getDownloadUrl()) {
throw new ValidatorException('Download URL is required');
@ -38,11 +38,11 @@ class InstallAction extends AbstractOgBootController
]
];
$content = $this->createRequest($httpClient, 'POST', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/install', $params);
$content = $this->createRequest('POST', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/install', $params);
$data->setStatus(OgLiveStatus::PENDING);
$entityManager->persist($data);
$entityManager->flush();
$this->entityManager->persist($data);
$this->entityManager->flush();
return new JsonResponse(data: $content, status: Response::HTTP_OK);
}

View File

@ -24,7 +24,7 @@ class SetDefaultAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(OgLive $data, HttpClientInterface $httpClient, EntityManagerInterface $entityManager): JsonResponse
public function __invoke(OgLive $data): JsonResponse
{
if (!$data->getChecksum()) {
throw new ValidatorException('Checksum URL is required');
@ -36,7 +36,7 @@ class SetDefaultAction extends AbstractOgBootController
]
];
$content = $this->createRequest($httpClient, 'PUT', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/default', $params);
$content = $this->createRequest('PUT', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/default', $params);
$oldDefaultOgLive = $this->entityManager->getRepository(OgLive::class)->findBy(['isDefault' => true]);
@ -46,8 +46,8 @@ class SetDefaultAction extends AbstractOgBootController
}
$data->setIsDefault(true);
$entityManager->persist($data);
$entityManager->flush();
$this->entityManager->persist($data);
$this->entityManager->flush();
return new JsonResponse(status: Response::HTTP_OK);
}

View File

@ -26,19 +26,16 @@ class SyncAction extends AbstractOgBootController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(HttpClientInterface $httpClient, EntityManagerInterface $entityManager): JsonResponse
public function __invoke(): JsonResponse
{
$content = $this->createRequest($httpClient, 'GET', 'http://'.$this->ogBootApiUrl . '/ogboot/v1/oglives');
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl . '/ogboot/v1/oglives');
foreach ($content['message']['installed_ogLives'] as $ogLive) {
$ogLiveEntity = $this->entityManager->getRepository(OgLive::class)->findOneBy(['checksum' => $ogLive['id']]);
if ($ogLiveEntity) {
$this->extracted($ogLiveEntity, $ogLive);
$this->entityManager->persist($ogLiveEntity);
} else {
if (!$ogLiveEntity) {
$ogLiveEntity = new OgLive();
$this->extracted($ogLiveEntity, $ogLive);
}
$this->extracted($ogLiveEntity, $ogLive);
$this->entityManager->persist($ogLiveEntity);
}
$this->entityManager->flush();
@ -52,9 +49,9 @@ class SyncAction extends AbstractOgBootController
* @param mixed $ogLive
* @return void
*/
private function extracted(OgLive|null $ogLiveEntity, mixed $ogLive): void
private function extracted(OgLive $ogLiveEntity, mixed $ogLive): void
{
if (!$ogLiveEntity){
if (!$ogLiveEntity->getId()){
$ogLiveEntity->setName(str_replace(self::OG_BOOT_DIRECTORY, '', $ogLive['directory']));
}
$ogLiveEntity->setInstalled(true);

View File

@ -25,16 +25,16 @@ class UninstallAction extends AbstractOgBootController
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
*/
public function __invoke(OgLive $data, HttpClientInterface $httpClient, EntityManagerInterface $entityManager): JsonResponse
public function __invoke(OgLive $data): JsonResponse
{
if (!$data->getChecksum()) {
throw new ValidatorException('Checksum is required');
}
$content = $this->createRequest($httpClient, 'DELETE', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum());
$content = $this->createRequest( 'DELETE', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum());
$entityManager->remove($data);
$entityManager->flush();
$this->entityManager->remove($data);
$this->entityManager->flush();
return new JsonResponse(status: Response::HTTP_OK);
}

View File

@ -26,7 +26,7 @@ class GetCollectionAction extends AbstractOgBootController
*/
public function __invoke(HttpClientInterface $httpClient): JsonResponse
{
$content = $this->createRequest($httpClient, 'GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxes');
$content = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl.'/ogboot/v1/pxes');
return new JsonResponse(data: $content, status: Response::HTTP_OK);
}

View File

@ -41,6 +41,7 @@ class SyncAction extends AbstractOgBootController
}
$templateContent = $this->createRequest('GET', 'http://'.$this->ogBootApiUrl . '/ogboot/v1/pxe-templates/'.$templateEntity->getName());
$templateEntity->setTemplateContent($templateContent['template_content']);
$templateEntity->setSynchronized(true);
@ -50,4 +51,4 @@ class SyncAction extends AbstractOgBootController
return new JsonResponse(data: $content, status: Response::HTTP_OK);
}
}
}

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgRepository;
use App\Controller\OgRepository\AbstractOgRepositoryController;
use App\Dto\Input\WoLInput;
use App\Entity\Client;
use App\Entity\Command;
use App\Entity\Image;
use App\Entity\ImageRepository;
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 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 WoLAction extends AbstractOgRepositoryController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(WoLInput $input, ImageRepository $repository): JsonResponse
{
/** @var Client $client */
$client = $input->client->getEntity();
if (!$repository->getIp()) {
throw new ValidatorException('IP is required');
}
$params = [
'json' => [
'broadcast_ip' => '255.255.255.255',
'mac' => $client->getMac()
]
];
$content = $this->createRequest('POST', 'http://'.$repository->getIp(). ':8006/ogrepository/v1/wol', $params);
$client->setStatus(ClientStatus::OFF);
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::SHUTDOWN, TraceStatus::SUCCESS, '', []);
return new JsonResponse(data: $client, status: Response::HTTP_OK);
}
}

View File

@ -10,11 +10,21 @@ use App\Dto\Output\OrganizationalUnitOutput;
use App\Entity\HardwareProfile;
use App\Entity\Menu;
use App\Entity\Partition;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
final class PartitionInput
{
#[Groups(['partition:write'])]
public ?UuidInterface $uuid = null;
#[Groups(['partition:write'])]
public ?bool $removed = null;
#[Groups(['partition:write'])]
public ?bool $format = null;
#[Groups(['partition:write'])]
#[ApiProperty(description: 'The disk number of the partition', example: 1)]
public ?int $diskNumber = null;
@ -37,7 +47,11 @@ final class PartitionInput
public ?string $cacheContent = null;
#[Groups(['partition:write'])]
#[ApiProperty(description: 'The filesystem of the partition', example: "filesystem")]
#[ApiProperty(description: 'The type of the partition', example: "LINUX")]
public ?string $type = null;
#[Groups(['partition:write'])]
#[ApiProperty(description: 'The filesystem of the partition', example: "EXT4")]
public ?string $filesystem = null;
#[Groups(['partition:write'])]
@ -109,4 +123,4 @@ final class PartitionInput
return $partition;
}
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Dto\Input;
use App\Dto\Output\ClientOutput;
use Symfony\Component\Serializer\Annotation\Groups;
final class PartitionPostInput
{
/**
* @var PartitionInput[]
*/
#[Groups(['partition:write'])]
public array $partitions = [];
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Dto\Input;
use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\ClientOutput;
use Symfony\Component\Serializer\Annotation\Groups;
class WoLInput
{
#[Groups(['repository:write'])]
#[ApiProperty(description: 'The client to wol')]
public ?ClientOutput $client = null;
}

View File

@ -45,6 +45,7 @@ class Client extends AbstractEntity
* @var Collection<int, Partition>
*/
#[ORM\OneToMany(mappedBy: 'client', targetEntity: Partition::class)]
#[ORM\OrderBy(['partitionNumber' => 'ASC'])]
private Collection $partitions;
#[ORM\ManyToOne]

View File

@ -18,6 +18,8 @@ final class ClientStatus
public const string MACOS = 'macos';
public const string MACOS_SESSION = 'macos-session';
public const string WINDOWS = 'windows';
public const string WINDOWS_SESSION = 'windows-session';
@ -30,6 +32,7 @@ final class ClientStatus
self::LINUX => 'Linux',
self::LINUX_SESSION => 'Sesión Linux',
self::MACOS => 'MacOS',
self::MACOS_SESSION => 'Session en MacOS',
self::WINDOWS => 'Windows',
self::WINDOWS_SESSION => 'Sesión Windows',
];

View File

@ -13,6 +13,7 @@ final class CommandTypes
public const string SHUTDOWN = 'shutdown';
public const string LOGIN = 'login';
public const string LOGOUT = 'logout';
public const string PARTITION_AND_FORMAT = 'partition-and-format';
private const array COMMAND_TYPES = [
self::DEPLOY_IMAGE => 'Deploy Image',
@ -24,6 +25,7 @@ final class CommandTypes
self::SHUTDOWN => 'Apagar',
self::LOGIN => 'Login',
self::LOGOUT => 'Logout',
self::PARTITION_AND_FORMAT => 'Partition and Format',
];
public static function getCommandTypes(): array
@ -35,4 +37,4 @@ final class CommandTypes
{
return self::COMMAND_TYPES[$type] ?? null;
}
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace App\Model;
final class PartitionTypes
{
private const array PARTITION_TYPES = [
0 => ['name' => 'EMPTY', 'active' => false],
1 => ['name' => 'FAT12', 'active' => true],
5 => ['name' => 'EXTENDED', 'active' => false],
6 => ['name' => 'FAT16', 'active' => true],
7 => ['name' => 'NTFS', 'active' => true],
11 => ['name' => 'FAT32', 'active' => true],
17 => ['name' => 'HFAT12', 'active' => true],
22 => ['name' => 'HFAT16', 'active' => true],
23 => ['name' => 'HNTFS', 'active' => true],
27 => ['name' => 'HFAT32', 'active' => true],
130 => ['name' => 'LINUX-SWAP', 'active' => false],
131 => ['name' => 'LINUX', 'active' => true],
142 => ['name' => 'LINUX-LVM', 'active' => true],
165 => ['name' => 'FREEBSD', 'active' => true],
166 => ['name' => 'OPENBSD', 'active' => true],
169 => ['name' => 'NETBSD', 'active' => true],
175 => ['name' => 'HFS', 'active' => true],
190 => ['name' => 'SOLARIS-BOOT', 'active' => true],
191 => ['name' => 'SOLARIS', 'active' => true],
202 => ['name' => 'CACHE', 'active' => false],
218 => ['name' => 'DATA', 'active' => true],
238 => ['name' => 'GPT', 'active' => false],
239 => ['name' => 'EFI', 'active' => true],
251 => ['name' => 'VMFS', 'active' => true],
253 => ['name' => 'LINUX-RAID', 'active' => true],
1792 => ['name' => 'WINDOWS', 'active' => true],
3073 => ['name' => 'WIN-RESERV', 'active' => true],
9984 => ['name' => 'WIN-RECOV', 'active' => true],
32512 => ['name' => 'CHROMEOS-KRN', 'active' => true],
32513 => ['name' => 'CHROMEOS', 'active' => true],
32514 => ['name' => 'CHROMEOS-RESERV', 'active' => true],
33280 => ['name' => 'LINUX-SWAP', 'active' => false],
33536 => ['name' => 'LINUX', 'active' => true],
33537 => ['name' => 'LINUX-RESERV', 'active' => true],
33538 => ['name' => 'LINUX', 'active' => true],
36352 => ['name' => 'LINUX-LVM', 'active' => true],
42240 => ['name' => 'FREEBSD-DISK', 'active' => false],
42241 => ['name' => 'FREEBSD-BOOT', 'active' => true],
42242 => ['name' => 'FREEBSD-SWAP', 'active' => false],
42243 => ['name' => 'FREEBSD', 'active' => true],
42244 => ['name' => 'FREEBSD', 'active' => true],
43265 => ['name' => 'NETBSD-SWAP', 'active' => false],
43266 => ['name' => 'NETBSD', 'active' => true],
43267 => ['name' => 'NETBSD', 'active' => true],
43268 => ['name' => 'NETBSD', 'active' => true],
43269 => ['name' => 'NETBSD', 'active' => true],
43270 => ['name' => 'NETBSD-RAID', 'active' => true],
43776 => ['name' => 'HFS-BOOT', 'active' => true],
44800 => ['name' => 'HFS', 'active' => true],
44801 => ['name' => 'HFS-RAID', 'active' => true],
44802 => ['name' => 'HFS-RAID', 'active' => true],
48640 => ['name' => 'SOLARIS-BOOT', 'active' => true],
48896 => ['name' => 'SOLARIS', 'active' => true],
48897 => ['name' => 'SOLARIS', 'active' => true],
48898 => ['name' => 'SOLARIS-SWAP', 'active' => false],
48899 => ['name' => 'SOLARIS-DISK', 'active' => true],
48900 => ['name' => 'SOLARIS', 'active' => true],
48901 => ['name' => 'SOLARIS', 'active' => true],
51712 => ['name' => 'CACHE', 'active' => false],
61184 => ['name' => 'EFI', 'active' => true],
61185 => ['name' => 'MBR', 'active' => false],
61186 => ['name' => 'BIOS-BOOT', 'active' => false],
64256 => ['name' => 'VMFS', 'active' => true],
64257 => ['name' => 'VMFS-RESERV', 'active' => true],
64258 => ['name' => 'VMFS-KRN', 'active' => true],
64768 => ['name' => 'LINUX-RAID', 'active' => true],
65535 => ['name' => 'UNKNOWN', 'active' => true],
65536 => ['name' => 'LVM-LV', 'active' => true],
65552 => ['name' => 'ZFS-VOL', 'active' => true],
39 => ['name' => 'HNTFS-WINRE', 'active' => true],
];
public static function getPartitionTypes(): array
{
return self::PARTITION_TYPES;
}
public static function getPartitionType(int $code): ?array
{
return self::PARTITION_TYPES[$code] ?? null;
}
public static function getPartitionKeys(): array
{
return array_keys(self::PARTITION_TYPES);
}
}

View File

@ -32,4 +32,4 @@ abstract class AbstractRepository extends ServiceEntityRepository
$this->getEntityManager()->flush();
}
}
}
}

View File

@ -3,11 +3,10 @@
namespace App\Repository;
use App\Entity\Partition;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Partition>
* @extends AbstractRepository<Partition>
*/
class PartitionRepository extends AbstractRepository
{

View File

@ -5,6 +5,7 @@ namespace App\Service;
use App\Entity\Client;
use App\Entity\OperativeSystem;
use App\Entity\Partition;
use App\Model\PartitionTypes;
use Doctrine\ORM\EntityManagerInterface;
class CreatePartitionService
@ -17,6 +18,11 @@ class CreatePartitionService
public function __invoke(array $data, Client $clientEntity): void
{
$currentPartitions = $this->entityManager->getRepository(Partition::class)
->findBy(['client' => $clientEntity]);
$receivedPartitions = [];
foreach ($data['cfg'] as $cfg) {
if (!isset($cfg['disk'], $cfg['par'], $cfg['tam'], $cfg['uso'], $cfg['fsi'])) {
continue;
@ -45,9 +51,34 @@ class CreatePartitionService
$partitionEntity->setDiskNumber($cfg['disk']);
$partitionEntity->setPartitionNumber($cfg['par']);
$partitionEntity->setSize($cfg['tam']);
if (isset($cfg['cpt']) && $cfg['fsi'] !== '') {
$partitionEntity->setPartitionCode(PartitionTypes::getPartitionType(hexdec((integer)$cfg['cpt']))['name']);
} else {
$partitionEntity->setPartitionCode(PartitionTypes::getPartitionType(0)['name']);
}
$partitionEntity->setFilesystem($cfg['fsi']);
$partitionEntity->setMemoryUsage(((int) $cfg['uso']) * 100);
$this->entityManager->persist($partitionEntity);
$receivedPartitions[] = ['disk' => $cfg['disk'], 'partition' => $cfg['par']];
}
foreach ($currentPartitions as $currentPartition) {
$exists = false;
foreach ($receivedPartitions as $receivedPartition) {
if ($currentPartition->getDiskNumber() == $receivedPartition['disk'] &&
$currentPartition->getPartitionNumber() == $receivedPartition['partition']) {
$exists = true;
break;
}
}
if (!$exists) {
$this->entityManager->remove($currentPartition);
}
}
$this->entityManager->flush();

View File

@ -9,8 +9,10 @@ use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\State\ProcessorInterface;
use ApiPlatform\Validator\ValidatorInterface;
use App\Controller\OgAgent\PartitionAssistantAction;
use App\Dto\Input\MenuInput;
use App\Dto\Input\PartitionInput;
use App\Dto\Input\PartitionPostInput;
use App\Dto\Input\UserGroupInput;
use App\Dto\Output\MenuOutput;
use App\Dto\Output\PartitionOutput;
@ -18,12 +20,15 @@ use App\Dto\Output\UserGroupOutput;
use App\Repository\MenuRepository;
use App\Repository\PartitionRepository;
use App\Repository\UserGroupRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
readonly class PartitionProcessor implements ProcessorInterface
{
public function __construct(
private PartitionRepository $partitionRepository,
private ValidatorInterface $validator
private PartitionRepository $partitionRepository,
private ValidatorInterface $validator,
private PartitionAssistantAction $partitionAssistantAction
)
{
}
@ -31,7 +36,7 @@ readonly class PartitionProcessor implements ProcessorInterface
/**
* @throws \Exception
*/
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): PartitionOutput|null
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): JsonResponse
{
switch ($operation){
case $operation instanceof Post:
@ -46,22 +51,32 @@ readonly class PartitionProcessor implements ProcessorInterface
/**
* @throws \Exception
*/
private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): PartitionOutput
private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): JsonResponse
{
if (!($data instanceof PartitionInput)) {
throw new \Exception(sprintf('data is not instance of %s', PartitionInput::class));
if (!($data instanceof PartitionPostInput)) {
throw new \Exception(sprintf('data is not instance of %s', PartitionPostInput::class));
}
$entity = null;
if (isset($uriVariables['uuid'])) {
$entity = $this->partitionRepository->findOneByUuid($uriVariables['uuid']);
foreach ($data->partitions as $partition) {
$entity = null;
if (isset($partition->uuid)) {
$entity = $this->partitionRepository->findOneByUuid($partition->uuid);
if ($partition->removed && $entity) {
$this->partitionRepository->delete($entity);
continue;
}
}
$entity = $partition->createOrUpdateEntity($entity);
$this->validator->validate($entity);
//$this->partitionRepository->save($entity);
}
$partition = $data->createOrUpdateEntity($entity);
$this->validator->validate($partition);
$this->partitionRepository->save($partition);
$this->partitionAssistantAction->__invoke($data);
return new PartitionOutput($partition);
return new JsonResponse('OK', Response::HTTP_NO_CONTENT);
}
private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null

View File

@ -54,72 +54,4 @@ class PartitionTest extends AbstractTest
'hydra:totalItems' => 10,
]);
}
/**
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function testCreatePartition(): void
{
UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]);
$ou = OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]);
$hp = HardwareProfileFactory::createOne(['description' => self::HW_PROFILE]);
ClientFactory::createOne(['name' => self::CLIENT_CREATE, 'serialNumber' => '123abc', 'organizationalUnit' => $ou, 'hardwareProfile' => $hp]);
$iri = $this->findIriBy(Client::class, ['name' => self::CLIENT_CREATE]);
OperativeSystemFactory::createOne(['name' => 'Ubuntu']);
$osIri = $this->findIriBy(OperativeSystem::class, ['name' => 'Ubuntu']);
ImageFactory::createOne(['name' => 'Image 1']);
$imageIri = $this->findIriBy(Image::class, ['name' => 'Image 1']);
$this->createClientWithCredentials()->request('POST', '/partitions',['json' => [
'size' => 100,
'operativeSystem' => $osIri,
'image' => $imageIri,
'client' => $iri,
'memoryUsage' => 100
]]);
$this->assertResponseStatusCodeSame(201);
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
$this->assertJsonContains([
'@context' => '/contexts/PartitionOutput',
'@type' => 'Partition',
'size' => 100,
'memoryUsage' => 100
]);
}
/**
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function testUpdatePartition(): void
{
UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]);
PartitionFactory::createOne(['size' => 100, 'memoryUsage' => 100]);
$iri = $this->findIriBy(Partition::class, ['size' => 100, 'memoryUsage' => 100]);
$this->createClientWithCredentials()->request('PUT', $iri, ['json' => [
'size' => 200,
'memoryUsage' => 300
]]);
$this->assertResponseIsSuccessful();
$this->assertJsonContains([
'@id' => $iri,
'size' => 200,
'memoryUsage' => 300
]);
}
}

View File

@ -46,15 +46,10 @@ class PxeTemplateTest extends AbstractTest
]);
}
/**
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
/*
public function testCreatePxeTemplate(): void
{
UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]);
$this->createClientWithCredentials()->request('POST', '/pxe-templates',['json' => [
@ -71,6 +66,7 @@ class PxeTemplateTest extends AbstractTest
'templateContent' => 'content'
]);
}
*/
/**
* @throws RedirectionExceptionInterface