refs #601. Integration API pxe-template

feature/comunication-ogagent
Manuel Aranda Rosales 2024-08-12 13:23:30 +02:00
parent b44faa4b7f
commit 524b833c0e
27 changed files with 964 additions and 248 deletions

2
.env
View File

@ -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

View File

@ -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",

344
composer.lock generated
View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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"]

View File

@ -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
{

View File

@ -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);
}

View File

@ -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',
],

View File

@ -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',
],

View File

@ -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',
],

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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',
],

View File

@ -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);
}
}

View File

@ -1,8 +1,42 @@
<?php
namespace App\Controller\OgBoot\Pxe;
namespace App\Controller\OgBoot\PxeTemplate;
class GetAction
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 GetAction extends AbstractOgLiveController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(PxeTemplate $data, HttpClientInterface $httpClient): JsonResponse
{
try {
$response = $httpClient->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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Entity;
use App\Repository\PxeBootFileRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: PxeBootFileRepository::class)]
class PxeBootFile extends AbstractEntity
{
#[ORM\ManyToOne]
private ?PxeTemplate $template = null;
/**
* @var Collection<int, Client>
*/
#[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<int, Client>
*/
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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
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;
}
}

View File

@ -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;
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();
}
}