Updated Partition and Image. Added UDS endpoints
testing/ogcore-api/pipeline/head This commit looks good Details

develop-jenkins
Manuel Aranda Rosales 2024-10-08 12:29:51 +02:00
parent ea35ddd1e4
commit c32363c974
23 changed files with 588 additions and 13 deletions

View File

@ -29,7 +29,7 @@ security:
- { path: ^/$, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI
- { path: ^/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI docs
- { path: ^/auth/login, roles: PUBLIC_ACCESS }
- { path: ^/opengnsys/rest/, roles: PUBLIC_ACCESS }
- { path: ^/opengnsys/rest, roles: PUBLIC_ACCESS }
- { path: ^/og-lives/install/webhook, roles: PUBLIC_ACCESS }
- { path: ^/auth/refresh, roles: PUBLIC_ACCESS }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }

View File

@ -0,0 +1,35 @@
<?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 Version20241008080902 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 `partition` ADD image_id INT NOT NULL');
$this->addSql('ALTER TABLE `partition` ADD CONSTRAINT FK_9EB910E43DA5256D FOREIGN KEY (image_id) REFERENCES image (id)');
$this->addSql('CREATE INDEX IDX_9EB910E43DA5256D ON `partition` (image_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE `partition` DROP FOREIGN KEY FK_9EB910E43DA5256D');
$this->addSql('DROP INDEX IDX_9EB910E43DA5256D ON `partition`');
$this->addSql('ALTER TABLE `partition` DROP image_id');
}
}

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 Version20241008081013 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 maintenance TINYINT(1) NOT 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 maintenance');
}
}

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 Version20241008092247 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 CHANGE software_profile_id software_profile_id INT DEFAULT NULL, CHANGE path path VARCHAR(255) DEFAULT NULL, CHANGE type type VARCHAR(255) DEFAULT NULL, CHANGE size size INT 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 CHANGE software_profile_id software_profile_id INT NOT NULL, CHANGE path path VARCHAR(255) NOT NULL, CHANGE type type VARCHAR(255) NOT NULL, CHANGE size size INT NOT NULL');
}
}

View File

@ -0,0 +1,35 @@
<?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 Version20241008092849 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 ADD organizational_unit_id INT NOT NULL');
$this->addSql('ALTER TABLE image ADD CONSTRAINT FK_C53D045FFB84408A FOREIGN KEY (organizational_unit_id) REFERENCES organizational_unit (id)');
$this->addSql('CREATE INDEX IDX_C53D045FFB84408A ON image (organizational_unit_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image DROP FOREIGN KEY FK_C53D045FFB84408A');
$this->addSql('DROP INDEX IDX_C53D045FFB84408A ON image');
$this->addSql('ALTER TABLE image DROP organizational_unit_id');
}
}

View File

