diff --git a/config/api_platform/Client.yaml b/config/api_platform/Client.yaml index 641ba9a..ee2b36c 100644 --- a/config/api_platform/Client.yaml +++ b/config/api_platform/Client.yaml @@ -34,6 +34,14 @@ resources: uriTemplate: /clients/change-organizational-units controller: App\Controller\ChangeOrganizationalUnitAction + agent_status: + provider: App\State\Provider\ClientProvider + class: ApiPlatform\Metadata\Post + method: POST + input: false + uriTemplate: /clients/{uuid}/agent/status + controller: App\Controller\OgAgent\StatusAction + properties: App\Entity\Client: id: diff --git a/config/api_platform/PxeBootFile.yaml b/config/api_platform/PxeBootFile.yaml deleted file mode 100644 index 62775c5..0000000 --- a/config/api_platform/PxeBootFile.yaml +++ /dev/null @@ -1,40 +0,0 @@ -resources: - App\Entity\PxeBootFile: - processor: App\State\Processor\PxeBootFileProcessor - input: App\Dto\Input\PxeBootFileInput - output: App\Dto\Output\PxeBootFileOutput - normalizationContext: - groups: ['default', 'pxe-boot-file:read'] - denormalizationContext: - groups: ['pxe-boot-file:write'] - operations: - ApiPlatform\Metadata\GetCollection: - provider: App\State\Provider\PxeBootFileProvider - filters: - - 'api_platform.filter.pxe_boot_file.order' - - 'api_platform.filter.pxe_boot_file.search' - - ApiPlatform\Metadata\Get: - provider: App\State\Provider\PxeBootFileProvider - ApiPlatform\Metadata\Put: - provider: App\State\Provider\PxeBootFileProvider - ApiPlatform\Metadata\Patch: - provider: App\State\Provider\PxeBootFileProvider - ApiPlatform\Metadata\Post: ~ - ApiPlatform\Metadata\Delete: ~ - - get_all: - shortName: PxeBootFile Server - description: Get collection of PxeBootFile - class: ApiPlatform\Metadata\GetCollection - method: GET - input: false - uriTemplate: /pxe-boot-files/server/get-collection - controller: App\Controller\OgBoot\PxeBootFile\GetCollectionAction - -properties: - App\Entity\PxeBootFile: - id: - identifier: false - uuid: - identifier: true \ No newline at end of file diff --git a/config/api_platform/PxeTemplate.yaml b/config/api_platform/PxeTemplate.yaml index 0f311af..ce4ae4d 100644 --- a/config/api_platform/PxeTemplate.yaml +++ b/config/api_platform/PxeTemplate.yaml @@ -24,6 +24,13 @@ resources: ApiPlatform\Metadata\Post: ~ ApiPlatform\Metadata\Delete: ~ + pxe_template_sync: + class: ApiPlatform\Metadata\Post + method: POST + input: false + uriTemplate: /pxe-templates/sync + controller: App\Controller\OgBoot\PxeTemplate\SyncAction + get_collection_templates: shortName: PxeTemplate Server description: Get collection of PxeTemplate @@ -54,12 +61,40 @@ resources: delete_template: shortName: PxeTemplate Server description: Delete PxeTemplate - class: ApiPlatform\Metadata\Get - method: GET + class: ApiPlatform\Metadata\Post + method: POST input: false uriTemplate: /pxe-templates/server/{uuid}/delete controller: App\Controller\OgBoot\PxeTemplate\DeleteAction + template_add_clients: + shortName: PxeTemplate Server + description: Add Client to PxeTemplate + class: ApiPlatform\Metadata\Post + method: POST + input: App\Dto\Input\PxeTemplateAddClientsInput + uriTemplate: /pxe-templates/{uuid}/add-clients + controller: App\Controller\OgBoot\PxeTemplate\AddClientAction + + template_sync_client: + shortName: PxeTemplate Server + description: Sync Client to PxeTemplate + class: ApiPlatform\Metadata\Post + method: POST + input: App\Dto\Input\PxeTemplateSyncClientInput + uriTemplate: /pxe-templates/{uuid}/sync-client + controller: App\Controller\OgBoot\PxeBootFile\PostAction + + template_delete_client: + shortName: PxeTemplate Server + description: Add Client to PxeTemplate + class: ApiPlatform\Metadata\Post + method: POST + input: App\Dto\Input\PxeTemplateDeleteClientInput + uriTemplate: /pxe-templates/{uuid}/delete-client + controller: App\Controller\OgBoot\PxeTemplate\DeleteClientAction + + properties: App\Entity\PxeTemplate: id: diff --git a/config/services.yaml b/config/services.yaml index dfa9740..294e4b8 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -134,11 +134,6 @@ services: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' $itemProvider: '@api_platform.doctrine.orm.state.item_provider' - App\State\Provider\PxeBootFileProvider: - bind: - $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' - $itemProvider: '@api_platform.doctrine.orm.state.item_provider' - App\State\Provider\CommandTaskProvider: bind: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' diff --git a/config/services/api_platform.yaml b/config/services/api_platform.yaml index 82f3fd0..96d9926 100644 --- a/config/services/api_platform.yaml +++ b/config/services/api_platform.yaml @@ -20,12 +20,12 @@ services: api_platform.filter.client.search: parent: 'api_platform.doctrine.orm.search_filter' - arguments: [ { 'id': 'exact', 'name': 'partial', 'serialNumber': 'exact', organizationalUnit.id: 'exact', mac: 'exact', ip: 'exact' } ] + arguments: [ { 'id': 'exact', 'name': 'partial', 'serialNumber': 'exact', 'template.id': 'exact', organizationalUnit.id: 'exact', mac: 'exact', ip: 'exact' } ] tags: [ 'api_platform.filter' ] api_platform.filter.client.exist: parent: 'api_platform.doctrine.orm.exists_filter' - arguments: [{'subnet': ~ }] + arguments: [{'subnet': ~, 'template': ~ }] tags: [ 'api_platform.filter' ] api_platform.filter.command.order: diff --git a/migrations/Version20241019073142.php b/migrations/Version20241019073142.php new file mode 100644 index 0000000..645dac2 --- /dev/null +++ b/migrations/Version20241019073142.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE client ADD agent_job_id 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 agent_job_id'); + } +} diff --git a/migrations/Version20241021061008.php b/migrations/Version20241021061008.php new file mode 100644 index 0000000..84ba8f8 --- /dev/null +++ b/migrations/Version20241021061008.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE client DROP FOREIGN KEY FK_C7440455F7E54CF3'); + $this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C7440455F7E54CF3 FOREIGN KEY (og_live_id) REFERENCES og_live (id) ON DELETE SET 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 FOREIGN KEY FK_C7440455F7E54CF3'); + $this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C7440455F7E54CF3 FOREIGN KEY (og_live_id) REFERENCES og_live (id)'); + } +} diff --git a/migrations/Version20241021071250.php b/migrations/Version20241021071250.php new file mode 100644 index 0000000..054ddd6 --- /dev/null +++ b/migrations/Version20241021071250.php @@ -0,0 +1,43 @@ +addSql('ALTER TABLE client DROP FOREIGN KEY FK_C7440455D4CBF752'); + $this->addSql('ALTER TABLE pxe_boot_file DROP FOREIGN KEY FK_7FD1F34B5DA0FB8'); + $this->addSql('DROP TABLE pxe_boot_file'); + $this->addSql('DROP INDEX IDX_C7440455D4CBF752 ON client'); + $this->addSql('ALTER TABLE client CHANGE pxe_boot_file_id template_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C74404555DA0FB8 FOREIGN KEY (template_id) REFERENCES pxe_template (id)'); + $this->addSql('CREATE INDEX IDX_C74404555DA0FB8 ON client (template_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TABLE pxe_boot_file (id INT AUTO_INCREMENT NOT NULL, template_id INT DEFAULT NULL, uuid CHAR(36) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci` COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, updated_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, synchronized TINYINT(1) DEFAULT NULL, INDEX IDX_7FD1F34B5DA0FB8 (template_id), UNIQUE INDEX UNIQ_7FD1F34BD17F50A6 (uuid), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' '); + $this->addSql('ALTER TABLE pxe_boot_file ADD CONSTRAINT FK_7FD1F34B5DA0FB8 FOREIGN KEY (template_id) REFERENCES pxe_template (id)'); + $this->addSql('ALTER TABLE client DROP FOREIGN KEY FK_C74404555DA0FB8'); + $this->addSql('DROP INDEX IDX_C74404555DA0FB8 ON client'); + $this->addSql('ALTER TABLE client CHANGE template_id pxe_boot_file_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C7440455D4CBF752 FOREIGN KEY (pxe_boot_file_id) REFERENCES pxe_boot_file (id)'); + $this->addSql('CREATE INDEX IDX_C7440455D4CBF752 ON client (pxe_boot_file_id)'); + } +} diff --git a/migrations/Version20241021201438.php b/migrations/Version20241021201438.php new file mode 100644 index 0000000..7c1dc59 --- /dev/null +++ b/migrations/Version20241021201438.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE client ADD pxe_sync 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 client DROP pxe_sync'); + } +} diff --git a/src/Controller/OgAgent/StatusAction.php b/src/Controller/OgAgent/StatusAction.php new file mode 100644 index 0000000..12f8b92 --- /dev/null +++ b/src/Controller/OgAgent/StatusAction.php @@ -0,0 +1,8 @@ +createRequest($httpClient, 'GET', $this->ogBootApiUrl . '/ogboot/v1/oglives'); - foreach ($content['message'] as $ogLive) { + foreach ($content['message']['installed_ogLives'] as $ogLive) { $ogLiveEntity = $this->entityManager->getRepository(OgLive::class)->findOneBy(['checksum' => $ogLive['id']]); if ($ogLiveEntity) { $this->extracted($ogLiveEntity, $ogLive); diff --git a/src/Controller/OgBoot/PxeBootFile/PostAction.php b/src/Controller/OgBoot/PxeBootFile/PostAction.php new file mode 100644 index 0000000..eeba300 --- /dev/null +++ b/src/Controller/OgBoot/PxeBootFile/PostAction.php @@ -0,0 +1,80 @@ +client->getEntity(); + + $data = [ + 'template_name' => $pxeTemplate->getName(), + 'mac' => strtolower($client->getMac()), + 'lang' => 'es_ES.UTF_8', + 'ip' => $client->getIp(), + 'server_ip' => '92.168.2.1', + 'router' => $client->getOrganizationalUnit()->getNetworkSettings()->getRouter(), + 'netmask' => $client->getOrganizationalUnit()->getNetworkSettings() ? $client->getOrganizationalUnit()->getNetworkSettings()->getNetmask() : '255.255.255.0', + 'computer_name' => $client->getName(), + 'netiface' => $client->getNetiface(), + 'group' => $client->getOrganizationalUnit()->getName(), + 'ogrepo' => $client->getRepository() ? $client->getRepository()->getIpAddress() : '192.168.2.1', + 'oglive' => $client->getOgLive() ? $client->getOgLive()->getDownloadUrl() : '', + 'oglog' => '192.168.2.1', + 'ogshare' => '192.168.2.1', + 'oglivedir' => 'ogLive', + 'ogprof' => 'false', + 'hardprofile' => $client->getHardwareProfile() ? $client->getHardwareProfile()->getDescription() : 'default', + 'ogntp' => $client->getOrganizationalUnit()->getNetworkSettings()?->getNtp(), + 'ogdns' => $client->getOrganizationalUnit()->getNetworkSettings()?->getDns(), + 'ogProxy' => $client->getOrganizationalUnit()->getNetworkSettings()?->getProxy(), + 'ogunit' => '', + 'resolution' => '788' + ]; + + try { + $response = $httpClient->request('POST', $this->ogBootApiUrl.'/ogboot/v1/pxes', [ + 'headers' => [ + 'accept' => 'application/json', + 'Content-Type' => 'application/json', + ], + 'json' => $data + ]); + } catch (TransportExceptionInterface $e) { + $client->setPxeSync(false); + $this->entityManager->persist($client); + $this->entityManager->flush(); + return new JsonResponse( data: $e->getMessage(), status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + $client->setPxeSync(true); + $this->entityManager->persist($client); + $this->entityManager->flush(); + + return new JsonResponse(data: json_decode($response->getContent(), true), status: Response::HTTP_OK); + } +} \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeTemplate/AddClientAction.php b/src/Controller/OgBoot/PxeTemplate/AddClientAction.php new file mode 100644 index 0000000..9ebc38c --- /dev/null +++ b/src/Controller/OgBoot/PxeTemplate/AddClientAction.php @@ -0,0 +1,44 @@ +clients; + + foreach ($clients as $client) { + /** @var Client $clientEntity */ + $clientEntity = $client->getEntity(); + $clientEntity->setTemplate($pxeTemplate); + + $this->entityManager->persist($clientEntity); + } + + $this->entityManager->flush(); + + return new JsonResponse(status: Response::HTTP_OK); + } +} \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeTemplate/DeleteClientAction.php b/src/Controller/OgBoot/PxeTemplate/DeleteClientAction.php new file mode 100644 index 0000000..77e07f3 --- /dev/null +++ b/src/Controller/OgBoot/PxeTemplate/DeleteClientAction.php @@ -0,0 +1,43 @@ +client; + + /** @var Client $clientEntity */ + $clientEntity = $client->getEntity(); + + $pxeTemplate->removeClient($clientEntity); + + $this->entityManager->persist($clientEntity); + $this->entityManager->flush(); + + return new JsonResponse(status: Response::HTTP_OK); + } +} \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeTemplate/GetAction.php b/src/Controller/OgBoot/PxeTemplate/GetAction.php index 5648a55..5bbc2c0 100644 --- a/src/Controller/OgBoot/PxeTemplate/GetAction.php +++ b/src/Controller/OgBoot/PxeTemplate/GetAction.php @@ -23,10 +23,10 @@ class GetAction extends AbstractOgBootController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function __invoke(PxeTemplate $data, HttpClientInterface $httpClient): JsonResponse + public function __invoke(PxeTemplate $template, HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/pxe-templates/'.$data->getName(), [ + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/pxe-templates/'.$template->getName(), [ 'headers' => [ 'accept' => 'application/json', ], @@ -37,6 +37,13 @@ class GetAction extends AbstractOgBootController $data = json_decode($response->getContent(), true); + $template->setName($data['template_name']); + $template->setTemplateContent($data['template_content']); + $template->setSynchronized(true); + + $this->entityManager->persist($template); + $this->entityManager->flush(); + return new JsonResponse( data: $data, status: Response::HTTP_OK); } } \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeTemplate/SyncAction.php b/src/Controller/OgBoot/PxeTemplate/SyncAction.php new file mode 100644 index 0000000..50746bd --- /dev/null +++ b/src/Controller/OgBoot/PxeTemplate/SyncAction.php @@ -0,0 +1,48 @@ +createRequest($httpClient, 'GET', $this->ogBootApiUrl . '/ogboot/v1/pxe-templates'); + + foreach ($content['message'] as $template) { + $templateEntity = $this->entityManager->getRepository(PxeTemplate::class)->findOneBy(['name' => $template]); + if ($templateEntity) { + $this->entityManager->persist($templateEntity); + } else { + $templateEntity = new PxeTemplate(); + $templateEntity->setName($template); + $templateEntity->setTemplateContent(''); + } + $this->entityManager->persist($templateEntity); + } + $this->entityManager->flush(); + + return new JsonResponse(data: $content, status: Response::HTTP_OK); + } +} \ No newline at end of file diff --git a/src/Dto/Input/ClientInput.php b/src/Dto/Input/ClientInput.php index 9d3a98f..e4bbc7b 100644 --- a/src/Dto/Input/ClientInput.php +++ b/src/Dto/Input/ClientInput.php @@ -7,6 +7,7 @@ use App\Dto\Output\HardwareProfileOutput; use App\Dto\Output\MenuOutput; use App\Dto\Output\OgLiveOutput; use App\Dto\Output\OrganizationalUnitOutput; +use App\Dto\Output\PxeTemplateOutput; use App\Entity\Client; use App\Entity\OgRepository; use Symfony\Component\Serializer\Annotation\Groups; @@ -78,6 +79,12 @@ final class ClientInput )] public ?MenuOutput $menu = null; + #[Groups(['client:write'])] + #[ApiProperty( + description: 'La plantilla PXE del cliente' + )] + public ?PxeTemplateOutput $template = null; + #[Groups(['client:write'])] #[ApiProperty( description: 'El perfil de hardware del cliente' @@ -133,6 +140,10 @@ final class ClientInput $this->ogLive = new OgLiveOutput($client->getOgLive()); } + if ($client->getTemplate()) { + $this->template = new PxeTemplateOutput($client->getTemplate()); + } + if ($client->getHardwareProfile()) { $this->hardwareProfile = new HardwareProfileOutput($client->getHardwareProfile()); } @@ -154,6 +165,7 @@ final class ClientInput $client->setMenu($this->menu?->getEntity()); $client->setOgLive($this->ogLive?->getEntity()); $client->setHardwareProfile($this->hardwareProfile?->getEntity()); + $client->setTemplate($this->template?->getEntity()); $client->setPosition($this->position); $client->setStatus($this->status); $client->setMaintenance($this->maintenance); diff --git a/src/Dto/Input/PxeBootFileInput.php b/src/Dto/Input/PxeBootFileInput.php deleted file mode 100644 index 3b0831d..0000000 --- a/src/Dto/Input/PxeBootFileInput.php +++ /dev/null @@ -1,55 +0,0 @@ -template = $bootFile->getTemplate(); - if ($bootFile->getClients()) { - foreach ($bootFile->getClients() as $client) { - $this->clients[] = new ClientOutput($client); - } - } - } - - public function createOrUpdateEntity(?PxeBootFile $bootFile = null): PxeBootFile - { - if (!$bootFile) { - $bootFile = new PxeBootFile(); - } - - $bootFile->setTemplate($this->template->getEntity()); - - foreach ($this->clients as $client) { - $clientsToAdd[] = $client->getEntity(); - } - $bootFile->setClients( $clientsToAdd ?? [] ); - - return $bootFile; - } -} \ No newline at end of file diff --git a/src/Dto/Input/PxeTemplateAddClientsInput.php b/src/Dto/Input/PxeTemplateAddClientsInput.php new file mode 100644 index 0000000..28cf393 --- /dev/null +++ b/src/Dto/Input/PxeTemplateAddClientsInput.php @@ -0,0 +1,20 @@ +menu = $client->getMenu() ? new MenuOutput($client->getMenu()) : null; $this->position = $client->getPosition(); + $this->template = $client->getTemplate() ? new PxeTemplateOutput($client->getTemplate()) : null; $this->hardwareProfile = $client->getHardwareProfile() ? new HardwareProfileOutput($client->getHardwareProfile()) : null; - $this->subnet = $client->getSubnet() ? $client->getSubnet()->getIpAddress(). '-' . $client->getSubnet()->getNetmask() : null; + $this->subnet = $client->getSubnet()?->getIpAddress(); $this->ogLive = $client->getOgLive() ? new OgLiveOutput($client->getOgLive()) : null; $this->status = $client->getStatus(); $this->createdAt = $client->getCreatedAt(); $this->createdBy = $client->getCreatedBy(); $this->maintenance = $client->isMaintenance(); + $this->pxeSync = $client->isPxeSync(); } } \ No newline at end of file diff --git a/src/Dto/Output/OgLiveOutput.php b/src/Dto/Output/OgLiveOutput.php index b881f35..45a9a57 100644 --- a/src/Dto/Output/OgLiveOutput.php +++ b/src/Dto/Output/OgLiveOutput.php @@ -28,6 +28,24 @@ final class OgLiveOutput extends AbstractOutput #[Groups(['og-live:read'])] public ?string $status = ''; + #[Groups(['og-live:read'])] + public ?string $checksum = ''; + + #[Groups(['og-live:read'])] + public ?string $distribution = ''; + + #[Groups(['og-live:read'])] + public ?string $revision = ''; + + #[Groups(['og-live:read'])] + public ?string $filename = ''; + + #[Groups(['og-live:read'])] + public ?string $kernel = ''; + + #[Groups(['og-live:read'])] + public ?string $architecture = ''; + #[Groups(['og-live:read'])] public \DateTime $createdAt; @@ -43,6 +61,12 @@ final class OgLiveOutput extends AbstractOutput $this->installed = $ogLive->isInstalled(); $this->isDefault = $ogLive->getIsDefault(); $this->downloadUrl = $ogLive->getDownloadUrl(); + $this->distribution = $ogLive->getDistribution(); + $this->revision = $ogLive->getRevision(); + $this->filename = $ogLive->getFilename(); + $this->checksum = $ogLive->getChecksum(); + $this->kernel = $ogLive->getKernel(); + $this->architecture = $ogLive->getArchitecture(); $this->status = $ogLive->getStatus(); $this->createdAt = $ogLive->getCreatedAt(); $this->createdBy = $ogLive->getCreatedBy(); diff --git a/src/Dto/Output/PxeBootFileOutput.php b/src/Dto/Output/PxeBootFileOutput.php deleted file mode 100644 index ff76bc6..0000000 --- a/src/Dto/Output/PxeBootFileOutput.php +++ /dev/null @@ -1,42 +0,0 @@ -template = new PxeTemplateOutput($bootFile->getTemplate()); - $this->clients = $bootFile->getClients()->map( - fn(Client $client) => new ClientOutput($client) - )->toArray(); - - $this->synchronized = $bootFile->isSynchronized(); - $this->createdAt = $bootFile->getCreatedAt(); - $this->createdBy = $bootFile->getCreatedBy(); - } -} \ No newline at end of file diff --git a/src/Dto/Output/PxeTemplateOutput.php b/src/Dto/Output/PxeTemplateOutput.php index e66ba17..a625e91 100644 --- a/src/Dto/Output/PxeTemplateOutput.php +++ b/src/Dto/Output/PxeTemplateOutput.php @@ -4,13 +4,14 @@ namespace App\Dto\Output; use ApiPlatform\Metadata\ApiProperty; use ApiPlatform\Metadata\Get; +use App\Entity\Client; use App\Entity\PxeTemplate; use Symfony\Component\Serializer\Annotation\Groups; #[Get(shortName: 'PxeTemplate')] final class PxeTemplateOutput extends AbstractOutput { - #[Groups(['pxe-template:read', 'pxe-boot-file:read'])] + #[Groups(['pxe-template:read', 'client:read'])] public string $name; #[Groups(['pxe-template:read'])] @@ -19,6 +20,9 @@ final class PxeTemplateOutput extends AbstractOutput #[Groups(['pxe-template:read'])] public ?string $templateContent = ''; + #[Groups(['pxe-template:read'])] + public ?int $clientsLength = 0; + #[Groups(['pxe-template:read'])] public \DateTime $createdAt; @@ -32,6 +36,7 @@ final class PxeTemplateOutput extends AbstractOutput $this->name = $pxeTemplate->getName(); $this->synchronized = $pxeTemplate->isSynchronized(); $this->templateContent = $pxeTemplate->getTemplateContent(); + $this->clientsLength = $pxeTemplate->getClients()->count(); $this->createdAt = $pxeTemplate->getCreatedAt(); $this->createdBy = $pxeTemplate->getCreatedBy(); } diff --git a/src/Entity/Client.php b/src/Entity/Client.php index 28b6e72..37546ed 100644 --- a/src/Entity/Client.php +++ b/src/Entity/Client.php @@ -58,7 +58,7 @@ class Client extends AbstractEntity private ?array $position = ['x' => 0, 'y' => 0]; #[ORM\ManyToOne(inversedBy: 'clients')] - private ?PxeBootFile $pxeBootFile = null; + private ?PxeTemplate $template = null; #[ORM\ManyToOne(inversedBy: 'clients')] private ?OgRepository $repository = null; @@ -67,11 +67,18 @@ class Client extends AbstractEntity #[ORM\JoinColumn( onDelete: 'SET NULL')] private ?Subnet $subnet = null; #[ORM\ManyToOne(inversedBy: 'clients')] + #[ORM\JoinColumn( onDelete: 'SET NULL')] private ?OgLive $ogLive = null; #[ORM\Column] private ?bool $maintenance = null; + #[ORM\Column(length: 255, nullable: true)] + private ?string $agentJobId = null; + + #[ORM\Column(nullable: true)] + private ?bool $pxeSync = null; + public function __construct() { parent::__construct(); @@ -240,18 +247,19 @@ class Client extends AbstractEntity return $this; } - public function getPxeBootFile(): ?PxeBootFile + public function getTemplate(): ?PxeTemplate { - return $this->pxeBootFile; + return $this->template; } - public function setPxeBootFile(?PxeBootFile $pxeBootFile): static + public function setTemplate(?PxeTemplate $template): static { - $this->pxeBootFile = $pxeBootFile; + $this->template = $template; return $this; } + public function getRepository(): ?OgRepository { return $this->repository; @@ -299,4 +307,28 @@ class Client extends AbstractEntity return $this; } + + public function getAgentJobId(): ?string + { + return $this->agentJobId; + } + + public function setAgentJobId(?string $agentJobId): static + { + $this->agentJobId = $agentJobId; + + return $this; + } + + public function isPxeSync(): ?bool + { + return $this->pxeSync; + } + + public function setPxeSync(?bool $pxeSync): static + { + $this->pxeSync = $pxeSync; + + return $this; + } } diff --git a/src/Entity/PxeBootFile.php b/src/Entity/PxeBootFile.php deleted file mode 100644 index b14dd3f..0000000 --- a/src/Entity/PxeBootFile.php +++ /dev/null @@ -1,82 +0,0 @@ - - */ - #[ORM\OneToMany(mappedBy: 'pxeBootFile', targetEntity: Client::class)] - private Collection $clients; - - public function __construct() - { - parent::__construct(); - $this->clients = new ArrayCollection(); - } - - public function getTemplate(): ?PxeTemplate - { - return $this->template; - } - - public function setTemplate(?PxeTemplate $template): static - { - $this->template = $template; - - return $this; - } - - /** - * @return Collection - */ - public function getClients(): Collection - { - return $this->clients; - } - - public function addClient(Client $client): static - { - if (!$this->clients->contains($client)) { - $this->clients->add($client); - $client->setPxeBootFile($this); - } - - return $this; - } - - public function removeClient(Client $client): static - { - if ($this->clients->removeElement($client)) { - // set the owning side to null (unless already changed) - if ($client->getPxeBootFile() === $this) { - $client->setPxeBootFile(null); - } - } - - return $this; - } - - public function setClients(array $clients): static - { - $this->clients->clear(); - - foreach ($clients as $client){ - $this->addClient($client); - } - - return $this; - } -} diff --git a/src/Entity/PxeTemplate.php b/src/Entity/PxeTemplate.php index 39a79b1..87b74b0 100644 --- a/src/Entity/PxeTemplate.php +++ b/src/Entity/PxeTemplate.php @@ -3,6 +3,7 @@ namespace App\Entity; use App\Repository\PxeTemplateRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -18,6 +19,12 @@ class PxeTemplate extends AbstractEntity #[ORM\Column(type: Types::TEXT)] private ?string $templateContent = null; + /** + * @var Collection + */ + #[ORM\OneToMany(mappedBy: 'template', targetEntity: Client::class)] + private Collection $clients; + public function getTemplateContent(): ?string { return $this->templateContent; @@ -29,4 +36,43 @@ class PxeTemplate extends AbstractEntity return $this; } + + /** + * @return Collection + */ + public function getClients(): Collection + { + return $this->clients; + } + + public function setClients(array $clients): static + { + $this->clients->clear(); + + foreach ($clients as $client){ + $this->addClient($client); + } + + return $this; + } + + public function addClient(Client $client): static + { + if (!$this->clients->contains($client)) { + $this->clients->add($client); + } + + return $this; + } + + public function removeClient(Client $client): static + { + if ($this->clients->removeElement($client)) { + if ($client->getTemplate() === $this) { + $client->setTemplate(null); + } + } + + return $this; + } } diff --git a/src/Repository/PxeBootFileRepository.php b/src/Repository/PxeBootFileRepository.php deleted file mode 100644 index 5733c80..0000000 --- a/src/Repository/PxeBootFileRepository.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ -class PxeBootFileRepository extends AbstractRepository -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, PxeBootFile::class); - } -} diff --git a/src/State/Processor/PxeBootFileProcessor.php b/src/State/Processor/PxeBootFileProcessor.php deleted file mode 100644 index b53e55b..0000000 --- a/src/State/Processor/PxeBootFileProcessor.php +++ /dev/null @@ -1,78 +0,0 @@ -processCreateOrUpdate($data, $operation, $uriVariables, $context); - case $operation instanceof Delete: - return $this->processDelete($data, $operation, $uriVariables, $context); - } - } - - /** - * @throws \Exception - * @throws TransportExceptionInterface - */ - private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): PxeBootFileOutput - { - if (!($data instanceof PxeBootFileInput)) { - throw new \Exception(sprintf('data is not instance of %s', PxeBootFileInput::class)); - } - - $entity = null; - if (isset($uriVariables['uuid'])) { - $entity = $this->bootFileRepository->findOneByUuid($uriVariables['uuid']); - } - - $pxeTemplate = $data->createOrUpdateEntity($entity); - $this->validator->validate($pxeTemplate); - $this->bootFileRepository->save($pxeTemplate); - - try { - $this->postService->__invoke($pxeTemplate); - } catch (\Exception $e) { - - } - - return new PxeBootFileOutput($pxeTemplate); - } - - private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null - { - $bootFile = $this->bootFileRepository->findOneByUuid($uriVariables['uuid']); - $this->bootFileRepository->delete($bootFile); - - return null; - } -} diff --git a/src/State/Provider/PxeBootFileProvider.php b/src/State/Provider/PxeBootFileProvider.php deleted file mode 100644 index f25bef9..0000000 --- a/src/State/Provider/PxeBootFileProvider.php +++ /dev/null @@ -1,71 +0,0 @@ -provideCollection($operation, $uriVariables, $context); - case $operation instanceof Patch: - case $operation instanceof Put: - return $this->provideInput($operation, $uriVariables, $context); - case $operation instanceof Get: - return $this->provideItem($operation, $uriVariables, $context); - } - } - - private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object - { - $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); - - $items = new \ArrayObject(); - foreach ($paginator->getIterator() as $item){ - $items[] = new PxeBootFileOutput($item); - } - - return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); - } - - public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null - { - $item = $this->itemProvider->provide($operation, $uriVariables, $context); - - if (!$item) { - throw new NotFoundHttpException('PxeBootFile not found'); - } - - return new PxeBootFileOutput($item); - } - - public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null - { - if (isset($uriVariables['uuid'])) { - $item = $this->itemProvider->provide($operation, $uriVariables, $context); - - return $item !== null ? new PxeBootFileInput($item) : null; - } - - return new PxeBootFileInput(); - } -}