diff --git a/composer.json b/composer.json index b7550df..9d05bf0 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "symfony/flex": "^2", "symfony/framework-bundle": "6.4.*", "symfony/http-client": "6.4.*", + "symfony/monolog-bundle": "^3.10", "symfony/property-access": "6.4.*", "symfony/property-info": "6.4.*", "symfony/runtime": "6.4.*", diff --git a/composer.lock b/composer.lock index 2bfe6d3..abefe8a 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": "aaa904068da3e39927da2e6658330011", + "content-hash": "2df97d4a1797242acadb47d83b3fbe98", "packages": [ { "name": "api-platform/core", @@ -2091,6 +2091,109 @@ ], "time": "2024-07-03T20:49:59+00:00" }, + { + "name": "monolog/monolog", + "version": "3.8.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67", + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.8.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2024-11-12T13:57:08+00:00" + }, { "name": "nelmio/cors-bundle", "version": "2.5.0", @@ -4840,6 +4943,166 @@ ], "time": "2024-07-26T14:52:04+00:00" }, + { + "name": "symfony/monolog-bridge", + "version": "v6.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bridge.git", + "reference": "9d14621e59f22c2b6d030d92d37ffe5ae1e60452" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/9d14621e59f22c2b6d030d92d37ffe5ae1e60452", + "reference": "9d14621e59f22c2b6d030d92d37ffe5ae1e60452", + "shasum": "" + }, + "require": { + "monolog/monolog": "^1.25.1|^2|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<5.4", + "symfony/http-foundation": "<5.4", + "symfony/security-core": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/mailer": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/security-core": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Monolog\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Monolog with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/monolog-bridge/tree/v6.4.13" + }, + "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-10-14T08:49:08+00:00" + }, + { + "name": "symfony/monolog-bundle", + "version": "v3.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bundle.git", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "shasum": "" + }, + "require": { + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "php": ">=7.2.5", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony MonologBundle", + "homepage": "https://symfony.com", + "keywords": [ + "log", + "logging" + ], + "support": { + "issues": "https://github.com/symfony/monolog-bundle/issues", + "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.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": "2023-11-06T17:08:13+00:00" + }, { "name": "symfony/password-hasher", "version": "v6.4.8", @@ -9976,7 +10239,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { @@ -9984,6 +10247,6 @@ "ext-ctype": "*", "ext-iconv": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/config/bundles.php b/config/bundles.php index 826d993..f1a3820 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -16,4 +16,5 @@ return [ Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], ]; diff --git a/config/packages/monolog.yaml b/config/packages/monolog.yaml new file mode 100644 index 0000000..9db7d8a --- /dev/null +++ b/config/packages/monolog.yaml @@ -0,0 +1,62 @@ +monolog: + channels: + - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists + +when@dev: + monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + channels: ["!event"] + # uncomment to get logging in your browser + # you may have to allow bigger header sizes in your Web server configuration + #firephp: + # type: firephp + # level: info + #chromephp: + # type: chromephp + # level: info + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine", "!console"] + +when@test: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + channels: ["!event"] + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + +when@prod: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + buffer_size: 50 # How many messages should be saved? Prevent memory leaks + nested: + type: stream + path: php://stderr + level: debug + formatter: monolog.formatter.json + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine"] + deprecation: + type: stream + channels: [deprecation] + path: php://stderr + formatter: monolog.formatter.json diff --git a/src/Controller/OgAgent/StatusAction.php b/src/Controller/OgAgent/StatusAction.php index 056b86f..5ce9d66 100644 --- a/src/Controller/OgAgent/StatusAction.php +++ b/src/Controller/OgAgent/StatusAction.php @@ -59,7 +59,7 @@ class StatusAction extends AbstractController ); } - public function getOgLiveStatus (Client $client): JsonResponse|int + public function getOgLiveStatus (Client $client): JsonResponse|int|string { try { $response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/status', [ @@ -77,7 +77,7 @@ class StatusAction extends AbstractController } catch (TransportExceptionInterface $e) { $client->setStatus(ClientStatus::OFF); - return Response::HTTP_INTERNAL_SERVER_ERROR; + return $e->getMessage(); } $data = json_decode($response->getContent(), true); diff --git a/src/Controller/OgAgent/Webhook/ClientsController.php b/src/Controller/OgAgent/Webhook/ClientsController.php index 112e461..e3a4f4c 100644 --- a/src/Controller/OgAgent/Webhook/ClientsController.php +++ b/src/Controller/OgAgent/Webhook/ClientsController.php @@ -10,11 +10,14 @@ use App\Entity\Software; use App\Entity\SoftwareProfile; use App\Entity\Trace; use App\Model\ClientStatus; +use App\Model\CommandTypes; use App\Model\ImageStatus; use App\Model\SoftwareTypes; use App\Model\TraceStatus; use App\Service\CreatePartitionService; +use App\Service\Trace\CreateService; use Doctrine\ORM\EntityManagerInterface; +use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -33,7 +36,9 @@ class ClientsController extends AbstractController public function __construct( protected readonly EntityManagerInterface $entityManager, public readonly CreateAuxFilesAction $createAuxFilesAction, - protected readonly CreatePartitionService $createPartitionService + protected readonly CreatePartitionService $createPartitionService, + protected readonly LoggerInterface $logger, + protected readonly CreateService $createService, ) { } @@ -56,38 +61,51 @@ class ClientsController extends AbstractController } } + $this->logger->info('Webhook data received', $data); + if ($data['nfn'] === 'RESPUESTA_CrearImagen') { $trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]); $image = $this->entityManager->getRepository(Image::class)->findOneBy(['uuid' => $data['idi']]); if (!$image) { + $this->logger->error('Image not found', $data); return new JsonResponse(['message' => 'Image not found'], Response::HTTP_NOT_FOUND); } + if (!$trace) { + $this->logger->error('Trace not found', $data); + return new JsonResponse(['message' => 'Trace not found'], Response::HTTP_NOT_FOUND); + } + if ($data['res'] === 1) { $trace->setStatus(TraceStatus::SUCCESS); $trace->setFinishedAt(new \DateTime()); $image->setStatus(ImageStatus::AUX_FILES_PENDING); $image->setCreated(true); + $this->logger->info('Start partition creation. ', ['image' => (string) $image->getUuid()]); if (isset($data['cfg'])) { $this->createPartitionService->__invoke($data, $image->getClient()); } + $this->logger->info('Starting software profile creation. ', ['image' => (string) $image->getUuid()]); $this->createSoftwareProfile($data['inv_sft'], $image); + $this->logger->info('Start aux files ogrepo API ', ['image' => (string) $image->getUuid()]); $this->createAuxFilesAction->__invoke($image); + $this->logger->info('End aux files ogrepo API ', ['image' => (string) $image->getUuid()]); } else { $trace->setStatus(TraceStatus::FAILED); $trace->setFinishedAt(new \DateTime()); $trace->setOutput($data['der']); $image->setCreated(false); $image->setStatus(ImageStatus::FAILED); + $this->logger->error('Image updated failed', $data); } - $this->entityManager->persist($image); + $this->entityManager->persist($image); $client = $trace->getClient(); $client->setStatus(ClientStatus::OG_LIVE); - $this->entityManager->persist($trace); $this->entityManager->flush(); + $this->logger->info('Image updated. Success.', ['image' => (string) $image->getUuid()]); } if ($data['nfn'] === 'RESPUESTA_RestaurarImagen') { @@ -112,26 +130,28 @@ class ClientsController extends AbstractController return new JsonResponse([], Response::HTTP_OK); } - public function createSoftwareProfile (string $base64Data, Image $image): void + public function createSoftwareProfile(string $base64Data, Image $image): void { $decodedData = base64_decode($base64Data); + $this->logger->info('Software profile decoded', ['data' => '']); + $softwareList = array_map('trim', explode(",", $decodedData)); + $softwareList = array_filter($softwareList); + $existingSoftware = $this->entityManager->getRepository(Software::class)->findBy(['name' => $softwareList]); + $existingNames = array_map(fn($software) => $software->getName(), $existingSoftware); + $newSoftwareNames = array_diff($softwareList, $existingNames); - $softwareList = explode("\n", $decodedData); + foreach ($newSoftwareNames as $software) { + $softwareEntity = new Software(); + $softwareEntity->setName($software); + $softwareEntity->setType(SoftwareTypes::APPLICATION); + $this->entityManager->persist($softwareEntity); + } $softwareProfile = new SoftwareProfile(); - $softwareProfile->setDescription('Perfil : '.$image->getName()); + $softwareProfile->setDescription('Perfil: ' . $image->getName()); $softwareProfile->setOrganizationalUnit($image->getClient()->getOrganizationalUnit()); - foreach ($softwareList as $software) { - $software = trim($software); - $softwareEntity = $this->entityManager->getRepository(Software::class)->findOneBy(['name' => $software]); - if (!$softwareEntity) { - $softwareEntity = new Software(); - $softwareEntity->setName($software); - $softwareEntity->setType(SoftwareTypes::APPLICATION); - $this->entityManager->persist($softwareEntity); - } - + foreach ($existingSoftware as $softwareEntity) { $softwareEntity->addSoftwareProfile($softwareProfile); } diff --git a/symfony.lock b/symfony.lock index caba1f7..c537b54 100644 --- a/symfony.lock +++ b/symfony.lock @@ -178,6 +178,18 @@ "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" } }, + "symfony/monolog-bundle": { + "version": "3.10", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.7", + "ref": "aff23899c4440dd995907613c1dd709b6f59503f" + }, + "files": [ + "config/packages/monolog.yaml" + ] + }, "symfony/phpunit-bridge": { "version": "7.1", "recipe": {