@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace App\Command\Migration;
use App\Entity\Client;
use App\Entity\Image;
use App\Entity\OrganizationalUnit;
use App\Model\OrganizationalUnitTypes;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand(name: 'opengnsys:migration:images', description: 'Migrate images data')]
class MigrateImagesCommand extends Command
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly ManagerRegistry $doctrine
)
{
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var EntityManagerInterface $oldDatabaseEntityManager */
$oldDatabaseEntityManager = $this->doctrine->getManager('og_1');
$imagesRepository = $this->entityManager->getRepository(Image::class);
$clientRepository = $this->entityManager->getRepository(Client::class);
$ouRepository = $this->entityManager->getRepository(OrganizationalUnit::class);
/** Obtener las imágenes de la base de datos antigua **/
$rsmOperativeSystems = new ResultSetMapping();
$rsmOperativeSystems->addScalarResult('idimagen', 'idimagen');
$rsmOperativeSystems->addScalarResult('nombreca', 'nombreca');
$rsmOperativeSystems->addScalarResult('idcentro', 'centros.idcentro');
$rsmOperativeSystems->addScalarResult('idordenador', 'ordenadores.idordenador');
$rsmOperativeSystems->addScalarResult('numdisk', 'numdisk');
$rsmOperativeSystems->addScalarResult('ruta', 'ruta');
$rsmOperativeSystems->addScalarResult('numpar', 'numpar');
$rsmOperativeSystems->addScalarResult('revision', 'revision');
$rsmOperativeSystems->addScalarResult('descripcion', 'descripcion');
$rsmOperativeSystems->addScalarResult('comentarios', 'comentarios');
$imagesQuery = $oldDatabaseEntityManager->createNativeQuery('SELECT idimagen, nombreca, ruta, ordenadores.idordenador, centros.idcentro, numdisk, numpar, revision, descripcion, imagenes.comentarios FROM imagenes LEFT JOIN ordenadores ON imagenes.idordenador = ordenadores.idordenador LEFT JOIN centros ON imagenes.idcentro = imagenes.idcentro', $rsmOperativeSystems);
$images = $imagesQuery->getResult();
/** Imágenes **/
$output->writeln("IMÁGENES TOTAL: ". count($images));
foreach ($images as $image){
$ouEntity = $ouRepository->findOneBy(['migrationId' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT.'-'.$image['centros.idcentro']]);
if (!$ouEntity) {
$output->writeln("No se ha encontrado la OU con id: ". $image['centros.idcentro']);
continue;
}
$clientEntity = $clientRepository->findOneBy(['migrationId' => $image['ordenadores.idordenador']]);
if(!$clientEntity){
$output->writeln("No se ha encontrado el cliente con id: ". $image['ordenadores.idordenador']);
continue;
}
$imageEntity = $imagesRepository->findOneBy(['migrationId' => $image['idimagen']]);
if(!$imageEntity) {
$imageEntity = new Image();
$imageEntity->setMigrationId((string) $image['idimagen']);
$imageEntity->setName($image['nombreca']);
$imageEntity->setClient($clientEntity);
$imageEntity->setOrganizationalUnit($ouEntity);
$imageEntity->setRevision((string) $image['revision']);
$imageEntity->setDescription($image['descripcion']);
$imageEntity->setComments($image['comentarios']);
}
$this->entityManager->persist($imageEntity);
}
$this->entityManager->flush();
return Command::SUCCESS;
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace App\Controller\UDS;
use App\Entity\Image;
use App\Entity\OrganizationalUnit;
use App\Model\OrganizationalUnitTypes;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;
#[AsController]
class OrganizationalUnitController extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager
)
{
}
#[Route('/opengnsys/rest//ous', methods: ['GET'])]
public function getOUs(Request $request): JsonResponse
{
$organizationalUnits = $this->entityManager
->getRepository(OrganizationalUnit::class)
->findBy(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT], ['name' => 'ASC']);
$data = [];
foreach ($organizationalUnits as $center) {
$data[] = [
'id' => $center->getId(),
'name' => $center->getName(),
'description' => $center->getDescription(),
];
}
return new JsonResponse($data, Response::HTTP_OK);
}
#[Route('/opengnsys/rest//ous/{centerId}/labs', methods: ['GET'])]
public function getClassrooms(Request $request, int $centerId): JsonResponse
{
$classrooms = $this->entityManager
->getRepository(OrganizationalUnit::class)
->findBy([
'type' => OrganizationalUnitTypes::CLASSROOM,
'parent' => $centerId
], ['name' => 'ASC']);
$data = [];
foreach ($classrooms as $classroom) {
$data[] = [
'id' => $classroom->getId(),
'name' => $classroom->getName(),
'description' => $classroom->getDescription(),
];
}
return new JsonResponse($data, Response::HTTP_OK);
}
#[Route('/opengnsys/rest//ous/{centerId}/images', methods: ['GET'])]
public function getImages(Request $request, int $centerId): JsonResponse
{
$images = $this->entityManager
->getRepository(Image::class)
->findBy([
'organizationalUnit' => $centerId,
], ['name' => 'ASC']);
$data = [];
foreach ($images as $image) {
$data[] = [
'id' => $image->getId(),
'name' => $image->getName(),
];
}
return new JsonResponse($data, Response::HTTP_OK);
}
}

View File

