diff --git a/CHANGELOG.md b/CHANGELOG.md index 71e10df..9016ae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ # Changelog +## [0.13.0] - 2025-05-20 +### Added +- Se ha creado la base para la comunicacion TLS con el agente. + +### Improved +- Refactorizacion de la API para la gestion de llamadas al agente + +### Fixed +- Se ha corregido un bug que hacia que no se eliminara la imagen al particionar. + +--- ## [0.12.1] - 2025-05-14 ### Improved - Se ha eliminado la restriccion en el formulario de crear/editar repositorio, que hacia que la comprobara el formato de IP. Ahora tambien puede ser DNS. @@ -13,10 +24,10 @@ - Se ha añadido un nuevo campo en plantillas (defecto) el cual nos permite tener una plantilla por defecto en caso de que se elimine una. - Se ha comenzado la integracion con ogGit. -## Improved +### Improved - Mejorado el comportamiento de la API al crear una imagen. Ahora se guardan datos del pc de origen. -## Fixed +### Fixed - Se ha corregido el bug en la creacion de clientes masivos donde no se le asignaba la plantilla PXE. - Se ha corregido un bug en el DTO de clientes, que hacia que PHP diera un timeout por bucle infinito. diff --git a/docker-compose.yaml b/docker-compose.yaml index c15177a..45a5841 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,7 +26,8 @@ services: - 8443:443 # Añadir el puerto 443 volumes: - ./public:/var/www/html/public:cached - - ./docker/certs:/etc/nginx/certs # Montar certificados en Nginx + - ./docker/certs:/etc/nginx/certs + - ./certs:/opt/opengnsys/ogcore/etc/certificates networks: - ogcore-network @@ -37,6 +38,7 @@ services: dockerfile: ./docker/Dockerfile-php volumes: - ./:/var/www/html + - ./certs:/opt/opengnsys/ogcore/etc/certificates depends_on: - database networks: diff --git a/docker/default.conf b/docker/default.conf index f10f718..f990570 100644 --- a/docker/default.conf +++ b/docker/default.conf @@ -12,11 +12,11 @@ server { root /var/www/html/public; index index.html index.php; + #ssl_certificate /opt/opengnsys/ogcore/etc/certificates/ogcore.crt; + #ssl_certificate_key /opt/opengnsys/ogcore/etc/certificates/ogcore.key; ssl_certificate /etc/nginx/certs/ogcore.uds-test.net.crt.pem; ssl_certificate_key /etc/nginx/certs/ogcore.uds-test.net.key.pem; - - location /opengnsys/rest/ous// { rewrite ^/opengnsys/rest/ous//([0-9]+)/images /opengnsys/rest/ous/$1/images; rewrite ^/opengnsys/rest/ous//([0-9]+)/labs /opengnsys/rest/ous/$1/labs; @@ -44,6 +44,9 @@ server { error_log /var/log/nginx/error.log debug; access_log /var/log/nginx/access.log; + + #ssl_client_certificate /opt/opengnsys/ogcore/etc/certificates/ca.crt; + #ssl_verify_client on; } server { diff --git a/env.json b/env.json index a9b8660..d77f392 100644 --- a/env.json +++ b/env.json @@ -1,12 +1,13 @@ { "vars": { - "OG_BOOT_API_URL": "192.168.68.51:8082", - "OG_DHCP_API_URL": "192.168.68.51:8081", - "OG_CORE_IP": "192.168.68.62", - "OG_LOG_IP": "192.168.68.51", + "OG_BOOT_API_URL": "127.0.0.1:8082", + "OG_DHCP_API_URL": "127.0.0.1:8081", + "OG_CORE_IP": "127.0.0.1", + "OG_LOG_IP": "127.0.0.1", "UDS_AUTH_LOGIN": "test", "UDS_AUTH_USERNAME": "test", "UDS_AUTH_PASSWORD": "test", - "UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/" + "UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/", + "SSL_ENABLED": "true" } } \ No newline at end of file diff --git a/ogagent.conf b/ogagent.conf new file mode 100644 index 0000000..e69de29 diff --git a/src/Controller/AuthValidatorController.php b/src/Controller/AuthValidatorController.php new file mode 100644 index 0000000..d22151b --- /dev/null +++ b/src/Controller/AuthValidatorController.php @@ -0,0 +1,54 @@ +jwtManager = $jwtManager; + } + + #[Route('/validate', name: 'auth_validate', methods: ['POST'])] + public function validate(Request $request): Response + { + $sslClientVerify = $request->headers->get('SSL_CLIENT_VERIFY'); + $clientCertOk = $sslClientVerify === 'SUCCESS'; + + $authHeader = $request->headers->get('Authorization'); + $hasValidJwt = $this->validateJwtToken($authHeader); + + if ($clientCertOk || $hasValidJwt) { + return new Response('Authorized', Response::HTTP_OK); + } + + return new Response('Unauthorized', Response::HTTP_UNAUTHORIZED); + } + + private function validateJwtToken(?string $authHeader): bool + { + if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) { + return false; + } + + $token = substr($authHeader, 7); + + try { + $payload = $this->jwtManager->parse($token); + + return true; + + } catch (\Exception $e) { + return false; + } + } +} diff --git a/src/Controller/OgAgent/AbstractOgAgentController.php b/src/Controller/OgAgent/AbstractOgAgentController.php new file mode 100644 index 0000000..97ed83d --- /dev/null +++ b/src/Controller/OgAgent/AbstractOgAgentController.php @@ -0,0 +1,87 @@ + [ + 'accept' => 'application/json', + 'Content-Type' => 'application/json', + 'Authorization' => $token, + ], + 'verify_peer' => false, + 'verify_host' => false, + 'timeout' => 10 + ]); + + + if ($this->sslEnabled === 'true') { + $params['verify_peer'] = true; + $params['verify_host'] = false; + $params['cafile'] = '/opt/opengnsys/ogcore/etc/certificates/ca.crt'; + $params['local_cert'] = '/opt/opengnsys/ogcore/etc/certificates/ogcore.crt'; + $params['local_pk'] = '/opt/opengnsys/ogcore/etc/certificates/ogcore.key'; + } + + try { + $response = $this->httpClient->request($method, $url, $params); + return json_decode($response->getContent(), true); + } catch (ClientExceptionInterface | ServerExceptionInterface $e) { + $this->logger->error(sprintf('Client/Server error in request to %s: %s', $url, $e->getMessage())); + + return [ + 'code' => Response::HTTP_INTERNAL_SERVER_ERROR, + 'error' => 'Client/Server error', + 'details' => $e->getMessage(), + ]; + } catch (TransportExceptionInterface $e) { + $this->logger->error(sprintf('Transport error in request to %s: %s', $url, $e->getMessage())); + + return [ + 'code' => Response::HTTP_INTERNAL_SERVER_ERROR, + 'error' => 'Client/Server error', + 'details' => $e->getMessage(), + ]; + } + } +} \ No newline at end of file diff --git a/src/Controller/OgAgent/CreateImageAction.php b/src/Controller/OgAgent/CreateImageAction.php index ed3bb96..907a0f9 100644 --- a/src/Controller/OgAgent/CreateImageAction.php +++ b/src/Controller/OgAgent/CreateImageAction.php @@ -34,19 +34,8 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -class CreateImageAction extends AbstractController +class CreateImageAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - protected readonly CreateRepositoryAction $createRepositoryAction, - protected readonly CreateTagAction $createTagAction, - ) - { - } - /** * @throws TransportExceptionInterface * @throws ServerExceptionInterface @@ -147,29 +136,25 @@ class CreateImageAction extends AbstractController throw new Exception("El tipo de partición '$partitionCode' no se encontró en la lista."); } - try { + $client = $client ?? $image->getClient(); + $this->logger->info('Creating image', ['image' => $image->getId()]); - $client = $client ?? $image->getClient(); - $this->logger->info('Creating image', ['image' => $image->getId()]); - $response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/opengnsys/CrearImagen', [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagen', + params: [ 'json' => $data, - ]); + ], + token: $client->getToken(), + ); + $this->logger->info('Creating image', ['image' => $imageImageRepository->getName(), 'repository' => $repository->getIp()]); - } catch (TransportExceptionInterface $e) { - $this->logger->error('Error creating image', ['image' => $image->getId(), 'error' => $e->getMessage()]); - return new JsonResponse( - data: ['error' => $e->getMessage()], - status: Response::HTTP_INTERNAL_SERVER_ERROR - ); + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error creating image'); } - $jobId = json_decode($response->getContent(), true)['job_id']; + $jobId = $response['job_id']; $client->setStatus(ClientStatus::BUSY); $this->entityManager->persist($client); diff --git a/src/Controller/OgAgent/DeployImageAction.php b/src/Controller/OgAgent/DeployImageAction.php index fe35468..2ab9d01 100644 --- a/src/Controller/OgAgent/DeployImageAction.php +++ b/src/Controller/OgAgent/DeployImageAction.php @@ -29,17 +29,8 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -class DeployImageAction extends AbstractController +class DeployImageAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - ) - { - } - /** * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface @@ -91,26 +82,22 @@ class DeployImageAction extends AbstractController 'ids' => '0' ]; - try { - $response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen', [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen', + params: [ 'json' => $data, - ]); - $this->logger->info('Deploying image', ['image' => $image->getId()]); + ], + token: $client->getToken(), + ); - $jobId = json_decode($response->getContent(), true)['job_id']; - } catch (ClientExceptionInterface | ServerExceptionInterface | TransportExceptionInterface | TransportException $e) { - $this->logger->error('Error deploying image', [ - 'image' => $image->getId() ?? 'unknown', - 'error' => $e->getMessage() - ]); - return null; + $this->logger->info('Deploying image', [ 'image' => $imageImageRepository->getName(), 'repository' => $repository->getIp()]); + + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error deploying image'); } + $jobId = $response['job_id']; $client->setStatus(ClientStatus::BUSY); $this->entityManager->persist($client); diff --git a/src/Controller/OgAgent/LoginAction.php b/src/Controller/OgAgent/LoginAction.php index 42fd7e1..a6d798f 100644 --- a/src/Controller/OgAgent/LoginAction.php +++ b/src/Controller/OgAgent/LoginAction.php @@ -27,17 +27,14 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -class LoginAction extends AbstractController +class LoginAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - ) - { - } - + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function __invoke(MultipleClientsInput $input): JsonResponse { foreach ($input->clients as $clientEntity) { @@ -60,26 +57,21 @@ class LoginAction extends AbstractController 'ids' => '0' ]; - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/IniciarSesion', [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'http://'.$client->getIp().':8000/opengnsys/IniciarSesion', + params: [ 'json' => $data, - ]); - $this->logger->info('Login client', ['client' => $client->getId()]); + ] + ); - } catch (TransportExceptionInterface $e) { - $this->logger->error('Login rebooting client', ['client' => $client->getId(), 'error' => $e->getMessage()]); - return new JsonResponse( - data: ['error' => $e->getMessage()], - status: Response::HTTP_INTERNAL_SERVER_ERROR - ); + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error logging in: '.$response['error']); } - $jobId = json_decode($response->getContent(), true)['job_id']; + $this->logger->info('Login client', ['client' => $client->getId()]); + + $jobId = $response['job_id']; $client->setStatus(ClientStatus::INITIALIZING); $this->entityManager->persist($client); diff --git a/src/Controller/OgAgent/PartitionAssistantAction.php b/src/Controller/OgAgent/PartitionAssistantAction.php index 5dfe433..d69dba9 100644 --- a/src/Controller/OgAgent/PartitionAssistantAction.php +++ b/src/Controller/OgAgent/PartitionAssistantAction.php @@ -28,17 +28,14 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -class PartitionAssistantAction extends AbstractController +class PartitionAssistantAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - ) - { - } - + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function __invoke(PartitionPostInput $input): JsonResponse { $partitions = $input->partitions; @@ -101,28 +98,28 @@ class PartitionAssistantAction extends AbstractController "ids" => "0" ]; - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/opengnsys/Configurar', [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'https://'.$client->getIp().':8000/opengnsys/Configurar', + params: [ 'json' => $result, - ]); - $this->logger->info('Partitioning disk', ['client' => $client->getId(), 'disk' => $diskNumber]); - } catch (TransportExceptionInterface $e) { - $this->logger->error('Error partitioning disk', ['client' => $client->getId(), 'disk' => $diskNumber, 'error' => $e->getMessage()]); - continue; + ], + token: $client->getToken(), + ); + + $this->logger->info('Partition assistant', ['client' => $client->getId()]); + + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error occurred while partitioning'); } - $jobId = json_decode($response->getContent(), true)['job_id']; + $jobId = $response['job_id']; $client->setStatus(ClientStatus::BUSY); $this->entityManager->persist($client); $this->entityManager->flush(); - $this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, []); + $this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data); } } diff --git a/src/Controller/OgAgent/PowerOffAction.php b/src/Controller/OgAgent/PowerOffAction.php index 8cde198..ed8c913 100644 --- a/src/Controller/OgAgent/PowerOffAction.php +++ b/src/Controller/OgAgent/PowerOffAction.php @@ -28,17 +28,14 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -class PowerOffAction extends AbstractController +class PowerOffAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - ) - { - } - + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function __invoke(MultipleClientsInput $input): JsonResponse { foreach ($input->clients as $clientEntity) { @@ -60,26 +57,23 @@ class PowerOffAction extends AbstractController 'ids' => '0' ]; - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/'.$endpoint, [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'https://'.$client->getIp().':8000/'.$endpoint, + params: [ 'json' => $data, - ]); - $this->logger->info('Powering off client', ['client' => $client->getId()]); - $jobId = json_decode($response->getContent(), true)['job_id']; + ], + token: $client->getToken(), + ); - } catch (ClientExceptionInterface | ServerExceptionInterface | TransportExceptionInterface | TransportException $e) { - $this->logger->error('Error power off client', [ - 'image' => $client->getIp(), - 'error' => $e->getMessage() - ]); - continue; + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error deploying image'); } + $this->logger->info('Powering off client', ['client' => $client->getId()]); + + $jobId = $response['job_id']; + $client->setStatus(ClientStatus::TURNING_OFF); $this->entityManager->persist($client); $this->entityManager->flush(); diff --git a/src/Controller/OgAgent/RebootAction.php b/src/Controller/OgAgent/RebootAction.php index 0be2163..b83af31 100644 --- a/src/Controller/OgAgent/RebootAction.php +++ b/src/Controller/OgAgent/RebootAction.php @@ -27,17 +27,14 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -class RebootAction extends AbstractController +class RebootAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - ) - { - } - + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function __invoke(MultipleClientsInput $input): JsonResponse { foreach ($input->clients as $clientEntity) { @@ -56,27 +53,22 @@ class RebootAction extends AbstractController 'ids' => '0' ]; - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/'.$endpoint, [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'http://'.$client->getIp().':8000/'.$endpoint, + params: [ 'json' => $data, - ]); + ], + token: $client->getToken(), + ); - $this->logger->info('Rebooting client', ['client' => $client->getId()]); - - } catch (TransportExceptionInterface $e) { - $this->logger->error('Error rebooting client', ['client' => $client->getId(), 'error' => $e->getMessage()]); - return new JsonResponse( - data: ['error' => $e->getMessage()], - status: Response::HTTP_INTERNAL_SERVER_ERROR - ); + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error deploying image'); } - $jobId = json_decode($response->getContent(), true)['job_id']; + $this->logger->info('Rebooting client', ['client' => $client->getId()]); + + $jobId = $response['job_id']; $client->setStatus(ClientStatus::INITIALIZING); $this->entityManager->persist($client); diff --git a/src/Controller/OgAgent/RunScriptAction.php b/src/Controller/OgAgent/RunScriptAction.php index e4a999c..840e6d2 100644 --- a/src/Controller/OgAgent/RunScriptAction.php +++ b/src/Controller/OgAgent/RunScriptAction.php @@ -15,24 +15,25 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Validator\Exception\ValidatorException; +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 RunScriptAction extends AbstractController +class RunScriptAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreateService $createService, - protected readonly LoggerInterface $logger, - ) - { - } - + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function __invoke(CommandExecuteInput $input): JsonResponse { /** @var Client $clientEntity */ foreach ($input->clients as $clientEntity) { + /** @var Client $client */ $client = $clientEntity->getEntity(); if (!$client->getIp()) { @@ -45,26 +46,22 @@ class RunScriptAction extends AbstractController 'ids' => '0' ]; - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/opengnsys/EjecutarScript', [ - 'verify_peer' => false, - 'verify_host' => false, - 'headers' => [ - 'Content-Type' => 'application/json', - ], + $response = $this->createRequest( + method: 'POST', + url: 'https://'.$client->getIp().':8000/opengnsys/EjecutarScript', + params: [ 'json' => $data, - ]); - $this->logger->info('Executing run-script', ['client' => $client->getId(), 'response' => $response->getContent()]); + ], + token: $client->getToken(), + ); - } catch (TransportExceptionInterface $e) { - $this->logger->error('Error executing run-script', ['client' => $client->getId(), 'error' => $e->getMessage()]); - return new JsonResponse( - data: ['error' => $e->getMessage()], - status: Response::HTTP_INTERNAL_SERVER_ERROR - ); + if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + throw new ValidatorException('Error deploying image'); } - $jobId = json_decode($response->getContent(), true)['job_id']; + $this->logger->info('Powering off client', ['client' => $client->getId()]); + + $jobId = $response['job_id']; $this->entityManager->persist($client); $this->entityManager->flush(); diff --git a/src/Controller/OgAgent/StatusAction.php b/src/Controller/OgAgent/StatusAction.php index dde6331..d188bd7 100644 --- a/src/Controller/OgAgent/StatusAction.php +++ b/src/Controller/OgAgent/StatusAction.php @@ -24,15 +24,8 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class StatusAction extends AbstractController +class StatusAction extends AbstractOgAgentController { - public function __construct( - protected readonly EntityManagerInterface $entityManager, - protected readonly HttpClientInterface $httpClient, - protected readonly CreatePartitionService $createPartitionService, - protected readonly LoggerInterface $logger, - ) {} - /** * @throws TransportExceptionInterface * @throws ServerExceptionInterface @@ -66,38 +59,37 @@ class StatusAction extends AbstractController ); } + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function getOgLiveStatus (Client $client): JsonResponse|int|string { $this->logger->info('Checking client status', ['client' => $client->getId()]); $params = [ - 'full-config' => false, + 'json' => [ + 'full-config' => false + ] ]; - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/opengnsys/status', [ - 'verify_peer' => false, - 'verify_host' => false, - 'timeout' => 10, - 'headers' => [ - 'Content-Type' => 'application/json', - ], - 'json' => $params, - ]); - $statusCode = $response->getStatusCode(); - $client->setStatus($statusCode === Response::HTTP_OK ? ClientStatus::OG_LIVE : ClientStatus::OFF); + $data = $this->createRequest( + method: 'POST', + url: 'https://' . $client->getIp() . ':8000/opengnsys/status', + params: $params, + token: $client->getToken(), + ); - } catch (TransportExceptionInterface $e) { - $this->logger->error('Error checking client status', ['client' => $client->getId(), 'error' => $e->getMessage()]); + if (isset($data['error']) && $data['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { + $this->logger->error('Error checking client status', ['client' => $client->getId()]); $client->setStatus(ClientStatus::OFF); $this->entityManager->persist($client); $this->entityManager->flush(); - - return $e->getMessage(); + throw new ValidatorException('Error deploying image'); } - $data = json_decode($response->getContent(), true); - if (isset($data['cfg'])) { $this->logger->info('Creating partitions', ['data' => $data['cfg']]); $this->createPartitionService->__invoke($data, $client); @@ -109,25 +101,22 @@ class StatusAction extends AbstractController return Response::HTTP_OK; } + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ public function getSOStatus (Client $client): JsonResponse|int { - try { - $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/opengnsys/status', [ - 'verify_peer' => false, - 'verify_host' => false, - 'timeout' => 10, - 'headers' => [ - 'Content-Type' => 'application/json', - ], - 'json' => [], - ]); - } catch (TransportExceptionInterface $e) { - $client->setStatus(ClientStatus::OFF); - $this->logger->error('Error checking client status', ['client' => $client->getId(), 'error' => $e->getMessage()]); - return Response::HTTP_INTERNAL_SERVER_ERROR; - } - - $data = json_decode($response->getContent(), true); + $data = $this->createRequest( + method: 'POST', + url: 'https://' . $client->getIp() . ':8000/opengnsys/status', + params: [ + 'full-config' => false, + ], + token: $client->getToken(), + ); if (isset($data['cfg'])) { $this->createPartitionService->__invoke($data, $client); diff --git a/src/Controller/OgAgent/Webhook/AgentController.php b/src/Controller/OgAgent/Webhook/AgentController.php index 017a4f1..4f4fb48 100644 --- a/src/Controller/OgAgent/Webhook/AgentController.php +++ b/src/Controller/OgAgent/Webhook/AgentController.php @@ -49,6 +49,7 @@ class AgentController extends AbstractController } $clientEntity->setStatus(ClientStatus::OG_LIVE); + $clientEntity->setToken($data['secret'] ?? null); $this->entityManager->persist($clientEntity); if (isset($data['cfg'])) { diff --git a/src/Controller/OgRepository/Image/SyncAction.php b/src/Controller/OgRepository/Image/SyncAction.php index 027693c..0c34fd7 100644 --- a/src/Controller/OgRepository/Image/SyncAction.php +++ b/src/Controller/OgRepository/Image/SyncAction.php @@ -51,6 +51,7 @@ class SyncAction extends AbstractOgRepositoryController $imageEntity->setName($image['name']); $imageEntity->setRemotePc(false); $imageEntity->setIsGlobal(false); + $imageEntity->setType('monolithic'); $this->entityManager->persist($imageEntity); } @@ -59,6 +60,7 @@ class SyncAction extends AbstractOgRepositoryController $imageImageRepositoryEntity = new ImageImageRepository(); } + $imageImageRepositoryEntity->setName($image['name']); $imageImageRepositoryEntity->setImageFullsum($image['fullsum']); $imageImageRepositoryEntity->setDatasize($image['datasize']); $imageImageRepositoryEntity->setStatus(ImageStatus::SUCCESS); diff --git a/src/Service/CreatePartitionService.php b/src/Service/CreatePartitionService.php index f5153b1..f48acfd 100644 --- a/src/Service/CreatePartitionService.php +++ b/src/Service/CreatePartitionService.php @@ -49,15 +49,19 @@ class CreatePartitionService $partitionEntity->setOperativeSystem(null); if (isset($cfg['soi']) && $cfg['soi'] !== '') { - $operativeSystem = $this->entityManager->getRepository(OperativeSystem::class) - ->findOneBy(['name' => $cfg['soi']]); + if ($cfg['soi'] === 'DATA') { + $partitionEntity->setImage(null); + } else { + $operativeSystem = $this->entityManager->getRepository(OperativeSystem::class) + ->findOneBy(['name' => $cfg['soi']]); - if (!$operativeSystem) { - $operativeSystem = new OperativeSystem(); - $operativeSystem->setName($cfg['soi']); - $this->entityManager->persist($operativeSystem); + if (!$operativeSystem) { + $operativeSystem = new OperativeSystem(); + $operativeSystem->setName($cfg['soi']); + $this->entityManager->persist($operativeSystem); + } + $partitionEntity->setOperativeSystem($operativeSystem); } - $partitionEntity->setOperativeSystem($operativeSystem); } $partitionEntity->setClient($clientEntity); diff --git a/src/Service/UDS/UDSClient.php b/src/Service/UDS/UDSClient.php index fe6dbad..5842986 100644 --- a/src/Service/UDS/UDSClient.php +++ b/src/Service/UDS/UDSClient.php @@ -25,13 +25,13 @@ class UDSClient public function __construct( private HttpClientInterface $httpClient, private readonly EntityManagerInterface $entityManager, - #[Autowire(env: 'UDS_URL')] + #[Autowire(env: 'REMOTE_PC_URL')] private readonly string $udsAPIurl, - #[Autowire(env: 'UDS_AUTH_LOGIN')] + #[Autowire(env: 'REMOTE_PC_AUTH_LOGIN')] private readonly string $udsAuthLogin, - #[Autowire(env: 'UDS_AUTH_USERNAME')] + #[Autowire(env: 'REMOTE_PC_AUTH_USERNAME')] private readonly string $udsAuthUsername, - #[Autowire(env: 'UDS_AUTH_PASSWORD')] + #[Autowire(env: 'REMOTE_PC_AUTH_PASSWORD')] private readonly string $udsAuthPassword, ) {