feat(dashboard): Affiche des indicateurs clés et des alertes sur le tableau de bord.

🐛 fix(server.twig): Corrige le lien cassé du bouton "Ajouter un nouveau serveur".

♻️ refactor(ServerController): Intègre le client OVH pour récupérer les informations des serveurs dédiés.

 feat(Ovh): Ajoute un service OVH pour récupérer les informations des serveurs.
This commit is contained in:
Serreau Jovann
2025-11-05 16:01:57 +01:00
parent 5447be0167
commit c727cd9cc4
5 changed files with 229 additions and 7 deletions

View File

@@ -23,7 +23,7 @@ class DashboardController extends AbstractController
CustomerAdvertPaymentRepository $customerAdvertPaymentRepository,
CustomerDevisRepository $customerDevisRepository,
SignClient $signClient,
UploaderHelper $uploaderHelper
UploaderHelper $uploaderHelper,
): Response
{
$invoiceList = [];
@@ -31,6 +31,7 @@ class DashboardController extends AbstractController
$devisList = [];
$remaining_amount = 0;
$services = [];
$servers = [];
if(in_array("ROLE_CUSTOMER",$this->getUser()->getRoles())) {
/** @var Customer $customer */
$customer = $this->getUser()->getCustomers()[0];
@@ -94,6 +95,8 @@ class DashboardController extends AbstractController
'status' => 'actif'
];
}
} else {
}
@@ -103,6 +106,7 @@ class DashboardController extends AbstractController
'devisList' => $devisList,
'active_services' => $services,
'remaining_amount' => $remaining_amount,
'servers' => $servers,
]);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Controller\Artemis\Infra;
use App\Service\Google\ComputeEngineClient;
use App\Service\Ovh\Client;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -11,13 +12,17 @@ use Symfony\Component\Routing\Attribute\Route;
class ServerController extends AbstractController
{
#[Route(path: '/artemis/infra/server',name: 'artemis_infrastructure_server')]
public function artemis(Request $request,ComputeEngineClient $computeEngineClient): Response
public function artemis(Request $request,ComputeEngineClient $computeEngineClient,Client $client): Response
{
$lists = [];
foreach ($computeEngineClient->list() as $instance) {
$lists[] = $computeEngineClient->detail($instance);
}
foreach ($client->servers() as $instance) {
$lists[] = $client->detail($instance);
}
return $this->render('artemis/infra/server.twig',[
'lists' => $lists
]);

View File

@@ -2,13 +2,15 @@
namespace App\Service\Ovh;
use App\Entity\Compute;
use Doctrine\ORM\EntityManagerInterface;
use Ovh\Api;
class Client
{
private Api $ovhClient;
public function __construct()
public function __construct(private readonly EntityManagerInterface $em)
{
$this->ovhClient = new Api(
$_ENV['OVH_KEY'] ?? '',
@@ -46,9 +48,39 @@ class Client
}
}
public function nddExpired()
public function servers()
{
$domain = $this->ovhClient->get('/domain');
dd($domain);
$list =[];
$servers = $this->ovhClient->get('/dedicated/server');
foreach ($servers as $server) {
$compute = $this->em->getRepository(Compute::class)
->findOneBy(['instanceId' => $server]);
$detail = $this->ovhClient->get('/dedicated/server/' . $server);
if (!$compute instanceof Compute) {
$compute = new Compute();
$compute->setInstanceId("ovh|".$server);
$compute->setZone($detail['region']."|".$detail['rack']);
$compute->setInternalIp($detail['ip']);
$compute->setExternalIp($detail['ip']);
$compute->setStatus('down');
}
$this->em->persist($compute);
$list[] = $compute;
}
$this->em->flush();
return $list;
}
public function detail(Compute $compute)
{
$c = explode("|",$compute->getInstanceId());
$detail = $this->ovhClient->get('/dedicated/server/' . $c[1]);
$compute->setStatus($detail['state'] == "ok"?"RUNNING":"DOWN");
$compute->name = $c[1];
$compute->type = $c[0];
return $compute;
}
}

View File

@@ -155,6 +155,187 @@
</div>
{% else %}
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800">
<p class="text-sm text-gray-500 dark:text-gray-400">CA En Cours</p>
<p class="text-2xl font-bold text-green-500">45 230 €</p>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800">
<p class="text-sm text-gray-500 dark:text-gray-400">CA Prévu</p>
<p class="text-2xl font-bold text-blue-400">62 500 €</p>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800">
<p class="text-sm text-gray-500 dark:text-gray-400">Total Impayés</p>
<p class="text-2xl font-bold text-red-500">8 120 €</p>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800 border-l-4 border-yellow-500">
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Écart / Objectif Prévu</p>
<p class="text-2xl font-bold text-yellow-500">
- 17 270 €
</p>
<p class="text-xs text-gray-400 dark:text-gray-500 mt-1">
(Reste à atteindre ce mois)
</p>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100">
<h2 class="text-xl font-semibold mb-4">🔔 Domaines à Renouveler</h2>
<ul class="space-y-2">
<li class="flex justify-between text-sm">
<span>mondomaine.com</span>
<span class="text-red-500 font-medium">J-7</span>
</li>
<li class="flex justify-between text-sm">
<span>autre-site.fr</span>
<span class="text-orange-400 font-medium">J-30</span>
</li>
</ul>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800">
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">📑 Factures à Valider</h2>
<div class="border-l-4 border-yellow-500 bg-yellow-50 dark:bg-yellow-900/50 p-3">
<p class="text-sm font-medium text-gray-900 dark:text-yellow-100">Facture #2025-001 (Client A)</p>
<p class="text-xs text-gray-600 dark:text-gray-300">Montant : 1 200 € - En attente</p>
</div>
</div>
</div>
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-4 mb-6">
<div class="flex flex-col items-center p-3 rounded-lg shadow-md bg-white dark:bg-gray-800 border-l-4 border-green-500">
<span class="text-sm font-semibold text-gray-900 dark:text-white truncate w-full text-center">WEB-PROD-01</span>
<span class="mt-1 px-2 text-xs font-bold text-white bg-green-500 rounded">OK</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg shadow-md bg-white dark:bg-gray-800 border-l-4 border-yellow-500">
<span class="text-sm font-semibold text-gray-900 dark:text-white truncate w-full text-center">DB-MAIN-02</span>
<span class="mt-1 px-2 text-xs font-bold text-gray-900 bg-yellow-500 rounded">ALERTE</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg shadow-md bg-white dark:bg-gray-800 border-l-4 border-red-500">
<span class="text-sm font-semibold text-gray-900 dark:text-white truncate w-full text-center">STAGING-03</span>
<span class="mt-1 px-2 text-xs font-bold text-white bg-red-500 rounded">DOWN</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg shadow-md bg-white dark:bg-gray-800 border-l-4 border-green-500">
<span class="text-sm font-semibold text-gray-900 dark:text-white truncate w-full text-center">MAIL-04</span>
<span class="mt-1 px-2 text-xs font-bold text-white bg-green-500 rounded">OK</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg shadow-md bg-white dark:bg-gray-800 border-l-4 border-orange-500">
<span class="text-sm font-semibold text-gray-900 dark:text-white truncate w-full text-center">BACKUP-05</span>
<span class="mt-1 px-2 text-xs font-bold text-white bg-orange-500 rounded">LATENCE</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg shadow-md bg-white dark:bg-gray-800 border-l-4 border-green-500">
<span class="text-sm font-semibold text-gray-900 dark:text-white truncate w-full text-center">DEV-TEST</span>
<span class="mt-1 px-2 text-xs font-bold text-white bg-green-500 rounded">OK</span>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800 border-l-4 border-orange-500">
<div class="flex justify-between items-start">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Ratio Coût Infra / CA</p>
<p class="text-2xl font-bold text-orange-500 mt-1">28.5%</p>
</div>
<div class="text-right">
<p class="text-sm text-red-500 font-semibold flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18"></path></svg>
+0.8 pt
</p>
<p class="text-xs text-gray-400 dark:text-gray-500">vs Mois Précédent</p>
</div>
</div>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800 border-l-4 border-teal-500">
<div class="flex justify-between items-start">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Ratio Coût Salarial / CA</p>
<p class="text-2xl font-bold text-teal-500 mt-1">35.0%</p>
</div>
<div class="text-right">
<p class="text-sm text-green-500 font-semibold flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path></svg>
-0.5 pt
</p>
<p class="text-xs text-gray-400 dark:text-gray-500">vs Mois Précédent</p>
</div>
</div>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800">
<div class="flex justify-between items-start">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Coût Google Cloud (Mois)</p>
<p class="text-2xl font-bold text-blue-500 mt-1">1 850,00 €</p>
</div>
<div class="text-right">
<p class="text-sm text-red-500 font-semibold flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18"></path></svg>
+3.5%
</p>
<p class="text-xs text-gray-400 dark:text-gray-500">vs Mois Précédent</p>
</div>
</div>
</div>
<div class="p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800">
<div class="flex justify-between items-start">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Coût OVH (Mois)</p>
<p class="text-2xl font-bold text-purple-500 mt-1">425,50 €</p>
</div>
<div class="text-right">
<p class="text-sm text-green-500 font-semibold flex items-center">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path></svg>
-1.2%
</p>
<p class="text-xs text-gray-400 dark:text-gray-500">vs Mois Précédent</p>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
<div class="md:col-span-2 p-6 rounded-lg shadow-xl bg-white dark:bg-gray-800 border-l-4 border-green-500">
<div class="flex justify-between items-center">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Statut de Rentabilité Globale</p>
<p class="text-3xl font-bold text-green-500 mt-1">
🟢 RENTRABLE
</p>
</div>
<div class="text-right">
<p class="text-sm text-gray-600 dark:text-gray-400">Total Coûts / CA :</p>
<p class="text-xl font-bold text-green-500">63.5%</p>
</div>
</div>
<p class="text-xs text-gray-400 dark:text-gray-500 mt-3">
(Coût Infra 28.5% + Coût Salarial 35.0%)
</p>
</div>
<div class="md:col-span-2">
</div>
</div>
{% endif %}
{# PETIT SCRIPT JAVASCRIPT POUR FAIRE FONCTIONNER LES ONGLETS #}

View File

@@ -6,7 +6,7 @@
<div class="flex justify-between items-center mb-6">
<h2 class="text-3xl font-semibold text-gray-800 dark:text-gray-200">Liste des Serveurs</h2>
<div>
<a h class="px-4 py-2 bg-blue-600 text-white font-medium rounded-md shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900">
<a href="" class="px-4 py-2 bg-blue-600 text-white font-medium rounded-md shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900">
+ Ajouter un nouveau serveur
</a>
</div>