@ -102,6 +102,13 @@ final class ClientInput
)]
public ?OgRepository $repository = null;
#[Groups(['client:write'])]
#[ApiProperty(
description: 'descriptions.client.validation'
)]
public ?bool $maintenance = false;
public function __construct(?Client $client = null)
{
if (!$client) {
@ -149,6 +156,7 @@ final class ClientInput
$client->setHardwareProfile($this->hardwareProfile?->getEntity());
$client->setPosition($this->position);
$client->setStatus($this->status);
$client->setMaintenance($this->maintenance);
return $client;
}

View File

@ -4,8 +4,10 @@ namespace App\Dto\Input;
use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\ClientOutput;
use App\Dto\Output\OrganizationalUnitOutput;
use App\Dto\Output\SoftwareProfileOutput;
use App\Entity\Image;
use App\Entity\OrganizationalUnit;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
@ -52,6 +54,10 @@ final class ImageInput
#[ApiProperty(description: 'The software profile of the image')]
public ?SoftwareProfileOutput $softwareProfile = null;
#[Groups(['image:write'])]
#[ApiProperty(description: 'The organizational unit of the image')]
public ?OrganizationalUnitOutput $organizationalUnit = null;
public function __construct(?Image $image = null)
{
if (!$image) {
@ -68,6 +74,7 @@ final class ImageInput
$this->size = $image->getSize();
$this->client = new ClientOutput($image->getClient());
$this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile());
$this->organizationalUnit = new OrganizationalUnitOutput($image->getOrganizationalUnit());
}
public function createOrUpdateEntity(?Image $image = null): Image
@ -87,6 +94,12 @@ final class ImageInput
$image->setClient($this->client->getEntity());
$image->setSoftwareProfile($this->softwareProfile->getEntity());
if ($this->organizationalUnit) {
$image->setOrganizationalUnit($this->organizationalUnit->getEntity());
} else {
$image->setOrganizationalUnit($this->client->getEntity()->getOrganizationalUnit());
}
return $image;
}
}

View File

@ -4,6 +4,7 @@ namespace App\Dto\Input;
use ApiPlatform\Metadata\ApiProperty;
use App\Dto\Output\ClientOutput;
use App\Dto\Output\ImageOutput;
use App\Dto\Output\OperativeSystemOutput;
use App\Dto\Output\OrganizationalUnitOutput;
use App\Entity\HardwareProfile;
@ -54,6 +55,10 @@ final class PartitionInput
#[ApiProperty(description: 'The memory usage of the partition', example: 100)]
public ?int $memoryUsage = null;
#[Groups(['partition:write'])]
#[ApiProperty(description: 'The image of the partition')]
public ?ImageOutput $image = null;
public function __construct(?Partition $partition = null)
{
if (!$partition) {
@ -69,6 +74,7 @@ final class PartitionInput
$this->operativeSystem = new OperativeSystemOutput($partition->getOperativeSystem());
$this->client = new ClientOutput($partition->getClient());
$this->memoryUsage = $partition->getMemoryUsage();
$this->image = new ImageOutput($partition->getImage());
}
public function createOrUpdateEntity(?Partition $partition = null): Partition
@ -86,6 +92,7 @@ final class PartitionInput
$partition->setOperativeSystem($this->operativeSystem->getEntity());
$partition->setClient($this->client->getEntity());
$partition->setMemoryUsage($this->memoryUsage * 100);
$partition->setImage($this->image->getEntity());
return $partition;
}

View File

@ -64,6 +64,9 @@ final class ClientOutput extends AbstractOutput
#[Groups(['client:read'])]
public ?string $createdBy = null;
#[Groups(['client:read'])]
public ?bool $maintenance = false;
public function __construct(Client $client)
{
parent::__construct($client);
@ -90,5 +93,6 @@ final class ClientOutput extends AbstractOutput
$this->status = $client->getStatus();
$this->createdAt = $client->getCreatedAt();
$this->createdBy = $client->getCreatedBy();
$this->maintenance = $client->isMaintenance();
}
}

View File

