From 750e36ec99c1d0226b6b340d71acbac3c66680f3 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Wed, 21 Aug 2024 09:17:48 +0200 Subject: [PATCH] refs #601. Integration API pxe-boot-file --- config/api_platform/OgLive.yaml | 12 +++- migrations/Version20240821065158.php | 31 +++++++++ src/Controller/OgBoot/OgLive/SyncAction.php | 66 ++++++++++++++++++- .../OgBoot/OgLive/UninstallAction.php | 16 +++-- .../PxeBootFile/GetCollectionAction.php | 2 +- .../OgBoot/PxeTemplate/PostAction.php | 8 ++- src/Dto/Output/PxeTemplateOutput.php | 2 +- src/Entity/PxeTemplate.php | 2 +- .../OgBoot/PxeBootFile/PostService.php | 21 ++++-- src/State/Processor/PxeBootFileProcessor.php | 8 ++- 10 files changed, 146 insertions(+), 22 deletions(-) create mode 100644 migrations/Version20240821065158.php diff --git a/config/api_platform/OgLive.yaml b/config/api_platform/OgLive.yaml index 4239240..d69ddad 100644 --- a/config/api_platform/OgLive.yaml +++ b/config/api_platform/OgLive.yaml @@ -23,6 +23,13 @@ resources: ApiPlatform\Metadata\Post: ~ ApiPlatform\Metadata\Delete: ~ + sync: + class: ApiPlatform\Metadata\Post + method: POST + input: false + uriTemplate: /og-lives/sync + controller: App\Controller\OgBoot\OgLive\SyncAction + get_collection_oglives: shortName: OgLive Server description: Get collection of OgLive @@ -80,9 +87,10 @@ resources: uninstall: shortName: OgLive Server description: Uninstall OgLive - class: ApiPlatform\Metadata\Get - method: GET + class: ApiPlatform\Metadata\Post + method: POST input: false + output: false uriTemplate: /og-lives/server/{uuid}/uninstall controller: App\Controller\OgBoot\OgLive\UninstallAction diff --git a/migrations/Version20240821065158.php b/migrations/Version20240821065158.php new file mode 100644 index 0000000..dfcd85a --- /dev/null +++ b/migrations/Version20240821065158.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE pxe_template CHANGE template_content template_content LONGTEXT NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE pxe_template CHANGE template_content template_content TINYTEXT NOT NULL'); + } +} diff --git a/src/Controller/OgBoot/OgLive/SyncAction.php b/src/Controller/OgBoot/OgLive/SyncAction.php index edaee84..6171cc8 100644 --- a/src/Controller/OgBoot/OgLive/SyncAction.php +++ b/src/Controller/OgBoot/OgLive/SyncAction.php @@ -2,7 +2,69 @@ namespace App\Controller\OgBoot\OgLive; -class SyncAction -{ +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\OgLive; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\AsController; +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 SyncAction extends AbstractOgLiveController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(HttpClientInterface $httpClient, EntityManagerInterface $entityManager): JsonResponse + { + try { + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/oglives', [ + 'headers' => [ + 'accept' => 'application/json', + ], + ]); + + } catch (TransportExceptionInterface $e) { + return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + $data = json_decode($response->getContent(), true); + + foreach ($data['installed_ogLives'] as $ogLive) { + $ogLiveEntity = $this->entityManager->getRepository(OgLive::class)->findOneBy(['checksum' => $ogLive['id']]); + if ($ogLiveEntity) { + $ogLiveEntity->setName($ogLive['filename']); + $ogLiveEntity->setInstalled(true); + $ogLiveEntity->setArchitecture($ogLive['architecture']); + $ogLiveEntity->setKernel($ogLive['kernel']); + $ogLiveEntity->setRevision($ogLive['revision']); + $ogLiveEntity->setDirectory($ogLive['directory']); + $ogLiveEntity->setChecksum($ogLive['id']); + $this->entityManager->persist($ogLiveEntity); + } else { + $ogLiveEntity = new OgLive(); + $ogLiveEntity->setName($ogLive['filename']); + $ogLiveEntity->setInstalled(true); + $ogLiveEntity->setArchitecture($ogLive['architecture']); + $ogLiveEntity->setKernel($ogLive['kernel']); + $ogLiveEntity->setRevision($ogLive['revision']); + $ogLiveEntity->setDirectory($ogLive['directory']); + $ogLiveEntity->setChecksum($ogLive['id']); + } + $this->entityManager->persist($ogLiveEntity); + + } + + $this->entityManager->flush(); + + return new JsonResponse( data: $data, status: Response::HTTP_OK); + } } \ No newline at end of file diff --git a/src/Controller/OgBoot/OgLive/UninstallAction.php b/src/Controller/OgBoot/OgLive/UninstallAction.php index e2981ec..ac9f047 100644 --- a/src/Controller/OgBoot/OgLive/UninstallAction.php +++ b/src/Controller/OgBoot/OgLive/UninstallAction.php @@ -4,6 +4,7 @@ namespace App\Controller\OgBoot\OgLive; use App\Controller\OgBoot\AbstractOgLiveController; use App\Entity\OgLive; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -17,12 +18,12 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; class UninstallAction extends AbstractOgLiveController { /** - * @throws TransportExceptionInterface * @throws ServerExceptionInterface * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface + * @throws TransportExceptionInterface */ - public function __invoke(OgLive $data, HttpClientInterface $httpClient): JsonResponse + public function __invoke(OgLive $data, HttpClientInterface $httpClient, EntityManagerInterface $entityManager): JsonResponse { try { $response = $httpClient->request('DELETE', $this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum(), [ @@ -30,12 +31,17 @@ class UninstallAction extends AbstractOgLiveController 'accept' => 'application/json', ], ]); + } catch (TransportExceptionInterface $e) { - return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + return new JsonResponse( data: $e->getMessage(), status: Response::HTTP_INTERNAL_SERVER_ERROR); } - $data = json_decode($response->getContent(), true); + if ($response->getStatusCode() === Response::HTTP_OK) { + $data->setInstalled(false); + $entityManager->persist($data); + $entityManager->flush(); + } - return new JsonResponse( data: $data, status: Response::HTTP_OK); + return new JsonResponse(status: Response::HTTP_OK); } } \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeBootFile/GetCollectionAction.php b/src/Controller/OgBoot/PxeBootFile/GetCollectionAction.php index 1b07fc6..f758745 100644 --- a/src/Controller/OgBoot/PxeBootFile/GetCollectionAction.php +++ b/src/Controller/OgBoot/PxeBootFile/GetCollectionAction.php @@ -24,7 +24,7 @@ class GetCollectionAction extends AbstractOgLiveController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function __invoke(PxeBootFile $data, HttpClientInterface $httpClient): JsonResponse + public function __invoke(HttpClientInterface $httpClient): JsonResponse { try { $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/pxes', [ diff --git a/src/Controller/OgBoot/PxeTemplate/PostAction.php b/src/Controller/OgBoot/PxeTemplate/PostAction.php index 6daf8d8..d07a016 100644 --- a/src/Controller/OgBoot/PxeTemplate/PostAction.php +++ b/src/Controller/OgBoot/PxeTemplate/PostAction.php @@ -38,9 +38,11 @@ class PostAction extends AbstractOgLiveController ], ]); - $data->setSynchronized(true); - $entityManager->persist($data); - $entityManager->flush(); + if ($response->getStatusCode() === Response::HTTP_OK) { + $data->setSynchronized(true); + $entityManager->persist($data); + $entityManager->flush(); + } $data = json_decode($response->getContent(), true); return new JsonResponse($data, Response::HTTP_OK); diff --git a/src/Dto/Output/PxeTemplateOutput.php b/src/Dto/Output/PxeTemplateOutput.php index fd7b5e9..e66ba17 100644 --- a/src/Dto/Output/PxeTemplateOutput.php +++ b/src/Dto/Output/PxeTemplateOutput.php @@ -10,7 +10,7 @@ use Symfony\Component\Serializer\Annotation\Groups; #[Get(shortName: 'PxeTemplate')] final class PxeTemplateOutput extends AbstractOutput { - #[Groups(['pxe-template:read'])] + #[Groups(['pxe-template:read', 'pxe-boot-file:read'])] public string $name; #[Groups(['pxe-template:read'])] diff --git a/src/Entity/PxeTemplate.php b/src/Entity/PxeTemplate.php index b2d3cfb..39a79b1 100644 --- a/src/Entity/PxeTemplate.php +++ b/src/Entity/PxeTemplate.php @@ -15,7 +15,7 @@ class PxeTemplate extends AbstractEntity use NameableTrait; use SynchronizedTrait; - #[ORM\Column(type: Types::TEXT, length: 255)] + #[ORM\Column(type: Types::TEXT)] private ?string $templateContent = null; public function getTemplateContent(): ?string diff --git a/src/Service/OgBoot/PxeBootFile/PostService.php b/src/Service/OgBoot/PxeBootFile/PostService.php index cc19f4d..e836af2 100644 --- a/src/Service/OgBoot/PxeBootFile/PostService.php +++ b/src/Service/OgBoot/PxeBootFile/PostService.php @@ -35,31 +35,40 @@ readonly class PostService foreach ($bootFile->getClients() as $client) { $data = [ - 'template_name' => $bootFile->getTemplate()->getName(), + 'template_name' => 'pxe_default', 'mac' => $client->getMac(), + 'lang' => 'es_ES.UTF_8', 'ip' => $client->getIp(), - 'server_ip' => '', + 'server_ip' => '92.168.2.1', 'router' => $client->getOrganizationalUnit()->getNetworkSettings()->getRouter(), 'netmask' => $client->getOrganizationalUnit()->getNetworkSettings()->getNetmask(), 'computer_name' => $client->getName(), 'netiface' => $client->getNetiface(), 'group' => $client->getOrganizationalUnit()->getName(), - 'ogrepo' => $client->getRepository() ? $client->getRepository()->getIpAddress() : $client->getOrganizationalUnit()->getNetworkSettings()->getRepository()->getIpAddress(), - 'oglive' => '', + 'ogrepo' => $client->getRepository() ? $client->getRepository()->getIpAddress() : '192.168.2.1', + 'oglive' => '127.0.0.1', + 'oglog' => '192.168.2.1', + 'ogshare' => '192.168.2.1', + 'oglivedir' => 'ogLive', + 'ogprof' => 'false', + 'hardprofile' => '', + 'ogntp' => $client->getOrganizationalUnit()->getNetworkSettings()->getNtp(), 'ogdns' => $client->getOrganizationalUnit()->getNetworkSettings()->getDns(), 'ogProxy' => $client->getOrganizationalUnit()->getNetworkSettings()->getProxy(), - 'ogunit' => '' + 'ogunit' => '', + 'resolution' => '768' ]; try { $response = $httpClient->request('POST', $this->ogBootApiUrl.'/ogboot/v1/pxes', [ 'headers' => [ 'accept' => 'application/json', + 'Content-Type' => 'application/json', ], 'json' => $data ]); } catch (TransportExceptionInterface $e) { - return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + return new JsonResponse( data: $e->getMessage(), status: Response::HTTP_INTERNAL_SERVER_ERROR); } return json_decode($response->getContent(), true); diff --git a/src/State/Processor/PxeBootFileProcessor.php b/src/State/Processor/PxeBootFileProcessor.php index 9b03645..b53e55b 100644 --- a/src/State/Processor/PxeBootFileProcessor.php +++ b/src/State/Processor/PxeBootFileProcessor.php @@ -13,6 +13,7 @@ use App\Dto\Input\PxeBootFileInput; use App\Dto\Output\PxeBootFileOutput; use App\Repository\PxeBootFileRepository; use App\Service\OgBoot\PxeBootFile\PostService; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; readonly class PxeBootFileProcessor implements ProcessorInterface { @@ -41,6 +42,7 @@ readonly class PxeBootFileProcessor implements ProcessorInterface /** * @throws \Exception + * @throws TransportExceptionInterface */ private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): PxeBootFileOutput { @@ -57,7 +59,11 @@ readonly class PxeBootFileProcessor implements ProcessorInterface $this->validator->validate($pxeTemplate); $this->bootFileRepository->save($pxeTemplate); - $this->postService->__invoke($pxeTemplate); + try { + $this->postService->__invoke($pxeTemplate); + } catch (\Exception $e) { + + } return new PxeBootFileOutput($pxeTemplate); }