From 524b833c0e6e826c3a8fbff0600479804282709a Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 12 Aug 2024 13:23:30 +0200 Subject: [PATCH] refs #601. Integration API pxe-template --- .env | 2 + composer.json | 2 +- composer.lock | 344 +++++++++--------- config/api_platform/OgLive.yaml | 17 +- config/api_platform/PxeTemplate.yaml | 67 ++++ config/services.yaml | 10 +- docker/Dockerfile-php | 11 + .../OgBoot/AbstractOgLiveController.php | 5 +- src/Controller/OgBoot/OgBootController.php | 39 +- src/Controller/OgBoot/OgLive/GetAction.php | 9 +- .../OgBoot/OgLive/GetCollectionAction.php | 8 +- .../OgBoot/OgLive/GetDefaultAction.php | 6 +- .../OgBoot/OgLive/GetIsosAction.php | 68 +++- .../OgBoot/OgLive/InstallAction.php | 13 +- .../OgBoot/OgLive/SetDefaultAction.php | 12 +- .../OgBoot/OgLive/UninstallAction.php | 9 +- .../OgBoot/PxeTemplate/DeleteAction.php | 38 +- .../OgBoot/PxeTemplate/GetAction.php | 38 +- .../PxeTemplate/GetCollectionAction.php | 37 +- .../OgBoot/PxeTemplate/PostAction.php | 51 ++- src/Entity/Client.php | 15 + src/Entity/OgLive.php | 120 ++++++ src/Entity/PxeBootFile.php | 69 ++++ src/Service/OgBoot/ConfigService.php | 43 ++- src/Service/OgBoot/StatusService.php | 44 ++- src/State/Processor/PxeTemplateProcessor.php | 66 +++- src/State/Provider/PxeTemplateProvider.php | 69 +++- 27 files changed, 964 insertions(+), 248 deletions(-) create mode 100644 src/Entity/PxeBootFile.php diff --git a/.env b/.env index 2d1c753..001e100 100644 --- a/.env +++ b/.env @@ -40,3 +40,5 @@ JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem JWT_PASSPHRASE=8b9154df37ffa91ef9186ce095324e39e50ff3b023bb1ed34383abd019ba4515 ###< lexik/jwt-authentication-bundle ### + +OGBOOT_API_URL=http://localhost:8085 diff --git a/composer.json b/composer.json index 580ef6b..7aa562a 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "symfony/expression-language": "6.4.*", "symfony/flex": "^2", "symfony/framework-bundle": "6.4.*", + "symfony/http-client": "6.4.*", "symfony/property-access": "6.4.*", "symfony/property-info": "6.4.*", "symfony/runtime": "6.4.*", @@ -89,7 +90,6 @@ "phpunit/phpunit": "^9.5", "symfony/browser-kit": "6.4.*", "symfony/css-selector": "6.4.*", - "symfony/http-client": "6.4.*", "symfony/maker-bundle": "^1.59", "symfony/phpunit-bridge": "^7.0", "symfony/web-profiler-bundle": "^6.4", diff --git a/composer.lock b/composer.lock index e756ea9..05fab12 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bf1165324e27bddd1a412f25e438fc4c", + "content-hash": "788f45c89f13c815d43700e8374bf655", "packages": [ { "name": "api-platform/core", @@ -4477,6 +4477,177 @@ ], "time": "2024-05-31T14:49:08+00:00" }, + { + "name": "symfony/http-client", + "version": "v6.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded", + "reference": "b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v6.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-07-15T09:26:24+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/http-foundation", "version": "v6.4.8", @@ -9224,177 +9395,6 @@ ], "time": "2024-05-31T14:49:08+00:00" }, - { - "name": "symfony/http-client", - "version": "v6.4.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client.git", - "reference": "61faba993e620fc22d4f0ab3b6bcf8fbb0d44b05" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/61faba993e620fc22d4f0ab3b6bcf8fbb0d44b05", - "reference": "61faba993e620fc22d4f0ab3b6bcf8fbb0d44b05", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.3" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "3.0" - }, - "require-dev": { - "amphp/amp": "^2.5", - "amphp/http-client": "^4.2.1", - "amphp/http-tunnel": "^1.0", - "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4|^2.0", - "nyholm/psr7": "^1.0", - "php-http/httplug": "^1.0|^2.0", - "psr/http-client": "^1.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", - "homepage": "https://symfony.com", - "keywords": [ - "http" - ], - "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.8" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-05-31T14:49:08+00:00" - }, - { - "name": "symfony/http-client-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to HTTP clients", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-04-18T09:32:20+00:00" - }, { "name": "symfony/maker-bundle", "version": "v1.60.0", diff --git a/config/api_platform/OgLive.yaml b/config/api_platform/OgLive.yaml index 3ea3e7b..0504100 100644 --- a/config/api_platform/OgLive.yaml +++ b/config/api_platform/OgLive.yaml @@ -11,8 +11,8 @@ resources: ApiPlatform\Metadata\GetCollection: provider: App\State\Provider\OgLiveProvider filters: - - 'api_platform.filter.og-live.order' - - 'api_platform.filter.og-live.search' + - 'api_platform.filter.og_live.order' + - 'api_platform.filter.og_live.search' ApiPlatform\Metadata\Get: provider: App\State\Provider\OgLiveProvider @@ -26,7 +26,7 @@ resources: get_collection: shortName: OgLive Server description: Get collection of OgLive - class: ApiPlatform\Metadata\Get + class: ApiPlatform\Metadata\GetCollection method: GET input: false uriTemplate: /og-lives/server/get-collection @@ -41,10 +41,19 @@ resources: uriTemplate: /og-lives/server/{uuid}/get controller: App\Controller\OgBoot\OgLive\GetAction + get_isos: + shortName: OgLive Server + description: Get Isos of OgLive + class: ApiPlatform\Metadata\GetCollection + method: GET + input: false + uriTemplate: /og-lives/server/get-isos + controller: App\Controller\OgBoot\OgLive\GetIsosAction + get_default: shortName: OgLive Server description: Get default OgLive - class: ApiPlatform\Metadata\Get + class: ApiPlatform\Metadata\GetCollection method: GET input: false uriTemplate: /og-lives/server/get-default diff --git a/config/api_platform/PxeTemplate.yaml b/config/api_platform/PxeTemplate.yaml index e69de29..0e36c96 100644 --- a/config/api_platform/PxeTemplate.yaml +++ b/config/api_platform/PxeTemplate.yaml @@ -0,0 +1,67 @@ +resources: + App\Entity\PxeTemplate: + processor: App\State\Processor\PxeTemplateProcessor + input: App\Dto\Input\PxeTemplateInput + output: App\Dto\Output\PxeTemplateOutput + normalizationContext: + groups: ['default', 'pxe-template:read'] + denormalizationContext: + groups: ['pxe-template:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\PxeTemplateProvider + filters: + - 'api_platform.filter.pxe_template.order' + - 'api_platform.filter.pxe_template.search' + + ApiPlatform\Metadata\Get: + provider: App\State\Provider\PxeTemplateProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\PxeTemplateProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\PxeTemplateProvider + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + + get_collection: + shortName: PxeTemplate Server + description: Get collection of PxeTemplate + class: ApiPlatform\Metadata\GetCollection + method: GET + input: false + uriTemplate: /pxe-templates/server/get-collection + controller: App\Controller\OgBoot\PxeTemplate\GetCollectionAction + + get: + shortName: PxeTemplate Server + description: Get PxeTemplate + class: ApiPlatform\Metadata\Get + method: GET + input: false + uriTemplate: /pxe-templates/server/{uuid}/get + controller: App\Controller\OgBoot\PxeTemplate\GetAction + + post: + shortName: PxeTemplate Server + description: Create PxeTemplate + class: ApiPlatform\Metadata\Post + method: POST + input: false + uriTemplate: /pxe-templates/server/{uuid}/post + controller: App\Controller\OgBoot\PxeTemplate\PostAction + + delete: + shortName: PxeTemplate Server + description: Delete PxeTemplate + class: ApiPlatform\Metadata\Get + method: GET + input: false + uriTemplate: /pxe-templates/server/{uuid}/delete + controller: App\Controller\OgBoot\PxeTemplate\DeleteAction + +properties: + App\Entity\PxeTemplate: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/services.yaml b/config/services.yaml index c3267cb..16b3247 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -4,11 +4,13 @@ imports: parameters: services: - # default configuration for services in *this* file _defaults: autowire: true # Automatically injects dependencies in your services. autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + bind: + $ogBootApiUrl: '%env(OGBOOT_API_URL)%' + App\: resource: '../src/' exclude: @@ -106,3 +108,9 @@ services: bind: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\PxeTemplateProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + diff --git a/docker/Dockerfile-php b/docker/Dockerfile-php index da6f17e..a4cdcb8 100644 --- a/docker/Dockerfile-php +++ b/docker/Dockerfile-php @@ -28,3 +28,14 @@ RUN apk del -f .build-deps COPY ./docker/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini +# Generate SSH keys +RUN ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -N "" + +# Optionally, copy public key to a specific location +RUN cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys + +# Expose any ports you may need +EXPOSE 9000 + +# Command to run the PHP-FPM server +CMD ["php-fpm"] diff --git a/src/Controller/OgBoot/AbstractOgLiveController.php b/src/Controller/OgBoot/AbstractOgLiveController.php index d5e8db5..89cbb0c 100644 --- a/src/Controller/OgBoot/AbstractOgLiveController.php +++ b/src/Controller/OgBoot/AbstractOgLiveController.php @@ -2,13 +2,12 @@ declare(strict_types=1); -namespace App\Controller\OgBoot\OgLive; +namespace App\Controller\OgBoot; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; -use Symfony\Component\Routing\Attribute\Route; + #[AsController] abstract class AbstractOgLiveController extends AbstractController { diff --git a/src/Controller/OgBoot/OgBootController.php b/src/Controller/OgBoot/OgBootController.php index 100ab39..f9e26f3 100644 --- a/src/Controller/OgBoot/OgBootController.php +++ b/src/Controller/OgBoot/OgBootController.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Controller\OgBoot; +use App\Service\OgBoot\ConfigService; +use App\Service\OgBoot\StatusService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; @@ -19,6 +21,13 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] class OgBootController extends AbstractController { + public function __construct( + private readonly StatusService $ogbootStatusService, + private readonly ConfigService $ogbootConfigService, + ) + { + } + /** * @throws TransportExceptionInterface * @throws ServerExceptionInterface @@ -26,19 +35,9 @@ class OgBootController extends AbstractController * @throws ClientExceptionInterface */ #[Route('/status', name: 'ogboot_status', methods: ['GET'])] - public function status(HttpClientInterface $httpClient): JsonResponse + public function status(): JsonResponse { - try { - $response = $httpClient->request('GET', 'https://api.example.com/ogboot/v1/status', [ - '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); + $data = $this->ogbootStatusService->__invoke(); return new JsonResponse( data: $data, status: Response::HTTP_OK); } @@ -50,20 +49,10 @@ class OgBootController extends AbstractController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - #[Route('/status', name: 'ogboot_config', methods: ['GET'])] - public function config(HttpClientInterface $httpClient): JsonResponse + #[Route('/config', name: 'ogboot_config', methods: ['GET'])] + public function config(): JsonResponse { - try { - $response = $httpClient->request('GET', 'https://api.example.com/ogboot/v1/config', [ - '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); + $data = $this->ogbootConfigService->__invoke(); return new JsonResponse( data: $data, status: Response::HTTP_OK); } diff --git a/src/Controller/OgBoot/OgLive/GetAction.php b/src/Controller/OgBoot/OgLive/GetAction.php index f0fcce6..c93d34b 100644 --- a/src/Controller/OgBoot/OgLive/GetAction.php +++ b/src/Controller/OgBoot/OgLive/GetAction.php @@ -2,7 +2,8 @@ namespace App\Controller\OgBoot\OgLive; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\OgLive; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -13,7 +14,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class GetAction extends AbstractController +class GetAction extends AbstractOgLiveController { /** * @throws TransportExceptionInterface @@ -21,10 +22,10 @@ class GetAction extends AbstractController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function __invoke(HttpClientInterface $httpClient): JsonResponse + public function __invoke(OgLive $data, HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('GET', 'https://api.example.com/ogboot/v1/oglives', [ + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum(), [ 'headers' => [ 'accept' => 'application/json', ], diff --git a/src/Controller/OgBoot/OgLive/GetCollectionAction.php b/src/Controller/OgBoot/OgLive/GetCollectionAction.php index cdcaca0..236a7fc 100644 --- a/src/Controller/OgBoot/OgLive/GetCollectionAction.php +++ b/src/Controller/OgBoot/OgLive/GetCollectionAction.php @@ -2,16 +2,18 @@ namespace App\Controller\OgBoot\OgLive; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use App\Controller\OgBoot\AbstractOgLiveController; 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; -class GetCollectionAction extends AbstractController +#[AsController] +class GetCollectionAction extends AbstractOgLiveController { /** * @throws TransportExceptionInterface @@ -22,7 +24,7 @@ class GetCollectionAction extends AbstractController public function __invoke(HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('GET', 'https://api.example.com/ogboot/v1/oglives', [ + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/oglives', [ 'headers' => [ 'accept' => 'application/json', ], diff --git a/src/Controller/OgBoot/OgLive/GetDefaultAction.php b/src/Controller/OgBoot/OgLive/GetDefaultAction.php index 34f86e5..9d0ff93 100644 --- a/src/Controller/OgBoot/OgLive/GetDefaultAction.php +++ b/src/Controller/OgBoot/OgLive/GetDefaultAction.php @@ -2,7 +2,7 @@ namespace App\Controller\OgBoot\OgLive; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use App\Controller\OgBoot\AbstractOgLiveController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -13,7 +13,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class GetDefaultAction extends AbstractController +class GetDefaultAction extends AbstractOgLiveController { /** * @throws TransportExceptionInterface @@ -24,7 +24,7 @@ class GetDefaultAction extends AbstractController public function __invoke(HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('GET', 'https://api.example.com/ogboot/v1/oglives/default', [ + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/oglives/default', [ 'headers' => [ 'accept' => 'application/json', ], diff --git a/src/Controller/OgBoot/OgLive/GetIsosAction.php b/src/Controller/OgBoot/OgLive/GetIsosAction.php index d9ca380..436f9d4 100644 --- a/src/Controller/OgBoot/OgLive/GetIsosAction.php +++ b/src/Controller/OgBoot/OgLive/GetIsosAction.php @@ -2,7 +2,71 @@ namespace App\Controller\OgBoot\OgLive; -class GetIsosAction -{ +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\OgLive; +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 GetIsosAction extends AbstractOgLiveController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(HttpClientInterface $httpClient): JsonResponse + { + $ogLivesInserted = 0; + + try { + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/oglives/isos', [ + '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); + + if (!empty($data['downloads'])) { + $ogLivesInserted = $this->insertOglives($data); + } + + return new JsonResponse( data: [ 'data' => $data, 'ogLivesInserted' => $ogLivesInserted], status: Response::HTTP_OK); + } + + public function insertOglives(array $data): int + { + $count = 0; + + foreach ($data['downloads'] as $ogLive ) { + $ogLiveEntity = $this->entityManager->getRepository(OgLive::class)->findOneBy(['name' => $ogLive['filename']]); + + if ($ogLiveEntity) { + continue; + } + + $ogLiveEntity = new OgLive(); + $ogLiveEntity->setName($ogLive['filename']); + $ogLiveEntity->setInstalled($ogLive['installed']); + $ogLiveEntity->setFilename($ogLive['filename']); + + $this->entityManager->persist($ogLiveEntity); + $count++; + } + + $this->entityManager->flush(); + + return $count; + } } \ No newline at end of file diff --git a/src/Controller/OgBoot/OgLive/InstallAction.php b/src/Controller/OgBoot/OgLive/InstallAction.php index bea4132..485cb4d 100644 --- a/src/Controller/OgBoot/OgLive/InstallAction.php +++ b/src/Controller/OgBoot/OgLive/InstallAction.php @@ -2,7 +2,8 @@ namespace App\Controller\OgBoot\OgLive; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\OgLive; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -13,7 +14,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class InstallAction extends AbstractController +class InstallAction extends AbstractOgLiveController { /** * @throws TransportExceptionInterface @@ -21,13 +22,17 @@ class InstallAction extends AbstractController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function __invoke(HttpClientInterface $httpClient): JsonResponse + public function __invoke(OgLive $data, HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('POST', 'https://api.example.com/ogboot/v1/oglives', [ + $response = $httpClient->request('POST', $this->ogBootApiUrl.'/ogboot/v1/oglives/install', [ 'headers' => [ 'accept' => 'application/json', + 'Content-Type' => 'application/json', ], + 'json' => [ + 'isoname' => $data->getName() + ] ]); } catch (TransportExceptionInterface $e) { return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); diff --git a/src/Controller/OgBoot/OgLive/SetDefaultAction.php b/src/Controller/OgBoot/OgLive/SetDefaultAction.php index 373c8ec..0f96d13 100644 --- a/src/Controller/OgBoot/OgLive/SetDefaultAction.php +++ b/src/Controller/OgBoot/OgLive/SetDefaultAction.php @@ -2,7 +2,8 @@ namespace App\Controller\OgBoot\OgLive; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\OgLive; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -13,7 +14,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class SetDefaultAction extends AbstractController +class SetDefaultAction extends AbstractOgLiveController { /** * @throws TransportExceptionInterface @@ -21,13 +22,16 @@ class SetDefaultAction extends AbstractController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function __invoke(HttpClientInterface $httpClient): JsonResponse + public function __invoke(OgLive $data, HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('POST', 'https://api.example.com/ogboot/v1/oglives/default', [ + $response = $httpClient->request('POST', $this->ogBootApiUrl.'/ogboot/v1/oglives/default', [ 'headers' => [ 'accept' => 'application/json', ], + 'json' => [ + 'checksum' => $data->getChecksum() + ] ]); } catch (TransportExceptionInterface $e) { return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); diff --git a/src/Controller/OgBoot/OgLive/UninstallAction.php b/src/Controller/OgBoot/OgLive/UninstallAction.php index 2c2fde1..e2981ec 100644 --- a/src/Controller/OgBoot/OgLive/UninstallAction.php +++ b/src/Controller/OgBoot/OgLive/UninstallAction.php @@ -2,7 +2,8 @@ namespace App\Controller\OgBoot\OgLive; -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\OgLive; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -13,7 +14,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class UninstallAction extends AbstractController +class UninstallAction extends AbstractOgLiveController { /** * @throws TransportExceptionInterface @@ -21,10 +22,10 @@ class UninstallAction extends AbstractController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function __invoke(HttpClientInterface $httpClient): JsonResponse + public function __invoke(OgLive $data, HttpClientInterface $httpClient): JsonResponse { try { - $response = $httpClient->request('DELETE', 'https://api.example.com/ogboot/v1/oglives', [ + $response = $httpClient->request('DELETE', $this->ogBootApiUrl.'/ogboot/v1/oglives/'.$data->getChecksum(), [ 'headers' => [ 'accept' => 'application/json', ], diff --git a/src/Controller/OgBoot/PxeTemplate/DeleteAction.php b/src/Controller/OgBoot/PxeTemplate/DeleteAction.php index 5a09574..4971708 100644 --- a/src/Controller/OgBoot/PxeTemplate/DeleteAction.php +++ b/src/Controller/OgBoot/PxeTemplate/DeleteAction.php @@ -2,7 +2,41 @@ namespace App\Controller\OgBoot\PxeTemplate; -class DeleteAction -{ +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\PxeTemplate; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +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 DeleteAction extends AbstractOgLiveController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(PxeTemplate $data, HttpClientInterface $httpClient): JsonResponse + { + try { + $response = $httpClient->request('DELETE', $this->ogBootApiUrl.'/ogboot/v1/pxe-templates/'.$data->getName(), [ + '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); + + return new JsonResponse( data: $data, 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 9981c52..19e91a3 100644 --- a/src/Controller/OgBoot/PxeTemplate/GetAction.php +++ b/src/Controller/OgBoot/PxeTemplate/GetAction.php @@ -1,8 +1,42 @@ request('GET', $this->ogBootApiUrl.'/ogboot/v1/pxe-templates/'.$data->getName(), [ + '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); + + return new JsonResponse( data: $data, status: Response::HTTP_OK); + } } \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeTemplate/GetCollectionAction.php b/src/Controller/OgBoot/PxeTemplate/GetCollectionAction.php index 46f7b74..6693311 100644 --- a/src/Controller/OgBoot/PxeTemplate/GetCollectionAction.php +++ b/src/Controller/OgBoot/PxeTemplate/GetCollectionAction.php @@ -2,7 +2,40 @@ namespace App\Controller\OgBoot\PxeTemplate; -class GetCollectionAction -{ +use App\Controller\OgBoot\AbstractOgLiveController; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +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 GetCollectionAction extends AbstractOgLiveController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(HttpClientInterface $httpClient): JsonResponse + { + try { + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/pxe-templates', [ + '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); + + return new JsonResponse( data: $data, status: Response::HTTP_OK); + } } \ No newline at end of file diff --git a/src/Controller/OgBoot/PxeTemplate/PostAction.php b/src/Controller/OgBoot/PxeTemplate/PostAction.php index 75fc0e7..a2f996c 100644 --- a/src/Controller/OgBoot/PxeTemplate/PostAction.php +++ b/src/Controller/OgBoot/PxeTemplate/PostAction.php @@ -2,7 +2,54 @@ namespace App\Controller\OgBoot\PxeTemplate; -class PostAction -{ +use App\Controller\OgBoot\AbstractOgLiveController; +use App\Entity\PxeTemplate; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +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 PostAction extends AbstractOgLiveController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(PxeTemplate $data, HttpClientInterface $httpClient): JsonResponse + { + try { + $response = $httpClient->request('POST', $this->ogBootApiUrl.'/ogboot/v1/pxe-templates', [ + 'headers' => [ + 'accept' => 'application/json', + 'Content-Type' => 'application/json', + ], + 'json' => [ + 'name_template' => $data->getName(), + 'content_template' => $data->getTemplateContent(), + ], + ]); + + $data = json_decode($response->getContent(), true); + return new JsonResponse($data, Response::HTTP_OK); + + } catch (ClientExceptionInterface $e) { + $errorResponse = $e->getResponse(); + $errorContent = $errorResponse ? $errorResponse->getContent(false) : 'Client error occurred'; + return new JsonResponse(['error' => $errorContent], Response::HTTP_BAD_REQUEST); + } catch (ServerExceptionInterface $e) { + $errorResponse = $e->getResponse(); + $errorContent = $errorResponse ? $errorResponse->getContent(false) : 'Server error occurred'; + return new JsonResponse(['error' => $errorContent], Response::HTTP_INTERNAL_SERVER_ERROR); + } catch (TransportExceptionInterface $e) { + return new JsonResponse(['error' => 'Transport error occurred'], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } } \ No newline at end of file diff --git a/src/Entity/Client.php b/src/Entity/Client.php index 638ee48..80ef646 100644 --- a/src/Entity/Client.php +++ b/src/Entity/Client.php @@ -57,6 +57,9 @@ class Client extends AbstractEntity #[ORM\Column(nullable: true)] private ?array $position = ['x' => 0, 'y' => 0]; + #[ORM\ManyToOne(inversedBy: 'clients')] + private ?PxeBootFile $pxeBootFile = null; + public function __construct() { parent::__construct(); @@ -224,4 +227,16 @@ class Client extends AbstractEntity return $this; } + + public function getPxeBootFile(): ?PxeBootFile + { + return $this->pxeBootFile; + } + + public function setPxeBootFile(?PxeBootFile $pxeBootFile): static + { + $this->pxeBootFile = $pxeBootFile; + + return $this; + } } diff --git a/src/Entity/OgLive.php b/src/Entity/OgLive.php index d77b8fe..e9c6e82 100644 --- a/src/Entity/OgLive.php +++ b/src/Entity/OgLive.php @@ -16,6 +16,30 @@ class OgLive extends AbstractEntity #[ORM\Column(length: 255, nullable: true)] private ?string $downloadUrl = null; + #[ORM\Column(length: 255, nullable: true)] + private ?string $checksum = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $distribution = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $kernel = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $architecture = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $revision = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $directory = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $filename = null; + + #[ORM\Column(nullable: true)] + private ?bool $installed = null; + public function getDownloadUrl(): ?string { return $this->downloadUrl; @@ -27,4 +51,100 @@ class OgLive extends AbstractEntity return $this; } + + public function getChecksum(): ?string + { + return $this->checksum; + } + + public function setChecksum(?string $checksum): static + { + $this->checksum = $checksum; + + return $this; + } + + public function getDistribution(): ?string + { + return $this->distribution; + } + + public function setDistribution(?string $distribution): static + { + $this->distribution = $distribution; + + return $this; + } + + public function getKernel(): ?string + { + return $this->kernel; + } + + public function setKernel(?string $kernel): static + { + $this->kernel = $kernel; + + return $this; + } + + public function getArchitecture(): ?string + { + return $this->architecture; + } + + public function setArchitecture(?string $architecture): static + { + $this->architecture = $architecture; + + return $this; + } + + public function getRevision(): ?string + { + return $this->revision; + } + + public function setRevision(?string $revision): static + { + $this->revision = $revision; + + return $this; + } + + public function getDirectory(): ?string + { + return $this->directory; + } + + public function setDirectory(?string $directory): static + { + $this->directory = $directory; + + return $this; + } + + public function getFilename(): ?string + { + return $this->filename; + } + + public function setFilename(?string $filename): static + { + $this->filename = $filename; + + return $this; + } + + public function isInstalled(): ?bool + { + return $this->installed; + } + + public function setInstalled(?bool $installed): static + { + $this->installed = $installed; + + return $this; + } } diff --git a/src/Entity/PxeBootFile.php b/src/Entity/PxeBootFile.php new file mode 100644 index 0000000..7316351 --- /dev/null +++ b/src/Entity/PxeBootFile.php @@ -0,0 +1,69 @@ + + */ + #[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; + } +} diff --git a/src/Service/OgBoot/ConfigService.php b/src/Service/OgBoot/ConfigService.php index 2da2d30..8b247b9 100644 --- a/src/Service/OgBoot/ConfigService.php +++ b/src/Service/OgBoot/ConfigService.php @@ -2,7 +2,46 @@ namespace App\Service\OgBoot; -class ConfigService -{ +use Symfony\Component\HttpClient\HttpClient; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +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; +readonly class ConfigService +{ + public function __construct( + private string $ogBootApiUrl + ) + { + } + + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke() + { + $httpClient = HttpClient::create([ + 'verify_peer' => false, // Ignorar la verificación del certificado SSL + 'verify_host' => false, // Ignorar la verificación del nombre del host + ]); + + try { + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/config', [ + 'headers' => [ + 'accept' => 'application/json', + ], + ]); + } catch (TransportExceptionInterface $e) { + return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + return json_decode($response->getContent(), true); + } } \ No newline at end of file diff --git a/src/Service/OgBoot/StatusService.php b/src/Service/OgBoot/StatusService.php index d4621b3..c935e28 100644 --- a/src/Service/OgBoot/StatusService.php +++ b/src/Service/OgBoot/StatusService.php @@ -2,7 +2,47 @@ namespace App\Service\OgBoot; -class StatusService -{ +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +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; +use Symfony\Component\HttpClient\HttpClient; + +readonly class StatusService +{ + public function __construct( + private string $ogBootApiUrl + ) + { + } + + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke() + { + $httpClient = HttpClient::create([ + 'verify_peer' => false, // Ignorar la verificación del certificado SSL + 'verify_host' => false, // Ignorar la verificación del nombre del host + ]); + + try { + $response = $httpClient->request('GET', $this->ogBootApiUrl.'/ogboot/v1/status', [ + 'headers' => [ + 'accept' => 'application/json', + ], + ]); + } catch (TransportExceptionInterface $e) { + return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + return json_decode($response->getContent(), true); + } } \ No newline at end of file diff --git a/src/State/Processor/PxeTemplateProcessor.php b/src/State/Processor/PxeTemplateProcessor.php index c2bc86a..637dc30 100644 --- a/src/State/Processor/PxeTemplateProcessor.php +++ b/src/State/Processor/PxeTemplateProcessor.php @@ -2,7 +2,67 @@ namespace App\State\Processor; -class PxeTemplateProcessor -{ +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; +use ApiPlatform\State\ProcessorInterface; +use ApiPlatform\Validator\ValidatorInterface; +use App\Dto\Input\PxeTemplateInput; +use App\Dto\Output\PxeTemplateOutput; +use App\Repository\PxeTemplateRepository; -} \ No newline at end of file +readonly class PxeTemplateProcessor implements ProcessorInterface +{ + public function __construct( + private PxeTemplateRepository $pxeTemplateRepository, + private ValidatorInterface $validator + ) + { + } + + /** + * @throws \Exception + */ + public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): PxeTemplateOutput|null + { + switch ($operation){ + case $operation instanceof Post: + case $operation instanceof Put: + case $operation instanceof Patch: + return $this->processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): PxeTemplateOutput + { + if (!($data instanceof PxeTemplateInput)) { + throw new \Exception(sprintf('data is not instance of %s', PxeTemplateInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->pxeTemplateRepository->findOneByUuid($uriVariables['uuid']); + } + + $pxeTemplate = $data->createOrUpdateEntity($entity); + $this->validator->validate($pxeTemplate); + $this->pxeTemplateRepository->save($pxeTemplate); + + return new PxeTemplateOutput($pxeTemplate); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $pxeTemplate = $this->pxeTemplateRepository->findOneByUuid($uriVariables['uuid']); + $this->pxeTemplateRepository->delete($pxeTemplate); + + return null; + } +} diff --git a/src/State/Provider/PxeTemplateProvider.php b/src/State/Provider/PxeTemplateProvider.php index 001daa9..8704364 100644 --- a/src/State/Provider/PxeTemplateProvider.php +++ b/src/State/Provider/PxeTemplateProvider.php @@ -2,7 +2,70 @@ namespace App\State\Provider; -class PxeTemplateProvider -{ +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Put; +use ApiPlatform\State\Pagination\TraversablePaginator; +use ApiPlatform\State\ProviderInterface; +use App\Dto\Input\PxeTemplateInput; +use App\Dto\Output\PxeTemplateOutput; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -} \ No newline at end of file +readonly class PxeTemplateProvider implements ProviderInterface +{ + public function __construct( + private ProviderInterface $collectionProvider, + private ProviderInterface $itemProvider + ) + { + } + + public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + switch ($operation){ + case $operation instanceof GetCollection: + return $this->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 PxeTemplateOutput($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('PxeTemplate not found'); + } + + return new PxeTemplateOutput($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 PxeTemplateInput($item) : null; + } + + return new PxeTemplateInput(); + } +}