@ -19,7 +19,7 @@ final class ImageOutput extends AbstractOutput
public ?string $comments = '';
#[Groups(['image:read'])]
public ?string $type = '';
public ?string $type = null;
#[Groups(['image:read'])]
public ?string $path = '';
@ -39,6 +39,9 @@ final class ImageOutput extends AbstractOutput
#[Groups(['image:read'])]
public ?SoftwareProfileOutput $softwareProfile = null;
#[Groups(['image:read'])]
public ?OrganizationalUnitOutput $organizationalUnit = null;
public function __construct(Image $image)
{
parent::__construct($image);
@ -53,5 +56,6 @@ final class ImageOutput extends AbstractOutput
$this->size = $image->getSize();
$this->clientOutput = new ClientOutput($image->getClient());
$this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile());
$this->organizationalUnit = new OrganizationalUnitOutput($image->getOrganizationalUnit());
}
}

View File

@ -68,6 +68,9 @@ class Client extends AbstractEntity
#[ORM\ManyToOne(inversedBy: 'clients')]
private ?OgLive $ogLive = null;
#[ORM\Column]
private ?bool $maintenance = null;
public function __construct()
{
parent::__construct();
@ -283,4 +286,16 @@ class Client extends AbstractEntity
return $this;
}
public function isMaintenance(): ?bool
{
return $this->maintenance;
}
public function setMaintenance(bool $maintenance): static
{
$this->maintenance = $maintenance;
return $this;
}
}

View File

@ -3,6 +3,8 @@
namespace App\Entity;
use App\Repository\ImageRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ImageRepository::class)]
@ -16,10 +18,10 @@ class Image extends AbstractEntity
#[ORM\Column(length: 255, nullable: true)]
private ?string $comments = null;
#[ORM\Column(length: 255)]
#[ORM\Column(length: 255, nullable: true)]
private ?string $path = null;
#[ORM\Column(length: 255)]
#[ORM\Column(length: 255, nullable: true)]
private ?string $type = null;
#[ORM\Column(length: 255, nullable: true)]
@ -28,7 +30,7 @@ class Image extends AbstractEntity
#[ORM\Column(length: 255, nullable: true)]
private ?string $info = null;
#[ORM\Column]
#[ORM\Column(length: 255, nullable: true)]
private ?int $size = null;
#[ORM\ManyToOne]
@ -36,9 +38,25 @@ class Image extends AbstractEntity
private ?Client $client = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
#[ORM\JoinColumn(nullable: true)]
private ?SoftwareProfile $softwareProfile = null;
/**
* @var Collection<int, Partition>
*/
#[ORM\OneToMany(mappedBy: 'image', targetEntity: Partition::class)]
private Collection $partitions;
#[ORM\ManyToOne(inversedBy: 'images')]
#[ORM\JoinColumn(nullable: false)]
private ?OrganizationalUnit $organizationalUnit = null;
public function __construct()
{
parent::__construct();
$this->partitions = new ArrayCollection();
}
public function getDescription(): ?string
{
return $this->description;
@ -68,7 +86,7 @@ class Image extends AbstractEntity
return $this->path;
}
public function setPath(string $path): static
public function setPath(?string $path): static
{
$this->path = $path;
@ -80,7 +98,7 @@ class Image extends AbstractEntity
return $this->type;
}
public function setType(string $type): static
public function setType(?string $type): static
{
$this->type = $type;
@ -116,7 +134,7 @@ class Image extends AbstractEntity
return $this->size;
}
public function setSize(int $size): static
public function setSize(?int $size): static
{
$this->size = $size;
@ -146,4 +164,46 @@ class Image extends AbstractEntity
return $this;
}
/**
* @return Collection<int, Partition>
*/
public function getPartitions(): Collection
{
return $this->partitions;
}
public function addPartition(Partition $partition): static
{
if (!$this->partitions->contains($partition)) {
$this->partitions->add($partition);
$partition->setImage($this);
}
return $this;
}
public function removePartition(Partition $partition): static
{
if ($this->partitions->removeElement($partition)) {
// set the owning side to null (unless already changed)
if ($partition->getImage() === $this) {
$partition->setImage(null);
}
}
return $this;
}
public function getOrganizationalUnit(): ?OrganizationalUnit
{
return $this->organizationalUnit;
}
public function setOrganizationalUnit(?OrganizationalUnit $organizationalUnit): static
{
$this->organizationalUnit = $organizationalUnit;
return $this;
}
}

View File

@ -97,6 +97,12 @@ class OrganizationalUnit extends AbstractEntity
#[ORM\Column]
private ?bool $reserved = false;
/**
* @var Collection<int, Image>
*/
#[ORM\OneToMany(mappedBy: 'organizationalUnit', targetEntity: Image::class)]
private Collection $images;
public function __construct()
{
parent::__construct();
@ -104,6 +110,7 @@ class OrganizationalUnit extends AbstractEntity
$this->users = new ArrayCollection();
$this->clients = new ArrayCollection();
$this->softwareProfiles = new ArrayCollection();
$this->images = new ArrayCollection();
}
public function getDescription(): ?string
@ -429,4 +436,34 @@ class OrganizationalUnit extends AbstractEntity
return $this;
}
/**
* @return Collection<int, Image>
*/
public function getImages(): Collection
{
return $this->images;
}
public function addImage(Image $image): static
{
if (!$this->images->contains($image)) {
$this->images->add($image);
$image->setOrganizationalUnit($this);
}
return $this;
}
public function removeImage(Image $image): static
{
if ($this->images->removeElement($image)) {
// set the owning side to null (unless already changed)
if ($image->getOrganizationalUnit() === $this) {
$image->setOrganizationalUnit(null);
}
}
return $this;
}
}

View File

@ -37,6 +37,10 @@ class Partition extends AbstractEntity
#[ORM\ManyToOne(inversedBy: 'partitions')]
private ?OperativeSystem $operativeSystem = null;
#[ORM\ManyToOne(inversedBy: 'partitions')]
#[ORM\JoinColumn(nullable: false)]
private ?Image $image = null;
public function getDiskNumber(): ?int
{
return $this->diskNumber;
@ -144,4 +148,16 @@ class Partition extends AbstractEntity
return $this;
}
public function getImage(): ?Image
{
return $this->image;
}
public function setImage(?Image $image): static
{
$this->image = $image;
return $this;
}
}

View File

@ -32,6 +32,7 @@ final class ClientFactory extends ModelFactory
'createdAt' => self::faker()->dateTime(),
'name' => self::faker()->text(255),
'updatedAt' => self::faker()->dateTime(),
'maintenance' => self::faker()->boolean(),
];
}

View File

@ -3,6 +3,7 @@
namespace App\Factory;
use App\Entity\Image;
use App\Model\OrganizationalUnitTypes;
use App\Repository\ImageRepository;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
@ -38,7 +39,7 @@ final class ImageFactory extends ModelFactory
'path' => self::faker()->text(255),
'size' => self::faker()->randomNumber(),
'softwareProfile' => SoftwareProfileFactory::new(),
'type' => self::faker()->text(255),
'organizationalUnit' => OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT])->_save(),
'updatedAt' => self::faker()->dateTime(),
];
}

View File

@ -43,6 +43,7 @@ final class PartitionFactory extends ModelFactory
'updatedAt' => self::faker()->dateTime(),
'operativeSystem' => OperativeSystemFactory::new(),
'client' => ClientFactory::new(),
'image' => ImageFactory::new(),
];
}

View File

@ -20,6 +20,7 @@ final readonly class OpenApiFactory implements OpenApiFactoryInterface
$this->addRefreshToken($openApi);
$this->addOgAgentEndpoints($openApi);
$this->addUDsEndpoints($openApi);
$this->addStatusEndpoint($openApi);
$this->addInstallOgLiveWebhookEndpoint($openApi);
@ -704,6 +705,89 @@ final readonly class OpenApiFactory implements OpenApiFactoryInterface
));
}
private function addUDsEndpoints(OpenApi $openApi): void
{
$openApi->getPaths()->addPath('/opengnsys/rest//ous', (new Model\PathItem())->withGet(
(new Model\Operation('getOUs'))
->withTags(['Organizational Unit'])
->withSummary('Obtener todas las Unidades Organizacionales')
->withResponses([
Response::HTTP_OK => [
'description' => 'Lista de Unidades Organizacionales',
'content' => [
'application/json' => [
'schema' => [
'type' => 'array',
'items' => [
'type' => 'object',
'properties' => [
'id' => [
'type' => 'integer',
'example' => 1,
],
'name' => [
'type' => 'string',
'example' => 'Nombre de la Unidad Organizacional',
],
'description' => [
'type' => 'string',
'example' => 'Descripción de la Unidad Organizacional',
]
]
]
]
]
]
]
])
));
$openApi->getPaths()->addPath('/opengnsys/rest//ous/{centerId}/labs', (new Model\PathItem())->withGet(
(new Model\Operation('getClassrooms'))
->withTags(['Organizational Unit'])
->withSummary('Obtener los laboratorios de una Unidad Organizacional específica')
->withParameters([
new Model\Parameter(
'centerId',
'path',
'El ID de la Unidad Organizacional',
true,
false,
)
])
->withResponses([
Response::HTTP_OK => [
'description' => 'Lista de Laboratorios',
'content' => [
'application/json' => [
'schema' => [
'type' => 'array',
'items' => [
'type' => 'object',
'properties' => [
'id' => [
'type' => 'integer',
'example' => 1,
],
'name' => [
'type' => 'string',
'example' => 'Nombre del Laboratorio',
],
'description' => [
'type' => 'string',
'example' => 'Descripción del Laboratorio',
]
]
]
]
]
]
]
])
));
}
private function addInstallOgLiveWebhookEndpoint(OpenApi $openApi): void
{
$openApi

View File

@ -47,7 +47,7 @@ class UDSClient
continue;
}
$classroom = $servicePoolInfo['ou'];
$classroom = $servicePoolInfo['lab'];
$maxAvailableSeats = $this->getMaxAvailableSeats($classroom);
$servicePool['max_srvs'] = $maxAvailableSeats;
$servicePool['osmanager_id'] = null;
@ -156,6 +156,9 @@ class UDSClient
$totalAvailableClients = 0;
foreach ($organizationalUnit->getClients() as $client) {
if ($client->isMaintenance()) {
continue;
}
$status = $client->getStatus();
$clientAvailable = in_array($status, ['active', 'windows', 'linux']);

View File

@ -8,8 +8,10 @@ use App\Entity\OrganizationalUnit;
use App\Entity\SoftwareProfile;
use App\Factory\ClientFactory;
use App\Factory\ImageFactory;
use App\Factory\OrganizationalUnitFactory;
use App\Factory\SoftwareProfileFactory;
use App\Factory\UserFactory;
use App\Model\OrganizationalUnitTypes;
use App\Model\UserGroupPermissions;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -68,13 +70,16 @@ class ImageTest extends AbstractTest
SoftwareProfileFactory::createOne(['description' => self::SOFTWARE_PROFILE]);
$swPIri = $this->findIriBy(SoftwareProfile::class, ['description' => self::SOFTWARE_PROFILE]);
OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]);
$ouIri = $this->findIriBy(OrganizationalUnit::class, ['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]);
$this->createClientWithCredentials()->request('POST', '/images',['json' => [
'name' => self::IMAGE_CREATE,
'size' => 123,
'path' => '/path/to/image',
'type' => 'type',
'client' => $clientIri,
'softwareProfile' => $swPIri
'softwareProfile' => $swPIri,
'organizationalUnit' => $ouIri,
]]);
$this->assertResponseStatusCodeSame(201);

View File

@ -3,11 +3,13 @@
namespace Functional;
use App\Entity\Client;
use App\Entity\Image;
use App\Entity\Menu;
use App\Entity\OperativeSystem;
use App\Entity\Partition;
use App\Factory\ClientFactory;
use App\Factory\HardwareProfileFactory;
use App\Factory\ImageFactory;
use App\Factory\MenuFactory;
use App\Factory\OperativeSystemFactory;
use App\Factory\OrganizationalUnitFactory;
@ -73,9 +75,13 @@ class PartitionTest extends AbstractTest
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
]]);